Compare commits
263 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ef84054dc | ||
|
|
7db1c9b8eb | ||
|
|
ae06a6ce41 | ||
|
|
0316450ee2 | ||
|
|
281305147b | ||
|
|
ef41e32af5 | ||
|
|
4ef8172f8d | ||
|
|
5106f9f958 | ||
|
|
2c61d8d94b | ||
|
|
bc8c8c1bb9 | ||
|
|
cbc08eb96d | ||
|
|
f4de65a647 | ||
|
|
0f42f18100 | ||
|
|
a9d9dc6658 | ||
|
|
07cd6a8b88 | ||
|
|
ab62690b97 | ||
|
|
e7a3ee477d | ||
|
|
1ec06f4bf0 | ||
|
|
849f93375c | ||
|
|
35ba6cef4e | ||
|
|
b0d63dae16 | ||
|
|
14d394aed8 | ||
|
|
50fea44ce2 | ||
|
|
98004c2328 | ||
|
|
eb7dda85a1 | ||
|
|
2f994b1227 | ||
|
|
a9bdde193d | ||
|
|
2ffef3bdda | ||
|
|
77b789e26a | ||
|
|
031f2dfeb8 | ||
|
|
cb0eef9edd | ||
|
|
8be85de6ef | ||
|
|
9cf7f2b83d | ||
|
|
95667ef98e | ||
|
|
b211ce02a8 | ||
|
|
739298c782 | ||
|
|
a1da6bff1a | ||
|
|
18a81d7ca0 | ||
|
|
6f15903019 | ||
|
|
a26f7a1292 | ||
|
|
ae8c5287e4 | ||
|
|
fd10362bef | ||
|
|
3af6cc53d1 | ||
|
|
54bb5f1879 | ||
|
|
13e3375e8a | ||
|
|
37157dc9e2 | ||
|
|
8fe3dce649 | ||
|
|
4ec4c45a90 | ||
|
|
19f46ed4f0 | ||
|
|
0e9509ae9b | ||
|
|
618dedc58e | ||
|
|
623b7a8d6f | ||
|
|
7c76f124bf | ||
|
|
f5973e0eee | ||
|
|
32634356a6 | ||
|
|
6d0a07a4cd | ||
|
|
e0b829f92f | ||
|
|
684572bd05 | ||
|
|
334eb5d423 | ||
|
|
bcbdaaa6ea | ||
|
|
986939e501 | ||
|
|
d416fd8c0f | ||
|
|
78119df2db | ||
|
|
e2e04e3f16 | ||
|
|
d37468975c | ||
|
|
589f77ef0e | ||
|
|
1e2d88cd5d | ||
|
|
da4425b5c0 | ||
|
|
0d7cb63978 | ||
|
|
2248560699 | ||
|
|
3daae94bca | ||
|
|
7299b76faf | ||
|
|
673dc6e873 | ||
|
|
9c544c0a4b | ||
|
|
8502ecc6d2 | ||
|
|
74b5638d99 | ||
|
|
e8de8735e2 | ||
|
|
dbcd19418c | ||
|
|
a10f040df6 | ||
|
|
88a7ff891c | ||
|
|
2b4db6c3bf | ||
|
|
4ddc426966 | ||
|
|
309ce43e05 | ||
|
|
61470c0d24 | ||
|
|
2301732e2d | ||
|
|
24ee8eb16a | ||
|
|
57065bb274 | ||
|
|
4ab4aa04da | ||
|
|
0ed39dad63 | ||
|
|
08531ee675 | ||
|
|
e7140ffec7 | ||
|
|
c58c4b7938 | ||
|
|
4e276471e5 | ||
|
|
c5eac63da1 | ||
|
|
866c6d0cf9 | ||
|
|
165294bfb1 | ||
|
|
2d5f0479bd | ||
|
|
e8068cf5ac | ||
|
|
d0171cf386 | ||
|
|
3ae99ea0b9 | ||
|
|
4e9450f200 | ||
|
|
dc2c49f4a9 | ||
|
|
c461e8b63c | ||
|
|
f47bc1163b | ||
|
|
851be2d76e | ||
|
|
63034e6cba | ||
|
|
84b9c5f5fd | ||
|
|
43c8fc6847 | ||
|
|
bc60bd23b2 | ||
|
|
e29120a9c1 | ||
|
|
d383230532 | ||
|
|
9a46896600 | ||
|
|
fba086134d | ||
|
|
2973364c02 | ||
|
|
542bb7caed | ||
|
|
fb47b6ae21 | ||
|
|
aeb301c8d5 | ||
|
|
704e14f008 | ||
|
|
d1050d6b02 | ||
|
|
afc96808e8 | ||
|
|
dc2bae4ae1 | ||
|
|
1d7da21e48 | ||
|
|
affd965d5d | ||
|
|
989161159d | ||
|
|
59a74153dc | ||
|
|
6690c269ef | ||
|
|
b7fd10b905 | ||
|
|
08e1cf1b7e | ||
|
|
54d891afa7 | ||
|
|
ae41782cd4 | ||
|
|
8591fe00b6 | ||
|
|
92f58cb3c1 | ||
|
|
4ad98ca505 | ||
|
|
b9374bde6b | ||
|
|
1ff29384b3 | ||
|
|
4fc714ff10 | ||
|
|
51f0c8a388 | ||
|
|
d01a65f73d | ||
|
|
65239f9ffe | ||
|
|
e5cefcce70 | ||
|
|
8002b5ec6a | ||
|
|
a575f5cc77 | ||
|
|
ab3a80e076 | ||
|
|
dda3798ba9 | ||
|
|
e6f906b9ca | ||
|
|
d74e43ddcc | ||
|
|
23ddce122b | ||
|
|
814bd26c07 | ||
|
|
2e4b39c19c | ||
|
|
3ee65748bb | ||
|
|
5f387737a1 | ||
|
|
4fa800b87a | ||
|
|
9338b3cf94 | ||
|
|
45e09af692 | ||
|
|
9d32f48ab8 | ||
|
|
290e7baead | ||
|
|
e780ae00d0 | ||
|
|
9ea224412d | ||
|
|
cd8ae07698 | ||
|
|
433a73e13d | ||
|
|
1e558f4da6 | ||
|
|
aef6e33c91 | ||
|
|
acd83ede2f | ||
|
|
bd51613e62 | ||
|
|
246cb39003 | ||
|
|
3b54c527b6 | ||
|
|
18368fefaa | ||
|
|
c361e1e31a | ||
|
|
e3d4152e32 | ||
|
|
d861ba1876 | ||
|
|
c942017b73 | ||
|
|
743d12e326 | ||
|
|
d371a3d5fd | ||
|
|
e1056126e6 | ||
|
|
72c267fbf3 | ||
|
|
0ed85b9d25 | ||
|
|
a8877d82b6 | ||
|
|
8896b0adf3 | ||
|
|
60b14e9b45 | ||
|
|
631e853b40 | ||
|
|
b409c8cc2f | ||
|
|
905212b109 | ||
|
|
05b7df26e6 | ||
|
|
1268afd3f8 | ||
|
|
c1b9b7a623 | ||
|
|
0b9160fb75 | ||
|
|
93c9419392 | ||
|
|
6121bcf171 | ||
|
|
702144180c | ||
|
|
d2b2f98941 | ||
|
|
ec95956e25 | ||
|
|
d6d7ce1b67 | ||
|
|
4cb36b0a5d | ||
|
|
2b3aea76a9 | ||
|
|
f50a31b4e8 | ||
|
|
b226c3aca3 | ||
|
|
4979666a89 | ||
|
|
c9636f85b9 | ||
|
|
436bc87a86 | ||
|
|
e89c2b242d | ||
|
|
02b26a65bb | ||
|
|
6a3e4bb59f | ||
|
|
b01ad360da | ||
|
|
c7f3740099 | ||
|
|
554595acd7 | ||
|
|
ee4ddd5446 | ||
|
|
ebab617a12 | ||
|
|
bc5d92a452 | ||
|
|
2f388dfb6a | ||
|
|
73a0197eb2 | ||
|
|
b6990e9e5d | ||
|
|
26e119bfc2 | ||
|
|
9f866ae608 | ||
|
|
023359b9d2 | ||
|
|
2128d047e1 | ||
|
|
a89349c5b9 | ||
|
|
d109b8beb6 | ||
|
|
9b40572921 | ||
|
|
aaf7a38cce | ||
|
|
1ed0759a50 | ||
|
|
213b73da6e | ||
|
|
5b6985fc5c | ||
|
|
538af01bf5 | ||
|
|
92d0589a37 | ||
|
|
f3269070b2 | ||
|
|
d93bd3eda7 | ||
|
|
0dbbc5d8b6 | ||
|
|
08efd5ecab | ||
|
|
dba1bcb0e3 | ||
|
|
348403abff | ||
|
|
c290cf45b7 | ||
|
|
175c8e6e50 | ||
|
|
f90667b23c | ||
|
|
cf69d591e4 | ||
|
|
e599491583 | ||
|
|
d1520773cf | ||
|
|
573ca97b6c | ||
|
|
0d97f14a1a | ||
|
|
b8f28abfdf | ||
|
|
9ac7c97e67 | ||
|
|
52b3eaacb5 | ||
|
|
9b01ae6db9 | ||
|
|
469487ad36 | ||
|
|
176c3c1601 | ||
|
|
94391234cc | ||
|
|
d84901f196 | ||
|
|
c6b117565d | ||
|
|
2a9124acb5 | ||
|
|
401a783d6a | ||
|
|
39483a30b6 | ||
|
|
0e2a07f8d7 | ||
|
|
36f5b0218d | ||
|
|
a1b3c56de7 | ||
|
|
6d664f133e | ||
|
|
732a433ec1 | ||
|
|
f7dcd1ba2c | ||
|
|
55a8b44224 | ||
|
|
e29db31d91 | ||
|
|
183d3c3ca4 | ||
|
|
c57e713696 | ||
|
|
4519f26adf | ||
|
|
c26f9cc01f | ||
|
|
f6f730b994 |
21
.flowconfig
@@ -19,6 +19,7 @@
|
||||
.*/node_modules/babel-core/.*
|
||||
.*/node_modules/bower/.*
|
||||
.*/node_modules/jsonlint/.*
|
||||
.*/node_modules/styled-components/.*
|
||||
|
||||
[include]
|
||||
|
||||
@@ -28,6 +29,8 @@ node_modules/react-native/flow
|
||||
flow/
|
||||
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
module.system=haste
|
||||
|
||||
experimental.strict_type_args=true
|
||||
@@ -40,11 +43,23 @@ suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-7]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-7]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-8]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-8]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
unsafe.enable_getters_and_setters=true
|
||||
|
||||
; We (i.e. the jitsi-meet project) are using the haste module system on Web as
|
||||
; well, not only on React Native. Unfortunately, Flow does not support .web.js
|
||||
; by default. Override Flow's defaults to include .web.js as well. Technically,
|
||||
; we have .native.js as well so the choice of .web.js may lead to errors.
|
||||
; Practically though, it is a potential future problem that we do not have at
|
||||
; the time of this writing.
|
||||
module.file_ext=.web.js
|
||||
; Flow's defaults:
|
||||
module.file_ext=.js
|
||||
module.file_ext=.jsx
|
||||
module.file_ext=.json
|
||||
|
||||
[version]
|
||||
^0.37.0
|
||||
^0.38.0
|
||||
|
||||
1
.gitignore
vendored
@@ -53,7 +53,6 @@ yarn-error.log
|
||||
#
|
||||
buck-out/
|
||||
\.buckd/
|
||||
android/app/libs
|
||||
*.keystore
|
||||
|
||||
# fastlane
|
||||
|
||||
@@ -5,8 +5,14 @@ debian/
|
||||
libs/
|
||||
node_modules/
|
||||
|
||||
# The following are checked by ESLint which supersedes JSHint.
|
||||
# The following are checked by ESLint with the maximum configuration which
|
||||
# supersedes JSHint.
|
||||
flow-typed/
|
||||
react/
|
||||
|
||||
# The following are checked by ESLint with the minimum configuration which does
|
||||
# not supersede JSHint but take advantage of advanced language features such as
|
||||
# Facebook Flow which are not supported by JSHint.
|
||||
modules/translation/translation.js
|
||||
|
||||
analytics.js
|
||||
|
||||
33
CONTRIBUTING.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# How to contribute
|
||||
We would love to have your help. Before you start working however, please read
|
||||
and follow this short guide.
|
||||
|
||||
# Reporting Issues
|
||||
Before you open an issue on GitHub, please discuss it on one of our
|
||||
[mailing lists](https://jitsi.org/Development/MailingLists) and wait for
|
||||
confirmation from one of the committers. Once you have that confirmation,
|
||||
please proceed to reporting the issue on GitHub, while providing as much
|
||||
information as possible. Mention the version of Jitsi Meet, Jicofo and JVB
|
||||
you are using, and explain (as detailed as you can) how the problem can
|
||||
be reproduced.
|
||||
|
||||
# Code contributions
|
||||
Found a bug and know how to fix it? Great! Please read on.
|
||||
|
||||
## Contributor License Agreement
|
||||
While the Jitsi projects are released under the
|
||||
[Apache License 2.0](https://github.com/jitsi/jitsi-meet/blob/master/LICENSE), the copyright
|
||||
holder and principal creator is [Atlassian](https://www.atlassian.com/). To
|
||||
ensure that we can continue making these projects available under an Open Source license,
|
||||
we need you to sign our Apache-based contributor
|
||||
license agreement as either a [corporation](https://jitsi.org/ccla) or an
|
||||
[individual](https://jitsi.org/icla). If you cannot accept the terms laid out
|
||||
in the agreement, unfortunately, we cannot accept your contribution.
|
||||
|
||||
## Creating Pull Requests
|
||||
- Make sure your code passes the linter rules beforehand. The linter is exeuted
|
||||
automatically when committing code.
|
||||
- Perform **one** logical change per pull request.
|
||||
- Maintain a clean list of commits, squash them if necessary.
|
||||
- Rebase your topic branch on top of the master branch before creating the pull
|
||||
request.
|
||||
@@ -2,3 +2,10 @@
|
||||
* Notifies interested parties that hangup procedure will start.
|
||||
*/
|
||||
export const BEFORE_HANGUP = "conference.before_hangup";
|
||||
|
||||
/**
|
||||
* Notifies interested parties that desktop sharing enable/disable state is
|
||||
* changed.
|
||||
*/
|
||||
export const DESKTOP_SHARING_ENABLED_CHANGED
|
||||
= "conference.desktop_sharing_enabled_changed";
|
||||
|
||||
12
Makefile
@@ -10,13 +10,7 @@ STYLES_DESTINATION = css/all.css
|
||||
STYLES_MAIN = css/main.scss
|
||||
WEBPACK = ./node_modules/.bin/webpack
|
||||
|
||||
all: update-deps compile deploy clean
|
||||
|
||||
# FIXME: there is a problem with node-sass not correctly installed (compiled)
|
||||
# a quick fix to make sure it is installed on every update
|
||||
# the problem appears on linux and not on macosx
|
||||
update-deps:
|
||||
$(NPM) update && $(NPM) install node-sass
|
||||
all: compile deploy clean
|
||||
|
||||
compile:
|
||||
$(WEBPACK) -p
|
||||
@@ -33,6 +27,8 @@ deploy-appbundle:
|
||||
cp \
|
||||
$(BUILD_DIR)/app.bundle.min.js \
|
||||
$(BUILD_DIR)/app.bundle.min.map \
|
||||
$(BUILD_DIR)/do_external_connect.min.js \
|
||||
$(BUILD_DIR)/do_external_connect.min.map \
|
||||
$(BUILD_DIR)/external_api.min.js \
|
||||
$(BUILD_DIR)/external_api.min.map \
|
||||
$(OUTPUT_DIR)/analytics.js \
|
||||
@@ -55,7 +51,7 @@ deploy-local:
|
||||
|
||||
source-package:
|
||||
mkdir -p source_package/jitsi-meet/css && \
|
||||
cp -r *.js *.html connection_optimization favicon.ico fonts images libs sounds LICENSE lang source_package/jitsi-meet && \
|
||||
cp -r *.js *.html connection_optimization favicon.ico fonts images libs static sounds LICENSE lang source_package/jitsi-meet && \
|
||||
cp css/all.css source_package/jitsi-meet/css && \
|
||||
(cd source_package ; tar cjf ../jitsi-meet.tar.bz2 jitsi-meet) && \
|
||||
rm -rf source_package
|
||||
|
||||
11
README.md
@@ -19,9 +19,11 @@ You can download Debian/Ubuntu binaries:
|
||||
* [testing](https://download.jitsi.org/testing/) ([instructions](https://jitsi.org/Main/InstallJitsiMeetDebianTestingRepository))
|
||||
* [nightly](https://download.jitsi.org/unstable/) ([instructions](https://jitsi.org/Main/InstallJitsiMeetDebianNightlyRepository))
|
||||
|
||||
## Building the sources
|
||||
You can get our mobile versions from here:
|
||||
* [Android](https://play.google.com/store/apps/details?id=org.jitsi.meet)
|
||||
* [iOS](https://itunes.apple.com/us/app/jitsi-meet/id1165103905)
|
||||
|
||||
Jitsi Meet uses [Browserify](http://browserify.org). If you want to make changes in the code you need to [install Browserify](http://browserify.org/#install). Browserify requires [nodejs](http://nodejs.org).
|
||||
## Building the sources
|
||||
|
||||
On Debian/Ubuntu systems, the required packages can be installed with:
|
||||
```
|
||||
@@ -82,6 +84,11 @@ npm unlink lib-jitsi-meet
|
||||
npm install
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
If you are looking to contribute to Jitsi Meet, first of all, thank you! Please
|
||||
see our [guidelines for contributing](CONTRIBUTING.md).
|
||||
|
||||
## Embedding in external applications
|
||||
|
||||
Jitsi Meet provides a very flexible way of embedding it in external applications by using the [Jitsi Meet API](doc/api.md).
|
||||
|
||||
@@ -91,7 +91,7 @@ android {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode Integer.parseInt("${version}")
|
||||
versionName "1.2.${version}"
|
||||
versionName "1.4.${version}"
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'x86'
|
||||
}
|
||||
@@ -139,6 +139,7 @@ if (project.hasProperty('JITSI_SIGNING')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-background-timer')
|
||||
compile project(':react-native-immersive')
|
||||
compile project(':react-native-keep-awake')
|
||||
compile project(':react-native-vector-icons')
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus"/>
|
||||
@@ -29,7 +30,8 @@
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:name=".MainActivity">
|
||||
android:name=".MainActivity"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
@@ -29,9 +29,11 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.oblador.vectoricons.VectorIconsPackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new org.jitsi.meet.audiomode.AudioModePackage()
|
||||
new org.jitsi.meet.audiomode.AudioModePackage(),
|
||||
new org.jitsi.meet.proximity.ProximityPackage()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.jitsi.meet.proximity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
|
||||
/**
|
||||
* Module implementing a simple API to enable a proximity sensor-controlled
|
||||
* wake lock. When the lock is held, if the proximity sensor detects a nearby
|
||||
* object it will dim the screen and disable touch controls. The functionality
|
||||
* is used with the conference audio-only mode.
|
||||
*/
|
||||
public class ProximityModule extends ReactContextBaseJavaModule {
|
||||
/**
|
||||
* React Native module name.
|
||||
*/
|
||||
private static final String MODULE_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.
|
||||
*/
|
||||
private final WakeLock wakeLock;
|
||||
|
||||
/**
|
||||
* Initializes a new module instance. There shall be a single instance of
|
||||
* this module throughout the lifetime of the application.
|
||||
*
|
||||
* @param reactContext The {@link ReactApplicationContext} where this module
|
||||
* is created.
|
||||
*/
|
||||
public ProximityModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
|
||||
WakeLock wakeLock;
|
||||
PowerManager powerManager
|
||||
= (PowerManager)
|
||||
reactContext.getSystemService(Context.POWER_SERVICE);
|
||||
|
||||
try {
|
||||
wakeLock
|
||||
= powerManager.newWakeLock(
|
||||
PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
||||
MODULE_NAME);
|
||||
} catch (Throwable ignored) {
|
||||
wakeLock = null;
|
||||
}
|
||||
|
||||
this.wakeLock = wakeLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this module to be used in the React Native bridge.
|
||||
*
|
||||
* @return The name of this module to be used in the React Native bridge.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return MODULE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires / releases the proximity sensor wake lock.
|
||||
*
|
||||
* @param enabled {@code true} to enable the proximity sensor; otherwise,
|
||||
* {@code false}.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void setEnabled(final boolean enabled) {
|
||||
if (wakeLock == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (enabled) {
|
||||
if (!wakeLock.isHeld()) {
|
||||
wakeLock.acquire();
|
||||
}
|
||||
} else if (wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.jitsi.meet.proximity;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implements {@link ReactPackage} for {@link ProximityModule}.
|
||||
*/
|
||||
public class ProximityPackage implements ReactPackage {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<Class<? extends JavaScriptModule>> createJSModules() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return List of native modules to be exposed by React Native.
|
||||
*/
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(
|
||||
ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
|
||||
modules.add(new ProximityModule(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(
|
||||
ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 38 KiB |
@@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
rootProject.name = 'jitsi-meet-react'
|
||||
|
||||
include ':app'
|
||||
include ':react-native-background-timer'
|
||||
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-keep-awake'
|
||||
|
||||
1
app.js
@@ -1,6 +1,5 @@
|
||||
/* application specific logic */
|
||||
|
||||
import "babel-polyfill";
|
||||
import "jquery";
|
||||
import "jquery-contextmenu";
|
||||
import "jquery-ui";
|
||||
|
||||
491
conference.js
@@ -20,6 +20,36 @@ import analytics from './modules/analytics/analytics';
|
||||
|
||||
import EventEmitter from "events";
|
||||
|
||||
import { showDesktopSharingButton } from './react/features/toolbox';
|
||||
|
||||
import {
|
||||
AVATAR_ID_COMMAND,
|
||||
AVATAR_URL_COMMAND,
|
||||
conferenceFailed,
|
||||
conferenceJoined,
|
||||
conferenceLeft,
|
||||
EMAIL_COMMAND
|
||||
} from './react/features/base/conference';
|
||||
import {
|
||||
updateDeviceList
|
||||
} from './react/features/base/devices';
|
||||
import {
|
||||
isFatalJitsiConnectionError
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import {
|
||||
participantJoined,
|
||||
participantLeft,
|
||||
participantRoleChanged,
|
||||
participantUpdated
|
||||
} from './react/features/base/participants';
|
||||
import {
|
||||
showDesktopPicker
|
||||
} from './react/features/desktop-picker';
|
||||
import {
|
||||
mediaPermissionPromptVisibilityChanged,
|
||||
suspendDetected
|
||||
} from './react/features/overlay';
|
||||
|
||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
|
||||
@@ -33,7 +63,10 @@ const ConnectionQualityEvents = JitsiMeetJS.events.connectionQuality;
|
||||
|
||||
const eventEmitter = new EventEmitter();
|
||||
|
||||
let room, connection, localAudio, localVideo;
|
||||
let room;
|
||||
let connection;
|
||||
let localAudio, localVideo;
|
||||
let initialAudioMutedState = false, initialVideoMutedState = false;
|
||||
|
||||
/**
|
||||
* Indicates whether extension external installation is in progress or not.
|
||||
@@ -42,16 +75,26 @@ let DSExternalInstallationInProgress = false;
|
||||
|
||||
import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/VideoContainer";
|
||||
|
||||
/*
|
||||
* Logic to open a desktop picker put on the window global for
|
||||
* lib-jitsi-meet to detect and invoke
|
||||
*/
|
||||
window.JitsiMeetScreenObtainer = {
|
||||
openDesktopPicker(onSourceChoose) {
|
||||
APP.store.dispatch(showDesktopPicker(onSourceChoose));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Known custom conference commands.
|
||||
*/
|
||||
const commands = {
|
||||
EMAIL: "email",
|
||||
AVATAR_URL: "avatar-url",
|
||||
AVATAR_ID: "avatar-id",
|
||||
AVATAR_ID: AVATAR_ID_COMMAND,
|
||||
AVATAR_URL: AVATAR_URL_COMMAND,
|
||||
CUSTOM_ROLE: "custom-role",
|
||||
EMAIL: EMAIL_COMMAND,
|
||||
ETHERPAD: "etherpad",
|
||||
SHARED_VIDEO: "shared-video",
|
||||
CUSTOM_ROLE: "custom-role"
|
||||
SHARED_VIDEO: "shared-video"
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -91,7 +134,10 @@ function createInitialLocalTracksAndConnect(roomName) {
|
||||
|
||||
JitsiMeetJS.mediaDevices.addEventListener(
|
||||
JitsiMeetJS.events.mediaDevices.PERMISSION_PROMPT_IS_SHOWN,
|
||||
browser => APP.UI.showUserMediaPermissionsGuidanceOverlay(browser));
|
||||
browser =>
|
||||
APP.store.dispatch(
|
||||
mediaPermissionPromptVisibilityChanged(true, browser))
|
||||
);
|
||||
|
||||
// First try to retrieve both audio and video.
|
||||
let tryCreateLocalTracks = createLocalTracks(
|
||||
@@ -109,8 +155,7 @@ function createInitialLocalTracksAndConnect(roomName) {
|
||||
|
||||
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
|
||||
.then(([tracks, con]) => {
|
||||
APP.UI.hideUserMediaPermissionsGuidanceOverlay();
|
||||
|
||||
APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false));
|
||||
if (audioAndVideoError) {
|
||||
if (audioOnlyError) {
|
||||
// If both requests for 'audio' + 'video' and 'audio' only
|
||||
@@ -134,17 +179,44 @@ function createInitialLocalTracksAndConnect(roomName) {
|
||||
* @param command the command
|
||||
* @param {string} value new value
|
||||
*/
|
||||
function sendData (command, value) {
|
||||
function sendData(command, value) {
|
||||
if(!room) {
|
||||
return;
|
||||
}
|
||||
|
||||
room.removeCommand(command);
|
||||
room.sendCommand(command, {value: value});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up initially the properties of the local participant - email, avatarID,
|
||||
* avatarURL, displayName, etc.
|
||||
*/
|
||||
function _setupLocalParticipantProperties() {
|
||||
const email = APP.settings.getEmail();
|
||||
email && sendData(commands.EMAIL, email);
|
||||
|
||||
const avatarUrl = APP.settings.getAvatarUrl();
|
||||
avatarUrl && sendData(commands.AVATAR_URL, avatarUrl);
|
||||
|
||||
if (!email && !avatarUrl) {
|
||||
sendData(commands.AVATAR_ID, APP.settings.getAvatarId());
|
||||
}
|
||||
|
||||
let nick = APP.settings.getDisplayName();
|
||||
if (config.useNicks && !nick) {
|
||||
nick = APP.UI.askForNickname();
|
||||
APP.settings.setDisplayName(nick);
|
||||
}
|
||||
nick && room.setDisplayName(nick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user nickname by user id.
|
||||
* @param {string} id user id
|
||||
* @returns {string?} user nickname or undefined if user is unknown.
|
||||
*/
|
||||
function getDisplayName (id) {
|
||||
function getDisplayName(id) {
|
||||
if (APP.conference.isLocalId(id)) {
|
||||
return APP.settings.getDisplayName();
|
||||
}
|
||||
@@ -161,7 +233,7 @@ function getDisplayName (id) {
|
||||
* @param {boolean} userInteraction - indicates if this local audio mute was a
|
||||
* result of user interaction
|
||||
*/
|
||||
function muteLocalAudio (muted) {
|
||||
function muteLocalAudio(muted) {
|
||||
muteLocalMedia(localAudio, muted, 'Audio');
|
||||
}
|
||||
|
||||
@@ -181,7 +253,7 @@ function muteLocalMedia(localMedia, muted, localMediaTypeString) {
|
||||
* Mute or unmute local video stream if it exists.
|
||||
* @param {boolean} muted if video stream should be muted or unmuted.
|
||||
*/
|
||||
function muteLocalVideo (muted) {
|
||||
function muteLocalVideo(muted) {
|
||||
muteLocalMedia(localVideo, muted, 'Video');
|
||||
}
|
||||
|
||||
@@ -203,8 +275,8 @@ function maybeRedirectToWelcomePage(options) {
|
||||
// save whether current user is guest or not, before navigating
|
||||
// to close page
|
||||
window.sessionStorage.setItem('guest', APP.tokenData.isGuest);
|
||||
assignWindowLocationPathname(
|
||||
options.feedbackSubmitted ? "close.html" : "close2.html");
|
||||
assignWindowLocationPathname('static/'
|
||||
+ (options.feedbackSubmitted ? "close.html" : "close2.html"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -266,7 +338,7 @@ function assignWindowLocationPathname(pathname) {
|
||||
* for gUM permission prompt
|
||||
* @returns {Promise<JitsiLocalTrack[]>}
|
||||
*/
|
||||
function createLocalTracks (options, checkForPermissionPrompt) {
|
||||
function createLocalTracks(options, checkForPermissionPrompt) {
|
||||
options || (options = {});
|
||||
|
||||
return JitsiMeetJS
|
||||
@@ -299,23 +371,6 @@ function createLocalTracks (options, checkForPermissionPrompt) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the display name for the local user
|
||||
* @param nickname {string} the new display name
|
||||
*/
|
||||
function changeLocalDisplayName(nickname = '') {
|
||||
const formattedNickname
|
||||
= nickname.trim().substr(0, MAX_DISPLAY_NAME_LENGTH);
|
||||
|
||||
if (formattedNickname === APP.settings.getDisplayName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
APP.settings.setDisplayName(formattedNickname);
|
||||
room.setDisplayName(formattedNickname);
|
||||
APP.UI.changeDisplayName(APP.conference.getMyUserId(), formattedNickname);
|
||||
}
|
||||
|
||||
class ConferenceConnector {
|
||||
constructor(resolve, reject, invite) {
|
||||
this._resolve = resolve;
|
||||
@@ -334,13 +389,10 @@ class ConferenceConnector {
|
||||
this._reject(err);
|
||||
}
|
||||
_onConferenceFailed(err, ...params) {
|
||||
APP.store.dispatch(conferenceFailed(room, err, ...params));
|
||||
logger.error('CONFERENCE FAILED:', err, ...params);
|
||||
APP.UI.hideRingOverLay();
|
||||
switch (err) {
|
||||
// room is locked by the password
|
||||
case ConferenceErrors.PASSWORD_REQUIRED:
|
||||
APP.UI.emitEvent(UIEvents.PASSWORD_REQUIRED);
|
||||
break;
|
||||
|
||||
case ConferenceErrors.CONNECTION_ERROR:
|
||||
{
|
||||
@@ -352,7 +404,7 @@ class ConferenceConnector {
|
||||
case ConferenceErrors.NOT_ALLOWED_ERROR:
|
||||
{
|
||||
// let's show some auth not allowed page
|
||||
assignWindowLocationPathname('authError.html');
|
||||
assignWindowLocationPathname('static/authError.html');
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -408,8 +460,6 @@ class ConferenceConnector {
|
||||
// the app. Both the errors above are unrecoverable from the library
|
||||
// perspective.
|
||||
room.leave().then(() => connection.disconnect());
|
||||
APP.UI.showPageReloadOverlay(
|
||||
false /* not a network type of failure */, err);
|
||||
break;
|
||||
|
||||
case ConferenceErrors.CONFERENCE_MAX_USERS:
|
||||
@@ -466,6 +516,23 @@ function disconnect() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
|
||||
*
|
||||
* @param {JitsiMeetJS.connection.error} error - The reported error.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function _connectionFailedHandler(error) {
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
APP.connection.removeEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED,
|
||||
_connectionFailedHandler);
|
||||
if (room)
|
||||
room.leave();
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
isModerator: false,
|
||||
audioMuted: false,
|
||||
@@ -517,12 +584,26 @@ export default {
|
||||
analytics.init();
|
||||
return createInitialLocalTracksAndConnect(options.roomName);
|
||||
}).then(([tracks, con]) => {
|
||||
tracks.forEach(track => {
|
||||
if((track.isAudioTrack() && initialAudioMutedState)
|
||||
|| (track.isVideoTrack() && initialVideoMutedState)) {
|
||||
track.mute();
|
||||
}
|
||||
});
|
||||
logger.log('initialized with %s local tracks', tracks.length);
|
||||
con.addEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED,
|
||||
_connectionFailedHandler);
|
||||
APP.connection = connection = con;
|
||||
this.isDesktopSharingEnabled =
|
||||
JitsiMeetJS.isDesktopSharingEnabled();
|
||||
eventEmitter.emit(
|
||||
JitsiMeetConferenceEvents.DESKTOP_SHARING_ENABLED_CHANGED,
|
||||
this.isDesktopSharingEnabled);
|
||||
|
||||
APP.store.dispatch(showDesktopSharingButton());
|
||||
|
||||
APP.remoteControl.init();
|
||||
this._bindConnectionFailedHandler(con);
|
||||
this._createRoom(tracks);
|
||||
|
||||
if (UIUtil.isButtonEnabled('contacts')
|
||||
@@ -558,55 +639,14 @@ export default {
|
||||
* @param {string} id id to check
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLocalId (id) {
|
||||
isLocalId(id) {
|
||||
return this.getMyUserId() === id;
|
||||
},
|
||||
/**
|
||||
* Binds a handler that will handle the case when the connection is dropped
|
||||
* in the middle of the conference.
|
||||
* @param {JitsiConnection} connection the connection to which the handler
|
||||
* will be bound to.
|
||||
* @private
|
||||
*/
|
||||
_bindConnectionFailedHandler (connection) {
|
||||
const handler = function (error, errMsg) {
|
||||
/* eslint-disable no-case-declarations */
|
||||
switch (error) {
|
||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
||||
case ConnectionErrors.OTHER_ERROR:
|
||||
case ConnectionErrors.SERVER_ERROR:
|
||||
|
||||
logger.error("XMPP connection error: " + errMsg);
|
||||
|
||||
// From all of the cases above only CONNECTION_DROPPED_ERROR
|
||||
// is considered a network type of failure
|
||||
const isNetworkFailure
|
||||
= error === ConnectionErrors.CONNECTION_DROPPED_ERROR;
|
||||
|
||||
APP.UI.showPageReloadOverlay(
|
||||
isNetworkFailure,
|
||||
"xmpp-conn-dropped:" + errMsg);
|
||||
|
||||
connection.removeEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED, handler);
|
||||
|
||||
// FIXME it feels like the conference should be stopped
|
||||
// by lib-jitsi-meet
|
||||
if (room)
|
||||
room.leave();
|
||||
|
||||
break;
|
||||
}
|
||||
/* eslint-enable no-case-declarations */
|
||||
};
|
||||
connection.addEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED, handler);
|
||||
},
|
||||
/**
|
||||
* Simulates toolbar button click for audio mute. Used by shortcuts and API.
|
||||
* @param mute true for mute and false for unmute.
|
||||
*/
|
||||
muteAudio (mute) {
|
||||
muteAudio(mute) {
|
||||
muteLocalAudio(mute);
|
||||
},
|
||||
/**
|
||||
@@ -617,36 +657,51 @@ export default {
|
||||
return this.audioMuted;
|
||||
},
|
||||
/**
|
||||
* Simulates toolbar button click for audio mute. Used by shortcuts and API.
|
||||
* Simulates toolbar button click for audio mute. Used by shortcuts
|
||||
* and API.
|
||||
* @param {boolean} force - If the track is not created, the operation
|
||||
* will be executed after the track is created. Otherwise the operation
|
||||
* will be ignored.
|
||||
*/
|
||||
toggleAudioMuted () {
|
||||
toggleAudioMuted(force = false) {
|
||||
if(!localAudio && force) {
|
||||
initialAudioMutedState = !initialAudioMutedState;
|
||||
return;
|
||||
}
|
||||
this.muteAudio(!this.audioMuted);
|
||||
},
|
||||
/**
|
||||
* Simulates toolbar button click for video mute. Used by shortcuts and API.
|
||||
* @param mute true for mute and false for unmute.
|
||||
*/
|
||||
muteVideo (mute) {
|
||||
muteVideo(mute) {
|
||||
muteLocalVideo(mute);
|
||||
},
|
||||
/**
|
||||
* Simulates toolbar button click for video mute. Used by shortcuts and API.
|
||||
* @param {boolean} force - If the track is not created, the operation
|
||||
* will be executed after the track is created. Otherwise the operation
|
||||
* will be ignored.
|
||||
*/
|
||||
toggleVideoMuted () {
|
||||
toggleVideoMuted(force = false) {
|
||||
if(!localVideo && force) {
|
||||
initialVideoMutedState = !initialVideoMutedState;
|
||||
return;
|
||||
}
|
||||
this.muteVideo(!this.videoMuted);
|
||||
},
|
||||
/**
|
||||
* Retrieve list of conference participants (without local user).
|
||||
* @returns {JitsiParticipant[]}
|
||||
*/
|
||||
listMembers () {
|
||||
listMembers() {
|
||||
return room.getParticipants();
|
||||
},
|
||||
/**
|
||||
* Retrieve list of ids of conference participants (without local user).
|
||||
* @returns {string[]}
|
||||
*/
|
||||
listMembersIds () {
|
||||
listMembersIds() {
|
||||
return room.getParticipants().map(p => p.getId());
|
||||
},
|
||||
/**
|
||||
@@ -654,7 +709,7 @@ export default {
|
||||
* @id id to search for participant
|
||||
* @return {boolean} whether the participant is moderator
|
||||
*/
|
||||
isParticipantModerator (id) {
|
||||
isParticipantModerator(id) {
|
||||
let user = room.getParticipantById(id);
|
||||
return user && user.isModerator();
|
||||
},
|
||||
@@ -662,10 +717,10 @@ export default {
|
||||
* Check if SIP is supported.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
sipGatewayEnabled () {
|
||||
sipGatewayEnabled() {
|
||||
return room.isSIPCallingSupported();
|
||||
},
|
||||
get membersCount () {
|
||||
get membersCount() {
|
||||
return room.getParticipants().length + 1;
|
||||
},
|
||||
/**
|
||||
@@ -675,8 +730,8 @@ export default {
|
||||
* @returns true if the callstats integration is enabled, otherwise returns
|
||||
* false.
|
||||
*/
|
||||
isCallstatsEnabled () {
|
||||
return room.isCallstatsEnabled();
|
||||
isCallstatsEnabled() {
|
||||
return room && room.isCallstatsEnabled();
|
||||
},
|
||||
/**
|
||||
* Sends the given feedback through CallStats if enabled.
|
||||
@@ -685,24 +740,69 @@ export default {
|
||||
* user feedback
|
||||
* @param detailedFeedback detailed feedback from the user. Not yet used
|
||||
*/
|
||||
sendFeedback (overallFeedback, detailedFeedback) {
|
||||
sendFeedback(overallFeedback, detailedFeedback) {
|
||||
return room.sendFeedback (overallFeedback, detailedFeedback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get speaker stats that track total dominant speaker time.
|
||||
*
|
||||
* @returns {object} A hash with keys being user ids and values being the
|
||||
* library's SpeakerStats model used for calculating time as dominant
|
||||
* speaker.
|
||||
*/
|
||||
getSpeakerStats() {
|
||||
return room.getSpeakerStats();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the connection times stored in the library.
|
||||
*/
|
||||
getConnectionTimes () {
|
||||
getConnectionTimes() {
|
||||
return this._room.getConnectionTimes();
|
||||
},
|
||||
// used by torture currently
|
||||
isJoined () {
|
||||
isJoined() {
|
||||
return this._room
|
||||
&& this._room.isJoined();
|
||||
},
|
||||
getConnectionState () {
|
||||
getConnectionState() {
|
||||
return this._room
|
||||
&& this._room.getConnectionState();
|
||||
},
|
||||
/**
|
||||
* Obtains current P2P ICE connection state.
|
||||
* @return {string|null} ICE connection state or <tt>null</tt> if there's no
|
||||
* P2P connection
|
||||
*/
|
||||
getP2PConnectionState() {
|
||||
return this._room
|
||||
&& this._room.getP2PConnectionState();
|
||||
},
|
||||
/**
|
||||
* Starts P2P (for tests only)
|
||||
* @private
|
||||
*/
|
||||
_startP2P() {
|
||||
try {
|
||||
this._room && this._room.startP2PSession();
|
||||
} catch (error) {
|
||||
logger.error("Start P2P failed", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Stops P2P (for tests only)
|
||||
* @private
|
||||
*/
|
||||
_stopP2P() {
|
||||
try {
|
||||
this._room && this._room.stopP2PSession();
|
||||
} catch (error) {
|
||||
logger.error("Stop P2P failed", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks whether or not our connection is currently in interrupted and
|
||||
* reconnect attempts are in progress.
|
||||
@@ -710,7 +810,7 @@ export default {
|
||||
* @returns {boolean} true if the connection is in interrupted state or
|
||||
* false otherwise.
|
||||
*/
|
||||
isConnectionInterrupted () {
|
||||
isConnectionInterrupted() {
|
||||
return this._room.isConnectionInterrupted();
|
||||
},
|
||||
/**
|
||||
@@ -721,20 +821,20 @@ export default {
|
||||
* @returns {JitsiParticipant|null} participant instance for given id or
|
||||
* null if not found.
|
||||
*/
|
||||
getParticipantById (id) {
|
||||
getParticipantById(id) {
|
||||
return room ? room.getParticipantById(id) : null;
|
||||
},
|
||||
/**
|
||||
* Checks whether the user identified by given id is currently connected.
|
||||
* Get participant connection status for the participant.
|
||||
*
|
||||
* @param {string} id participant's identifier(MUC nickname)
|
||||
*
|
||||
* @returns {boolean|null} true if participant's connection is ok or false
|
||||
* if the user is having connectivity issues.
|
||||
* @returns {ParticipantConnectionStatus|null} the status of the participant
|
||||
* or null if no such participant is found or participant is the local user.
|
||||
*/
|
||||
isParticipantConnectionActive (id) {
|
||||
getParticipantConnectionStatus(id) {
|
||||
let participant = this.getParticipantById(id);
|
||||
return participant ? participant.isConnectionActive() : null;
|
||||
return participant ? participant.getConnectionStatus() : null;
|
||||
},
|
||||
/**
|
||||
* Gets the display name foe the <tt>JitsiParticipant</tt> identified by
|
||||
@@ -745,7 +845,7 @@ export default {
|
||||
* @return {string} the participant's display name or the default string if
|
||||
* absent.
|
||||
*/
|
||||
getParticipantDisplayName (id) {
|
||||
getParticipantDisplayName(id) {
|
||||
let displayName = getDisplayName(id);
|
||||
if (displayName) {
|
||||
return displayName;
|
||||
@@ -758,7 +858,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
getMyUserId () {
|
||||
getMyUserId() {
|
||||
return this._room
|
||||
&& this._room.myUserId();
|
||||
},
|
||||
@@ -784,7 +884,7 @@ export default {
|
||||
* @param id the id for the user audio level to return (the id value is
|
||||
* returned for the participant using getMyUserId() method)
|
||||
*/
|
||||
getPeerSSRCAudioLevel (id) {
|
||||
getPeerSSRCAudioLevel(id) {
|
||||
return this.audioLevelsMap[id];
|
||||
},
|
||||
/**
|
||||
@@ -804,7 +904,7 @@ export default {
|
||||
},
|
||||
// end used by torture
|
||||
|
||||
getLogs () {
|
||||
getLogs() {
|
||||
return room.getLogs();
|
||||
},
|
||||
|
||||
@@ -813,7 +913,7 @@ export default {
|
||||
* debugging.
|
||||
* @param filename (optional) specify target filename
|
||||
*/
|
||||
saveLogs (filename = 'meetlog.json') {
|
||||
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
|
||||
let logs = APP.conference.getLogs();
|
||||
@@ -887,21 +987,7 @@ export default {
|
||||
this.invite = new Invite(room);
|
||||
this._room = room; // FIXME do not use this
|
||||
|
||||
let email = APP.settings.getEmail();
|
||||
email && sendData(this.commands.defaults.EMAIL, email);
|
||||
|
||||
let avatarUrl = APP.settings.getAvatarUrl();
|
||||
avatarUrl && sendData(this.commands.defaults.AVATAR_URL,
|
||||
avatarUrl);
|
||||
!email && sendData(
|
||||
this.commands.defaults.AVATAR_ID, APP.settings.getAvatarId());
|
||||
|
||||
let nick = APP.settings.getDisplayName();
|
||||
if (config.useNicks && !nick) {
|
||||
nick = APP.UI.askForNickname();
|
||||
APP.settings.setDisplayName(nick);
|
||||
}
|
||||
nick && room.setDisplayName(nick);
|
||||
_setupLocalParticipantProperties();
|
||||
|
||||
this._setupListeners();
|
||||
},
|
||||
@@ -937,13 +1023,13 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Start using provided video stream.
|
||||
* Stops previous video stream.
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useVideoStream (newStream) {
|
||||
/**
|
||||
* Start using provided video stream.
|
||||
* Stops previous video stream.
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useVideoStream(newStream) {
|
||||
return room.replaceTrack(localVideo, newStream)
|
||||
.then(() => {
|
||||
// We call dispose after doing the replace because
|
||||
@@ -978,7 +1064,7 @@ export default {
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useAudioStream (newStream) {
|
||||
useAudioStream(newStream) {
|
||||
return room.replaceTrack(localAudio, newStream)
|
||||
.then(() => {
|
||||
// We call dispose after doing the replace because
|
||||
@@ -1001,8 +1087,9 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
videoSwitchInProgress: false,
|
||||
toggleScreenSharing (shareScreen = !this.isSharingScreen) {
|
||||
toggleScreenSharing(shareScreen = !this.isSharingScreen) {
|
||||
if (this.videoSwitchInProgress) {
|
||||
logger.warn("Switch in progress.");
|
||||
return;
|
||||
@@ -1125,14 +1212,20 @@ export default {
|
||||
/**
|
||||
* Setup interaction between conference and UI.
|
||||
*/
|
||||
_setupListeners () {
|
||||
_setupListeners() {
|
||||
// add local streams when joined to the conference
|
||||
room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
|
||||
APP.store.dispatch(conferenceJoined(room));
|
||||
|
||||
APP.UI.mucJoined();
|
||||
APP.API.notifyConferenceJoined(APP.conference.roomName);
|
||||
APP.UI.markVideoInterrupted(false);
|
||||
});
|
||||
|
||||
room.on(
|
||||
ConferenceEvents.CONFERENCE_LEFT,
|
||||
(...args) => APP.store.dispatch(conferenceLeft(room, ...args)));
|
||||
|
||||
room.on(
|
||||
ConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
function (authEnabled, authLogin) {
|
||||
@@ -1146,6 +1239,12 @@ export default {
|
||||
if (user.isHidden())
|
||||
return;
|
||||
|
||||
APP.store.dispatch(participantJoined({
|
||||
id,
|
||||
name: user.getDisplayName(),
|
||||
role: user.getRole()
|
||||
}));
|
||||
|
||||
logger.log('USER %s connnected', id, user);
|
||||
APP.API.notifyUserJoined(id);
|
||||
APP.UI.addUser(user);
|
||||
@@ -1154,6 +1253,7 @@ export default {
|
||||
APP.UI.updateUserRole(user);
|
||||
});
|
||||
room.on(ConferenceEvents.USER_LEFT, (id, user) => {
|
||||
APP.store.dispatch(participantLeft(id, user));
|
||||
logger.log('USER %s LEFT', id, user);
|
||||
APP.API.notifyUserLeft(id);
|
||||
APP.UI.removeUser(id, user.getDisplayName());
|
||||
@@ -1162,6 +1262,7 @@ export default {
|
||||
|
||||
|
||||
room.on(ConferenceEvents.USER_ROLE_CHANGED, (id, role) => {
|
||||
APP.store.dispatch(participantRoleChanged(id, role));
|
||||
if (this.isLocalId(id)) {
|
||||
logger.info(`My role changed, new role: ${role}`);
|
||||
if (this.isModerator !== room.isModerator()) {
|
||||
@@ -1229,27 +1330,20 @@ export default {
|
||||
|
||||
room.on(ConferenceEvents.TALK_WHILE_MUTED, () => {
|
||||
APP.UI.showToolbar(6000);
|
||||
UIUtil.animateShowElement($("#talkWhileMutedPopup"), true, 5000);
|
||||
|
||||
APP.UI.showCustomToolbarPopup('#talkWhileMutedPopup', true, 5000);
|
||||
});
|
||||
|
||||
/*
|
||||
room.on(ConferenceEvents.IN_LAST_N_CHANGED, (inLastN) => {
|
||||
//FIXME
|
||||
if (config.muteLocalVideoIfNotInLastN) {
|
||||
// TODO mute or unmute if required
|
||||
// mark video on UI
|
||||
// APP.UI.markVideoMuted(true/false);
|
||||
}
|
||||
});
|
||||
*/
|
||||
room.on(
|
||||
ConferenceEvents.LAST_N_ENDPOINTS_CHANGED, (ids, enteringIds) => {
|
||||
APP.UI.handleLastNEndpoints(ids, enteringIds);
|
||||
ConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
|
||||
(leavingIds, enteringIds) => {
|
||||
APP.UI.handleLastNEndpoints(leavingIds, enteringIds);
|
||||
});
|
||||
|
||||
room.on(
|
||||
ConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
|
||||
(id, isActive) => {
|
||||
APP.UI.participantConnectionStatusChanged(id, isActive);
|
||||
id => {
|
||||
APP.UI.participantConnectionStatusChanged(id);
|
||||
});
|
||||
room.on(ConferenceEvents.DOMINANT_SPEAKER_CHANGED, (id) => {
|
||||
if (this.isLocalId(id)) {
|
||||
@@ -1272,10 +1366,15 @@ export default {
|
||||
room.on(ConferenceEvents.CONNECTION_RESTORED, () => {
|
||||
APP.UI.markVideoInterrupted(false);
|
||||
});
|
||||
room.on(ConferenceEvents.MESSAGE_RECEIVED, (id, text, ts) => {
|
||||
room.on(ConferenceEvents.MESSAGE_RECEIVED, (id, body, ts) => {
|
||||
let nick = getDisplayName(id);
|
||||
APP.API.notifyReceivedChatMessage(id, nick, text, ts);
|
||||
APP.UI.addMessage(id, nick, text, ts);
|
||||
APP.API.notifyReceivedChatMessage({
|
||||
id,
|
||||
nick,
|
||||
body,
|
||||
ts
|
||||
});
|
||||
APP.UI.addMessage(id, nick, body, ts);
|
||||
});
|
||||
APP.UI.addListener(UIEvents.MESSAGE_CREATED, (message) => {
|
||||
APP.API.notifySendingChatMessage(message);
|
||||
@@ -1364,6 +1463,7 @@ export default {
|
||||
});
|
||||
|
||||
room.on(ConferenceEvents.SUSPEND_DETECTED, () => {
|
||||
APP.store.dispatch(suspendDetected());
|
||||
// After wake up, we will be in a state where conference is left
|
||||
// there will be dialog shown to user.
|
||||
// We do not want video/audio as we show an overlay and after it
|
||||
@@ -1384,9 +1484,6 @@ export default {
|
||||
if (localAudio) {
|
||||
localAudio.dispose();
|
||||
}
|
||||
|
||||
// show overlay
|
||||
APP.UI.showSuspendedOverlay();
|
||||
});
|
||||
|
||||
room.on(ConferenceEvents.DTMF_SUPPORT_CHANGED, (isDTMFSupported) => {
|
||||
@@ -1424,21 +1521,36 @@ export default {
|
||||
|
||||
APP.UI.addListener(UIEvents.EMAIL_CHANGED, this.changeLocalEmail);
|
||||
room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => {
|
||||
APP.store.dispatch(participantUpdated({
|
||||
id: from,
|
||||
email: data.value
|
||||
}));
|
||||
APP.UI.setUserEmail(from, data.value);
|
||||
});
|
||||
|
||||
room.addCommandListener(
|
||||
this.commands.defaults.AVATAR_URL,
|
||||
(data, from) => {
|
||||
APP.store.dispatch(
|
||||
participantUpdated({
|
||||
id: from,
|
||||
avatarURL: data.value
|
||||
}));
|
||||
APP.UI.setUserAvatarUrl(from, data.value);
|
||||
});
|
||||
|
||||
room.addCommandListener(this.commands.defaults.AVATAR_ID,
|
||||
(data, from) => {
|
||||
APP.store.dispatch(
|
||||
participantUpdated({
|
||||
id: from,
|
||||
avatarID: data.value
|
||||
}));
|
||||
APP.UI.setUserAvatarID(from, data.value);
|
||||
});
|
||||
|
||||
APP.UI.addListener(UIEvents.NICKNAME_CHANGED, changeLocalDisplayName);
|
||||
APP.UI.addListener(UIEvents.NICKNAME_CHANGED,
|
||||
this.changeLocalDisplayName.bind(this));
|
||||
|
||||
APP.UI.addListener(UIEvents.START_MUTED_CHANGED,
|
||||
(startAudioMuted, startVideoMuted) => {
|
||||
@@ -1545,7 +1657,6 @@ export default {
|
||||
})
|
||||
.catch((err) => {
|
||||
APP.UI.showDeviceErrorDialog(null, err);
|
||||
APP.UI.setSelectedCameraFromSettings();
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -1567,7 +1678,6 @@ export default {
|
||||
})
|
||||
.catch((err) => {
|
||||
APP.UI.showDeviceErrorDialog(err, null);
|
||||
APP.UI.setSelectedMicFromSettings();
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -1583,7 +1693,6 @@ export default {
|
||||
logger.warn('Failed to change audio output device. ' +
|
||||
'Default or previously set audio output device ' +
|
||||
'will be used instead.', err);
|
||||
APP.UI.setSelectedAudioOutputFromSettings();
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -1679,8 +1788,8 @@ export default {
|
||||
}
|
||||
|
||||
mediaDeviceHelper.setCurrentMediaDevices(devices);
|
||||
|
||||
APP.UI.onAvailableDevicesChanged(devices);
|
||||
APP.store.dispatch(updateDeviceList(devices));
|
||||
});
|
||||
|
||||
this.deviceChangeListener = (devices) =>
|
||||
@@ -1813,7 +1922,7 @@ export default {
|
||||
* @param {boolean} [requestFeedback=false] if user feedback should be
|
||||
* requested
|
||||
*/
|
||||
hangup (requestFeedback = false) {
|
||||
hangup(requestFeedback = false) {
|
||||
eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
|
||||
APP.UI.hideRingOverLay();
|
||||
let requestFeedbackPromise = requestFeedback
|
||||
@@ -1846,8 +1955,16 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const localId = room ? room.myUserId() : undefined;
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
id: localId,
|
||||
local: true,
|
||||
email
|
||||
}));
|
||||
|
||||
APP.settings.setEmail(email);
|
||||
APP.UI.setUserEmail(room.myUserId(), email);
|
||||
APP.UI.setUserEmail(localId, email);
|
||||
sendData(commands.EMAIL, email);
|
||||
},
|
||||
|
||||
@@ -1862,8 +1979,16 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const localId = room ? room.myUserId() : undefined;
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
id: localId,
|
||||
local: true,
|
||||
avatarURL: url
|
||||
}));
|
||||
|
||||
APP.settings.setAvatarUrl(url);
|
||||
APP.UI.setUserAvatarUrl(room.myUserId(), url);
|
||||
APP.UI.setUserAvatarUrl(localId, url);
|
||||
sendData(commands.AVATAR_URL, url);
|
||||
},
|
||||
|
||||
@@ -1875,7 +2000,7 @@ export default {
|
||||
* @throws NetworkError or InvalidStateError or Error if the operation
|
||||
* fails.
|
||||
*/
|
||||
sendEndpointMessage (to, payload) {
|
||||
sendEndpointMessage(to, payload) {
|
||||
room.sendEndpointMessage(to, payload);
|
||||
},
|
||||
|
||||
@@ -1884,7 +2009,7 @@ export default {
|
||||
* @param {String} eventName the name of the event
|
||||
* @param {Function} listener the listener.
|
||||
*/
|
||||
addListener (eventName, listener) {
|
||||
addListener(eventName, listener) {
|
||||
eventEmitter.addListener(eventName, listener);
|
||||
},
|
||||
|
||||
@@ -1894,7 +2019,37 @@ export default {
|
||||
* listener
|
||||
* @param {Function} listener the listener.
|
||||
*/
|
||||
removeListener (eventName, listener) {
|
||||
removeListener(eventName, listener) {
|
||||
eventEmitter.removeListener(eventName, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the participant given by participantId is currently in the
|
||||
* last N set if there's one supported.
|
||||
*
|
||||
* @param participantId the identifier of the participant
|
||||
* @returns {boolean} {true} if the participant given by the participantId
|
||||
* is currently in the last N set or if there's no last N set at this point
|
||||
* and {false} otherwise
|
||||
*/
|
||||
isInLastN(participantId) {
|
||||
return room.isInLastN(participantId);
|
||||
},
|
||||
/**
|
||||
* Changes the display name for the local user
|
||||
* @param nickname {string} the new display name
|
||||
*/
|
||||
changeLocalDisplayName(nickname = '') {
|
||||
const formattedNickname
|
||||
= nickname.trim().substr(0, MAX_DISPLAY_NAME_LENGTH);
|
||||
|
||||
if (formattedNickname === APP.settings.getDisplayName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
APP.settings.setDisplayName(formattedNickname);
|
||||
room.setDisplayName(formattedNickname);
|
||||
APP.UI.changeDisplayName(this.getMyUserId(),
|
||||
formattedNickname);
|
||||
}
|
||||
};
|
||||
|
||||
26
config.js
@@ -20,6 +20,13 @@ var config = { // eslint-disable-line no-unused-vars
|
||||
//focusUserJid: 'focus@auth.jitsi-meet.example.com', // The real JID of focus participant - can be overridden here
|
||||
//defaultSipNumber: '', // Default SIP number
|
||||
|
||||
// The STUN servers that will be used in the peer to peer connections
|
||||
p2pStunServers: [
|
||||
{ urls: "stun:stun.l.google.com:19302" },
|
||||
{ urls: "stun:stun1.l.google.com:19302" },
|
||||
{ urls: "stun:stun2.l.google.com:19302" }
|
||||
],
|
||||
|
||||
// The ID of the jidesha extension for Chrome.
|
||||
desktopSharingChromeExtId: null,
|
||||
// Whether desktop sharing should be disabled on Chrome.
|
||||
@@ -40,7 +47,7 @@ var config = { // eslint-disable-line no-unused-vars
|
||||
// up to and including 41. On Firefox 42 and higher, we will run without the
|
||||
// extension.
|
||||
// If set to -1, an extension will be required for all versions of Firefox.
|
||||
desktopSharingFirefoxMaxVersionExtRequired: -1,
|
||||
desktopSharingFirefoxMaxVersionExtRequired: 51,
|
||||
// The URL to the Firefox extension for desktop sharing.
|
||||
desktopSharingFirefoxExtensionURL: null,
|
||||
|
||||
@@ -53,8 +60,6 @@ var config = { // eslint-disable-line no-unused-vars
|
||||
disableStats: false,
|
||||
disableAudioLevels: false,
|
||||
channelLastN: -1, // The default value of the channel attribute last-n.
|
||||
adaptiveLastN: false,
|
||||
//disableAdaptiveSimulcast: false,
|
||||
enableRecording: false,
|
||||
enableWelcomePage: true,
|
||||
//enableClosePage: false, // enabling the close page will ignore the welcome
|
||||
@@ -79,6 +84,17 @@ var config = { // eslint-disable-line no-unused-vars
|
||||
enableUserRolesBasedOnToken: false,
|
||||
// Suspending video might cause problems with audio playback. Disabling until these are fixed.
|
||||
disableSuspendVideo: true,
|
||||
// disables or enables RTX (RFC 4588).
|
||||
disableRtx: true
|
||||
// disables or enables RTX (RFC 4588) (defaults to false).
|
||||
disableRtx: false,
|
||||
// Sets the preferred resolution (height) for local video. Defaults to 360.
|
||||
resolution: 720,
|
||||
// Enables peer to peer mode. When enabled system will try to establish
|
||||
// direct connection given that there are exactly 2 participants in
|
||||
// the room. If that succeeds the conference will stop sending data through
|
||||
// the JVB and use the peer to peer connection instead. When 3rd participant
|
||||
// joins the conference will be moved back to the JVB connection.
|
||||
//enableP2P: true
|
||||
// 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
|
||||
};
|
||||
|
||||
@@ -4,6 +4,14 @@ const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
import AuthHandler from './modules/UI/authentication/AuthHandler';
|
||||
import jitsiLocalStorage from './modules/util/JitsiLocalStorage';
|
||||
|
||||
import {
|
||||
connectionEstablished,
|
||||
connectionFailed
|
||||
} from './react/features/base/connection';
|
||||
import {
|
||||
isFatalJitsiConnectionError
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
|
||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
|
||||
@@ -67,6 +75,18 @@ function connect(id, password, roomName) {
|
||||
connection.addEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED, handleConnectionFailed
|
||||
);
|
||||
connection.addEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED, connectionFailedHandler);
|
||||
|
||||
function connectionFailedHandler(error, errMsg) {
|
||||
APP.store.dispatch(connectionFailed(connection, error, errMsg));
|
||||
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
connection.removeEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED,
|
||||
connectionFailedHandler);
|
||||
}
|
||||
}
|
||||
|
||||
function unsubscribe() {
|
||||
connection.removeEventListener(
|
||||
@@ -80,6 +100,7 @@ function connect(id, password, roomName) {
|
||||
}
|
||||
|
||||
function handleConnectionEstablished() {
|
||||
APP.store.dispatch(connectionEstablished(connection));
|
||||
unsubscribe();
|
||||
resolve(connection);
|
||||
}
|
||||
|
||||
3
connection_optimization/.eslintrc.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
'extends': '../react/.eslintrc.js'
|
||||
};
|
||||
@@ -1,75 +1,87 @@
|
||||
/* global config, getRoomName, getConfigParamsFromUrl */
|
||||
/* global createConnectionExternally */
|
||||
/* global config,
|
||||
createConnectionExternally,
|
||||
getConfigParamsFromUrl,
|
||||
getRoomName */
|
||||
|
||||
/**
|
||||
* Implements extrnal connect using createConnectionExtenally function defined
|
||||
* Implements external connect using createConnectionExternally function defined
|
||||
* in external_connect.js for Jitsi Meet. Parses the room name and token from
|
||||
* the url and executes createConnectionExtenally.
|
||||
* the URL and executes createConnectionExternally.
|
||||
*
|
||||
* NOTE: If you are using lib-jitsi-meet without Jitsi Meet you should use this
|
||||
* file as reference only because the implementation is Jitsi Meet specific.
|
||||
* file as reference only because the implementation is Jitsi Meet-specific.
|
||||
*
|
||||
* NOTE: For optimal results this file should be included right after
|
||||
* exrnal_connect.js.
|
||||
* external_connect.js.
|
||||
*/
|
||||
|
||||
const hashParams = getConfigParamsFromUrl('hash', true);
|
||||
const searchParams = getConfigParamsFromUrl('search', true);
|
||||
|
||||
// URL params have higher proirity than config params.
|
||||
let url
|
||||
= hashParams.hasOwnProperty('config.externalConnectUrl')
|
||||
? hashParams['config.externalConnectUrl']
|
||||
: config.externalConnectUrl;
|
||||
|
||||
if (url && window.createConnectionExternally) {
|
||||
const roomName = getRoomName();
|
||||
|
||||
if (roomName) {
|
||||
url += `?room=${roomName}`;
|
||||
|
||||
const token
|
||||
= hashParams['config.token'] || config.token || searchParams.jwt;
|
||||
|
||||
if (token) {
|
||||
url += `&token=${token}`;
|
||||
}
|
||||
|
||||
createConnectionExternally(
|
||||
url,
|
||||
connectionInfo => {
|
||||
// Sets that global variable to be used later by connect method
|
||||
// in connection.js.
|
||||
window.XMPPAttachInfo = {
|
||||
status: 'success',
|
||||
data: connectionInfo
|
||||
};
|
||||
checkForConnectHandlerAndConnect();
|
||||
},
|
||||
errorCallback);
|
||||
} else {
|
||||
errorCallback();
|
||||
}
|
||||
} else {
|
||||
errorCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes createConnectionExternally function.
|
||||
* Check if connect from connection.js was executed and executes the handler
|
||||
* that is going to finish the connect work.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
(function () {
|
||||
var hashParams = getConfigParamsFromUrl("hash", true);
|
||||
var searchParams = getConfigParamsFromUrl("search", true);
|
||||
function checkForConnectHandlerAndConnect() {
|
||||
window.APP
|
||||
&& window.APP.connect.status === 'ready'
|
||||
&& window.APP.connect.handler();
|
||||
}
|
||||
|
||||
//Url params have higher proirity than config params
|
||||
var url = config.externalConnectUrl;
|
||||
if(hashParams.hasOwnProperty('config.externalConnectUrl'))
|
||||
url = hashParams["config.externalConnectUrl"];
|
||||
/**
|
||||
* Implements a callback to be invoked if anything goes wrong.
|
||||
*
|
||||
* @param {Error} error - The specifics of what went wrong.
|
||||
* @returns {void}
|
||||
*/
|
||||
function errorCallback(error) {
|
||||
// The value of error is undefined if external connect is disabled.
|
||||
error && console.warn(error);
|
||||
|
||||
/**
|
||||
* Check if connect from connection.js was executed and executes the handler
|
||||
* that is going to finish the connect work.
|
||||
*/
|
||||
function checkForConnectHandlerAndConnect() {
|
||||
|
||||
if(window.APP && window.APP.connect.status === "ready") {
|
||||
window.APP.connect.handler();
|
||||
}
|
||||
}
|
||||
|
||||
function error_callback(error){
|
||||
if(error) //error=undefined if external connect is disabled.
|
||||
console.warn(error);
|
||||
// Sets that global variable to be used later by connect method in
|
||||
// connection.js
|
||||
window.XMPPAttachInfo = {
|
||||
status: "error"
|
||||
};
|
||||
checkForConnectHandlerAndConnect();
|
||||
}
|
||||
|
||||
if(!url || !window.createConnectionExternally) {
|
||||
error_callback();
|
||||
return;
|
||||
}
|
||||
var room_name = getRoomName();
|
||||
if(!room_name) {
|
||||
error_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
url += "?room=" + room_name;
|
||||
|
||||
var token = hashParams["config.token"] || config.token ||
|
||||
searchParams.jwt;
|
||||
if(token)
|
||||
url += "&token=" + token;
|
||||
|
||||
createConnectionExternally(url, function(connectionInfo) {
|
||||
// Sets that global variable to be used later by connect method in
|
||||
// connection.js
|
||||
window.XMPPAttachInfo = {
|
||||
status: "success",
|
||||
data: connectionInfo
|
||||
};
|
||||
checkForConnectHandlerAndConnect();
|
||||
}, error_callback);
|
||||
})();
|
||||
// Sets that global variable to be used later by connect method in
|
||||
// connection.js.
|
||||
window.XMPPAttachInfo = {
|
||||
status: 'error'
|
||||
};
|
||||
checkForConnectHandlerAndConnect();
|
||||
}
|
||||
|
||||
@@ -66,18 +66,4 @@
|
||||
@include keyframes(slideInExtContainer) {
|
||||
from { width: 0; }
|
||||
to { width: $sidebarWidth; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fade in / out animations
|
||||
**/
|
||||
|
||||
@include keyframes(fadeIn) {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@include keyframes(fadeOut) {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
@@ -3,21 +3,25 @@
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
html, body{
|
||||
margin:0px;
|
||||
height:100%;
|
||||
color: $defaultColor;
|
||||
body {
|
||||
margin: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
background: #000000;
|
||||
overflow: hidden;
|
||||
color: $defaultColor;
|
||||
background: $defaultBackground;
|
||||
&.filmstrip-only {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html, body, input, textarea, keygen, select, button {
|
||||
body, input, textarea, keygen, select, button {
|
||||
font-family: $baseFontFamily !important;
|
||||
}
|
||||
|
||||
@@ -80,7 +84,7 @@ form {
|
||||
height: 74px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
.leftwatermark {
|
||||
@@ -102,7 +106,7 @@ form {
|
||||
font-size: 11pt;
|
||||
color: rgba(255,255,255,.50);
|
||||
text-decoration: none;
|
||||
z-index: 100;
|
||||
z-index: $poweredByZ;
|
||||
}
|
||||
|
||||
.connected {
|
||||
@@ -122,6 +126,7 @@ form {
|
||||
z-index: $tooltipsZ;
|
||||
&-inner {
|
||||
background-color: $tooltipBg;
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
&-arrow {
|
||||
|
||||
@@ -212,24 +212,24 @@
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
:not(.default-scrollbar)::-webkit-scrollbar {
|
||||
background: #06a5df;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
:not(.default-scrollbar)::-webkit-scrollbar-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
:not(.default-scrollbar)::-webkit-scrollbar-track {
|
||||
background: black;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track-piece {
|
||||
:not(.default-scrollbar)::-webkit-scrollbar-track-piece {
|
||||
background: black;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
:not(.default-scrollbar)::-webkit-scrollbar-thumb {
|
||||
background: #06a5df;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
.settingsContent {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
|
||||
#localVideoPreview {
|
||||
width: 50%;
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
.deviceSelection {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: left;
|
||||
margin-left: 10px;
|
||||
|
||||
.device {
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
|
||||
select {
|
||||
flex: 1;
|
||||
margin_right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@
|
||||
flex-direction: column-reverse;
|
||||
flex-wrap: nowrap;
|
||||
position: relative;
|
||||
z-index: 1; // Set z-index to make element visible
|
||||
width: $hideFilmstripButtonWidth;
|
||||
z-index: $zindex1; // Set z-index to make element visible.
|
||||
width: $filmstripToggleButtonWidth;
|
||||
|
||||
button {
|
||||
font-size: 14px;
|
||||
@@ -50,16 +50,16 @@
|
||||
position:relative;
|
||||
height:196px;
|
||||
padding: 0;
|
||||
/*The filmstrip should not be covered by the left toolbar*/
|
||||
/* The filmstrip should not be covered by the left toolbar. */
|
||||
padding-left: $defaultToolbarSize + 5;
|
||||
bottom: 0;
|
||||
width:auto;
|
||||
border: $thumbnailsBorder solid transparent;
|
||||
z-index: 5;
|
||||
z-index: $filmstripVideosZ;
|
||||
transition: bottom 2s;
|
||||
overflow: visible !important;
|
||||
/*!!!Removes the gap between the local video container and the remote
|
||||
videos.*/
|
||||
/*!!! Removes the gap between the local video container and the remote
|
||||
videos. */
|
||||
font-size: 0pt;
|
||||
|
||||
&.hidden {
|
||||
@@ -79,8 +79,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Focused video thumbnail.
|
||||
*/
|
||||
* Focused video thumbnail.
|
||||
*/
|
||||
&.videoContainerFocused {
|
||||
transition-duration: 0.5s;
|
||||
-webkit-transition-duration: 0.5s;
|
||||
@@ -97,8 +97,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Hovered video thumbnail.
|
||||
*/
|
||||
* Hovered video thumbnail.
|
||||
*/
|
||||
&:hover {
|
||||
cursor: hand;
|
||||
border: $thumbnailVideoBorder solid $videoThumbnailHovered;
|
||||
@@ -110,7 +110,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* With TemasysWebRTC plugin <object/> element is used
|
||||
/* With the TemasysWebRTC plugin <object/> element is used
|
||||
instead of <video/> */
|
||||
& > video,
|
||||
& > object {
|
||||
@@ -121,4 +121,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Style the filmstrip videos in filmstrip-only mode.
|
||||
*/
|
||||
&__videos-filmstripOnly {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
padding-right: $defaultToolbarSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,86 @@
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
&__button {
|
||||
float: none !important;
|
||||
&-filmstrip-only {
|
||||
background-color: $inlayFilmstripOnlyBg;
|
||||
color: $inlayFilmstripOnlyColor;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
bottom: 30px;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
max-height: 120px;
|
||||
height: 80%;
|
||||
right: 0px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
&__content {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
> .button-control {
|
||||
align-self: center;
|
||||
}
|
||||
> #reloadProgressBar {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
margin-bottom: 0px;
|
||||
width: 100%;
|
||||
border-radius: 0px;
|
||||
> .aui-progress-indicator-value {
|
||||
border-radius: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__container {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
&__text {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
font-size: 50px;
|
||||
align-self: center;
|
||||
color: $inlayIconColor;
|
||||
opacity: 0.6;
|
||||
}
|
||||
&__icon-container {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
&__avatar-container {
|
||||
position: relative;
|
||||
> img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__icon-background {
|
||||
background: $inlayIconBg;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1010;
|
||||
z-index: $jitsipopoverZ;
|
||||
display: none;
|
||||
max-width: 300px;
|
||||
min-width: 100px;
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 8px;
|
||||
z-index: 1;
|
||||
z-index: $zindex1;
|
||||
width: 0;
|
||||
height: 0;
|
||||
content: '';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
overflow: hidden;
|
||||
padding: 20px;
|
||||
margin-left: 10px;
|
||||
z-index: 10;
|
||||
z-index: $zindex10;
|
||||
border-radius: $borderRadius;
|
||||
background-attachment: scroll;
|
||||
background-size: auto auto;
|
||||
|
||||
@@ -1,34 +1,10 @@
|
||||
/*Initialize*/
|
||||
ul.loginmenu {
|
||||
font-family: $baseFontFamily;
|
||||
line-height: normal;
|
||||
display:none;
|
||||
div.loginmenu {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
padding-bottom: 7px;
|
||||
top: 45px;
|
||||
left: -5px;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
border: 1px solid rgba(256, 256, 256, 0.2);
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
ul.loginmenu li {
|
||||
list-style-type: none;
|
||||
padding: 7px;
|
||||
color: #fff;
|
||||
font-size: 11pt;
|
||||
cursor: default;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
ul.loginmenu:after {
|
||||
content: url('../images/dropdownPointer.png');
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 18px;
|
||||
top: 40px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
a.disabled {
|
||||
@@ -36,23 +12,7 @@ a.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.loginmenuPadding {
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.loginmenu.extendedToolbarPopup {
|
||||
left: 55px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
ul.loginmenu.extendedToolbarPopup:after {
|
||||
content: url('../images/leftDropdownPointer.png');
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
left: -7px;
|
||||
top: 20px;
|
||||
left: 40px;
|
||||
}
|
||||
200
css/_mixins.scss
@@ -2,52 +2,52 @@
|
||||
* Animation mixin.
|
||||
*/
|
||||
@mixin animation($animate...) {
|
||||
$max: length($animate);
|
||||
$animations: '';
|
||||
$max: length($animate);
|
||||
$animations: '';
|
||||
|
||||
@for $i from 1 through $max {
|
||||
$animations: #{$animations + nth($animate, $i)};
|
||||
@for $i from 1 through $max {
|
||||
$animations: #{$animations + nth($animate, $i)};
|
||||
|
||||
@if $i < $max {
|
||||
$animations: #{$animations + ", "};
|
||||
@if $i < $max {
|
||||
$animations: #{$animations + ", "};
|
||||
}
|
||||
}
|
||||
}
|
||||
-webkit-animation: $animations;
|
||||
-moz-animation: $animations;
|
||||
-o-animation: $animations;
|
||||
animation: $animations;
|
||||
-webkit-animation: $animations;
|
||||
-moz-animation: $animations;
|
||||
-o-animation: $animations;
|
||||
animation: $animations;
|
||||
}
|
||||
|
||||
@mixin flex() {
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keyframes mixin.
|
||||
*/
|
||||
@mixin keyframes($animationName) {
|
||||
@-webkit-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@-moz-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@-o-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@-webkit-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@-moz-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@-o-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
@keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin circle($diameter) {
|
||||
width: $diameter;
|
||||
height: $diameter;
|
||||
border-radius: 50%;
|
||||
width: $diameter;
|
||||
height: $diameter;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,10 +60,10 @@
|
||||
}
|
||||
|
||||
@mixin absoluteAligning() {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
@include transform(translate(-50%, -50%));
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
@include transform(translate(-50%, -50%));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,81 +75,115 @@
|
||||
}
|
||||
|
||||
@mixin transform($func) {
|
||||
-moz-transform: $func;
|
||||
-ms-transform: $func;
|
||||
-webkit-transform: $func;
|
||||
-o-transform: $func;
|
||||
transform: $func;
|
||||
-moz-transform: $func;
|
||||
-ms-transform: $func;
|
||||
-webkit-transform: $func;
|
||||
-o-transform: $func;
|
||||
transform: $func;
|
||||
}
|
||||
|
||||
@mixin transition($transition...) {
|
||||
-moz-transition: $transition;
|
||||
-o-transition: $transition;
|
||||
-webkit-transition: $transition;
|
||||
transition: $transition;
|
||||
-moz-transition: $transition;
|
||||
-o-transition: $transition;
|
||||
-webkit-transition: $transition;
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin styling placeholder
|
||||
**/
|
||||
* Mixin styling a placeholder.
|
||||
**/
|
||||
@mixin placeholder() {
|
||||
$selectors: (
|
||||
"::-webkit-input-placeholder",
|
||||
"::-moz-placeholder",
|
||||
":-moz-placeholder",
|
||||
":-ms-input-placeholder"
|
||||
);
|
||||
$selectors: (
|
||||
"::-webkit-input-placeholder",
|
||||
"::-moz-placeholder",
|
||||
":-moz-placeholder",
|
||||
":-ms-input-placeholder"
|
||||
);
|
||||
|
||||
@each $selector in $selectors {
|
||||
#{$selector} {
|
||||
@content;
|
||||
@each $selector in $selectors {
|
||||
#{$selector} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin styling a slider track for different browsers.
|
||||
**/
|
||||
@mixin slider() {
|
||||
$selectors: (
|
||||
"input[type=range]::-webkit-slider-runnable-track",
|
||||
"input[type=range]::-moz-range-track",
|
||||
"input[type=range]::-ms-track"
|
||||
);
|
||||
|
||||
@each $selector in $selectors {
|
||||
#{$selector} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin styling a slider thumb for different browsers.
|
||||
**/
|
||||
@mixin slider-thumb() {
|
||||
$selectors: (
|
||||
"input[type=range]::-webkit-slider-thumb",
|
||||
"input[type=range]::-moz-range-thumb",
|
||||
"input[type=range]::-ms-thumb"
|
||||
);
|
||||
|
||||
@each $selector in $selectors {
|
||||
#{$selector} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin box-shadow($h, $y, $blur, $color, $inset: false) {
|
||||
@if $inset {
|
||||
-webkit-box-shadow: inset $h $y $blur $color;
|
||||
-moz-box-shadow: inset $h $y $blur $color;
|
||||
box-shadow: inset $h $y $blur $color;
|
||||
} @else {
|
||||
-webkit-box-shadow: $h $y $blur $color;
|
||||
-moz-box-shadow: $h $y $blur $color;
|
||||
box-shadow: $h $y $blur $color;
|
||||
}
|
||||
@if $inset {
|
||||
-webkit-box-shadow: inset $h $y $blur $color;
|
||||
-moz-box-shadow: inset $h $y $blur $color;
|
||||
box-shadow: inset $h $y $blur $color;
|
||||
} @else {
|
||||
-webkit-box-shadow: $h $y $blur $color;
|
||||
-moz-box-shadow: $h $y $blur $color;
|
||||
box-shadow: $h $y $blur $color;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin no-box-shadow {
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@mixin box-sizing($box-model) {
|
||||
-webkit-box-sizing: $box-model; // Safari <= 5
|
||||
-moz-box-sizing: $box-model; // Firefox <= 19
|
||||
box-sizing: $box-model;
|
||||
-webkit-box-sizing: $box-model; // Safari <= 5
|
||||
-moz-box-sizing: $box-model; // Firefox <= 19
|
||||
box-sizing: $box-model;
|
||||
}
|
||||
|
||||
@mixin border-radius($radius) {
|
||||
-webkit-border-radius: $radius;
|
||||
border-radius: $radius;
|
||||
/* stops bg color from leaking outside the border: */
|
||||
background-clip: padding-box;
|
||||
-webkit-border-radius: $radius;
|
||||
border-radius: $radius;
|
||||
/* stops bg color from leaking outside the border: */
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
@mixin opacity($opacity) {
|
||||
opacity: $opacity;
|
||||
$opacity-ie: $opacity * 100;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=$opacity-ie);
|
||||
filter: alpha(opacity=$opacity-ie); //IE8
|
||||
opacity: $opacity;
|
||||
$opacity-ie: $opacity * 100;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=$opacity-ie);
|
||||
filter: alpha(opacity=$opacity-ie); //IE8
|
||||
}
|
||||
|
||||
@mixin text-truncate {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,5 +191,5 @@
|
||||
* (opacity) value.
|
||||
*/
|
||||
@mixin transparentBg($color, $alpha) {
|
||||
background-color: rgba(red($color), green($color), blue($color), $alpha);
|
||||
background-color: rgba(red($color), green($color), blue($color), $alpha);
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
#notice {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
.notice {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
z-index: $zindex3;
|
||||
margin-top: 6px;
|
||||
|
||||
@include transform(translateX(-50%));
|
||||
|
||||
&__message {
|
||||
background-color: #000000;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
#noticeText {
|
||||
background-color: #000000;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1015;
|
||||
z-index: $popoverZ;
|
||||
display: none;
|
||||
max-width: 300px;
|
||||
min-width: 100px;
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
}
|
||||
|
||||
// Link Appearance
|
||||
&__link {
|
||||
&__link,
|
||||
&__contents {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
@@ -40,11 +41,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
&__text,
|
||||
&__slider {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&__slider {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
html, body {
|
||||
width: 100%;
|
||||
height:100%;
|
||||
color: $defaultColor;
|
||||
background: $defaultBackground;
|
||||
}
|
||||
|
||||
.redirectPageMessage {
|
||||
width: 30%;
|
||||
margin: 20% auto;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 0;
|
||||
z-index: 800;
|
||||
z-index: $sideToolbarContainerZ;
|
||||
|
||||
/**
|
||||
* Labels inside the side panel.
|
||||
@@ -113,6 +113,12 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#deviceOptionsWrapper {
|
||||
button {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile
|
||||
*/
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
#toast-container.notification-bottom-right {
|
||||
$videoOffset: 2 * ($thumbnailVideoMargin + $thumbnailsBorder) + $thumbnailVideoBorder;
|
||||
bottom: 135px;
|
||||
right: $hideFilmstripButtonWidth + $videoOffset;
|
||||
right: $filmstripToggleButtonWidth + $videoOffset;
|
||||
}
|
||||
|
||||
#toast-container * {
|
||||
|
||||
@@ -1,184 +1,256 @@
|
||||
.toolbar {
|
||||
background-color: $toolbarBackground;
|
||||
position: relative;
|
||||
z-index: $toolbarZ;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
|
||||
/**
|
||||
* Splitter button in the toolbar.
|
||||
*/
|
||||
&__splitter {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
margin: 0 $splitterToolbarButtonMargin;
|
||||
background: $splitterColor;
|
||||
}
|
||||
}
|
||||
|
||||
#mainToolbarContainer{
|
||||
display: block;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
z-index: $toolbarZ;
|
||||
pointer-events: none;
|
||||
min-height: 100px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#subject {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
width: auto;
|
||||
padding: 5px;
|
||||
margin-left: 40%;
|
||||
margin-right: 40%;
|
||||
text-align: center;
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,.85) , rgba(255,255,255,.35));
|
||||
box-shadow: 0 0 2px #000000, 0 0 10px #000000;
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
}
|
||||
|
||||
#mainToolbar {
|
||||
height: $defaultToolbarSize;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 30px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: auto;
|
||||
border-radius: 3px;
|
||||
.button:first-child {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
}
|
||||
.button:last-child {
|
||||
border-bottom-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
#extendedToolbar {
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
width: $defaultToolbarSize;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding-top: 10px;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
transform: translateX(-100%);
|
||||
-webkit-transform: translateX(-100%);
|
||||
}
|
||||
|
||||
#toolbar_button_hangup {
|
||||
color: #BF2117;
|
||||
font-size: $hangupFontSize !important;
|
||||
}
|
||||
|
||||
#toolbar_button_etherpad {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mainToolbar a.button:last-child::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
color: #FFFFFF;
|
||||
top:0px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
font-size: $toolbarFontSize !important;
|
||||
line-height: 50px !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.button.unclickable {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.button.toggled {
|
||||
background: $toolbarToggleBackground !important;
|
||||
}
|
||||
|
||||
a.button.unclickable:hover,
|
||||
a.button.unclickable:active,
|
||||
a.button.unclickable.selected{
|
||||
cursor: default;
|
||||
background: none;
|
||||
}
|
||||
|
||||
a.button:hover,
|
||||
a.button:active,
|
||||
a.button.selected {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
// sum opacity with background layer should give us 0.8
|
||||
background: $toolbarSelectBackground;
|
||||
}
|
||||
|
||||
a.button>#avatar {
|
||||
width: 30px;
|
||||
border-radius: 50%;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#feedbackButton {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Round badge.
|
||||
*/
|
||||
.badge-round {
|
||||
background-color: $toolbarBadgeBackground;
|
||||
color: $toolbarBadgeColor;
|
||||
font-size: 9px;
|
||||
line-height: 13px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
min-width: 13px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
color: $toolbarBadgeColor;
|
||||
// Do not inherit the font-family from the toolbar button, because it's an
|
||||
// icon style.
|
||||
font-family: $baseFontFamily;
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
line-height: 13px;
|
||||
min-width: 13px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toolbar button styles.
|
||||
*/
|
||||
.button {
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
z-index: $zindex1;
|
||||
display: inline-block;
|
||||
font-size: $toolbarFontSize !important;
|
||||
height: 50px;
|
||||
line-height: 50px !important;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
top:0px;
|
||||
vertical-align: middle;
|
||||
width: 50px;
|
||||
|
||||
&_hangup {
|
||||
color: $hangupColor;
|
||||
font-size: $hangupFontSize !important;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:hover, &:active {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:not(.toggled) {
|
||||
&:hover, &:active {
|
||||
// sum opacity with background layer should give us 0.8
|
||||
background: $toolbarSelectBackground;
|
||||
}
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: $toolbarToggleBackground;
|
||||
|
||||
&.icon-camera {
|
||||
@extend .icon-camera-disabled;
|
||||
}
|
||||
|
||||
&.icon-full-screen {
|
||||
@extend .icon-exit-full-screen;
|
||||
}
|
||||
|
||||
&.icon-microphone {
|
||||
@extend .icon-mic-disabled;
|
||||
}
|
||||
}
|
||||
|
||||
&.unclickable {
|
||||
cursor: default;
|
||||
|
||||
&:hover, &:active, &.selected {
|
||||
background: none;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar-container {
|
||||
display: block;
|
||||
left:0;
|
||||
min-height: 100px;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right:0;
|
||||
text-align: center;
|
||||
top:0;
|
||||
z-index: $toolbarZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toolbar specific round badge.
|
||||
* Common toolbar styles.
|
||||
*/
|
||||
.toolbar .badge-round {
|
||||
position: absolute;
|
||||
right: 9px;
|
||||
bottom: 9px;
|
||||
.toolbar {
|
||||
background-color: $toolbarBackground;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
position: relative;
|
||||
z-index: $toolbarZ;
|
||||
|
||||
/**
|
||||
* Splitter button in the toolbar.
|
||||
*/
|
||||
&__splitter {
|
||||
background: $splitterColor;
|
||||
display: inline-block;
|
||||
height: 50%;
|
||||
margin: 0 $splitterToolbarButtonMargin;
|
||||
vertical-align: middle;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary toolbar styles.
|
||||
*/
|
||||
&_primary {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 30px;
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
height: $defaultToolbarSize;
|
||||
border-radius: 3px;
|
||||
opacity: 0;
|
||||
|
||||
@include transform(translateX(-50%));
|
||||
|
||||
.button:first-child {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
}
|
||||
.button:last-child {
|
||||
border-bottom-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&_primary a.button:last-child::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Secondary toolbar styles.
|
||||
*/
|
||||
&_secondary {
|
||||
position: absolute;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
height: 100%;
|
||||
justify-content: flex-start;
|
||||
left: 0;
|
||||
padding-top: 10px;
|
||||
top: 0;
|
||||
transform: translateX(-100%);
|
||||
width: $defaultToolbarSize;
|
||||
-webkit-transform: translateX(-100%);
|
||||
|
||||
.button.toggled:not(.icon-raised-hand) {
|
||||
background: $toolbarSelectBackground;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
&.unclickable {
|
||||
cursor: default;
|
||||
|
||||
&:hover, &:active, &.selected {
|
||||
background: none;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Styles the toolbar in filmstrip-only mode.
|
||||
*/
|
||||
&_filmstrip-only {
|
||||
border-radius: 3px;
|
||||
bottom: 0;
|
||||
display: inline-block;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: $defaultToolbarSize;
|
||||
|
||||
.button:first-child {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
.button:last-child {
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toolbar specific round badge.
|
||||
*/
|
||||
.badge-round {
|
||||
bottom: 9px;
|
||||
position: absolute;
|
||||
right: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.subject {
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,.85) , rgba(255,255,255,.35));
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
box-shadow: 0 0 2px #000000, 0 0 10px #000000;
|
||||
margin-left: 40%;
|
||||
margin-right: 40%;
|
||||
padding: 5px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
z-index: $zindex3;
|
||||
|
||||
&.subject_slide-in {
|
||||
top: 80px;
|
||||
@include transition(top .3s ease-in);
|
||||
}
|
||||
|
||||
&.subject_slide-out {
|
||||
top: 0;
|
||||
@include transition(top .3s ease-out);
|
||||
}
|
||||
}
|
||||
|
||||
a.button>#avatar {
|
||||
border-radius: 50%;
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
#feedbackButton {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,9 +344,13 @@ a.button>#avatar {
|
||||
* START of fade in animation for main toolbar
|
||||
*/
|
||||
.fadeIn {
|
||||
@include animation('fadeIn .3s linear .2s forwards');
|
||||
opacity: 1;
|
||||
|
||||
@include transition(all .3s ease-in);
|
||||
}
|
||||
|
||||
.fadeOut {
|
||||
@include animation('fadeOut .5s linear forwards');
|
||||
opacity: 0;
|
||||
|
||||
@include transition(all .3s ease-out);
|
||||
}
|
||||
|
||||
@@ -4,22 +4,21 @@
|
||||
* Style variables
|
||||
*/
|
||||
$baseFontFamily: 'open_sanslight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
$toolbarFontSize: 1.9em;
|
||||
$hangupColor: #bf2117;
|
||||
$hangupFontSize: 2em;
|
||||
|
||||
/**
|
||||
* Size variables.
|
||||
*/
|
||||
$defaultToolbarSize: 50px;
|
||||
|
||||
// Video layout.
|
||||
$thumbnailToolbarHeight: 22px;
|
||||
$thumbnailIndicatorBorder: 2px;
|
||||
$thumbnailIndicatorSize: $thumbnailToolbarHeight;
|
||||
$thumbnailVideoMargin: 5px;
|
||||
$thumbnailVideoMargin: 2px;
|
||||
$thumbnailsBorder: 2px;
|
||||
$thumbnailVideoBorder: 2px;
|
||||
$hideFilmstripButtonWidth: 17px;
|
||||
$filmstripToggleButtonWidth: 17px;
|
||||
|
||||
|
||||
/**
|
||||
@@ -34,14 +33,16 @@ $tooltipBg: rgba(0,0,0, 0.7);
|
||||
/**
|
||||
* Toolbar
|
||||
*/
|
||||
$toolbarTitleColor: #FFFFFF;
|
||||
$toolbarTitleFontSize: 19px;
|
||||
$defaultToolbarSize: 50px;
|
||||
$splitterToolbarButtonMargin: 18px;
|
||||
$toolbarBackground: rgba(0, 0, 0, 0.5);
|
||||
$toolbarSelectBackground: rgba(0, 0, 0, .6);
|
||||
$toolbarBadgeBackground: #165ECC;
|
||||
$toolbarBadgeColor: #FFFFFF;
|
||||
$toolbarFontSize: 1.9em;
|
||||
$toolbarSelectBackground: rgba(0, 0, 0, .6);
|
||||
$toolbarTitleColor: #FFFFFF;
|
||||
$toolbarTitleFontSize: 19px;
|
||||
$toolbarToggleBackground: #12499C;
|
||||
$splitterToolbarButtonMargin: 18px;
|
||||
|
||||
/**
|
||||
* Main controls
|
||||
@@ -78,6 +79,11 @@ $rateStarDefault: #ccc;
|
||||
$rateStarActivity: #165ecc;
|
||||
$rateStarSize: 34px;
|
||||
|
||||
/**
|
||||
* Modals
|
||||
*/
|
||||
$modalButtonFontSize: 14px;
|
||||
|
||||
/**
|
||||
* Notifications
|
||||
*/
|
||||
@@ -104,13 +110,26 @@ $happySoftwareBackground: transparent;
|
||||
/**
|
||||
* Z-indexes. TODO: Replace this by a function.
|
||||
*/
|
||||
$tooltipsZ: 901;
|
||||
$toolbarZ: 900;
|
||||
$overlayZ: 902;
|
||||
$notificationZ: 1012;
|
||||
$ringingZ: 800;
|
||||
$dropdownZ: 901;
|
||||
$zindex0: 0;
|
||||
$zindex1: 1;
|
||||
$zindex2: 2;
|
||||
$zindex3: 3;
|
||||
$filmstripVideosZ: 5;
|
||||
$zindex10: 10;
|
||||
$reloadZ: 20;
|
||||
$poweredByZ: 100;
|
||||
$ringingZ: 300;
|
||||
$sideToolbarContainerZ: 300;
|
||||
$toolbarZ: 400;
|
||||
$tooltipsZ: 401;
|
||||
$dropdownMaskZ: 900;
|
||||
$dropdownZ: 901;
|
||||
$overlayZ: 902;
|
||||
$jitsipopoverZ: 1010;
|
||||
$centeredVideoLabelZ: 1011;
|
||||
$notificationZ: 1012;
|
||||
$popoverZ: 1015;
|
||||
|
||||
|
||||
/**
|
||||
* Font Colors
|
||||
@@ -129,8 +148,13 @@ $linkFontColor: #489afe;
|
||||
$linkHoverFontColor: #287ade;
|
||||
|
||||
/**
|
||||
* Landing
|
||||
* Unsupported browser
|
||||
*/
|
||||
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
|
||||
$unsupportedBrowserButtonBgColor: #ff9a00;
|
||||
$unsupportedBrowserTextColor: #4a4a4a;
|
||||
$unsupportedBrowserTextSmallFontSize: 17px;
|
||||
$unsupportedBrowserTitleColor: #fff;
|
||||
$unsupportedBrowserTitleFontSize: 24px;
|
||||
$unsupportedDesktopBrowserTextColor: rgba(255, 255, 255, 0.7);
|
||||
$unsupportedDesktopBrowserTextFontSize: 21px;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
&__toptoolbar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 3;
|
||||
z-index: $zindex3;
|
||||
width: 100%;
|
||||
box-sizing: border-box; // Includes the padding in the 100% width.
|
||||
}
|
||||
@@ -59,7 +59,7 @@
|
||||
float: left;
|
||||
@include circle($thumbnailIndicatorSize);
|
||||
box-sizing: border-box;
|
||||
z-index: 3;
|
||||
z-index: $zindex3;
|
||||
background: $dominantSpeakerBg;
|
||||
color: $thumbnailPictogramColor;
|
||||
border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor;
|
||||
@@ -113,7 +113,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
visibility: hidden;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
z-index: $zindex1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -171,7 +171,7 @@
|
||||
}
|
||||
|
||||
#etherpad {
|
||||
z-index: 0;
|
||||
z-index: $zindex0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +193,7 @@
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
line-height: $thumbnailToolbarHeight;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +233,7 @@
|
||||
padding: 3px 5px;
|
||||
font-size: 9pt;
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,7 +283,7 @@
|
||||
top: 0px;
|
||||
right: 0;
|
||||
margin: 7px;
|
||||
z-index: 3;
|
||||
z-index: $zindex3;
|
||||
width: 18px;
|
||||
height: 13px;
|
||||
color: #FFF;
|
||||
@@ -301,7 +301,7 @@
|
||||
margin-top: -17px;
|
||||
width: 6px;
|
||||
height: 35px;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
border: none;
|
||||
|
||||
.audiodot-top,
|
||||
@@ -344,13 +344,13 @@
|
||||
background-clip: padding-box;
|
||||
-webkit-border-radius: 5px;
|
||||
-webkit-background-clip: padding-box;
|
||||
z-index: 20; /*The reload button should appear on top of the header!*/
|
||||
z-index: $reloadZ; /*The reload button should appear on top of the header!*/
|
||||
}
|
||||
|
||||
.audiolevel {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
z-index: $zindex0;
|
||||
border-radius:1px;
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -408,7 +408,7 @@
|
||||
.noMic {
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
z-index: 1;
|
||||
z-index: $zindex1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url("../images/noMic.png");
|
||||
@@ -420,7 +420,7 @@
|
||||
.noVideo {
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
z-index: 1;
|
||||
z-index: $zindex1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url("../images/noVideo.png");
|
||||
@@ -453,7 +453,7 @@
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
@@ -477,7 +477,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
top:50%;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
@@ -506,7 +506,7 @@
|
||||
#videoResolutionLabel,
|
||||
.centeredVideoLabel {
|
||||
display: none;
|
||||
z-index: 1011;
|
||||
z-index: $centeredVideoLabelZ;
|
||||
}
|
||||
|
||||
.centeredVideoLabel {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #acacac;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
#disable_welcome:checked + label
|
||||
@@ -35,7 +35,7 @@
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #acacac;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
#enter_room_form {
|
||||
@@ -74,7 +74,7 @@
|
||||
float: left;
|
||||
background-color: #FFFFFF;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
&__reload {
|
||||
@@ -83,7 +83,7 @@
|
||||
color: #acacac;
|
||||
font-size: 1.9em;
|
||||
line-height: 55px;
|
||||
z-index: 3;
|
||||
z-index: $zindex3;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
@@ -104,7 +104,7 @@
|
||||
outline: none;
|
||||
float:left;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
&_overlay {
|
||||
color: $primaryButtonColor;
|
||||
background-color: $overlayButtonBg;
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
background-color: $primaryButtonBackground;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
&_primary {
|
||||
background-color: $primaryButtonBackground;
|
||||
border: 1px solid $primaryButtonBackground;
|
||||
@@ -86,4 +98,4 @@
|
||||
&_center {
|
||||
float: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
css/components/_input-slider.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Disable the default webkit styles for range inputs (sliders).
|
||||
*/
|
||||
input[type=range]{
|
||||
-webkit-appearance: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the default focus styles for webkit range inputs (sliders).
|
||||
*/
|
||||
input[type=range]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the mixin for a range input style.
|
||||
*/
|
||||
@include slider {
|
||||
background: $sliderTrackBackground;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
height: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the mixin for a range input thumb style.
|
||||
*/
|
||||
@include slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
background: white;
|
||||
border: 1px solid $sliderThumbBackground;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 0px 1px $sliderThumbBackground;
|
||||
cursor: pointer;
|
||||
height: 14px;
|
||||
margin-top: -4px;
|
||||
width: 14px;
|
||||
}
|
||||
@@ -8,4 +8,13 @@
|
||||
text-decoration: underline;
|
||||
@include transition(color .1s ease-in);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper links are links that are meant to open a documentation page or more
|
||||
* detailed info.
|
||||
*/
|
||||
.helper-link {
|
||||
@extend .link;
|
||||
font-size: 12px;
|
||||
}
|
||||
@@ -37,8 +37,11 @@
|
||||
@import 'overlay/overlay';
|
||||
@import 'inlay';
|
||||
@import 'reload_overlay/reload_overlay';
|
||||
@import 'modals/desktop-picker/desktop-picker';
|
||||
@import 'modals/device-selection/device-selection';
|
||||
@import 'modals/dialog';
|
||||
@import 'modals/feedback/feedback';
|
||||
@import 'modals/speaker_stats/speaker_stats';
|
||||
@import 'videolayout_default';
|
||||
@import 'notice';
|
||||
@import 'popup_menu';
|
||||
@@ -52,7 +55,6 @@
|
||||
@import 'welcome_page';
|
||||
@import 'toolbars';
|
||||
@import 'side_toolbar_container';
|
||||
@import 'device_settings_dialog';
|
||||
@import 'jquery.contextMenu';
|
||||
@import 'keyboard-shortcuts';
|
||||
@import 'redirect_page';
|
||||
@@ -60,14 +62,14 @@
|
||||
@import 'components/link';
|
||||
@import 'shortcuts/main';
|
||||
@import 'components/button-control';
|
||||
@import 'components/_input-control.scss';
|
||||
@import 'components/input-control';
|
||||
@import 'components/input-slider';
|
||||
@import "modals/invite/invite";
|
||||
@import "connection-info";
|
||||
@import 'aui-components/dropdown';
|
||||
@import '404';
|
||||
@import 'policy';
|
||||
@import 'filmstrip';
|
||||
@import 'unsupported-browser/unsupported-desktop-browser';
|
||||
@import 'unsupported-browser/unsupported-mobile-browser';
|
||||
@import 'unsupported-browser/main';
|
||||
|
||||
/* Modules END */
|
||||
|
||||
@@ -76,3 +76,7 @@
|
||||
border-bottom: 1px solid $auiBorderColor;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog-footer {
|
||||
font-size: $modalButtonFontSize;
|
||||
}
|
||||
|
||||
59
css/modals/desktop-picker/_desktop-picker.scss
Normal file
@@ -0,0 +1,59 @@
|
||||
.desktop-picker-pane {
|
||||
height: 320px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
|
||||
&.source-type-screen {
|
||||
.desktop-picker-source {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.desktop-source-preview-thumbnail {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.desktop-source-preview-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.source-type-window {
|
||||
.desktop-picker-source {
|
||||
display: inline-block;
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.desktop-picker-source {
|
||||
color: $defaultDarkFontColor;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
&.is-selected {
|
||||
.desktop-source-preview-image-container {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: $borderRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.desktop-source-preview-label {
|
||||
margin-top: 3px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.desktop-source-preview-thumbnail {
|
||||
box-shadow: 5px 5px 5px grey;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.desktop-source-preview-image-container {
|
||||
padding: 10px;
|
||||
}
|
||||
84
css/modals/device-selection/_device-selection.scss
Normal file
@@ -0,0 +1,84 @@
|
||||
.device-selection {
|
||||
color: $feedbackInputTextColor;
|
||||
|
||||
.device-selectors {
|
||||
font-size: 14px;
|
||||
|
||||
> div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
> div:last-child {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.device-selection-column-selectors,
|
||||
.device-selection-column-video {
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.device-selection-column-selectors {
|
||||
width: 46%;
|
||||
}
|
||||
.device-selection-column-video {
|
||||
width: 49%;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.device-selection-video-container {
|
||||
background: black;
|
||||
height: 156px;
|
||||
margin: 15px 0 5px;
|
||||
|
||||
.video-input-preview {
|
||||
position: relative;
|
||||
|
||||
.video-input-preview-muted {
|
||||
color: $participantNameColor;
|
||||
display: none;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
&.video-muted .video-input-preview-muted {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.video-input-preview-display {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.audio-output-preview {
|
||||
text-align: right;
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.audio-input-preview {
|
||||
background: #f4f5f7;
|
||||
border-radius: 5px;
|
||||
height: 6px;
|
||||
|
||||
.audio-input-preview-level {
|
||||
background: #0052cc;
|
||||
border-radius: 5px;
|
||||
height: 100%;
|
||||
-webkit-transition: width .1s ease-in-out;
|
||||
-moz-transition: width .1s ease-in-out;
|
||||
-o-transition: width .1s ease-in-out;
|
||||
transition: width .1s ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
css/modals/speaker_stats/_speaker_stats.scss
Normal file
@@ -0,0 +1,56 @@
|
||||
.speaker-stats {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
color: $auiDialogColor;
|
||||
width: 100%;
|
||||
font-weight: 500;
|
||||
|
||||
.speaker-stats-item__status-dot {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
|
||||
&.status-active {
|
||||
background: green;
|
||||
}
|
||||
|
||||
&.status-inactive {
|
||||
background: gray;
|
||||
}
|
||||
}
|
||||
|
||||
.status-user-left {
|
||||
color: $placeHolderColor;
|
||||
}
|
||||
|
||||
.speaker-stats-item__status,
|
||||
.speaker-stats-item__name,
|
||||
.speaker-stats-item__time {
|
||||
display: inline-block;
|
||||
margin: 5px 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.speaker-stats-item__status {
|
||||
width: 5%;
|
||||
}
|
||||
.speaker-stats-item__name {
|
||||
width: 40%;
|
||||
}
|
||||
.speaker-stats-item__time {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
.speaker-stats-item:nth-child(even) {
|
||||
background: whitesmoke;
|
||||
}
|
||||
|
||||
.speaker-stats-item__name,
|
||||
.speaker-stats-item__time {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,16 @@
|
||||
position: fixed;
|
||||
z-index: $overlayZ;
|
||||
background: $defaultBackground;
|
||||
&.filmstrip-only {
|
||||
@include transparentBg($filmstripOnlyOverlayBg, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
&__container-light {
|
||||
@include transparentBg($defaultBackground, 0.7);
|
||||
&.filmstrip-only {
|
||||
@include transparentBg($filmstripOnlyOverlayBg, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
@@ -21,6 +27,11 @@
|
||||
width: 56%;
|
||||
left: 50%;
|
||||
@include transform(translateX(-50%));
|
||||
&.filmstrip-only {
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
@include transform(none);
|
||||
}
|
||||
|
||||
&_bottom {
|
||||
position: absolute;
|
||||
@@ -33,4 +44,4 @@
|
||||
bottom: 24px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.reload_overlay_msg {
|
||||
.reload_overlay_text {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
@@ -13,4 +13,7 @@
|
||||
#reloadProgressBar {
|
||||
width: 180px;
|
||||
margin: 5px auto;
|
||||
}
|
||||
> .aui-progress-indicator-value {
|
||||
background: $reloadProgressBarBg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ $baseLight: #FFFFFF;
|
||||
*/
|
||||
$controlBackground: $baseLight;
|
||||
$controlColor: #333333;
|
||||
$sliderTrackBackground: #474747;
|
||||
$sliderThumbBackground: #3572b0;
|
||||
|
||||
/**
|
||||
* Buttons
|
||||
@@ -33,10 +35,14 @@ $primaryButtonFontWeight: 400;
|
||||
|
||||
$buttonShadowColor: #192d4f;
|
||||
|
||||
$overlayButtonBg: #0074E0;
|
||||
|
||||
/**
|
||||
* Color variables
|
||||
**/
|
||||
$defaultBackground: #474747;
|
||||
$filmstripOnlyOverlayBg: #000;
|
||||
$reloadProgressBarBg: #0074E0;
|
||||
|
||||
/**
|
||||
* Connection indicator
|
||||
@@ -58,6 +64,10 @@ $dialogTitleFontWeight: 400;
|
||||
**/
|
||||
$inlayColorBg: lighten($defaultBackground, 20%);
|
||||
$inlayBorderColor: lighten($auiDialogContentBg, 10%);
|
||||
$inlayIconBg: #000;
|
||||
$inlayIconColor: #fff;
|
||||
$inlayFilmstripOnlyColor: #474747;
|
||||
$inlayFilmstripOnlyBg: #fff;
|
||||
|
||||
// Main controls
|
||||
$inputBackground: $controlBackground;
|
||||
|
||||
3
css/unsupported-browser/_main.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
@import 'no-mobile-app';
|
||||
@import 'unsupported-desktop-browser';
|
||||
@import 'unsupported-mobile-browser';
|
||||
21
css/unsupported-browser/_no-mobile-app.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
.no-mobile-app {
|
||||
margin: 30% auto 0;
|
||||
max-width: 25em;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
|
||||
&__title {
|
||||
border-bottom: 1px solid $auiBorderColor;
|
||||
color: $unsupportedBrowserTitleColor;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.5px;
|
||||
padding-bottom: em(17, 24);
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: $unsupportedBrowserTextSmallFontSize;
|
||||
font-weight: 300;
|
||||
letter-spacing: 1px;
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +1,39 @@
|
||||
.supported-browser {
|
||||
color: #929391;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 1em 7px;
|
||||
vertical-align: middle;
|
||||
width: 138px;
|
||||
.unsupported-desktop-browser {
|
||||
@include absoluteAligning();
|
||||
|
||||
&__button {
|
||||
background-color: #62c82a;
|
||||
border: 1px solid #3c8117;
|
||||
border-radius: 10px;
|
||||
color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
height: 26px;
|
||||
margin: 15px auto 0px auto;
|
||||
padding-top: 13px;
|
||||
text-align: center;
|
||||
width: 115px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
|
||||
&__title {
|
||||
color: $unsupportedBrowserTitleColor;
|
||||
font-weight: 300;
|
||||
font-size: $unsupportedBrowserTitleFontSize;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
color: $unsupportedDesktopBrowserTextColor;
|
||||
font-size: $unsupportedDesktopBrowserTextFontSize;
|
||||
font-weight: 300;
|
||||
letter-spacing: 1px;
|
||||
margin-top: 16px;
|
||||
|
||||
&_small {
|
||||
@extend .unsupported-desktop-browser__description;
|
||||
font-size: $unsupportedBrowserTextSmallFontSize;
|
||||
}
|
||||
}
|
||||
|
||||
&__link {
|
||||
color: #087dba;
|
||||
text-decoration: none;
|
||||
color: $linkFontColor;
|
||||
@include transition(color .1s ease-out);
|
||||
|
||||
&:hover {
|
||||
color: $linkHoverFontColor;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
@include transition(color .1s ease-in);
|
||||
}
|
||||
|
||||
&:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-list
|
||||
{
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
&__logo {
|
||||
margin: 20px auto 0px auto;
|
||||
|
||||
&_chrome {
|
||||
background-image: url('../../images/chrome.png');
|
||||
height: 78px;
|
||||
width: 78px;
|
||||
}
|
||||
|
||||
&_chromium {
|
||||
background-image: url('../../images/chromium.png');
|
||||
height: 78px;
|
||||
width: 77px;
|
||||
}
|
||||
|
||||
&_firefox {
|
||||
background-image: url('../../images/firefox.png');
|
||||
height: 80px;
|
||||
width: 86px;
|
||||
}
|
||||
|
||||
&_opera {
|
||||
background-image: url('../../images/opera.png');
|
||||
height: 78px;
|
||||
width: 73px;
|
||||
}
|
||||
|
||||
&_ie {
|
||||
background-image: url('../../images/ie.png');
|
||||
height: 78px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
&_safari {
|
||||
background-image: url('../../images/safari.png');
|
||||
height: 79px;
|
||||
width: 78px;
|
||||
}
|
||||
}
|
||||
|
||||
&__text
|
||||
{
|
||||
line-height: 1.2em;
|
||||
|
||||
&_small {
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
|
||||
&__tile {
|
||||
background-color: #e8e8e8;
|
||||
border: 1px solid #cfcfcf;
|
||||
border-radius: 10px;
|
||||
height: 163px;
|
||||
margin-top: 5px;
|
||||
width: 138px;
|
||||
}
|
||||
}
|
||||
|
||||
.unsupported-desktop-browser {
|
||||
display: block;
|
||||
height: 565px;
|
||||
margin: auto;
|
||||
overflow:hidden;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0; left: 0; bottom: 0; right: 0;
|
||||
width:500px;
|
||||
|
||||
&__page {
|
||||
display:inline-block;
|
||||
font-size: 28px;
|
||||
padding-top: 25px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin: 0 auto;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
&-wrapper {
|
||||
background: #fff;
|
||||
display: block;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
2
debian/jitsi-meet-tokens.install
vendored
@@ -1 +1 @@
|
||||
prosody-plugins/ /usr/share/jitsi-meet/
|
||||
resources/prosody-plugins/ /usr/share/jitsi-meet/
|
||||
|
||||
9
debian/jitsi-meet-web-config.postinst
vendored
@@ -65,7 +65,7 @@ case "$1" in
|
||||
# SSL for nginx
|
||||
db_get jitsi-meet/cert-choice
|
||||
CERT_CHOICE="$RET"
|
||||
UPLOADED_CERT_CHOICE="A certificate is available and the files are uploaded on the server"
|
||||
UPLOADED_CERT_CHOICE="I want to use my own certificate"
|
||||
|
||||
if [ "$CERT_CHOICE" = "$UPLOADED_CERT_CHOICE" ] ; then
|
||||
db_set jitsi-meet/cert-path-key "/etc/ssl/$JVB_HOSTNAME.key"
|
||||
@@ -223,6 +223,13 @@ case "$1" in
|
||||
invoke-rc.d apache2 reload
|
||||
fi
|
||||
|
||||
echo "----------------"
|
||||
echo ""
|
||||
echo "You can now switch to a Let’s Encrypt certificate. To do so, execute:"
|
||||
echo "/usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh"
|
||||
echo ""
|
||||
echo "----------------"
|
||||
|
||||
# and we're done with debconf
|
||||
db_stop
|
||||
;;
|
||||
|
||||
3
debian/jitsi-meet-web-config.templates
vendored
@@ -1,9 +1,10 @@
|
||||
Template: jitsi-meet/cert-choice
|
||||
Type: select
|
||||
__Choices: Self-signed certificate will be generated, A certificate is available and the files are uploaded on the server
|
||||
__Choices: Generate a new self-signed certificate (You will later get a chance to obtain a Let's encrypt certificate), I want to use my own certificate
|
||||
_Description: SSL certificate for the Jitsi Meet instance
|
||||
Jitsi Meet is best to be set up with an SSL certificate.
|
||||
Having no certificate, a self-signed one will be generated.
|
||||
By choosing self-signed you will later have a chance to install Let’s Encrypt certificates.
|
||||
Having a certificate signed by a recognised CA, it can be uploaded on the server
|
||||
and point its location. The default filenames will be /etc/ssl/--domain.name--.key
|
||||
for the key and /etc/ssl/--domain.name--.crt for the certificate.
|
||||
|
||||
5
debian/jitsi-meet-web.install
vendored
@@ -1,11 +1,14 @@
|
||||
*.js /usr/share/jitsi-meet/
|
||||
interface_config.js /usr/share/jitsi-meet/
|
||||
logging_config.js /usr/share/jitsi-meet/
|
||||
*.json /usr/share/jitsi-meet/
|
||||
*.html /usr/share/jitsi-meet/
|
||||
*.ico /usr/share/jitsi-meet/
|
||||
libs /usr/share/jitsi-meet/
|
||||
static /usr/share/jitsi-meet/
|
||||
css/all.css /usr/share/jitsi-meet/css/
|
||||
sounds /usr/share/jitsi-meet/
|
||||
fonts /usr/share/jitsi-meet/
|
||||
images /usr/share/jitsi-meet/
|
||||
lang /usr/share/jitsi-meet/
|
||||
connection_optimization /usr/share/jitsi-meet/
|
||||
resources/*.sh /usr/share/jitsi-meet/scripts/
|
||||
|
||||
4
debian/po/templates.pot
vendored
@@ -20,13 +20,13 @@ msgstr ""
|
||||
#. Type: select
|
||||
#. Choices
|
||||
#: ../jitsi-meet-web-config.templates:1001
|
||||
msgid "Self-signed certificate will be generated"
|
||||
msgid "Generate a new self-signed certificate (You will later get a chance to obtain a Let's encrypt certificate)"
|
||||
msgstr ""
|
||||
|
||||
#. Type: select
|
||||
#. Choices
|
||||
#: ../jitsi-meet-web-config.templates:1001
|
||||
msgid "A certificate is available and the files are uploaded on the server"
|
||||
msgid "I want to use my own certificate"
|
||||
msgstr ""
|
||||
|
||||
#. Type: select
|
||||
|
||||
71
doc/api.md
@@ -10,37 +10,56 @@ To embed Jitsi Meet in your application you need to add the Jitsi Meet API libra
|
||||
<script src="https://meet.jit.si/external_api.js"></script>
|
||||
```
|
||||
|
||||
The next step for embedding Jitsi Meet is to create the Jitsi Meet API object:
|
||||
|
||||
```javascript
|
||||
<script>
|
||||
var domain = "meet.jit.si";
|
||||
var room = "JitsiMeetAPIExample";
|
||||
var width = 700;
|
||||
var height = 700;
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height);
|
||||
</script>
|
||||
```
|
||||
|
||||
You can use the above lines to indicate where exactly you want the Jitsi Meet conference to be placed in your HTML code,
|
||||
or you can specify the parent HTML element for the Jitsi Meet conference in the `JitsiMeetExternalAPI`
|
||||
constructor:
|
||||
## API
|
||||
|
||||
### `api = new JitsiMeetExternalAPI(domain, room, [width], [height], [htmlElement], [configOverwite], [interfaceConfigOverwrite], [noSsl], [jwt])`
|
||||
|
||||
The next step for embedding Jitsi Meet is to create the Jitsi Meet API object.
|
||||
Its constructor gets a number of options:
|
||||
|
||||
* **domain**: domain used to build the conference URL, "meet.jit.si" for
|
||||
example.
|
||||
* **room**: name of the room to join.
|
||||
* **width**: (optional) width for the iframe which will be created.
|
||||
* **height**: (optional) height for the iframe which will be created.
|
||||
* **htmlElement**: (optional) HTL DOM Element where the iframe will be added as
|
||||
a child.
|
||||
* **configOverwite**: (optional) JS object with overrides for options defined in
|
||||
[config.js].
|
||||
* **interfaceConfigOverwrite**: (optional) JS object with overrides for options
|
||||
defined in [interface_config.js].
|
||||
* **noSsl**: (optional, defaults to true) Boolean indicating if the server
|
||||
should be contacted using HTTP or HTTPS.
|
||||
* **jwt**: (optional) [JWT](https://jwt.io/) token.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var domain = "meet.jit.si";
|
||||
var room = "JitsiMeetAPIExample";
|
||||
var width = 700;
|
||||
var height = 700;
|
||||
var htmlElement = document.querySelector('#meet');
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
|
||||
```
|
||||
|
||||
If you don't specify the room the user will enter in new conference with a random room name.
|
||||
|
||||
You can overwrite options set in [config.js]() and [interface_config.js](). For example, to enable the film-strip-only interface mode and disable simulcast, you can use:
|
||||
You can overwrite options set in [config.js] and [interface_config.js].
|
||||
For example, to enable the filmstrip-only interface mode, you can use:
|
||||
|
||||
```javascript
|
||||
var configOverwrite = {disableSimulcast: true};
|
||||
var interfaceConfigOverwrite = {filmStripOnly: true};
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite);
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, undefined, undefined, interfaceConfigOverwrite);
|
||||
```
|
||||
|
||||
## Controlling the embedded Jitsi Meet Conference
|
||||
You can also pass a jwt token to Jitsi Meet:
|
||||
|
||||
```javascript
|
||||
var jwt = "<jwt_token>";
|
||||
var noSsl = false;
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite, noSsl, jwt);
|
||||
```
|
||||
|
||||
### Controlling the embedded Jitsi Meet Conference
|
||||
|
||||
You can control the embedded Jitsi Meet conference using the `JitsiMeetExternalAPI` object by using `executeCommand`:
|
||||
|
||||
@@ -65,7 +84,7 @@ api.executeCommand('toggleAudio')
|
||||
api.executeCommand('toggleVideo')
|
||||
```
|
||||
|
||||
* **toggleFilmStrip** - Hides / shows the film strip. No arguments are required.
|
||||
* **toggleFilmStrip** - Hides / shows the filmstrip. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleFilmStrip')
|
||||
```
|
||||
@@ -104,12 +123,13 @@ You can also execute multiple commands using the `executeCommands` method:
|
||||
```javascript
|
||||
api.executeCommands(commands)
|
||||
```
|
||||
The `commands` parameter is an object with the names of the commands as keys and the arguments for the commands asvalues:
|
||||
The `commands` parameter is an object with the names of the commands as keys and the arguments for the commands as values:
|
||||
```javascript
|
||||
api.executeCommands({displayName: ['nickname'], toggleAudio: []});
|
||||
```
|
||||
|
||||
You can add event listeners to the embedded Jitsi Meet using the `addEventListener` method.
|
||||
**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods (`addListener` or `on`).**
|
||||
```javascript
|
||||
api.addEventListener(event, listener)
|
||||
```
|
||||
@@ -179,6 +199,7 @@ changes. The listener will receive an object with the following structure:
|
||||
You can also add multiple event listeners by using `addEventListeners`.
|
||||
This method requires one argument of type Object. The object argument must
|
||||
have the names of the events as keys and the listeners of the events as values.
|
||||
**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods.**
|
||||
|
||||
```javascript
|
||||
function incomingMessageListener(object)
|
||||
@@ -197,12 +218,13 @@ api.addEventListeners({
|
||||
```
|
||||
|
||||
If you want to remove a listener you can use `removeEventListener` method with argument the name of the event.
|
||||
|
||||
**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods( `removeListener`).**
|
||||
```javascript
|
||||
api.removeEventListener("incomingMessage");
|
||||
```
|
||||
|
||||
If you want to remove more than one event you can use `removeEventListeners` method with an Array with the names of the events as an argument.
|
||||
**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods.**
|
||||
```javascript
|
||||
api.removeEventListeners(["incomingMessage", "outgoingMessageListener"]);
|
||||
```
|
||||
@@ -221,3 +243,4 @@ NOTE: It's a good practice to remove the conference before the page is unloaded.
|
||||
|
||||
[config.js]: https://github.com/jitsi/jitsi-meet/blob/master/config.js
|
||||
[interface_config.js]: https://github.com/jitsi/jitsi-meet/blob/master/interface_config.js
|
||||
[EventEmitter]: https://nodejs.org/api/events.html
|
||||
|
||||
@@ -82,3 +82,12 @@
|
||||
imports in other files should use the same name. Don't define the class
|
||||
`Registry` in ReducerRegistry.js and then import it as `Reducers` in other
|
||||
files.
|
||||
|
||||
* The names of global constants (including ES6 module-global constants) should
|
||||
be written in uppercase with underscores to separate words. For example,
|
||||
`BACKGROUND_COLOR`.
|
||||
|
||||
* The underscore character at the beginning of a name signals that the
|
||||
respective variable, function, property is non-public i.e. private, protected,
|
||||
or internal. In contrast, the lack of an underscore at the beginning of a name
|
||||
signals public API.
|
||||
|
||||
@@ -20,7 +20,7 @@ server {
|
||||
|
||||
root /usr/share/jitsi-meet;
|
||||
index index.html index.htm;
|
||||
error_page 404 /404.html;
|
||||
error_page 404 /static/404.html;
|
||||
|
||||
location /config.js {
|
||||
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
ErrorDocument 404 /static/404.html
|
||||
|
||||
Alias "/config.js" "/etc/jitsi/meet/jitsi-meet.example.com-config.js"
|
||||
<Location /config.js>
|
||||
Require all granted
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# Overview
|
||||
Jitsi Meet supports logging to an [InfluxDB](http://influxdb.com/) database.
|
||||
|
||||
# Configuration
|
||||
The following needs to be done to enable this functionality.
|
||||
|
||||
## Install InfluxDB
|
||||
The details are outside the scope of the document, see http://influxdb.com/download/ .
|
||||
|
||||
## Create an InfluxDB database
|
||||
Use the InfluxDB admin interface (running on port 8083) and create a database. In this example we name it <code>jitsi_database</code>
|
||||
|
||||
## Enable logging for Jitsi Videobridge
|
||||
Add the following properties to <code>/usr/share/jitsi-videobridge/.sip-communicator/sip-communicator.properties</code>.
|
||||
|
||||
- org.jitsi.videobridge.log.INFLUX_DB_ENABLED=true
|
||||
- org.jitsi.videobridge.log.INFLUX_URL_BASE=http://influxdb.example.com:8086
|
||||
- org.jitsi.videobridge.log.INFLUX_DATABASE=jitsi_database
|
||||
- org.jitsi.videobridge.log.INFLUX_USER=user
|
||||
- org.jitsi.videobridge.log.INFLUX_PASS=pass
|
||||
|
||||
## Enable logging for Jicofo
|
||||
Add the same properties as above to <code>/usr/share/jicofo/.sip-communicator/sip-communicator.properties</code>.
|
||||
|
||||
## Enable logging for Jitsi Meet itself
|
||||
Change "logStats" to "true" in <code>/etc/jitsi/meet/you-domain.config.js</code> or the <code>config.js</code> file used in your installation.
|
||||
|
||||
# User interface
|
||||
You can explore the database using the [Jiloin](https://github.com/jitsi/jiloin) web interface.
|
||||
@@ -6,6 +6,34 @@ change references to that to match your host, and generate some passwords for
|
||||
|
||||
There are also some complete [example config files](https://github.com/jitsi/jitsi-meet/tree/master/doc/example-config-files/) available, mentioned in each section.
|
||||
|
||||
## Network description
|
||||
|
||||
This how the network look like:
|
||||
```
|
||||
+ +
|
||||
| |
|
||||
| |
|
||||
v |
|
||||
443 |
|
||||
+-------+ |
|
||||
| | |
|
||||
| NginX | |
|
||||
| | |
|
||||
+--+-+--+ |
|
||||
| | |
|
||||
+------------+ | | +--------------+ |
|
||||
| | | | | | |
|
||||
| jitsi-meet +<---+ +--->+ prosody/xmpp | |
|
||||
| |files 5280 | | |
|
||||
+------------+ +--------------+ v
|
||||
5222,5347^ ^5347 4443
|
||||
+--------+ | | +-------------+
|
||||
| | | | | |
|
||||
| jicofo +----^ ^----+ videobridge |
|
||||
| | | |
|
||||
+--------+ +-------------+
|
||||
```
|
||||
|
||||
## Install prosody
|
||||
```sh
|
||||
apt-get install prosody
|
||||
@@ -76,7 +104,9 @@ Add a new file `jitsi.example.com` in `/etc/nginx/sites-available` (see also the
|
||||
server_names_hash_bucket_size 64;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen 443;
|
||||
# tls configuration that is not covered in this guide
|
||||
# we recommend the use of https://certbot.eff.org/
|
||||
server_name jitsi.example.com;
|
||||
# set the root
|
||||
root /srv/jitsi.example.com;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Jitsi Meet mobile apps
|
||||
|
||||
Jitsi Meet can also be built as a standalone mobile application for
|
||||
iOS and Android. It uses the [React Native]() framework.
|
||||
iOS and Android. It uses the [React Native] framework.
|
||||
|
||||
First make sure the [React Native dependencies]() are installed.
|
||||
First make sure the [React Native dependencies] are installed.
|
||||
|
||||
**NOTE**: This document assumes the app is being built on a macOS system.
|
||||
|
||||
@@ -22,6 +22,8 @@ work properly with the native plugins we require.
|
||||
npm install -g ios-deploy
|
||||
```
|
||||
|
||||
You may need to add ```--unsafe-perm=true``` if you are running on [Mac OS 10.11 or greater](https://github.com/phonegap/ios-deploy#os-x-1011-el-capitan-or-greater).
|
||||
|
||||
2. Build the app
|
||||
|
||||
There are 2 ways to build the app: using the CLI or using Xcode.
|
||||
@@ -62,8 +64,8 @@ work properly with the native plugins we require.
|
||||
|
||||
## Android
|
||||
|
||||
The [React Native dependencies]() page has very detailed information on how to
|
||||
setup [Android Studio]() and the required components for getting the necessary
|
||||
The [React Native dependencies] page has very detailed information on how to
|
||||
setup [Android Studio] and the required components for getting the necessary
|
||||
build environment. Make sure you follow it closely.
|
||||
|
||||
1. Building the app
|
||||
@@ -79,7 +81,7 @@ build environment. Make sure you follow it closely.
|
||||
|
||||
## Debugging
|
||||
|
||||
The official documentation on [debugging]() is quite extensive, it is the
|
||||
The official documentation on [debugging] is quite extensive, it is the
|
||||
preferred method for debugging.
|
||||
|
||||
**NOTE**: When using Chrome Developer Tools for debugging the JavaScript code
|
||||
|
||||
36
flow-typed/npm/react-i18next_v2.x.x.js
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// flow-typed signature: 57cf34196930be78935a42e5c8ac3cb6
|
||||
// flow-typed version: ae6284e7b7/react-i18next_v2.x.x/flow_>=v0.36.x_<=v0.39.x
|
||||
|
||||
declare module 'react-i18next' {
|
||||
declare type TFunction = (key?: ?string, data?: ?Object) => string;
|
||||
declare type Locales = string | Array<string>;
|
||||
|
||||
declare type StatelessComponent<P> = (props: P) => ?React$Element<any>;
|
||||
|
||||
declare type Comp<P> = StatelessComponent<P> | Class<React$Component<*, P, *>>;
|
||||
|
||||
declare type Translator<OP, P> = {
|
||||
(component: StatelessComponent<P>): Class<React$Component<void, OP, void>>;
|
||||
<Def, St>(component: Class<React$Component<Def, P, St>>): Class<React$Component<Def, OP, St>>;
|
||||
}
|
||||
|
||||
declare function translate<OP, P>(locales: Locales): Translator<OP, P>;
|
||||
|
||||
declare type NamespacesProps = {
|
||||
components: Array<Comp<*>>,
|
||||
i18n: { loadNamespaces: Function },
|
||||
};
|
||||
|
||||
declare function loadNamespaces(props: NamespacesProps): Promise<void>;
|
||||
|
||||
declare type ProviderProps = { i18n: Object, children: React$Element<any> };
|
||||
|
||||
declare var I18nextProvider: Class<React$Component<void, ProviderProps, void>>;
|
||||
|
||||
declare type InterpolateProps = {
|
||||
children?: React$Element<any>,
|
||||
className?: string,
|
||||
};
|
||||
|
||||
declare var Interpolate: Class<React$Component<void, InterpolateProps, void>>;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 234 B |
|
Before Width: | Height: | Size: 611 B |
@@ -113,6 +113,11 @@
|
||||
|
||||
window.setTimeout(
|
||||
function () { window.location.replace(href); }, delay);
|
||||
|
||||
// Call extra handler if defined.
|
||||
if (typeof postLoadErrorHandler === "function") {
|
||||
postLoadErrorHandler();
|
||||
}
|
||||
};
|
||||
window.removeEventListener(
|
||||
'error', loadErrHandler, true /* capture phase */);
|
||||
@@ -122,9 +127,9 @@
|
||||
'error', loadErrHandler, true /* capture phase type of listener */);
|
||||
</script>
|
||||
<script><!--#include virtual="/config.js" --></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
|
||||
<script src="utils.js?v=1"></script>
|
||||
<script src="static/utils.js?v=1"></script>
|
||||
<!--#include virtual="connection_optimization/connection_optimization.html" -->
|
||||
<script src="connection_optimization/do_external_connect.js?v=1"></script>
|
||||
<script src="libs/do_external_connect.min.js?v=1"></script>
|
||||
<script><!--#include virtual="/interface_config.js" --></script>
|
||||
<script><!--#include virtual="/logging_config.js" --></script>
|
||||
<script src="libs/lib-jitsi-meet.min.js?v=139"></script>
|
||||
|
||||
@@ -70,5 +70,16 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
|
||||
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
|
||||
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 undefined,
|
||||
* default to true.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
MOBILE_APP_PROMO: true
|
||||
};
|
||||
|
||||
BIN
ios/app/Images.xcassets/AppIcon.appiconset/AppIcon-76@1x.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
ios/app/Images.xcassets/AppIcon.appiconset/AppIcon-76@2x.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
ios/app/Images.xcassets/AppIcon.appiconset/AppIcon-83.5@2x.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
@@ -2,53 +2,103 @@
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-29@2x.png",
|
||||
"scale" : "2x"
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-29@3x.png",
|
||||
"scale" : "3x"
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-40@2x.png",
|
||||
"scale" : "2x"
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60@2x.png",
|
||||
"scale" : "3x"
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60@2x.png",
|
||||
"scale" : "2x"
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60@3x.png",
|
||||
"scale" : "3x"
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "AppIcon-29@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "AppIcon-40@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "AppIcon-76@1x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "AppIcon-76@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "AppIcon-83.5@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchScreen-480@1x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchScreen-480@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "LaunchScreen-480@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
ios/app/Images.xcassets/LaunchScreen.imageset/LaunchScreen-480@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 278 KiB |
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2</string>
|
||||
<string>1.4</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -80,9 +80,10 @@
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
|
||||
24
ios/app/Proximity.m
Normal file
@@ -0,0 +1,24 @@
|
||||
#import "RCTBridgeModule.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface Proximity : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@implementation Proximity
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
/**
|
||||
* Enables / disables the proximity sensor monitoring. On iOS enabling the
|
||||
* proximity sensor automatically dims the screen and disables touch controls,
|
||||
* so there is nothing else to do (unlike on Android)!
|
||||
*
|
||||
* @param enabled {@code YES} to enable proximity (sensor) monitoring;
|
||||
* {@code NO}, otherwise.
|
||||
*/
|
||||
RCT_EXPORT_METHOD(setEnabled:(BOOL)enabled) {
|
||||
[[UIDevice currentDevice] setProximityMonitoringEnabled:enabled];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -14,6 +14,7 @@
|
||||
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
|
||||
0B42DFAE1E2FD90700111B12 /* AudioMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B42DFAD1E2FD90700111B12 /* AudioMode.m */; };
|
||||
0B96CAF11E8CF0E8005F348C /* Proximity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B96CAF01E8CF0E8005F348C /* Proximity.m */; };
|
||||
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
|
||||
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
|
||||
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
|
||||
@@ -25,6 +26,7 @@
|
||||
2602576C1D0A7703001E3363 /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2602576B1D0A7703001E3363 /* jitsi.ttf */; };
|
||||
3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 821D8ABD506944B4BDBB069B /* libRNVectorIcons.a */; };
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
|
||||
7FAD39BE09A84D6AB0ABACA8 /* libRNBackgroundTimer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27A0018BBB2C4FD5A4F9CE71 /* libRNBackgroundTimer.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA8C046B2BF46279796F07D /* libKCKeepAwake.a */; };
|
||||
B30EF2311DC0ED7C00690F45 /* WebRTC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B30EF2301DC0ED7C00690F45 /* WebRTC.framework */; };
|
||||
@@ -184,6 +186,13 @@
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
B332D04E1E54E3170086EA16 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RNBackgroundTimer;
|
||||
};
|
||||
B3BA19D41DC6B37B00BCD481 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||
@@ -263,7 +272,9 @@
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
|
||||
0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNBackgroundTimer.xcodeproj; path = "../node_modules/react-native-background-timer/ios/RNBackgroundTimer.xcodeproj"; sourceTree = "<group>"; };
|
||||
0B42DFAD1E2FD90700111B12 /* AudioMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AudioMode.m; path = app/AudioMode.m; sourceTree = "<group>"; };
|
||||
0B96CAF01E8CF0E8005F348C /* Proximity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Proximity.m; path = app/Proximity.m; sourceTree = "<group>"; };
|
||||
0EA8C046B2BF46279796F07D /* libKCKeepAwake.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libKCKeepAwake.a; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
|
||||
@@ -277,6 +288,7 @@
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
|
||||
22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
|
||||
2602576B1D0A7703001E3363 /* jitsi.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = jitsi.ttf; path = ../android/app/src/main/assets/fonts/jitsi.ttf; sourceTree = "<group>"; };
|
||||
27A0018BBB2C4FD5A4F9CE71 /* libRNBackgroundTimer.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNBackgroundTimer.a; sourceTree = "<group>"; };
|
||||
5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = KCKeepAwake.xcodeproj; path = "../node_modules/react-native-keep-awake/ios/KCKeepAwake.xcodeproj"; sourceTree = "<group>"; };
|
||||
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
|
||||
@@ -315,7 +327,7 @@
|
||||
BF9643881C34FBC800B0BBDF /* GLKit.framework in Frameworks */,
|
||||
B30EF2311DC0ED7C00690F45 /* WebRTC.framework in Frameworks */,
|
||||
BF96438E1C34FBE100B0BBDF /* VideoToolbox.framework in Frameworks */,
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||
901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */,
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
|
||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
|
||||
@@ -327,8 +339,9 @@
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
|
||||
BFC745141CB829B300673F38 /* libRCTWebRTC.a in Frameworks */,
|
||||
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||
7FAD39BE09A84D6AB0ABACA8 /* libRNBackgroundTimer.a in Frameworks */,
|
||||
3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */,
|
||||
901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -415,6 +428,7 @@
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
B3A9D0241E0481E10009343D /* POSIX.m */,
|
||||
0B96CAF01E8CF0E8005F348C /* Proximity.m */,
|
||||
);
|
||||
name = app;
|
||||
sourceTree = "<group>";
|
||||
@@ -488,6 +502,7 @@
|
||||
BFC7450D1CB829A700673F38 /* RCTWebRTC.xcodeproj */,
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */,
|
||||
0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */,
|
||||
22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
@@ -524,6 +539,14 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B332D0301E54E3170086EA16 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B332D04F1E54E3170086EA16 /* libRNBackgroundTimer.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3BA19B71DC6B02F00BCD481 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -653,6 +676,10 @@
|
||||
ProductGroup = 146834001AC3E56700842450 /* Products */;
|
||||
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = B332D0301E54E3170086EA16 /* Products */;
|
||||
ProjectRef = 0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 26D589F81D0B42EE00FC396B /* Products */;
|
||||
ProjectRef = 22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */;
|
||||
@@ -806,6 +833,13 @@
|
||||
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
B332D04F1E54E3170086EA16 /* libRNBackgroundTimer.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNBackgroundTimer.a;
|
||||
remoteRef = B332D04E1E54E3170086EA16 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
B3BA19D51DC6B37B00BCD481 /* libRCTImage-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
@@ -914,6 +948,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B3A9D0251E0481E10009343D /* POSIX.m in Sources */,
|
||||
0B96CAF11E8CF0E8005F348C /* Proximity.m in Sources */,
|
||||
0B42DFAE1E2FD90700111B12 /* AudioMode.m in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
@@ -952,6 +987,7 @@
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
);
|
||||
@@ -969,6 +1005,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeet.ios;
|
||||
PRODUCT_NAME = "jitsi-meet-react";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -988,6 +1025,7 @@
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
);
|
||||
@@ -1005,6 +1043,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeet.ios;
|
||||
PRODUCT_NAME = "jitsi-meet-react";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -1050,6 +1089,7 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
);
|
||||
@@ -1095,6 +1135,7 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../node_modules/react-native/React/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
);
|
||||
|
||||
@@ -13,5 +13,7 @@
|
||||
"sk": "Slowakisch",
|
||||
"sl": "Slowenisch",
|
||||
"sv": "Schwedisch",
|
||||
"tr": "Türkisch"
|
||||
"tr": "Türkisch",
|
||||
"zhCN": "Chinesisch (China)",
|
||||
"nb": "Norwegisch (Bokmal)"
|
||||
}
|
||||
19
lang/languages-eo.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"en": "",
|
||||
"bg": "",
|
||||
"de": "",
|
||||
"es": "",
|
||||
"fr": "",
|
||||
"hy": "",
|
||||
"it": "",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "",
|
||||
"sl": "",
|
||||
"sv": "",
|
||||
"tr": "",
|
||||
"zhCN": "",
|
||||
"nb": ""
|
||||
}
|
||||
18
lang/languages-nb.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"en": "",
|
||||
"bg": "",
|
||||
"de": "",
|
||||
"es": "",
|
||||
"fr": "",
|
||||
"hy": "",
|
||||
"it": "",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "",
|
||||
"sl": "",
|
||||
"sv": "",
|
||||
"tr": "",
|
||||
"zhCN": ""
|
||||
}
|
||||
@@ -13,5 +13,7 @@
|
||||
"sk": "Eslovac",
|
||||
"sl": "Eslovèn",
|
||||
"sv": "Suedés",
|
||||
"tr": "Turc"
|
||||
"tr": "Turc",
|
||||
"zhCN": "Chinés (China)",
|
||||
"nb": "Norvegian Bokmål"
|
||||
}
|
||||
@@ -6,12 +6,14 @@
|
||||
"fr": "Francês",
|
||||
"hy": "Armênio",
|
||||
"it": "Italiano",
|
||||
"oc": "Provençal",
|
||||
"oc": "Occitano",
|
||||
"pl": "Polonês",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ru": "Russo",
|
||||
"sk": "Eslovaco",
|
||||
"sl": "Esloveno",
|
||||
"sv": "Sueco",
|
||||
"tr": "Turco"
|
||||
"tr": "Turco",
|
||||
"zhCN": "Chinês (China)",
|
||||
"nb": "Bokmal norueguês"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"en": "English (английский)",
|
||||
"en": "Английский",
|
||||
"bg": "Болгарский",
|
||||
"de": "Немецкий",
|
||||
"es": "Испанский",
|
||||
@@ -7,11 +7,12 @@
|
||||
"hy": "Армянский",
|
||||
"it": "Итальянский",
|
||||
"oc": "Окситанский",
|
||||
"pl": "",
|
||||
"pl": "Польский",
|
||||
"ptBR": "Португальский (Бразилия)",
|
||||
"ru": "",
|
||||
"ru": "Русский",
|
||||
"sk": "Словацкий",
|
||||
"sl": "Словенский",
|
||||
"sv": "Шведский",
|
||||
"tr": "Турецкий"
|
||||
"tr": "Турецкий",
|
||||
"zhCN": "Китайский (Китай)"
|
||||
}
|
||||
20
lang/languages-zhCN.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"en": "英语",
|
||||
"bg": "保加利亚语",
|
||||
"de": "德语",
|
||||
"es": "西班牙语",
|
||||
"fr": "法语",
|
||||
"hy": "亚美尼亚语",
|
||||
"it": "意大利语",
|
||||
"oc": "欧西坦语",
|
||||
"pl": "波兰语",
|
||||
"ptBR": "葡萄牙语(巴西)",
|
||||
"ru": "俄语",
|
||||
"sk": "斯洛伐克语",
|
||||
"sl": "斯洛文尼亚语",
|
||||
"sv": "瑞典语",
|
||||
"tr": "土耳其语",
|
||||
"zhCN": "中文(中国)",
|
||||
"nb": "",
|
||||
"eo": ""
|
||||
}
|
||||
@@ -13,5 +13,8 @@
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"sv": "Swedish",
|
||||
"tr": "Turkish"
|
||||
"tr": "Turkish",
|
||||
"zhCN": "Chinese (China)",
|
||||
"nb": "Norwegian Bokmal",
|
||||
"eo": "Esperanto"
|
||||
}
|
||||
|
||||
@@ -39,41 +39,46 @@
|
||||
"videoMute": "Kamera starten oder stoppen"
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "Los",
|
||||
"roomname": "Konferenzname eingeben",
|
||||
"disable": "Diesen Hinweis nicht mehr anzeigen",
|
||||
"feature1": {
|
||||
"title": "Einfach zu benutzen",
|
||||
"content": "Kein Download nötig. __app__ läuft direkt im Browser. Einfach die Konferenzadresse teilen und los geht's."
|
||||
"content": "Kein Download nötig. __app__ läuft direkt im Browser. Einfach die Konferenzadresse teilen und los geht's.",
|
||||
"title": "Einfach zu benutzen"
|
||||
},
|
||||
"feature2": {
|
||||
"title": "Niedrige Bandbreite",
|
||||
"content": "Videokonferenzen mit mehreren Teilnehmen mit weniger als 128Kpbs. Bildschirmfreigaben und Telefonkonferenzen kommen sogar mit noch weniger Bandbreite aus."
|
||||
"content": "Videokonferenzen mit mehreren Teilnehmen mit weniger als 128Kpbs. Bildschirmfreigaben und Telefonkonferenzen kommen sogar mit noch weniger Bandbreite aus.",
|
||||
"title": "Niedrige Bandbreite"
|
||||
},
|
||||
"feature3": {
|
||||
"title": "Open Source",
|
||||
"content": "__app__ steht unter der Apache Lizenz. Es steht ihnen frei __app__ gemäss dieser Lizenz herunterzuladen, zu verändern oder zu verbreiten."
|
||||
"content": "__app__ steht unter der Apache Lizenz. Es steht ihnen frei __app__ gemäss dieser Lizenz herunterzuladen, zu verändern oder zu verbreiten.",
|
||||
"title": "Open Source"
|
||||
},
|
||||
"feature4": {
|
||||
"title": "Unbegrenzte Anzahl Benutzer",
|
||||
"content": "Es gibt keine künstliche Beschränkung der Anzahl der Benutzer oder Konferenzteilnehmer. Die Leistung des Servers und die Bandbreite sind die einzigen limitierenden Faktoren."
|
||||
"content": "Es gibt keine künstliche Beschränkung der Anzahl der Benutzer oder Konferenzteilnehmer. Die Leistung des Servers und die Bandbreite sind die einzigen limitierenden Faktoren.",
|
||||
"title": "Unbegrenzte Anzahl Benutzer"
|
||||
},
|
||||
"feature5": {
|
||||
"title": "Bildschirmfreigabe",
|
||||
"content": "Es ist ganz einfach den Bildschirm zu teilen. __app__ ist ideal für Online-Präsentationen, Vorlesungen und Fernwartungsanfragen."
|
||||
"content": "Es ist ganz einfach den Bildschirm zu teilen. __app__ ist ideal für Online-Präsentationen, Vorlesungen und Fernwartungsanfragen.",
|
||||
"title": "Bildschirmfreigabe"
|
||||
},
|
||||
"feature6": {
|
||||
"title": "Sichere Konferenzen",
|
||||
"content": "Privatsphäre gewünscht? __app__ Konferenzen können mit einem Passwort geschützt werden um ungebetene Gäste fernzuhalten und Unterbrechungen zu vermeiden."
|
||||
"content": "Privatsphäre gewünscht? __app__ Konferenzen können mit einem Passwort geschützt werden um ungebetene Gäste fernzuhalten und Unterbrechungen zu vermeiden.",
|
||||
"title": "Sichere Konferenzen"
|
||||
},
|
||||
"feature7": {
|
||||
"title": "Freigegebene Notizen",
|
||||
"content": "__app__ verwendet Etherpad, ein Editor zur kollaborativen Bearbeitung von Texten."
|
||||
"content": "__app__ verwendet Etherpad, ein Editor zur kollaborativen Bearbeitung von Texten.",
|
||||
"title": "Freigegebene Notizen"
|
||||
},
|
||||
"feature8": {
|
||||
"title": "Benutzungsstatistiken",
|
||||
"content": "Die Verwendung kann durch die Integration mit Piwik, Google Analytics und anderen Überwachungs- und Statistikprogrammen protokolliert werden."
|
||||
}
|
||||
"content": "Die Verwendung kann durch die Integration mit Piwik, Google Analytics und anderen Überwachungs- und Statistikprogrammen protokolliert werden.",
|
||||
"title": "Benutzungsstatistiken"
|
||||
},
|
||||
"go": "Los",
|
||||
"join": "Beitreten",
|
||||
"privacy": "Privatsphäre",
|
||||
"roomname": "Konferenzname eingeben",
|
||||
"roomnamePlaceHolder": "Konferenzname",
|
||||
"sendFeedback": "Senden Sie uns Ihr Feedback",
|
||||
"terms": "Bedingungen"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
@@ -110,6 +115,13 @@
|
||||
"profile": "Profil bearbeiten",
|
||||
"raiseHand": "Hand erheben"
|
||||
},
|
||||
"unsupportedBrowser": {
|
||||
"appInstalled": "oder wenn die App bereits installiert ist<br/>, <strong>dann</strong>",
|
||||
"appNotInstalled": "Sie benötigen <strong>__app__</strong> um der Konferenz mit dem Mobilgerät beizutreten",
|
||||
"downloadApp": "App herunterladen",
|
||||
"joinConversation": "Der Konferenz beitreten",
|
||||
"startConference": "Konferenz starten"
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Chat öffnen / schliessen",
|
||||
"filmstrip": "Videos anzeigen / verbergen",
|
||||
@@ -154,7 +166,8 @@
|
||||
"kick": "Hinauswerfen",
|
||||
"muted": "Stummgeschaltet",
|
||||
"domute": "Stummschalten",
|
||||
"flip": "Spiegeln"
|
||||
"flip": "Spiegeln",
|
||||
"remoteControl": "Fernsteuerung"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "Verbindungsdaten",
|
||||
@@ -312,7 +325,12 @@
|
||||
"externalInstallationMsg": "Die Bildschirmfreigabeerweiterung muss installiert werden.",
|
||||
"muteParticipantTitle": "Teilnehmer stummschalten?",
|
||||
"muteParticipantBody": "Sie können die Stummschaltung anderer Teilnehmer nicht aufheben, aber ein Teilnehmer kann seine eigene Stummschaltung jederzeit beenden.",
|
||||
"muteParticipantButton": "Stummschalten"
|
||||
"muteParticipantButton": "Stummschalten",
|
||||
"remoteControlTitle": "Fernsteuerung",
|
||||
"remoteControlDeniedMessage": "__user__ hat die Anfrage zur Fernsteuerung verweigert.",
|
||||
"remoteControlAllowedMessage": "__user__ hat die Anfrage zur Fernsteuerung angenommen.",
|
||||
"remoteControlErrorMessage": "Beim Anfordern der Fernsteuerungsberechtigung von __user__ ist ein Fehler aufgetreten.",
|
||||
"remoteControlStopMessage": "Die Fernsteuerung wurde beendet."
|
||||
},
|
||||
"\u0005dialog": {},
|
||||
"email": {
|
||||
@@ -375,6 +393,7 @@
|
||||
"failedToStart": "Live-Streaming konnte nicht gestartet werden",
|
||||
"buttonTooltip": "Live-Stream starten / stoppen",
|
||||
"streamIdRequired": "Bitte Stream-ID eingeben um das Live-Streaming zu starten.",
|
||||
"streamIdHelp": "Wo ist die Stream-ID zu finden?",
|
||||
"error": "Das Live-Streaming ist fehlgeschlagen. Bitte versuchen Sie es erneut.",
|
||||
"busy": "All Aufnahmegeräte sind momentan ausgelastet. Bitte versuchen Sie es später noch einmal."
|
||||
}
|
||||
|
||||
374
lang/main-eo.json
Normal file
@@ -0,0 +1,374 @@
|
||||
{
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "",
|
||||
"poweredby": "",
|
||||
"feedback": "",
|
||||
"inviteUrlDefaultMsg": "",
|
||||
"me": "",
|
||||
"speaker": "",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
"androidGrantPermissions": "",
|
||||
"firefoxGrantPermissions": "",
|
||||
"operaGrantPermissions": "",
|
||||
"iexplorerGrantPermissions": "",
|
||||
"safariGrantPermissions": "",
|
||||
"nwjsGrantPermissions": ""
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"disable": "",
|
||||
"feature1": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature2": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature3": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature4": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature5": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature6": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature7": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"feature8": {
|
||||
"content": "",
|
||||
"title": ""
|
||||
},
|
||||
"go": "",
|
||||
"join": "",
|
||||
"privacy": "",
|
||||
"roomname": "",
|
||||
"roomnamePlaceHolder": "",
|
||||
"sendFeedback": "",
|
||||
"terms": ""
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "",
|
||||
"videomute": "",
|
||||
"authenticate": "",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "",
|
||||
"Settings": "",
|
||||
"hangup": "",
|
||||
"login": "",
|
||||
"logout": "",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"unsupportedBrowser": {
|
||||
"appInstalled": "",
|
||||
"appNotInstalled": "",
|
||||
"downloadApp": "",
|
||||
"joinConversation": "",
|
||||
"startConference": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "",
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
"title": "",
|
||||
"popover": ""
|
||||
},
|
||||
"messagebox": ""
|
||||
},
|
||||
"settings": {
|
||||
"title": "",
|
||||
"update": "",
|
||||
"name": "",
|
||||
"startAudioMuted": "",
|
||||
"startVideoMuted": "",
|
||||
"selectCamera": "",
|
||||
"selectMic": "",
|
||||
"selectAudioOutput": "",
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "",
|
||||
"moderator": "",
|
||||
"videomute": "",
|
||||
"mute": "",
|
||||
"kick": "",
|
||||
"muted": "",
|
||||
"domute": "",
|
||||
"flip": "",
|
||||
"remoteControl": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "",
|
||||
"packetloss": "",
|
||||
"resolution": "",
|
||||
"less": "",
|
||||
"more": "",
|
||||
"address": "",
|
||||
"remoteport": "",
|
||||
"remoteport_plural": "",
|
||||
"localport": "",
|
||||
"localport_plural": "",
|
||||
"localaddress": "",
|
||||
"localaddress_plural": "",
|
||||
"remoteaddress": "",
|
||||
"remoteaddress_plural": "",
|
||||
"transport": "",
|
||||
"bandwidth": "",
|
||||
"na": ""
|
||||
},
|
||||
"notify": {
|
||||
"disconnected": "",
|
||||
"moderator": "",
|
||||
"connected": "",
|
||||
"somebody": "",
|
||||
"me": "",
|
||||
"focus": "",
|
||||
"focusFail": "",
|
||||
"grantedTo": "",
|
||||
"grantedToUnknown": "",
|
||||
"muted": "",
|
||||
"mutedTitle": "",
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "",
|
||||
"popupError": "",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "",
|
||||
"passwordError2": "",
|
||||
"connectError": "",
|
||||
"connectErrorWithMsg": "",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "",
|
||||
"copy": "",
|
||||
"error": "",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "",
|
||||
"failtoinstall": "",
|
||||
"failedpermissions": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "",
|
||||
"lockMessage": "",
|
||||
"warning": "",
|
||||
"passwordNotSupported": "",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "",
|
||||
"SLDFailure": "",
|
||||
"SRDFailure": "",
|
||||
"oops": "",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "",
|
||||
"passwordRequired": "",
|
||||
"Ok": "",
|
||||
"done": "",
|
||||
"Remove": "",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"removeSharedVideoTitle": "",
|
||||
"removeSharedVideoMsg": "",
|
||||
"alreadySharedVideoMsg": "",
|
||||
"WaitingForHost": "",
|
||||
"WaitForHostMsg": "",
|
||||
"IamHost": "",
|
||||
"Cancel": "",
|
||||
"Submit": "",
|
||||
"retry": "",
|
||||
"logoutTitle": "",
|
||||
"logoutQuestion": "",
|
||||
"sessTerminated": "",
|
||||
"hungUp": "",
|
||||
"joinAgain": "",
|
||||
"Share": "",
|
||||
"Save": "",
|
||||
"recording": "",
|
||||
"recordingToken": "",
|
||||
"Dial": "",
|
||||
"sipMsg": "",
|
||||
"passwordCheck": "",
|
||||
"passwordMsg": "",
|
||||
"shareLink": "",
|
||||
"settings1": "",
|
||||
"settings2": "",
|
||||
"settings3": "",
|
||||
"yourPassword": "",
|
||||
"Back": "",
|
||||
"serviceUnavailable": "",
|
||||
"gracefulShutdown": "",
|
||||
"Yes": "",
|
||||
"reservationError": "",
|
||||
"reservationErrorMsg": "",
|
||||
"password": "",
|
||||
"userPassword": "",
|
||||
"token": "",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "",
|
||||
"extensionRequired": "",
|
||||
"firefoxExtensionPrompt": "",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "",
|
||||
"sorryFeedback": "",
|
||||
"liveStreaming": "",
|
||||
"streamKey": "",
|
||||
"startLiveStreaming": "",
|
||||
"stopStreamingWarning": "",
|
||||
"stopRecordingWarning": "",
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
"cameraErrorPresent": "",
|
||||
"cameraUnsupportedResolutionError": "",
|
||||
"cameraUnknownError": "",
|
||||
"cameraPermissionDeniedError": "",
|
||||
"cameraNotFoundError": "",
|
||||
"cameraConstraintFailedError": "",
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "",
|
||||
"remoteControlTitle": "",
|
||||
"remoteControlDeniedMessage": "",
|
||||
"remoteControlAllowedMessage": "",
|
||||
"remoteControlErrorMessage": "",
|
||||
"remoteControlStopMessage": ""
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": "",
|
||||
"subject": "",
|
||||
"body": "",
|
||||
"and": ""
|
||||
},
|
||||
"connection": {
|
||||
"ERROR": "",
|
||||
"CONNECTING": "",
|
||||
"RECONNECTING": "",
|
||||
"CONNFAIL": "",
|
||||
"AUTHENTICATING": "",
|
||||
"AUTHFAIL": "",
|
||||
"CONNECTED": "",
|
||||
"DISCONNECTED": "",
|
||||
"DISCONNECTING": "",
|
||||
"ATTACHED": ""
|
||||
},
|
||||
"recording": {
|
||||
"pending": "",
|
||||
"on": "",
|
||||
"off": "",
|
||||
"failedToStart": "",
|
||||
"buttonTooltip": "",
|
||||
"error": "",
|
||||
"unavailable": ""
|
||||
},
|
||||
"liveStreaming": {
|
||||
"pending": "",
|
||||
"on": "",
|
||||
"off": "",
|
||||
"unavailable": "",
|
||||
"failedToStart": "",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "",
|
||||
"streamIdHelp": "",
|
||||
"error": "",
|
||||
"busy": ""
|
||||
}
|
||||
}
|
||||
362
lang/main-nb.json
Normal file
@@ -0,0 +1,362 @@
|
||||
{
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "",
|
||||
"poweredby": "",
|
||||
"feedback": "",
|
||||
"inviteUrlDefaultMsg": "",
|
||||
"me": "",
|
||||
"speaker": "",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
"androidGrantPermissions": "",
|
||||
"firefoxGrantPermissions": "",
|
||||
"operaGrantPermissions": "",
|
||||
"iexplorerGrantPermissions": "",
|
||||
"safariGrantPermissions": "",
|
||||
"nwjsGrantPermissions": ""
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "",
|
||||
"roomname": "",
|
||||
"disable": "",
|
||||
"feature1": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature2": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature3": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature4": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature5": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature6": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature7": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"feature8": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "",
|
||||
"videomute": "",
|
||||
"authenticate": "",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "",
|
||||
"Settings": "",
|
||||
"hangup": "",
|
||||
"login": "",
|
||||
"logout": "",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "",
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
"title": "",
|
||||
"popover": ""
|
||||
},
|
||||
"messagebox": ""
|
||||
},
|
||||
"settings": {
|
||||
"title": "",
|
||||
"update": "",
|
||||
"name": "",
|
||||
"startAudioMuted": "",
|
||||
"startVideoMuted": "",
|
||||
"selectCamera": "",
|
||||
"selectMic": "",
|
||||
"selectAudioOutput": "",
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "",
|
||||
"moderator": "",
|
||||
"videomute": "",
|
||||
"mute": "",
|
||||
"kick": "",
|
||||
"muted": "",
|
||||
"domute": "",
|
||||
"flip": "",
|
||||
"remoteControl": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "",
|
||||
"packetloss": "",
|
||||
"resolution": "",
|
||||
"less": "",
|
||||
"more": "",
|
||||
"address": "",
|
||||
"remoteport": "",
|
||||
"remoteport_plural": "",
|
||||
"localport": "",
|
||||
"localport_plural": "",
|
||||
"localaddress": "",
|
||||
"localaddress_plural": "",
|
||||
"remoteaddress": "",
|
||||
"remoteaddress_plural": "",
|
||||
"transport": "",
|
||||
"bandwidth": "",
|
||||
"na": ""
|
||||
},
|
||||
"notify": {
|
||||
"disconnected": "",
|
||||
"moderator": "",
|
||||
"connected": "",
|
||||
"somebody": "",
|
||||
"me": "",
|
||||
"focus": "",
|
||||
"focusFail": "",
|
||||
"grantedTo": "",
|
||||
"grantedToUnknown": "",
|
||||
"muted": "",
|
||||
"mutedTitle": "",
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "",
|
||||
"popupError": "",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "",
|
||||
"passwordError2": "",
|
||||
"connectError": "",
|
||||
"connectErrorWithMsg": "",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "",
|
||||
"copy": "",
|
||||
"error": "",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "",
|
||||
"failtoinstall": "",
|
||||
"failedpermissions": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "",
|
||||
"lockMessage": "",
|
||||
"warning": "",
|
||||
"passwordNotSupported": "",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "",
|
||||
"SLDFailure": "",
|
||||
"SRDFailure": "",
|
||||
"oops": "",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "",
|
||||
"passwordRequired": "",
|
||||
"Ok": "",
|
||||
"done": "",
|
||||
"Remove": "",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"removeSharedVideoTitle": "",
|
||||
"removeSharedVideoMsg": "",
|
||||
"alreadySharedVideoMsg": "",
|
||||
"WaitingForHost": "",
|
||||
"WaitForHostMsg": "",
|
||||
"IamHost": "",
|
||||
"Cancel": "",
|
||||
"Submit": "",
|
||||
"retry": "",
|
||||
"logoutTitle": "",
|
||||
"logoutQuestion": "",
|
||||
"sessTerminated": "",
|
||||
"hungUp": "",
|
||||
"joinAgain": "",
|
||||
"Share": "",
|
||||
"Save": "",
|
||||
"recording": "",
|
||||
"recordingToken": "",
|
||||
"Dial": "",
|
||||
"sipMsg": "",
|
||||
"passwordCheck": "",
|
||||
"passwordMsg": "",
|
||||
"shareLink": "",
|
||||
"settings1": "",
|
||||
"settings2": "",
|
||||
"settings3": "",
|
||||
"yourPassword": "",
|
||||
"Back": "",
|
||||
"serviceUnavailable": "",
|
||||
"gracefulShutdown": "",
|
||||
"Yes": "",
|
||||
"reservationError": "",
|
||||
"reservationErrorMsg": "",
|
||||
"password": "",
|
||||
"userPassword": "",
|
||||
"token": "",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "",
|
||||
"extensionRequired": "",
|
||||
"firefoxExtensionPrompt": "",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "",
|
||||
"sorryFeedback": "",
|
||||
"liveStreaming": "",
|
||||
"streamKey": "",
|
||||
"startLiveStreaming": "",
|
||||
"stopStreamingWarning": "",
|
||||
"stopRecordingWarning": "",
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
"cameraErrorPresent": "",
|
||||
"cameraUnsupportedResolutionError": "",
|
||||
"cameraUnknownError": "",
|
||||
"cameraPermissionDeniedError": "",
|
||||
"cameraNotFoundError": "",
|
||||
"cameraConstraintFailedError": "",
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "",
|
||||
"remoteControlTitle": "",
|
||||
"remoteControlDeniedMessage": "",
|
||||
"remoteControlAllowedMessage": "",
|
||||
"remoteControlErrorMessage": "",
|
||||
"remoteControlStopMessage": ""
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": "",
|
||||
"subject": "",
|
||||
"body": "",
|
||||
"and": ""
|
||||
},
|
||||
"connection": {
|
||||
"ERROR": "",
|
||||
"CONNECTING": "",
|
||||
"RECONNECTING": "",
|
||||
"CONNFAIL": "",
|
||||
"AUTHENTICATING": "",
|
||||
"AUTHFAIL": "",
|
||||
"CONNECTED": "",
|
||||
"DISCONNECTED": "",
|
||||
"DISCONNECTING": "",
|
||||
"ATTACHED": ""
|
||||
},
|
||||
"recording": {
|
||||
"pending": "",
|
||||
"on": "",
|
||||
"off": "",
|
||||
"failedToStart": "",
|
||||
"buttonTooltip": "",
|
||||
"error": "",
|
||||
"unavailable": ""
|
||||
},
|
||||
"liveStreaming": {
|
||||
"pending": "",
|
||||
"on": "",
|
||||
"off": "",
|
||||
"unavailable": "",
|
||||
"failedToStart": "",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "",
|
||||
"streamIdHelp": "",
|
||||
"error": "",
|
||||
"busy": ""
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@
|
||||
"roomUnlocked": "Qual que siá amb lo ligam pòt participar",
|
||||
"passwordSetRemotely": "causit per qualqu'un mai",
|
||||
"connectionsettings": "Paramètres de connexion",
|
||||
"poweredby": "Produit per",
|
||||
"feedback": "Donatz-nos vòstre vejaire",
|
||||
"poweredby": "produit per",
|
||||
"feedback": "Donatz-nos lo vòstre vejaire",
|
||||
"inviteUrlDefaultMsg": "Vòstra conferéncia es en cors de creacion...",
|
||||
"me": "ieu",
|
||||
"speaker": "Nautparlaire",
|
||||
"raisedHand": "Volriatz charrar",
|
||||
"raisedHand": "Volriá charrar",
|
||||
"defaultNickname": "ex. Joan Delpuèch",
|
||||
"defaultLink": "ex. __url__",
|
||||
"callingName": "__name__",
|
||||
@@ -39,41 +39,46 @@
|
||||
"videoMute": "Aviar o arrestar vòstra camerà"
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "Crear",
|
||||
"roomname": "Sasissètz un nom de sala",
|
||||
"disable": "Afichar pas mai aquesta pagina",
|
||||
"feature1": {
|
||||
"title": "De bon utilizar",
|
||||
"content": "Cap de telecargament pas requesit. __app__ s'utiliza dirèctament dempuèi vòstre navigador. Partejar simplament l'URL de vòstra conferéncia amb los autres per començar."
|
||||
"content": "Cap de telecargament pas requesit. __app__ s'utiliza dirèctament dempuèi vòstre navigador. Partejar simplament l'URL de vòstra conferéncia amb los autres per començar.",
|
||||
"title": "De bon utilizar"
|
||||
},
|
||||
"feature2": {
|
||||
"title": "Benda passanta febla",
|
||||
"content": "Las videoconferéncias de mantun participant necessitan mens de 128 kbps. Lo partiment d'ecran e las conferéncias amb solament d'àudio son possiblas amb plan mens de debit."
|
||||
"content": "Las videoconferéncias de mantun participant necessitan mens de 128 kbps. Lo partiment d'ecran e las conferéncias amb solament d'àudio son possiblas amb plan mens de debit.",
|
||||
"title": "Benda passanta febla"
|
||||
},
|
||||
"feature3": {
|
||||
"title": "Open source",
|
||||
"content": "__app__ es jos licéncia Apache. Sètz liure de telecargar, d'utilizar, de modificar e de partejar __app__ segon aquesta licéncia liura."
|
||||
"content": "__app__ es jos licéncia Apache. Sètz liure de telecargar, d'utilizar, de modificar e de partejar __app__ segon aquesta licéncia liura.",
|
||||
"title": "Open source"
|
||||
},
|
||||
"feature4": {
|
||||
"title": "Nombre d'utilizaires illimitat",
|
||||
"content": "I a pas de restriccions artificialas a prepaus del nombre d'utilizaires o de participants a una conferéncia. La poténcia del servidor e la benda passanta son los sols factors limitants."
|
||||
"content": "I a pas de restriccions artificialas a prepaus del nombre d'utilizaires o de participants a una conferéncia. La poténcia del servidor e la benda passanta son los sols factors limitants.",
|
||||
"title": "Nombre d'utilizaires illimitat"
|
||||
},
|
||||
"feature5": {
|
||||
"title": "Partiment d'ecran",
|
||||
"content": "Es aisit de partejar vòstre ecran amb d'autras personas. __app__ es ideal per las presentacions en linha, los corses, e las sessions de supòrt tecnic."
|
||||
"content": "Es aisit de partejar vòstre ecran amb d'autras personas. __app__ es ideal per las presentacions en linha, los corses, e las sessions de supòrt tecnic.",
|
||||
"title": "Partiment d'ecran"
|
||||
},
|
||||
"feature6": {
|
||||
"title": "Salas securizadas",
|
||||
"content": "Besonh de confidencialitat ? Las salas de conferéncia __app__ pòdon èsser securizadas per un senhal per exclure los convidats pas desirats, e prevenir de las interrupcions."
|
||||
"content": "Besonh de confidencialitat ? Las salas de conferéncia __app__ pòdon èsser securizadas per un senhal per exclure los convidats pas desirats, e prevenir de las interrupcions.",
|
||||
"title": "Salas securizadas"
|
||||
},
|
||||
"feature7": {
|
||||
"title": "Nòtas partejadas",
|
||||
"content": "__app__ prepausa Etherpad, un editor de tèxte collaboratiu en temps real qu'es parfèit pels procèsses verbals, l'edicion d'articles e plan mai encara."
|
||||
"content": "__app__ prepausa Etherpad, un editor de tèxte collaboratiu en temps real qu'es parfèit pels procèsses verbals, l'edicion d'articles e plan mai encara.",
|
||||
"title": "Nòtas partejadas"
|
||||
},
|
||||
"feature8": {
|
||||
"title": "Estatisticas d'utilizacion",
|
||||
"content": "Aprenètz mai a prepaus de vòstres utilizaires amb una integracion aisida de Piwik, Google Analytics e d'autres sistèmas d'estatisticas e supervision d'utilizacion."
|
||||
}
|
||||
"content": "Aprenètz mai a prepaus de vòstres utilizaires amb una integracion aisida de Piwik, Google Analytics e d'autres sistèmas d'estatisticas e supervision d'utilizacion.",
|
||||
"title": "Estatisticas d'utilizacion"
|
||||
},
|
||||
"go": "Crear",
|
||||
"join": "PARTICIPATZ",
|
||||
"privacy": "Vida privada",
|
||||
"roomname": "Sasissètz un nom de sala",
|
||||
"roomnamePlaceHolder": "nom de la sala",
|
||||
"sendFeedback": "Mandar vòstra opinion",
|
||||
"terms": "Tèrmes"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
@@ -108,7 +113,14 @@
|
||||
"micDisabled": "Lo microfòn es pas disponible",
|
||||
"filmstrip": "Mostrar / escondre vidèos",
|
||||
"profile": "Modificar vòstre perfil",
|
||||
"raiseHand": "Demandar / Demandar pas mai la paraula"
|
||||
"raiseHand": "o se l'avètz ja<br /><strong>alara</strong>"
|
||||
},
|
||||
"unsupportedBrowser": {
|
||||
"appInstalled": "o se ja l'avètz<br /><strong>alara</strong>",
|
||||
"appNotInstalled": "Vos cal <strong>__app__</strong> per participar a la conversacion a partir de vòstre mobil",
|
||||
"downloadApp": "Telecargar l'aplicacion",
|
||||
"joinConversation": "Participar a la conversacion",
|
||||
"startConference": "Començar una conferéncia"
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Dobrir / tampar lo chat",
|
||||
@@ -126,15 +138,15 @@
|
||||
"title": "Paramètres",
|
||||
"update": "Mesa a jorn",
|
||||
"name": "Nom",
|
||||
"startAudioMuted": "Tot lo mond comença sens son",
|
||||
"startVideoMuted": "Tot lo mond comença escondut",
|
||||
"selectCamera": "Camèra",
|
||||
"startAudioMuted": "Començan totes sens son",
|
||||
"startVideoMuted": "Començan totes sens vidèo",
|
||||
"selectCamera": "Camerà",
|
||||
"selectMic": "Microfòn",
|
||||
"selectAudioOutput": "Sortida àudio",
|
||||
"followMe": "Tot lo mond me sèc",
|
||||
"noDevice": "Pas cap",
|
||||
"noPermission": "La permission d'utilizar l'aparelh es pas estada donada",
|
||||
"cameraAndMic": "Camèra e microfòn",
|
||||
"cameraAndMic": "Camerà e microfòn",
|
||||
"moderator": "MODERATOR",
|
||||
"password": "DEFINIR UN SENHAL",
|
||||
"audioVideo": "ÀUDIO E VIDÈO",
|
||||
@@ -149,12 +161,13 @@
|
||||
"videothumbnail": {
|
||||
"editnickname": "Clicatz per modificar<br/>vòstre nom",
|
||||
"moderator": "Lo proprietari de<br/>aquesta conferéncia",
|
||||
"videomute": "Un participant a<br/>arrestat sa camèra.",
|
||||
"videomute": "Un participant a<br/>arrestat sa camerà.",
|
||||
"mute": "Un participant a copat son micro",
|
||||
"kick": "Exclure",
|
||||
"muted": "Mut",
|
||||
"domute": "Copar lo son",
|
||||
"flip": "Revirar"
|
||||
"flip": "Revirar",
|
||||
"remoteControl": "Contraròtle alonhat"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "Donadas de connexion",
|
||||
@@ -162,7 +175,7 @@
|
||||
"packetloss": "Pèrda de paquets :",
|
||||
"resolution": "Resolucion :",
|
||||
"less": "Amagar lo detalh",
|
||||
"more": "Mostrar lo deta1h",
|
||||
"more": "Ne veire mai",
|
||||
"address": "Adreça :",
|
||||
"remoteport": "Pòrt distant :",
|
||||
"remoteport_plural": "Pòrts distants :",
|
||||
@@ -208,7 +221,7 @@
|
||||
"createPassword": "Crear un senhal",
|
||||
"detectext": "Una error s'es produita pendent la deteccion de l'extension de partiment d'ecran.",
|
||||
"failtoinstall": "Fracàs de l'installacion de l'extension de partiment d'ecran",
|
||||
"failedpermissions": "Fracàs d'obtencion de las permissions per utilizar lo micro e/o la camèra.",
|
||||
"failedpermissions": "Fracàs d'obtencion de las permissions per utilizar lo micro e/o la camerà.",
|
||||
"conferenceReloadTitle": "Malurosament, quicòm truquèt",
|
||||
"conferenceReloadMsg": "Sèm a trobar una solucion per aquò",
|
||||
"conferenceDisconnectTitle": "Sètz estat desconnectat. Vos cal benlèu verificar vòstra connexion.",
|
||||
@@ -224,7 +237,7 @@
|
||||
"internalError": "Ops ! Quicòm a pas fonccionat. L'error seguenta s'es produsida : [setRemoteDescription]",
|
||||
"unableToSwitch": "Impossible de cambiar lo flux vidèo.",
|
||||
"SLDFailure": "Ops! Quicòm a trucat e lo micro es pas estat copat! (Fracàs SLD)",
|
||||
"SRDFailure": "Ops! Quicòm a trucat e la camèra es pas estada copada! (Fracàs SRD)",
|
||||
"SRDFailure": "Ops ! Quicòm a trucat e la camerà es pas estada arrestada ! (Fracàs SRD)",
|
||||
"oops": "Ops !",
|
||||
"currentPassword": "L'actual senhal es",
|
||||
"passwordLabel": "Senhal",
|
||||
@@ -298,21 +311,26 @@
|
||||
"cameraErrorPresent": "I a agut una error pendent la connexion a la camerà.",
|
||||
"cameraUnsupportedResolutionError": "Vòstra camerà pren pas en carga la resolucion vidèo que cal.",
|
||||
"cameraUnknownError": "Impossible d'emplegar la camerà per una rason desconeguda.",
|
||||
"cameraPermissionDeniedError": "La camèra es pas estada trobada.",
|
||||
"cameraNotFoundError": "La camèra es pas estada trobada.",
|
||||
"cameraPermissionDeniedError": "La camerà es pas estada trobada.",
|
||||
"cameraNotFoundError": "La camerà es pas estada trobada.",
|
||||
"cameraConstraintFailedError": "Vòstra camerà satisfà pas totas las constrentas necessàrias.",
|
||||
"micUnknownError": "Impossible d'utilizar lo microfòn per una rason desconeguda.",
|
||||
"micPermissionDeniedError": "Avètz pas donat l'autorizacion d'utilizar vòstre microfòn. Podètz encara participar a la conferéncia mai los demai vos ausiràn pas. Utilizatz lo boton del microfòn dins la barra d'adreça per resòlvre aquò.",
|
||||
"micNotFoundError": "Lo microfòn es pas estat trobat.",
|
||||
"micConstraintFailedError": "Vòstre microfòn satisfà pas totas las constrentas necessàrias.",
|
||||
"micNotSendingData": "Podèm pas aver l'accès a vòstre microfòn. Mercés de ne causir un autre dins lo menú de paramètres o ensajatz de tornar dubrir l'aplicacion.",
|
||||
"cameraNotSendingData": "Podèm pas aver l'accès a vòstra camèra. Mercés de verificar se una autra aplicacion es pas a l'utilizar, causissètz una autra camèra dins lo menú de paramètres o ensajatz de tornar dubrir l'aplicacion.",
|
||||
"cameraNotSendingData": "Podèm pas aver l'accès a vòstra camerà. Mercés de verificar se una autra aplicacion es pas a l'utilizar, causissètz una autra camerà dins lo menú de paramètres o ensajatz de tornar dubrir l'aplicacion.",
|
||||
"goToStore": "Anar sul webstore",
|
||||
"externalInstallationTitle": "Extension requesida :",
|
||||
"externalInstallationMsg": "Avètz d'installar nòstra extension de partiment d'ecran.",
|
||||
"muteParticipantTitle": "Copar lo micro als participants ?",
|
||||
"muteParticipantBody": "Poiretz pas lo tornar activar lo microfòn, mai eles pòdon o far quand vòlon.",
|
||||
"muteParticipantButton": "Copar lo son"
|
||||
"muteParticipantButton": "Copar lo son",
|
||||
"remoteControlTitle": "Contraròtle alonhat",
|
||||
"remoteControlDeniedMessage": "__user__ a refusat vòstra demanda de contraròtle alonhat !",
|
||||
"remoteControlAllowedMessage": "__user__ a acceptat vòstra demanda de contraròtle alonhat !",
|
||||
"remoteControlErrorMessage": "Error al moment de demandar lo contraròtle alonhat a __user__ !",
|
||||
"remoteControlStopMessage": "La session de contraròtle alonhat es acabada !"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
@@ -371,6 +389,7 @@
|
||||
"failedToStart": "Lo dirècte a pas capitat de s'aviar",
|
||||
"buttonTooltip": "Aviar / arrestar lo dirècte",
|
||||
"streamIdRequired": "Mercé de completar lo stream id per aviar lo dirècte.",
|
||||
"streamIdHelp": "Ont tròbi aquò ?",
|
||||
"error": "Fracàs de la transmission en dirècte. Mercés de tornar ensajar.",
|
||||
"busy": "Tots los enresgistraires son ocupats. Mercés de tornar ensajar mai tard."
|
||||
}
|
||||
|
||||
@@ -39,41 +39,46 @@
|
||||
"videoMute": "Iniciar ou parar sua câmera"
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "IR",
|
||||
"roomname": "Digite o nome da sala",
|
||||
"disable": "Não mostre esta página novamente",
|
||||
"feature1": {
|
||||
"title": "Simples para usar",
|
||||
"content": "Não precisa baixar nada. __app__ trabalha diretamente no seu navegador. Simplesmente compartilhe sua URL da conferência com outros para começar."
|
||||
"content": "Não precisa baixar nada. __app__ trabalha diretamente no seu navegador. Simplesmente compartilhe sua URL da conferência com outros para começar.",
|
||||
"title": "Simples para usar"
|
||||
},
|
||||
"feature2": {
|
||||
"title": "Largura de banda baixa",
|
||||
"content": "Conferências de vídeo de multipartes trabalha com tão pouco quanto 128 kbps. Compartilhamento de tela e conferências de áudio somente são possíveis com muito menos."
|
||||
"content": "Conferências de vídeo de multipartes trabalha com tão pouco quanto 128 kbps. Compartilhamento de tela e conferências de áudio somente são possíveis com muito menos.",
|
||||
"title": "Largura de banda baixa"
|
||||
},
|
||||
"feature3": {
|
||||
"title": "Código aberto",
|
||||
"content": "__app__ é licenciado sob a Licença Apache. Você é livre para baixar, usar, modificar e compartilhar ela com a mesma licença."
|
||||
"content": "__app__ é licenciado sob a Licença Apache. Você é livre para baixar, usar, modificar e compartilhar ela com a mesma licença.",
|
||||
"title": "Código aberto"
|
||||
},
|
||||
"feature4": {
|
||||
"title": "Usuários ilimitados",
|
||||
"content": "Aqui não há restrições artificiais no número de usuários ou participantes da conferência. A potência do servidor e largura de banda são os únicos fatores limitantes."
|
||||
"content": "Aqui não há restrições artificiais no número de usuários ou participantes da conferência. A potência do servidor e largura de banda são os únicos fatores limitantes.",
|
||||
"title": "Usuários ilimitados"
|
||||
},
|
||||
"feature5": {
|
||||
"title": "Compartilhamento de tela",
|
||||
"content": "É fácil compartilhar sua tela com outros. __app__ é ideal para apresentações online, leituras, e sessões de suporte técnico."
|
||||
"content": "É fácil compartilhar sua tela com outros. __app__ é ideal para apresentações online, leituras, e sessões de suporte técnico.",
|
||||
"title": "Compartilhamento de tela"
|
||||
},
|
||||
"feature6": {
|
||||
"title": "Salas seguras",
|
||||
"content": "Precisa alguma privacidade? Salas de conferência do __app__ podem ser seguras com uma senha para excluir visitantes indesejados e prevenir interrupções."
|
||||
"content": "Precisa alguma privacidade? Salas de conferência do __app__ podem ser seguras com uma senha para excluir visitantes indesejados e prevenir interrupções.",
|
||||
"title": "Salas seguras"
|
||||
},
|
||||
"feature7": {
|
||||
"title": "Notas compartilhadas",
|
||||
"content": "__app_ disponibiliza o Etherpad, um editor de texto colaborativo em tempo real, que é ótimo para reuniões rápidas, escrevendo artigos, e mais."
|
||||
"content": "__app_ disponibiliza o Etherpad, um editor de texto colaborativo em tempo real, que é ótimo para reuniões rápidas, escrevendo artigos, e mais.",
|
||||
"title": "Notas compartilhadas"
|
||||
},
|
||||
"feature8": {
|
||||
"title": "Estatísticas de uso",
|
||||
"content": "Aprenda sobre seus usuários através de integração fácil com o Piwik, Google Analytics, e outros sistemas de monitoramento e estatísticas."
|
||||
}
|
||||
"content": "Aprenda sobre seus usuários através de integração fácil com o Piwik, Google Analytics, e outros sistemas de monitoramento e estatísticas.",
|
||||
"title": "Estatísticas de uso"
|
||||
},
|
||||
"go": "IR",
|
||||
"join": "Entrar",
|
||||
"privacy": "Política de Privacidade",
|
||||
"roomname": "Digite o nome da sala",
|
||||
"roomnamePlaceHolder": "Nome da sala",
|
||||
"sendFeedback": "Enviar comentários",
|
||||
"terms": "Termos"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
@@ -110,6 +115,13 @@
|
||||
"profile": "Editar seu perfil",
|
||||
"raiseHand": "Erguer o baixar sua mão"
|
||||
},
|
||||
"unsupportedBrowser": {
|
||||
"appInstalled": "ou se você já tenha isso<br /> <strong>então</strong>",
|
||||
"appNotInstalled": "Você precisa do <strong>__app__</strong> para começar um bate-papo no seu celular",
|
||||
"downloadApp": "Baixe o Aplicativo",
|
||||
"joinConversation": "Entre no bate-papo",
|
||||
"startConference": "Comece uma conferência"
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Abrir / fechar bate-papo",
|
||||
"filmstrip": "Mostrar/ocultar vídeos",
|
||||
@@ -154,7 +166,8 @@
|
||||
"kick": "Chutar fora",
|
||||
"muted": "Mudo",
|
||||
"domute": "Mudo",
|
||||
"flip": "Inverter"
|
||||
"flip": "Inverter",
|
||||
"remoteControl": "Controle remoto"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "Dados da conexão",
|
||||
@@ -312,7 +325,12 @@
|
||||
"externalInstallationMsg": "Você precisa instalar nossa extensão de compartilhamento de tela.",
|
||||
"muteParticipantTitle": "Deixar mudo este participante?",
|
||||
"muteParticipantBody": "Você não está habilitado para tirar o mudo deles, mas eles podem tirar o mudo deles mesmos a qualquer tempo.",
|
||||
"muteParticipantButton": "Mudo"
|
||||
"muteParticipantButton": "Mudo",
|
||||
"remoteControlTitle": "Controle remoto",
|
||||
"remoteControlDeniedMessage": "__user__ rejeitou sua requisição de controle remoto!",
|
||||
"remoteControlAllowedMessage": "__user__ aceitou sua requisição de controle remoto!",
|
||||
"remoteControlErrorMessage": "Um erro ocorreu enquanto tentava requerer a permissão de controle remoto de __user__!",
|
||||
"remoteControlStopMessage": "A sessão de controle remoto terminou!"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
@@ -371,6 +389,7 @@
|
||||
"failedToStart": "Falha ao iniciar a transmissão ao vivo",
|
||||
"buttonTooltip": "Iniciar / parar live stream",
|
||||
"streamIdRequired": "Por favor digite o id da transmissão ao vivo para começar a transmitir.",
|
||||
"streamIdHelp": "Aonde eu encontro isto?",
|
||||
"error": "Falha na transmissão ao vivo. Tente novamente",
|
||||
"busy": "Todos os gravadores estão ocupados no momento. Por favor, tente mais tarde."
|
||||
}
|
||||
|
||||