mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-31 03:42:29 +00:00
Compare commits
141 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53e784094a | ||
|
|
0e92e48376 | ||
|
|
4c9943ac38 | ||
|
|
4bd0fd145d | ||
|
|
01ae82eb28 | ||
|
|
e21eae0933 | ||
|
|
2f047c50dc | ||
|
|
e397e1a80c | ||
|
|
b09e86352f | ||
|
|
8687b69167 | ||
|
|
6c5468d904 | ||
|
|
d6b0f8d4c5 | ||
|
|
a8cd4ff12c | ||
|
|
8509efc8af | ||
|
|
23a0053dad | ||
|
|
5849980092 | ||
|
|
e81fc2b254 | ||
|
|
2ad869a036 | ||
|
|
7a8c84e990 | ||
|
|
0de01e93dd | ||
|
|
6fa93e5b44 | ||
|
|
2144ec1e3f | ||
|
|
68d2f60ace | ||
|
|
3d671ae71f | ||
|
|
8ed47f9d99 | ||
|
|
b50f858556 | ||
|
|
5de1a74429 | ||
|
|
2063ad467d | ||
|
|
679acbae16 | ||
|
|
a5b706a99e | ||
|
|
542e61357e | ||
|
|
3743602c67 | ||
|
|
ee651840bf | ||
|
|
0765c60d77 | ||
|
|
7fa17322a1 | ||
|
|
cfa3047330 | ||
|
|
9e033deb7b | ||
|
|
f6c914f6f0 | ||
|
|
06ff02c2a5 | ||
|
|
63fd263890 | ||
|
|
94f3d4b279 | ||
|
|
fdc96044ad | ||
|
|
91487ffc94 | ||
|
|
7a57dcc08a | ||
|
|
913a54713d | ||
|
|
39a8681e8e | ||
|
|
a7015b0d1a | ||
|
|
5305f23332 | ||
|
|
acbf3adab7 | ||
|
|
366b2f1374 | ||
|
|
2189ab7ee6 | ||
|
|
349c04d8d1 | ||
|
|
c7c6249ad7 | ||
|
|
5319227a8f | ||
|
|
3aff812ee2 | ||
|
|
88eabf23f4 | ||
|
|
a70beaf7b6 | ||
|
|
c91bffa73c | ||
|
|
ea163dbbba | ||
|
|
18bc99d6b5 | ||
|
|
bab94a207d | ||
|
|
ef39baab47 | ||
|
|
2edaaac7bf | ||
|
|
113e50c074 | ||
|
|
900a675864 | ||
|
|
49b3b49f3e | ||
|
|
23935d3d39 | ||
|
|
3fd33d0f50 | ||
|
|
8c3317b8e9 | ||
|
|
99a9fc054f | ||
|
|
967dcfc3d2 | ||
|
|
0051b3b79c | ||
|
|
cbcee201f0 | ||
|
|
1fa4a53a48 | ||
|
|
6a0b92638c | ||
|
|
2e81b8493e | ||
|
|
57ba702dda | ||
|
|
62bafcaf63 | ||
|
|
7de5c9c1d2 | ||
|
|
8248b14555 | ||
|
|
23ef0c8d9d | ||
|
|
58a4f59fd8 | ||
|
|
0c851934fb | ||
|
|
8d58dbee38 | ||
|
|
cd5e84e4ef | ||
|
|
09ba14eb04 | ||
|
|
b22f1965aa | ||
|
|
df6f920b44 | ||
|
|
f13b2462c8 | ||
|
|
c0e80c14f8 | ||
|
|
2b1176df53 | ||
|
|
05bfbf5620 | ||
|
|
4af706bd83 | ||
|
|
b62e4d5ee9 | ||
|
|
bd98d661d3 | ||
|
|
1f7c5529e9 | ||
|
|
0453346cf4 | ||
|
|
15090243d0 | ||
|
|
b22e3ee253 | ||
|
|
e693554961 | ||
|
|
0efca9a9a8 | ||
|
|
5d22061c0a | ||
|
|
84be7fd739 | ||
|
|
5d269ad0aa | ||
|
|
a4d5c41b3a | ||
|
|
846fb9abb0 | ||
|
|
0f33e59e4d | ||
|
|
896650d005 | ||
|
|
6d6b5a7917 | ||
|
|
db5010be9d | ||
|
|
be8860080c | ||
|
|
42f124b0f6 | ||
|
|
7249ababb7 | ||
|
|
079be92468 | ||
|
|
dda2a2feba | ||
|
|
ae726cfdc0 | ||
|
|
1a04e5a9af | ||
|
|
cac68dbaba | ||
|
|
3c04634609 | ||
|
|
6c12681b9c | ||
|
|
b1b5f3e6f0 | ||
|
|
5baa167a08 | ||
|
|
343d17d19a | ||
|
|
0370cc47fc | ||
|
|
083fc955dc | ||
|
|
a6e268f784 | ||
|
|
7e0a9bc37c | ||
|
|
f25bc818d7 | ||
|
|
9beae22803 | ||
|
|
920b0af269 | ||
|
|
6c674bef2a | ||
|
|
e74fbbb38b | ||
|
|
fb3f916802 | ||
|
|
c80d47d3dd | ||
|
|
693ee1dcf8 | ||
|
|
640c0faff1 | ||
|
|
207ac47aa7 | ||
|
|
8844f83a59 | ||
|
|
4a5a1cd5f4 | ||
|
|
09d63d38ab | ||
|
|
6bf0f9b2ec |
@@ -3,6 +3,7 @@ build/*
|
||||
|
||||
# Third-party source code which we (1) do not want to modify or (2) try to
|
||||
# modify as little as possible.
|
||||
flow-typed/*
|
||||
libs/*
|
||||
|
||||
# ESLint will by default ignore its own configuration file. However, there does
|
||||
|
||||
@@ -4,7 +4,10 @@ module.exports = {
|
||||
'commonjs': true,
|
||||
'es6': true
|
||||
},
|
||||
'extends': 'eslint:recommended',
|
||||
'extends': [
|
||||
'eslint:recommended',
|
||||
'plugin:flowtype/recommended'
|
||||
],
|
||||
'globals': {
|
||||
// The globals that (1) are accessed but not defined within many of our
|
||||
// files, (2) are certainly defined, and (3) we would like to use
|
||||
@@ -12,12 +15,16 @@ module.exports = {
|
||||
// files.
|
||||
'__filename': false
|
||||
},
|
||||
'parser': 'babel-eslint',
|
||||
'parserOptions': {
|
||||
'ecmaFeatures': {
|
||||
'experimentalObjectRestSpread': true
|
||||
},
|
||||
'sourceType': 'module'
|
||||
},
|
||||
'plugins': [
|
||||
'flowtype'
|
||||
],
|
||||
'rules': {
|
||||
'new-cap': [
|
||||
'error',
|
||||
|
||||
50
.flowconfig
Normal file
50
.flowconfig
Normal file
@@ -0,0 +1,50 @@
|
||||
[ignore]
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
.*/node_modules/.*/node_modules/fbjs/.*
|
||||
|
||||
; Ignore duplicate module providers
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
.*/Libraries/react-native/ReactNative.js
|
||||
|
||||
; Ignore packages in node_modules which we (i.e. the jitsi-meet project) have
|
||||
; seen to cause errors and we have chosen not to fix.
|
||||
.*/node_modules/babel-core/.*
|
||||
.*/node_modules/bower/.*
|
||||
.*/node_modules/jsonlint/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
node_modules/react-native/flow
|
||||
flow/
|
||||
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
experimental.strict_type_args=true
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||
|
||||
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\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
unsafe.enable_getters_and_setters=true
|
||||
|
||||
[version]
|
||||
^0.37.0
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,2 +1,3 @@
|
||||
*.bundle.js -text -diff
|
||||
*.pbxproj -text
|
||||
lib-jitsi-meet.js -text -diff
|
||||
|
||||
20
.gitignore
vendored
20
.gitignore
vendored
@@ -4,7 +4,6 @@ deploy-local.sh
|
||||
libs/
|
||||
all.css
|
||||
*css.map
|
||||
unsupported_browser.css
|
||||
.remote-sync.json
|
||||
.sync-config.cson
|
||||
|
||||
@@ -36,21 +35,34 @@ DerivedData
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
|
||||
# Android/IJ
|
||||
# Android/IntelliJ
|
||||
#
|
||||
*.iml
|
||||
build/
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# BUCK
|
||||
#
|
||||
buck-out/
|
||||
\.buckd/
|
||||
android/app/libs
|
||||
android/keystores/debug.keystore
|
||||
*.keystore
|
||||
|
||||
# fastlane
|
||||
#
|
||||
# It is recommended to not store the screenshots in the git repo. Instead, use
|
||||
# fastlane to re-generate the screenshots whenever they are needed. For more
|
||||
# information about the recommended setup visit:
|
||||
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
|
||||
#
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
# The following do not need to be checked because they do not represent JS
|
||||
# source code.
|
||||
build/
|
||||
debian/
|
||||
libs/
|
||||
node_modules/
|
||||
|
||||
# The following are checked by ESLint which supersedes JSHint.
|
||||
flow-typed/
|
||||
react/
|
||||
|
||||
analytics.js
|
||||
webpack.config.babel.js
|
||||
|
||||
4
ConferenceEvents.js
Normal file
4
ConferenceEvents.js
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Notifies interested parties that hangup procedure will start.
|
||||
*/
|
||||
export const BEFORE_HANGUP = "conference.before_hangup";
|
||||
3
Makefile
3
Makefile
@@ -8,7 +8,6 @@ OUTPUT_DIR = .
|
||||
STYLES_BUNDLE = css/all.bundle.css
|
||||
STYLES_DESTINATION = css/all.css
|
||||
STYLES_MAIN = css/main.scss
|
||||
STYLES_UNSUPPORTED_BROWSER = css/unsupported_browser.scss
|
||||
WEBPACK = ./node_modules/.bin/webpack
|
||||
|
||||
all: update-deps compile deploy clean
|
||||
@@ -47,7 +46,6 @@ deploy-lib-jitsi-meet:
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-css:
|
||||
$(NODE_SASS) css/unsupported_browser.scss css/unsupported_browser.css ; \
|
||||
$(NODE_SASS) $(STYLES_MAIN) $(STYLES_BUNDLE) && \
|
||||
$(CLEANCSS) $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
|
||||
rm $(STYLES_BUNDLE)
|
||||
@@ -59,6 +57,5 @@ 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 css/all.css source_package/jitsi-meet/css && \
|
||||
cp css/unsupported_browser.css source_package/jitsi-meet/css && \
|
||||
(cd source_package ; tar cjf ../jitsi-meet.tar.bz2 jitsi-meet) && \
|
||||
rm -rf source_package
|
||||
|
||||
15
README.md
15
README.md
@@ -1,5 +1,5 @@
|
||||
Jitsi Meet - Secure, Simple and Scalable Video Conferences
|
||||
====
|
||||
# Jitsi Meet - Secure, Simple and Scalable Video Conferences
|
||||
|
||||
Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, scalable video conferences. You can see [Jitsi Meet in action](http://youtu.be/7vFUVClsNh0) here at the session #482 of the VoIP Users Conference.
|
||||
|
||||
You can also try it out yourself at https://meet.jit.si .
|
||||
@@ -16,6 +16,7 @@ For other systems, or if you wish to install all components manually, see the [d
|
||||
|
||||
You can download Debian/Ubuntu binaries:
|
||||
* [stable](https://download.jitsi.org/stable/) ([instructions](https://jitsi.org/Main/InstallJitsiMeetDebianStableRepository))
|
||||
* [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
|
||||
@@ -34,7 +35,7 @@ To build the Jitsi Meet application, just type
|
||||
make
|
||||
```
|
||||
|
||||
## Working with the library sources(lib-jitsi-meet).
|
||||
## Working with the library sources (lib-jitsi-meet)
|
||||
|
||||
By default the library is build from its git repository sources. The default dependency path in package.json is :
|
||||
```json
|
||||
@@ -81,6 +82,14 @@ npm unlink lib-jitsi-meet
|
||||
npm install
|
||||
```
|
||||
|
||||
## 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).
|
||||
|
||||
## Mobile app
|
||||
Jitsi Meet is also available as a React Native application for Android and iOS.
|
||||
Instructions on how to build it can be found [here](doc/mobile.md).
|
||||
|
||||
## Discuss
|
||||
Please use the [Jitsi dev mailing list](http://lists.jitsi.org/pipermail/dev/) to discuss feature requests before opening an issue on Github.
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ android {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode Integer.parseInt("${version}")
|
||||
versionName "1.1.${version}"
|
||||
versionName "1.2.${version}"
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'x86'
|
||||
}
|
||||
@@ -139,12 +139,13 @@ if (project.hasProperty('JITSI_SIGNING')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-immersive')
|
||||
compile project(':react-native-keep-awake')
|
||||
compile project(':react-native-vector-icons')
|
||||
compile project(':react-native-webrtc')
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||
compile 'com.facebook.react:react-native:+'
|
||||
compile 'com.facebook.react:react-native:+' // From node_modules
|
||||
}
|
||||
|
||||
apply from: '../../node_modules/react-native-vector-icons/fonts.gradle'
|
||||
@@ -152,6 +153,6 @@ apply from: '../../node_modules/react-native-vector-icons/fonts.gradle'
|
||||
// Run this once to be able to run the application with BUCK
|
||||
// puts all compile dependencies into folder libs for BUCK to use
|
||||
task copyDownloadableDepsToLibs(type: Copy) {
|
||||
from configurations.compile
|
||||
into 'libs'
|
||||
from configurations.compile
|
||||
into 'libs'
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!-- WebRTC -->
|
||||
<!-- XXX: ACCESS_NETWORK_STATE is required by WebRTC. -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<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"/>
|
||||
|
||||
@@ -13,8 +16,8 @@
|
||||
<uses-feature android:name="android.hardware.camera.autofocus"/>
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="16"
|
||||
android:targetSdkVersion="22" />
|
||||
android:minSdkVersion="19"
|
||||
android:targetSdkVersion="23" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@@ -35,11 +38,19 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:host="beta.hipchat.me" android:scheme="https" />
|
||||
<data android:host="beta.meet.jit.si" android:scheme="https" />
|
||||
<data android:host="chaos.hipchat.me" android:scheme="https" />
|
||||
<data android:host="enso.me" android:scheme="https" />
|
||||
<data android:host="hipchat.me" android:scheme="https" />
|
||||
<data android:host="meet.jit.si" android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="org.jitsi.meet" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.app.Application;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -15,7 +16,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@@ -28,7 +29,9 @@ 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.oney.WebRTCModule.WebRTCModulePackage()
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new org.jitsi.meet.audiomode.AudioModePackage()
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -48,6 +51,8 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
|
||||
if (!getReactNativeHost()
|
||||
.getReactInstanceManager()
|
||||
.getDevSupportManager()
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
package org.jitsi.meet.audiomode;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Module implementing a simple API to select the appropriate audio device for a
|
||||
* conference call.
|
||||
*
|
||||
* Audio calls should use <tt>AudioModeModule.AUDIO_CALL</tt>, which uses the
|
||||
* builtin earpiece, wired headset or bluetooth headset. The builtin earpiece is
|
||||
* the default audio device.
|
||||
*
|
||||
* Video calls should should use <tt>AudioModeModule.VIDEO_CALL</tt>, which uses
|
||||
* the builtin speaker, earpiece, wired headset or bluetooth headset. The
|
||||
* builtin speaker is the default audio device.
|
||||
*
|
||||
* Before a call has started and after it has ended the
|
||||
* <tt>AudioModeModule.DEFAULT</tt> mode should be used.
|
||||
*/
|
||||
public class AudioModeModule extends ReactContextBaseJavaModule {
|
||||
/**
|
||||
* Constants representing the audio mode.
|
||||
* - DEFAULT: Used before and after every call. It represents the default
|
||||
* audio routing scheme.
|
||||
* - AUDIO_CALL: Used for audio only calls. It will use the earpiece by
|
||||
* default, unless a wired or Bluetooth headset is connected.
|
||||
* - VIDEO_CALL: Used for video calls. It will use the speaker by default,
|
||||
* unless a wired or Bluetooth headset is connected.
|
||||
*/
|
||||
private static final int DEFAULT = 0;
|
||||
private static final int AUDIO_CALL = 1;
|
||||
private static final int VIDEO_CALL = 2;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final String ACTION_HEADSET_PLUG
|
||||
= (Build.VERSION.SDK_INT >= 21)
|
||||
? AudioManager.ACTION_HEADSET_PLUG
|
||||
: Intent.ACTION_HEADSET_PLUG;
|
||||
|
||||
/**
|
||||
* React Native module name.
|
||||
*/
|
||||
private static final String MODULE_NAME = "AudioMode";
|
||||
|
||||
/**
|
||||
* Tag used when logging messages.
|
||||
*/
|
||||
static final String TAG = MODULE_NAME;
|
||||
|
||||
/**
|
||||
* {@link AudioManager} instance used to interact with the Android audio
|
||||
* subsystem.
|
||||
*/
|
||||
private final AudioManager audioManager;
|
||||
|
||||
/**
|
||||
* {@link BluetoothHeadsetMonitor} for detecting Bluetooth device changes in
|
||||
* old (< M) Android versions.
|
||||
*/
|
||||
private BluetoothHeadsetMonitor bluetoothHeadsetMonitor;
|
||||
|
||||
/**
|
||||
* {@link Handler} for running all operations on the main thread.
|
||||
*/
|
||||
private final Handler mainThreadHandler
|
||||
= new Handler(Looper.getMainLooper());
|
||||
|
||||
/**
|
||||
* {@link Runnable} for running update operation on the main thread.
|
||||
*/
|
||||
private final Runnable mainThreadRunner
|
||||
= new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mode != -1) {
|
||||
updateAudioRoute(mode);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Audio mode currently in use.
|
||||
*/
|
||||
private int mode = -1;
|
||||
|
||||
/**
|
||||
* 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 AudioModeModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
|
||||
audioManager
|
||||
= (AudioManager)
|
||||
reactContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
// Setup runtime device change detection.
|
||||
setupAudioRouteChangeDetection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a mapping with the constants this module is exporting.
|
||||
*
|
||||
* @return a {@link Map} mapping the constants to be exported with their
|
||||
* values.
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getConstants() {
|
||||
Map<String, Object> constants = new HashMap<>();
|
||||
|
||||
constants.put("AUDIO_CALL", AUDIO_CALL);
|
||||
constants.put("DEFAULT", DEFAULT);
|
||||
constants.put("VIDEO_CALL", VIDEO_CALL);
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name for this module, to be used in the React Native bridge.
|
||||
*
|
||||
* @return a string with the module name.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return MODULE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to trigger an audio route update when devices change. It
|
||||
* makes sure the operation is performed on the main thread.
|
||||
*/
|
||||
void onAudioDeviceChange() {
|
||||
mainThreadHandler.post(mainThreadRunner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the output route to a Bluetooth device.
|
||||
*
|
||||
* @param enabled true if Bluetooth should use used, false otherwise.
|
||||
*/
|
||||
private void setBluetoothAudioRoute(boolean enabled) {
|
||||
if (enabled) {
|
||||
audioManager.startBluetoothSco();
|
||||
audioManager.setBluetoothScoOn(true);
|
||||
} else {
|
||||
audioManager.setBluetoothScoOn(false);
|
||||
audioManager.stopBluetoothSco();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method to set the current audio mode.
|
||||
*
|
||||
* @param mode the desired audio mode.
|
||||
* @param promise a {@link Promise} which will be resolved if the audio mode
|
||||
* could be updated successfully, and it will be rejected otherwise.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void setMode(final int mode, final Promise promise) {
|
||||
if (mode != DEFAULT && mode != AUDIO_CALL && mode != VIDEO_CALL) {
|
||||
promise.reject("setMode", "Invalid audio mode " + mode);
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (updateAudioRoute(mode)) {
|
||||
AudioModeModule.this.mode = mode;
|
||||
promise.resolve(null);
|
||||
} else {
|
||||
promise.reject(
|
||||
"setMode",
|
||||
"Failed to set the requested audio mode");
|
||||
}
|
||||
}
|
||||
};
|
||||
mainThreadHandler.post(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the audio route change detection mechanism. We use the
|
||||
* {@link android.media.AudioDeviceCallback} API on Android >= 23 only.
|
||||
*/
|
||||
private void setupAudioRouteChangeDetection() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
setupAudioRouteChangeDetectionM();
|
||||
} else {
|
||||
setupAudioRouteChangeDetectionPreM();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Audio route change detection mechanism for Android API >= 23.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
private void setupAudioRouteChangeDetectionM() {
|
||||
android.media.AudioDeviceCallback audioDeviceCallback =
|
||||
new android.media.AudioDeviceCallback() {
|
||||
@Override
|
||||
public void onAudioDevicesAdded(
|
||||
AudioDeviceInfo[] addedDevices) {
|
||||
Log.d(TAG, "Audio devices added");
|
||||
onAudioDeviceChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioDevicesRemoved(
|
||||
AudioDeviceInfo[] removedDevices) {
|
||||
Log.d(TAG, "Audio devices removed");
|
||||
onAudioDeviceChange();
|
||||
}
|
||||
};
|
||||
|
||||
audioManager.registerAudioDeviceCallback(audioDeviceCallback, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Audio route change detection mechanism for Android API < 23.
|
||||
*/
|
||||
private void setupAudioRouteChangeDetectionPreM() {
|
||||
Context context = getReactApplicationContext();
|
||||
|
||||
// Detect changes in wired headset connections.
|
||||
IntentFilter wiredHeadSetFilter = new IntentFilter(ACTION_HEADSET_PLUG);
|
||||
BroadcastReceiver wiredHeadsetReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "Wired headset added / removed");
|
||||
onAudioDeviceChange();
|
||||
}
|
||||
};
|
||||
context.registerReceiver(wiredHeadsetReceiver, wiredHeadSetFilter);
|
||||
|
||||
// Detect Bluetooth device changes.
|
||||
bluetoothHeadsetMonitor = new BluetoothHeadsetMonitor(this, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the audio route for the given mode.
|
||||
*
|
||||
* @param mode the audio mode to be used when computing the audio route.
|
||||
* @return true if the audio route was updated successfully, false
|
||||
* otherwise.
|
||||
*/
|
||||
private boolean updateAudioRoute(int mode) {
|
||||
Log.d(TAG, "Update audio route for mode: " + mode);
|
||||
|
||||
if (mode == DEFAULT) {
|
||||
audioManager.setMode(AudioManager.MODE_NORMAL);
|
||||
audioManager.abandonAudioFocus(null);
|
||||
audioManager.setSpeakerphoneOn(false);
|
||||
audioManager.setMicrophoneMute(true);
|
||||
setBluetoothAudioRoute(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
||||
audioManager.setMicrophoneMute(false);
|
||||
|
||||
if (audioManager.requestAudioFocus(
|
||||
null,
|
||||
AudioManager.STREAM_VOICE_CALL,
|
||||
AudioManager.AUDIOFOCUS_GAIN)
|
||||
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
|
||||
Log.d(TAG, "Audio focus request failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean useSpeaker = (mode == VIDEO_CALL);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// On Android >= M we use the AudioDeviceCallback API, so turn on
|
||||
// Bluetooth SCO from the start.
|
||||
if (audioManager.isBluetoothScoAvailableOffCall()) {
|
||||
audioManager.startBluetoothSco();
|
||||
}
|
||||
} else {
|
||||
// On older Android versions we must set the Bluetooth route
|
||||
// manually. Also disable the speaker in that case.
|
||||
setBluetoothAudioRoute(
|
||||
bluetoothHeadsetMonitor.isHeadsetAvailable());
|
||||
if (bluetoothHeadsetMonitor.isHeadsetAvailable()) {
|
||||
useSpeaker = false;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: isWiredHeadsetOn is not deprecated when used just for knowing if
|
||||
// there is a wired headset connected, regardless of audio being routed
|
||||
// to it.
|
||||
audioManager.setSpeakerphoneOn(
|
||||
useSpeaker
|
||||
&& !(audioManager.isWiredHeadsetOn()
|
||||
|| audioManager.isBluetoothScoOn()));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.jitsi.meet.audiomode;
|
||||
|
||||
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 AudioModeModule}.
|
||||
*/
|
||||
public class AudioModePackage 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 AudioModeModule(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(
|
||||
ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package org.jitsi.meet.audiomode;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Helper class to detect and handle Bluetooth device changes. It monitors
|
||||
* Bluetooth headsets being connected / disconnected and notifies the module
|
||||
* about device changes when this occurs.
|
||||
*/
|
||||
public class BluetoothHeadsetMonitor {
|
||||
/**
|
||||
* {@link AudioModeModule} where this monitor reports.
|
||||
*/
|
||||
private final AudioModeModule audioModeModule;
|
||||
|
||||
/**
|
||||
* The {@link Context} in which {@link #audioModeModule} executes.
|
||||
*/
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* Reference to a proxy object which allows us to query connected devices.
|
||||
*/
|
||||
private BluetoothHeadset headset;
|
||||
|
||||
/**
|
||||
* Flag indicating if there are any Bluetooth headset devices currently
|
||||
* available.
|
||||
*/
|
||||
private boolean headsetAvailable = false;
|
||||
|
||||
/**
|
||||
* {@link Handler} for running all operations on the main thread.
|
||||
*/
|
||||
private final Handler mainThreadHandler
|
||||
= new Handler(Looper.getMainLooper());
|
||||
|
||||
/**
|
||||
* Helper for running Bluetooth operations on the main thread.
|
||||
*/
|
||||
private final Runnable updateDevicesRunnable
|
||||
= new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
headsetAvailable
|
||||
= (headset != null)
|
||||
&& !headset.getConnectedDevices().isEmpty();
|
||||
audioModeModule.onAudioDeviceChange();
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothHeadsetMonitor(
|
||||
AudioModeModule audioModeModule,
|
||||
Context context) {
|
||||
this.audioModeModule = audioModeModule;
|
||||
this.context = context;
|
||||
|
||||
AudioManager audioManager
|
||||
= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
if (!audioManager.isBluetoothScoAvailableOffCall()) {
|
||||
Log.w(AudioModeModule.TAG, "Bluetooth SCO is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
if (getBluetoothHeadsetProfileProxy()) {
|
||||
registerBluetoothReceiver();
|
||||
|
||||
// Initial detection.
|
||||
updateDevices();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getBluetoothHeadsetProfileProxy() {
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (adapter == null) {
|
||||
Log.w(AudioModeModule.TAG, "Device doesn't support Bluetooth");
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: The profile listener listens for system services of the given
|
||||
// type being available to the application. That is, if our Bluetooth
|
||||
// adapter has the "headset" profile.
|
||||
BluetoothProfile.ServiceListener listener
|
||||
= new BluetoothProfile.ServiceListener() {
|
||||
@Override
|
||||
public void onServiceConnected(
|
||||
int profile,
|
||||
BluetoothProfile proxy) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
headset = (BluetoothHeadset) proxy;
|
||||
updateDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(int profile) {
|
||||
// The logic is the same as the logic of onServiceConnected.
|
||||
onServiceConnected(profile, /* proxy */ null);
|
||||
}
|
||||
};
|
||||
|
||||
return
|
||||
adapter.getProfileProxy(
|
||||
context,
|
||||
listener,
|
||||
BluetoothProfile.HEADSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current headset availability.
|
||||
*
|
||||
* @return true if there is a Bluetooth headset connected, false otherwise.
|
||||
*/
|
||||
public boolean isHeadsetAvailable() {
|
||||
return headsetAvailable;
|
||||
}
|
||||
|
||||
private void onBluetoothReceiverReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||
// XXX: This action will be fired when a Bluetooth headset is
|
||||
// connected or disconnected to the system. This is not related to
|
||||
// audio routing.
|
||||
int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
|
||||
|
||||
switch (state) {
|
||||
case BluetoothHeadset.STATE_CONNECTED:
|
||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||
Log.d(
|
||||
AudioModeModule.TAG,
|
||||
"BT headset connection state changed: " + state);
|
||||
updateDevices();
|
||||
break;
|
||||
}
|
||||
} else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
|
||||
// XXX: This action will be fired when the connection established
|
||||
// with a Bluetooth headset (called a SCO connection) changes state.
|
||||
// When the SCO connection is active we route audio to it.
|
||||
int state
|
||||
= intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -99);
|
||||
|
||||
switch (state) {
|
||||
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
|
||||
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
|
||||
Log.d(
|
||||
AudioModeModule.TAG,
|
||||
"BT SCO connection state changed: " + state);
|
||||
updateDevices();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerBluetoothReceiver() {
|
||||
BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
onBluetoothReceiverReceive(context, intent);
|
||||
}
|
||||
};
|
||||
IntentFilter filter = new IntentFilter();
|
||||
|
||||
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
|
||||
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
||||
context.registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if there are new devices connected / disconnected and fires the
|
||||
* {@link AudioModeModule#onAudioDeviceChange()} callback.
|
||||
*/
|
||||
private void updateDevices() {
|
||||
mainThreadHandler.post(updateDevicesRunnable);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
rootProject.name = 'jitsi-meet-react'
|
||||
|
||||
include ':app'
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
include ':react-native-vector-icons'
|
||||
|
||||
4
app.js
4
app.js
@@ -22,6 +22,7 @@ import conference from './conference';
|
||||
import API from './modules/API/API';
|
||||
|
||||
import translation from "./modules/translation/translation";
|
||||
import remoteControl from "./modules/remotecontrol/RemoteControl";
|
||||
|
||||
const APP = {
|
||||
// Used by do_external_connect.js if we receive the attach data after
|
||||
@@ -59,7 +60,8 @@ const APP = {
|
||||
*/
|
||||
ConferenceUrl : null,
|
||||
connection: null,
|
||||
API
|
||||
API,
|
||||
remoteControl
|
||||
};
|
||||
|
||||
// TODO The execution of the mobile app starts from react/index.native.js.
|
||||
|
||||
234
conference.js
234
conference.js
@@ -10,13 +10,16 @@ import Recorder from './modules/recorder/Recorder';
|
||||
|
||||
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
|
||||
|
||||
import {reportError} from './modules/util/helpers';
|
||||
import { reload, reportError } from './modules/util/helpers';
|
||||
|
||||
import UIEvents from './service/UI/UIEvents';
|
||||
import UIUtil from './modules/UI/util/UIUtil';
|
||||
import * as JitsiMeetConferenceEvents from './ConferenceEvents';
|
||||
|
||||
import analytics from './modules/analytics/analytics';
|
||||
|
||||
import EventEmitter from "events";
|
||||
|
||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
|
||||
@@ -28,6 +31,8 @@ const TrackErrors = JitsiMeetJS.errors.track;
|
||||
|
||||
const ConnectionQualityEvents = JitsiMeetJS.events.connectionQuality;
|
||||
|
||||
const eventEmitter = new EventEmitter();
|
||||
|
||||
let room, connection, localAudio, localVideo;
|
||||
|
||||
/**
|
||||
@@ -198,10 +203,8 @@ function maybeRedirectToWelcomePage(options) {
|
||||
// save whether current user is guest or not, before navigating
|
||||
// to close page
|
||||
window.sessionStorage.setItem('guest', APP.tokenData.isGuest);
|
||||
if (options.feedbackSubmitted)
|
||||
window.location.pathname = "close.html";
|
||||
else
|
||||
window.location.pathname = "close2.html";
|
||||
assignWindowLocationPathname(
|
||||
options.feedbackSubmitted ? "close.html" : "close2.html");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -214,11 +217,42 @@ function maybeRedirectToWelcomePage(options) {
|
||||
if (config.enableWelcomePage) {
|
||||
setTimeout(() => {
|
||||
APP.settings.setWelcomePageEnabled(true);
|
||||
window.location.pathname = "/";
|
||||
assignWindowLocationPathname('./');
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a specific pathname to window.location.pathname taking into account
|
||||
* the context root of the Web app.
|
||||
*
|
||||
* @param {string} pathname - The pathname to assign to
|
||||
* window.location.pathname. If the specified pathname is relative, the context
|
||||
* root of the Web app will be prepended to the specified pathname before
|
||||
* assigning it to window.location.pathname.
|
||||
* @return {void}
|
||||
*/
|
||||
function assignWindowLocationPathname(pathname) {
|
||||
const windowLocation = window.location;
|
||||
|
||||
if (!pathname.startsWith('/')) {
|
||||
// XXX To support a deployment in a sub-directory, assume that the room
|
||||
// (name) is the last non-directory component of the path (name).
|
||||
let contextRoot = windowLocation.pathname;
|
||||
|
||||
contextRoot
|
||||
= contextRoot.substring(0, contextRoot.lastIndexOf('/') + 1);
|
||||
|
||||
// A pathname equal to ./ specifies the current directory. It will be
|
||||
// fine but pointless to include it because contextRoot is the current
|
||||
// directory.
|
||||
pathname.startsWith('./') && (pathname = pathname.substring(2));
|
||||
pathname = contextRoot + pathname;
|
||||
}
|
||||
|
||||
windowLocation.pathname = pathname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create local tracks of specified types.
|
||||
* @param {Object} options
|
||||
@@ -318,7 +352,7 @@ class ConferenceConnector {
|
||||
case ConferenceErrors.NOT_ALLOWED_ERROR:
|
||||
{
|
||||
// let's show some auth not allowed page
|
||||
window.location.pathname = "authError.html";
|
||||
assignWindowLocationPathname('authError.html');
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -383,7 +417,7 @@ class ConferenceConnector {
|
||||
APP.UI.notifyMaxUsersLimitReached();
|
||||
break;
|
||||
case ConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
|
||||
window.location.reload();
|
||||
reload();
|
||||
break;
|
||||
default:
|
||||
this._handleConferenceFailed(err, ...params);
|
||||
@@ -485,10 +519,11 @@ export default {
|
||||
}).then(([tracks, con]) => {
|
||||
logger.log('initialized with %s local tracks', tracks.length);
|
||||
APP.connection = connection = con;
|
||||
this._bindConnectionFailedHandler(con);
|
||||
this._createRoom(tracks);
|
||||
this.isDesktopSharingEnabled =
|
||||
JitsiMeetJS.isDesktopSharingEnabled();
|
||||
APP.remoteControl.init();
|
||||
this._bindConnectionFailedHandler(con);
|
||||
this._createRoom(tracks);
|
||||
|
||||
if (UIUtil.isButtonEnabled('contacts')
|
||||
&& !interfaceConfig.filmStripOnly) {
|
||||
@@ -901,43 +936,40 @@ export default {
|
||||
return options;
|
||||
},
|
||||
|
||||
/**
|
||||
* Start using provided video stream.
|
||||
* Stops previous video stream.
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useVideoStream (stream) {
|
||||
let promise = Promise.resolve();
|
||||
if (localVideo) {
|
||||
// this calls room.removeTrack internally
|
||||
// so we don't need to remove it manually
|
||||
promise = localVideo.dispose();
|
||||
}
|
||||
localVideo = stream;
|
||||
|
||||
return promise.then(function () {
|
||||
if (stream) {
|
||||
return room.addTrack(stream);
|
||||
}
|
||||
}).then(() => {
|
||||
if (stream) {
|
||||
this.videoMuted = stream.isMuted();
|
||||
this.isSharingScreen = stream.videoType === 'desktop';
|
||||
/**
|
||||
* 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
|
||||
// dispose will try and do a new o/a after the
|
||||
// track removes itself. Doing it after means
|
||||
// the JitsiLocalTrack::conference member is already
|
||||
// cleared, so it won't try and do the o/a
|
||||
if (localVideo) {
|
||||
localVideo.dispose();
|
||||
}
|
||||
localVideo = newStream;
|
||||
if (newStream) {
|
||||
this.videoMuted = newStream.isMuted();
|
||||
this.isSharingScreen = newStream.videoType === 'desktop';
|
||||
|
||||
APP.UI.addLocalStream(stream);
|
||||
APP.UI.addLocalStream(newStream);
|
||||
|
||||
stream.videoType === 'camera'
|
||||
&& APP.UI.setCameraButtonEnabled(true);
|
||||
} else {
|
||||
this.videoMuted = false;
|
||||
this.isSharingScreen = false;
|
||||
}
|
||||
|
||||
APP.UI.setVideoMuted(this.getMyUserId(), this.videoMuted);
|
||||
|
||||
APP.UI.updateDesktopSharingButtons();
|
||||
});
|
||||
newStream.videoType === 'camera'
|
||||
&& APP.UI.setCameraButtonEnabled(true);
|
||||
} else {
|
||||
this.videoMuted = false;
|
||||
this.isSharingScreen = false;
|
||||
}
|
||||
APP.UI.setVideoMuted(this.getMyUserId(), this.videoMuted);
|
||||
APP.UI.updateDesktopSharingButtons();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -946,31 +978,27 @@ export default {
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useAudioStream (stream) {
|
||||
let promise = Promise.resolve();
|
||||
if (localAudio) {
|
||||
// this calls room.removeTrack internally
|
||||
// so we don't need to remove it manually
|
||||
promise = localAudio.dispose();
|
||||
}
|
||||
localAudio = stream;
|
||||
|
||||
return promise.then(function () {
|
||||
if (stream) {
|
||||
return room.addTrack(stream);
|
||||
}
|
||||
}).then(() => {
|
||||
if (stream) {
|
||||
this.audioMuted = stream.isMuted();
|
||||
|
||||
APP.UI.addLocalStream(stream);
|
||||
} else {
|
||||
this.audioMuted = false;
|
||||
}
|
||||
|
||||
APP.UI.setMicrophoneButtonEnabled(true);
|
||||
APP.UI.setAudioMuted(this.getMyUserId(), this.audioMuted);
|
||||
});
|
||||
useAudioStream (newStream) {
|
||||
return room.replaceTrack(localAudio, newStream)
|
||||
.then(() => {
|
||||
// We call dispose after doing the replace because
|
||||
// dispose will try and do a new o/a after the
|
||||
// track removes itself. Doing it after means
|
||||
// the JitsiLocalTrack::conference member is already
|
||||
// cleared, so it won't try and do the o/a
|
||||
if (localAudio) {
|
||||
localAudio.dispose();
|
||||
}
|
||||
localAudio = newStream;
|
||||
if (newStream) {
|
||||
this.audioMuted = newStream.isMuted();
|
||||
APP.UI.addLocalStream(newStream);
|
||||
} else {
|
||||
this.audioMuted = false;
|
||||
}
|
||||
APP.UI.setMicrophoneButtonEnabled(true);
|
||||
APP.UI.setAudioMuted(this.getMyUserId(), this.audioMuted);
|
||||
});
|
||||
},
|
||||
|
||||
videoSwitchInProgress: false,
|
||||
@@ -988,7 +1016,7 @@ export default {
|
||||
let externalInstallation = false;
|
||||
|
||||
if (shareScreen) {
|
||||
createLocalTracks({
|
||||
this.screenSharingPromise = createLocalTracks({
|
||||
devices: ['desktop'],
|
||||
desktopSharingExtensionExternalInstallation: {
|
||||
interval: 500,
|
||||
@@ -1077,7 +1105,10 @@ export default {
|
||||
dialogTitleKey, dialogTxt, false);
|
||||
});
|
||||
} else {
|
||||
createLocalTracks({ devices: ['video'] }).then(
|
||||
APP.remoteControl.receiver.stop();
|
||||
this.screenSharingPromise = createLocalTracks(
|
||||
{ devices: ['video'] })
|
||||
.then(
|
||||
([stream]) => this.useVideoStream(stream)
|
||||
).then(() => {
|
||||
this.videoSwitchInProgress = false;
|
||||
@@ -1109,6 +1140,8 @@ export default {
|
||||
}
|
||||
);
|
||||
|
||||
room.on(ConferenceEvents.PARTCIPANT_FEATURES_CHANGED,
|
||||
user => APP.UI.onUserFeaturesChanged(user));
|
||||
room.on(ConferenceEvents.USER_JOINED, (id, user) => {
|
||||
if (user.isHidden())
|
||||
return;
|
||||
@@ -1344,11 +1377,13 @@ export default {
|
||||
this.deviceChangeListener);
|
||||
|
||||
// stop local video
|
||||
if (localVideo)
|
||||
if (localVideo) {
|
||||
localVideo.dispose();
|
||||
}
|
||||
// stop local audio
|
||||
if (localAudio)
|
||||
if (localAudio) {
|
||||
localAudio.dispose();
|
||||
}
|
||||
|
||||
// show overlay
|
||||
APP.UI.showSuspendedOverlay();
|
||||
@@ -1439,7 +1474,7 @@ export default {
|
||||
APP.UI.addListener(UIEvents.LOGOUT, () => {
|
||||
AuthHandler.logout(room).then(url => {
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
UIUtil.redirect(url);
|
||||
} else {
|
||||
this.hangup(true);
|
||||
}
|
||||
@@ -1605,12 +1640,23 @@ export default {
|
||||
},
|
||||
/**
|
||||
* Adds any room listener.
|
||||
* @param eventName one of the ConferenceEvents
|
||||
* @param callBack the function to be called when the event occurs
|
||||
* @param {string} eventName one of the ConferenceEvents
|
||||
* @param {Function} listener the function to be called when the event
|
||||
* occurs
|
||||
*/
|
||||
addConferenceListener(eventName, callBack) {
|
||||
room.on(eventName, callBack);
|
||||
addConferenceListener(eventName, listener) {
|
||||
room.on(eventName, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes any room listener.
|
||||
* @param {string} eventName one of the ConferenceEvents
|
||||
* @param {Function} listener the listener to be removed.
|
||||
*/
|
||||
removeConferenceListener(eventName, listener) {
|
||||
room.off(eventName, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* Inits list of current devices and event listener for device change.
|
||||
* @private
|
||||
@@ -1768,6 +1814,7 @@ export default {
|
||||
* requested
|
||||
*/
|
||||
hangup (requestFeedback = false) {
|
||||
eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
|
||||
APP.UI.hideRingOverLay();
|
||||
let requestFeedbackPromise = requestFeedback
|
||||
? APP.UI.requestFeedbackOnHangup()
|
||||
@@ -1818,5 +1865,36 @@ export default {
|
||||
APP.settings.setAvatarUrl(url);
|
||||
APP.UI.setUserAvatarUrl(room.myUserId(), url);
|
||||
sendData(commands.AVATAR_URL, url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a message via the data channel.
|
||||
* @param {string} to the id of the endpoint that should receive the
|
||||
* message. If "" - the message will be sent to all participants.
|
||||
* @param {object} payload the payload of the message.
|
||||
* @throws NetworkError or InvalidStateError or Error if the operation
|
||||
* fails.
|
||||
*/
|
||||
sendEndpointMessage (to, payload) {
|
||||
room.sendEndpointMessage(to, payload);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds new listener.
|
||||
* @param {String} eventName the name of the event
|
||||
* @param {Function} listener the listener.
|
||||
*/
|
||||
addListener (eventName, listener) {
|
||||
eventEmitter.addListener(eventName, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes listener.
|
||||
* @param {String} eventName the name of the event that triggers the
|
||||
* listener
|
||||
* @param {Function} listener the listener.
|
||||
*/
|
||||
removeListener (eventName, listener) {
|
||||
eventEmitter.removeListener(eventName, listener);
|
||||
}
|
||||
};
|
||||
|
||||
10
config.js
10
config.js
@@ -20,10 +20,10 @@ 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
|
||||
|
||||
// Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
|
||||
desktopSharingChromeMethod: 'ext',
|
||||
// The ID of the jidesha extension for Chrome.
|
||||
desktopSharingChromeExtId: 'diibjkoicjeejcmhdnailmkgecihlobk',
|
||||
desktopSharingChromeExtId: null,
|
||||
// Whether desktop sharing should be disabled on Chrome.
|
||||
desktopSharingChromeDisabled: true,
|
||||
// The media sources to use when using screen sharing with the Chrome
|
||||
// extension.
|
||||
desktopSharingChromeSources: ['screen', 'window', 'tab'],
|
||||
@@ -78,5 +78,7 @@ var config = { // eslint-disable-line no-unused-vars
|
||||
// edit their profile.
|
||||
enableUserRolesBasedOnToken: false,
|
||||
// Suspending video might cause problems with audio playback. Disabling until these are fixed.
|
||||
disableSuspendVideo: true
|
||||
disableSuspendVideo: true,
|
||||
// disables or enables RTX (RFC 4588).
|
||||
disableRtx: true
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
display: none;
|
||||
position: relative;
|
||||
background-size: contain;
|
||||
border: $thumbnailVideoBorder solid $thumbnailBorderColor;
|
||||
border: $thumbnailVideoBorder solid transparent;
|
||||
border-radius: $borderRadius;
|
||||
margin: 0 $thumbnailVideoMargin;
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
0 0 3px $videoThumbnailSelected !important;
|
||||
}
|
||||
|
||||
.remotevideomenu {
|
||||
.remotevideomenu > .icon-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
box-shadow: inset 0 0 3px $videoThumbnailHovered,
|
||||
0 0 3px $videoThumbnailHovered;
|
||||
|
||||
.remotevideomenu {
|
||||
.remotevideomenu > .icon-menu {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
@@ -121,4 +121,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-mic-camera-combined:before {
|
||||
content: "\e903";
|
||||
}
|
||||
.icon-feedback:before {
|
||||
content: "\e91d";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.inlay {
|
||||
margin-top: 14%;
|
||||
@include border-radius(3px);
|
||||
@include border-radius(4px);
|
||||
padding: 40px 38px 44px;
|
||||
color: #fff;
|
||||
background: $inlayColorBg;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
color: $popoverFontColor;
|
||||
background-color: $popoverBg;
|
||||
background-clip: padding-box;
|
||||
border-radius: 3px;
|
||||
border-radius: $borderRadius;
|
||||
/*-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);*/
|
||||
/*box-shadow: 0 5px 10px rgba(0, 0, 0, 0.4);*/
|
||||
white-space: normal;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
@charset "UTF-8";
|
||||
/*!
|
||||
* jQuery contextMenu - Plugin for simple contextMenu handling
|
||||
*
|
||||
* Version: v2.1.1
|
||||
*
|
||||
* Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF)
|
||||
* Web: http://swisnl.github.io/jQuery-contextMenu/
|
||||
*
|
||||
* Copyright (c) 2011-2016 SWIS BV and contributors
|
||||
*
|
||||
* Licensed under
|
||||
* MIT License http://www.opensource.org/licenses/mit-license
|
||||
*
|
||||
* Date: 2016-02-28T09:53:18.890Z
|
||||
/*!
|
||||
* jQuery contextMenu - Plugin for simple contextMenu handling
|
||||
*
|
||||
* Version: v2.1.1
|
||||
*
|
||||
* Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF)
|
||||
* Web: http://swisnl.github.io/jQuery-contextMenu/
|
||||
*
|
||||
* Copyright (c) 2011-2016 SWIS BV and contributors
|
||||
*
|
||||
* Licensed under
|
||||
* MIT License http://www.opensource.org/licenses/mit-license
|
||||
*
|
||||
* Date: 2016-02-28T09:53:18.890Z
|
||||
*/
|
||||
@font-face {
|
||||
font-family: "context-menu-icons";
|
||||
@@ -88,7 +88,7 @@
|
||||
list-style-type: none;
|
||||
background: #fff;
|
||||
border: 1px solid #bebebe;
|
||||
border-radius: 3px;
|
||||
border-radius: $borderRadius;
|
||||
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
|
||||
}
|
||||
@@ -156,8 +156,8 @@
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inputs
|
||||
/**
|
||||
* Inputs
|
||||
*/
|
||||
.context-menu-item.context-menu-input {
|
||||
padding: 5px 10px;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
padding: 0;
|
||||
margin: 2px 0;
|
||||
bottom: 0;
|
||||
width: 100px;
|
||||
height: auto;
|
||||
|
||||
&:first-child {
|
||||
@@ -66,4 +65,9 @@
|
||||
|
||||
span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
|
||||
display:block !important;
|
||||
}
|
||||
}
|
||||
|
||||
.remote-control-spinner {
|
||||
top: 6px;
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
@@ -127,3 +127,10 @@ $inputControlEmColor: #f29424;
|
||||
//buttons
|
||||
$linkFontColor: #489afe;
|
||||
$linkHoverFontColor: #287ade;
|
||||
|
||||
/**
|
||||
* Landing
|
||||
*/
|
||||
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
|
||||
$unsupportedBrowserButtonBgColor: #ff9a00;
|
||||
$unsupportedBrowserTextColor: #4a4a4a;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
&__background {
|
||||
@include topLeft();
|
||||
background-color: black;
|
||||
border-radius: $borderRadius - 1;
|
||||
border-radius: $borderRadius;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -474,6 +474,7 @@
|
||||
#localConnectionMessage {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
top:50%;
|
||||
z-index: 2;
|
||||
|
||||
@@ -67,5 +67,7 @@
|
||||
@import '404';
|
||||
@import 'policy';
|
||||
@import 'filmstrip';
|
||||
@import 'unsupported-browser/unsupported-desktop-browser';
|
||||
@import 'unsupported-browser/unsupported-mobile-browser';
|
||||
|
||||
/* Modules END */
|
||||
|
||||
@@ -85,9 +85,6 @@ $popupMenuSelectedItemBackground: rgba(256, 256, 256, .2);
|
||||
// Toolbar
|
||||
$splitterColor: #ccc;
|
||||
|
||||
// Thumbnail
|
||||
$thumbnailBorderColor: rgba(71, 71, 71, .7);
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
|
||||
132
css/unsupported-browser/_unsupported-desktop-browser.scss
Normal file
132
css/unsupported-browser/_unsupported-desktop-browser.scss
Normal file
@@ -0,0 +1,132 @@
|
||||
.supported-browser {
|
||||
color: #929391;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 1em 7px;
|
||||
vertical-align: middle;
|
||||
width: 138px;
|
||||
|
||||
&__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;
|
||||
}
|
||||
|
||||
&__link {
|
||||
color: #087dba;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&: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%;
|
||||
}
|
||||
}
|
||||
69
css/unsupported-browser/_unsupported-mobile-browser.scss
Normal file
69
css/unsupported-browser/_unsupported-mobile-browser.scss
Normal file
@@ -0,0 +1,69 @@
|
||||
.unsupported-mobile-browser {
|
||||
background-color: #fff;
|
||||
height: 100vh;
|
||||
padding: 35px 0;
|
||||
width: 100vw;
|
||||
|
||||
&__body {
|
||||
color: $unsupportedBrowserTextColor;
|
||||
margin: auto;
|
||||
max-width: 40em;
|
||||
text-align: center;
|
||||
width: 75%;
|
||||
|
||||
a:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-size: 1.8em;
|
||||
line-height: em(29px, 21px);
|
||||
margin-bottom: 0.65em;
|
||||
|
||||
&_small {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 1em;
|
||||
margin-top: em(21, 18);
|
||||
|
||||
strong {
|
||||
font-size: em(21, 18);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__logo {
|
||||
height: 108px;
|
||||
width: 77px;
|
||||
}
|
||||
|
||||
&__button {
|
||||
border: 0;
|
||||
height: 42px;
|
||||
margin: 0 auto;
|
||||
max-width: 300px;
|
||||
width: 98%;
|
||||
@include border-radius(8px);
|
||||
background-color: $unsupportedBrowserButtonBgColor;
|
||||
font-size: 1.5em;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.5px;
|
||||
text-shadow: 0px 1px 2px $unsupportedBrowserTextColor;
|
||||
|
||||
// Disable standard button effects.
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
|
||||
&:active {
|
||||
background-color: $unsupportedBrowserButtonBgColor;
|
||||
}
|
||||
|
||||
&_primary {
|
||||
background-color: $primaryUnsupportedBrowserButtonBgColor;
|
||||
|
||||
&:active {
|
||||
background-color: $primaryUnsupportedBrowserButtonBgColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
@import 'variables';
|
||||
|
||||
body {
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-color: white;
|
||||
color: #424242;
|
||||
font-family: $baseFontFamily;
|
||||
font-size: 28px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
#wrap{
|
||||
display: block;
|
||||
position: absolute;
|
||||
width:500px;
|
||||
height: 565px;
|
||||
overflow:hidden;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
top: 0; left: 0; bottom: 0; right: 0;
|
||||
}
|
||||
.firefox{
|
||||
font-size: 11pt;
|
||||
color: #c8c8c8;
|
||||
width: 468px;
|
||||
text-align: center;
|
||||
margin: 30px auto 0px auto;
|
||||
padding-left: 15px;
|
||||
}
|
||||
#text{
|
||||
display:inline-block;
|
||||
font-size: 28px;
|
||||
/* width: 568px; */
|
||||
vertical-align:middle;
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #087dba;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.browser {
|
||||
width: 138px;
|
||||
height: 163px;
|
||||
margin-top: 5px;
|
||||
background-color: #e8e8e8;
|
||||
border: 1px solid #cfcfcf;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.browser_wrapper
|
||||
{
|
||||
width: 138px;
|
||||
/* height: 188px; */
|
||||
vertical-align: middle;
|
||||
color: #929391;
|
||||
font-size: 20px;
|
||||
float: left;
|
||||
margin-left: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.browser_text
|
||||
{
|
||||
height: 2em;
|
||||
}
|
||||
.supported_browsers
|
||||
{
|
||||
margin: 0px auto 0px auto;
|
||||
/* width: 660px; */
|
||||
}
|
||||
|
||||
.clear
|
||||
{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.button
|
||||
{
|
||||
background-color: #62c82a;
|
||||
border: 1px solid #3c8117;
|
||||
border-radius: 10px;
|
||||
color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
width: 115px;
|
||||
height: 26px;
|
||||
padding-top: 13px;
|
||||
margin: 15px auto 0px auto;
|
||||
}
|
||||
|
||||
.logo
|
||||
{
|
||||
margin: 20px auto 0px auto;
|
||||
}
|
||||
|
||||
#chrome_logo
|
||||
{
|
||||
width: 78px;
|
||||
height: 78px;
|
||||
background-image: url('../images/chrome.png');
|
||||
}
|
||||
#chromium_logo
|
||||
{
|
||||
width: 77px;
|
||||
height: 78px;
|
||||
background-image: url('../images/chromium.png');
|
||||
}
|
||||
#firefox_logo
|
||||
{
|
||||
width: 86px;
|
||||
height: 80px;
|
||||
background-image: url('../images/firefox.png');
|
||||
}
|
||||
|
||||
#opera_logo
|
||||
{
|
||||
width: 73px;
|
||||
height: 78px;
|
||||
background-image: url('../images/opera.png');
|
||||
}
|
||||
|
||||
#safari_logo
|
||||
{
|
||||
width: 78px;
|
||||
height: 79px;
|
||||
background-image: url('../images/safari.png');
|
||||
}
|
||||
|
||||
#ie_logo
|
||||
{
|
||||
width: 80px;
|
||||
height: 78px;
|
||||
background-image: url('../images/ie.png');
|
||||
}
|
||||
|
||||
1
debian/jitsi-meet-web.install
vendored
1
debian/jitsi-meet-web.install
vendored
@@ -4,7 +4,6 @@
|
||||
*.ico /usr/share/jitsi-meet/
|
||||
libs /usr/share/jitsi-meet/
|
||||
css/all.css /usr/share/jitsi-meet/css/
|
||||
css/unsupported_browser.css /usr/share/jitsi-meet/css/
|
||||
sounds /usr/share/jitsi-meet/
|
||||
fonts /usr/share/jitsi-meet/
|
||||
images /usr/share/jitsi-meet/
|
||||
|
||||
211
doc/api.md
211
doc/api.md
@@ -1,17 +1,17 @@
|
||||
Jitsi Meet API
|
||||
============
|
||||
# Jitsi Meet API
|
||||
|
||||
You can use Jitsi Meet API to embed Jitsi Meet in to your application.
|
||||
You can use the Jitsi Meet API to embed Jitsi Meet in to your application.
|
||||
|
||||
Installation
|
||||
==========
|
||||
## Installation
|
||||
|
||||
To embed Jitsi Meet in your application you need to add the Jitsi Meet API library:
|
||||
|
||||
To embed Jitsi Meet in your application you need to add Jitsi Meet API library
|
||||
```javascript
|
||||
<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
|
||||
The next step for embedding Jitsi Meet is to create the Jitsi Meet API object:
|
||||
|
||||
```javascript
|
||||
<script>
|
||||
var domain = "meet.jit.si";
|
||||
@@ -21,169 +21,174 @@ The next step for embedding Jitsi Meet is to create the Jitsi Meet API object
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height);
|
||||
</script>
|
||||
```
|
||||
You can paste that lines in your html code where you want to be placed the Jitsi Meet conference
|
||||
or you can specify the parent HTML element for the Jitsi Meet conference in the JitsiMeetExternalAPI
|
||||
constructor.
|
||||
|
||||
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:
|
||||
|
||||
```javascript
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
|
||||
```
|
||||
If you don't specify room the user will enter in new conference with 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:
|
||||
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:
|
||||
|
||||
```javascript
|
||||
var configOverwrite = {enableSimulcast: false};
|
||||
var interfaceConfigOverwrite = {filmStripOnly: true};
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite);
|
||||
var configOverwrite = {disableSimulcast: true};
|
||||
var interfaceConfigOverwrite = {filmStripOnly: true};
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite);
|
||||
```
|
||||
|
||||
Controlling embedded Jitsi Meet Conference
|
||||
=========
|
||||
## Controlling the embedded Jitsi Meet Conference
|
||||
|
||||
You can control the embedded Jitsi Meet conference using the JitsiMeetExternalAPI object.
|
||||
You can control the embedded Jitsi Meet conference using the `JitsiMeetExternalAPI` object by using `executeCommand`:
|
||||
|
||||
You can send command to Jitsi Meet conference using ```executeCommand```.
|
||||
```
|
||||
```javascript
|
||||
api.executeCommand(command, ...arguments)
|
||||
```
|
||||
The ```command``` parameter is String object with the name of the command.
|
||||
Currently we support the following commands:
|
||||
|
||||
The `command` parameter is String object with the name of the command. The following commands are currently supported:
|
||||
|
||||
* **displayName** - sets the display name of the local participant. This command requires one argument -
|
||||
the new display name to be set
|
||||
```
|
||||
* **displayName** - Sets the display name of the local participant. This command requires one argument - the new display name to be set.
|
||||
```javascript
|
||||
api.executeCommand('displayName', 'New Nickname');
|
||||
```
|
||||
* **toggleAudio** - mutes / unmutes the audio for the local participant. No arguments are required.
|
||||
```
|
||||
|
||||
* **toggleAudio** - Mutes / unmutes the audio for the local participant. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleAudio')
|
||||
```
|
||||
* **toggleVideo** - mutes / unmutes the video for the local participant. No arguments are required.
|
||||
```
|
||||
|
||||
* **toggleVideo** - Mutes / unmutes the video for the local participant. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleVideo')
|
||||
```
|
||||
* **toggleFilmStrip** - hides / shows the film strip. No arguments are required.
|
||||
```
|
||||
api.executeCommand('filmStrip')
|
||||
```
|
||||
* **toggleChat** - hides / shows the chat. No arguments are required.
|
||||
|
||||
* **toggleFilmStrip** - Hides / shows the film strip. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleFilmStrip')
|
||||
```
|
||||
|
||||
* **toggleChat** - Hides / shows the chat. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleChat')
|
||||
```
|
||||
* **toggleContactList** - hides / shows the contact list. No arguments are required.
|
||||
```
|
||||
|
||||
* **toggleContactList** - Hides / shows the contact list. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleContactList')
|
||||
```
|
||||
|
||||
* **toggleShareScreen** - starts / stops the screen sharing. No arguments are required.
|
||||
```
|
||||
* **toggleShareScreen** - Starts / stops screen sharing. No arguments are required.
|
||||
```javascript
|
||||
api.executeCommand('toggleShareScreen')
|
||||
```
|
||||
|
||||
* **hangup** - Hangups the call. No arguments are required.
|
||||
```
|
||||
```javascript
|
||||
api.executeCommand('hangup')
|
||||
```
|
||||
|
||||
* **email** - Hangups the call. No arguments are required.
|
||||
```
|
||||
* **email** - Changes the local email address. This command requires one argument - the new email address to be set.
|
||||
```javascript
|
||||
api.executeCommand('email', 'example@example.com')
|
||||
```
|
||||
|
||||
* **avatarUrl** - Hangups the call. No arguments are required.
|
||||
```
|
||||
api.executeCommand('avatarUrl', 'avatarUrl')
|
||||
* **avatarUrl** - Changes the local avatar URL. This command requires one argument - the new avatar URL to be set.
|
||||
```javascript
|
||||
api.executeCommand('avatarUrl', 'https://avatars0.githubusercontent.com/u/3671647')
|
||||
```
|
||||
|
||||
You can also execute multiple commands using the method ```executeCommands```.
|
||||
```
|
||||
You can also execute multiple commands using the `executeCommands` method:
|
||||
```javascript
|
||||
api.executeCommands(commands)
|
||||
```
|
||||
The ```commands``` parameter is object with keys the names of the commands and values the arguments for the
|
||||
commands.
|
||||
|
||||
```
|
||||
The `commands` parameter is an object with the names of the commands as keys and the arguments for the commands asvalues:
|
||||
```javascript
|
||||
api.executeCommands({displayName: ['nickname'], toggleAudio: []});
|
||||
```
|
||||
|
||||
You can add event listeners to the embedded Jitsi Meet using ```addEventListener``` method.
|
||||
```
|
||||
You can add event listeners to the embedded Jitsi Meet using the `addEventListener` method.
|
||||
```javascript
|
||||
api.addEventListener(event, listener)
|
||||
```
|
||||
The ```event``` parameter is String object with the name of the event.
|
||||
The ```listener``` paramenter is Function object with one argument that will be notified when the event occurs
|
||||
with data related to the event.
|
||||
|
||||
Currently we support the following events:
|
||||
The `event` parameter is a String object with the name of the event.
|
||||
The `listener` parameter is a Function object with one argument that will be notified when the event occurs with data related to the event.
|
||||
|
||||
* **incomingMessage** - event notifications about incoming
|
||||
messages. The listener will receive object with the following structure:
|
||||
```
|
||||
The following events are currently supported:
|
||||
|
||||
* **incomingMessage** - Event notifications about incoming
|
||||
messages. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
"from": from,//JID of the user that sent the message
|
||||
"nick": nick,//the nickname of the user that sent the message
|
||||
"message": txt//the text of the message
|
||||
"from": from, // JID of the user that sent the message
|
||||
"nick": nick, // the nickname of the user that sent the message
|
||||
"message": txt // the text of the message
|
||||
}
|
||||
```
|
||||
* **outgoingMessage** - event notifications about outgoing
|
||||
messages. The listener will receive object with the following structure:
|
||||
```
|
||||
|
||||
* **outgoingMessage** - Event notifications about outgoing
|
||||
messages. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
"message": txt//the text of the message
|
||||
"message": txt // the text of the message
|
||||
}
|
||||
```
|
||||
|
||||
* **displayNameChanged** - event notifications about display name
|
||||
change. The listener will receive object with the following structure:
|
||||
```
|
||||
changes. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
jid: jid,//the JID of the participant that changed his display name
|
||||
displayname: displayName //the new display name
|
||||
"jid": jid, // the JID of the participant that changed his display name
|
||||
"displayname": displayName // the new display name
|
||||
}
|
||||
```
|
||||
* **participantJoined** - event notifications about new participant.
|
||||
The listener will receive object with the following structure:
|
||||
```
|
||||
|
||||
* **participantJoined** - event notifications about new participants who join the room. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
jid: jid //the jid of the participant
|
||||
"jid": jid // the JID of the participant
|
||||
}
|
||||
```
|
||||
* **participantLeft** - event notifications about participant that left room.
|
||||
The listener will receive object with the following structure:
|
||||
```
|
||||
|
||||
* **participantLeft** - event notifications about participants that leave the room. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
jid: jid //the jid of the participant
|
||||
"jid": jid // the JID of the participant
|
||||
}
|
||||
```
|
||||
* **videoConferenceJoined** - event notifications fired when the local user has joined the video conference.
|
||||
The listener will receive object with the following structure:
|
||||
```
|
||||
|
||||
* **videoConferenceJoined** - event notifications fired when the local user has joined the video conference. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
roomName: room //the room name of the conference
|
||||
"roomName": room // the room name of the conference
|
||||
}
|
||||
```
|
||||
* **videoConferenceLeft** - event notifications fired when the local user has left the video conference.
|
||||
The listener will receive object with the following structure:
|
||||
```
|
||||
|
||||
* **videoConferenceLeft** - event notifications fired when the local user has left the video conference. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
roomName: room //the room name of the conference
|
||||
"roomName": room // the room name of the conference
|
||||
}
|
||||
```
|
||||
|
||||
* **readyToClose** - event notification fired when Jitsi Meet is ready to be closed (hangup operations are completed).
|
||||
|
||||
You can also add multiple event listeners by using ```addEventListeners```.
|
||||
You can also add multiple event listeners by using `addEventListeners`.
|
||||
This method requires one argument of type Object. The object argument must
|
||||
have keys with the names of the events and values the listeners of the events.
|
||||
have the names of the events as keys and the listeners of the events as values.
|
||||
|
||||
```
|
||||
```javascript
|
||||
function incomingMessageListener(object)
|
||||
{
|
||||
...
|
||||
// ...
|
||||
}
|
||||
|
||||
function outgoingMessageListener(object)
|
||||
{
|
||||
...
|
||||
// ...
|
||||
}
|
||||
|
||||
api.addEventListeners({
|
||||
@@ -191,20 +196,28 @@ api.addEventListeners({
|
||||
outgoingMessage: outgoingMessageListener})
|
||||
```
|
||||
|
||||
If you want to remove a listener you can use ```removeEventListener``` method with argument the name of the event.
|
||||
```
|
||||
If you want to remove a listener you can use `removeEventListener` method with argument the name of the event.
|
||||
|
||||
```javascript
|
||||
api.removeEventListener("incomingMessage");
|
||||
```
|
||||
|
||||
If you want to remove more than one event you can use ```removeEventListeners``` method with argument
|
||||
array with the names of the events.
|
||||
```
|
||||
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.
|
||||
```javascript
|
||||
api.removeEventListeners(["incomingMessage", "outgoingMessageListener"]);
|
||||
```
|
||||
|
||||
You can remove the embedded Jitsi Meet Conference with the following code:
|
||||
You can get the number of participants in the conference with the following API function:
|
||||
```javascript
|
||||
var numberOfParticipants = api.getNumberOfParticipants();
|
||||
```
|
||||
|
||||
You can remove the embedded Jitsi Meet Conference with the following API function:
|
||||
```javascript
|
||||
api.dispose()
|
||||
```
|
||||
|
||||
It is a good practice to remove the conference before the page is unloaded.
|
||||
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
|
||||
|
||||
22
doc/examples/api.html
Normal file
22
doc/examples/api.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<html itemscope itemtype="http://schema.org/Product" prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/html">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script src="https://meet.jit.si/external_api.js"></script>
|
||||
<script>
|
||||
var domain = "meet.jit.si";
|
||||
var room = "JitsiMeetAPIExample";
|
||||
var width = 700;
|
||||
var height = 180;
|
||||
var htmlElement = undefined;
|
||||
var configOverwrite = {};
|
||||
var interfaceConfigOverwrite = {
|
||||
filmStripOnly: true
|
||||
};
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height,
|
||||
htmlElement, configOverwrite, interfaceConfigOverwrite);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -131,9 +131,9 @@ Or autostart it by adding the line in `/etc/rc.local`:
|
||||
|
||||
## Install Jitsi Conference Focus (jicofo)
|
||||
|
||||
Install JDK and Ant if missing:
|
||||
Install JDK and Maven if missing:
|
||||
```
|
||||
apt-get install default-jdk ant
|
||||
apt-get install default-jdk maven
|
||||
```
|
||||
|
||||
_NOTE: When installing on older Debian releases keep in mind that you need JDK >= 1.7._
|
||||
@@ -145,12 +145,14 @@ git clone https://github.com/jitsi/jicofo.git
|
||||
Build distribution package. Replace {os-name} with one of: 'lin', 'lin64', 'macosx', 'win', 'win64'.
|
||||
```sh
|
||||
cd jicofo
|
||||
ant dist.{os-name}
|
||||
mvn package -DskipTests -Dassembly.skipAssembly=false
|
||||
```
|
||||
Run jicofo:
|
||||
```sh
|
||||
cd dist/{os-name}'
|
||||
./jicofo.sh --host=127.0.0.1 --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
|
||||
=======
|
||||
unzip target/jicofo-{os-name}-1.0-SNAPSHOT.zip
|
||||
cd jicofo-{os-name}-1.0-SNAPSHOT'
|
||||
./jicofo.sh --host=localhost --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
|
||||
```
|
||||
|
||||
## Deploy Jitsi Meet
|
||||
@@ -159,6 +161,8 @@ Checkout and configure Jitsi Meet:
|
||||
cd /srv
|
||||
git clone https://github.com/jitsi/jitsi-meet.git
|
||||
mv jitsi-meet/ jitsi.example.com
|
||||
npm install
|
||||
make
|
||||
```
|
||||
|
||||
Edit host names in `/srv/jitsi.example.com/config.js` (see also the example config file):
|
||||
@@ -167,11 +171,11 @@ var config = {
|
||||
hosts: {
|
||||
domain: 'jitsi.example.com',
|
||||
muc: 'conference.jitsi.example.com',
|
||||
bridge: 'jitsi-videobridge.jitsi.example.com'
|
||||
bridge: 'jitsi-videobridge.jitsi.example.com',
|
||||
focus: 'focus.jitsi.example.com'
|
||||
},
|
||||
useNicks: false,
|
||||
bosh: '//jitsi.example.com/http-bind', // FIXME: use xep-0156 for that
|
||||
desktopSharing: 'false' // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
|
||||
//chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
|
||||
//minChromeExtVersion: '0.1' // Required version of Chrome extension
|
||||
};
|
||||
|
||||
94
doc/mobile.md
Normal file
94
doc/mobile.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# 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.
|
||||
|
||||
First make sure the [React Native dependencies]() are installed.
|
||||
|
||||
**NOTE**: This document assumes the app is being built on a macOS system.
|
||||
|
||||
**NOTE**: The app must be built for an actual device since the simulators don't
|
||||
work properly with the native plugins we require.
|
||||
|
||||
|
||||
## iOS
|
||||
|
||||
1. Install some extra dependencies
|
||||
|
||||
- Install ios-deploy globally (in case you want to use the React Native CLI
|
||||
to deploy the app to the device)
|
||||
|
||||
```bash
|
||||
npm install -g ios-deploy
|
||||
```
|
||||
|
||||
2. Build the app
|
||||
|
||||
There are 2 ways to build the app: using the CLI or using Xcode.
|
||||
|
||||
Using the CLI:
|
||||
|
||||
```bash
|
||||
react-native run-ios --device
|
||||
```
|
||||
|
||||
When the app is launched from the CLI the output can be checked with the
|
||||
following command:
|
||||
|
||||
```bash
|
||||
react-native log-ios
|
||||
```
|
||||
|
||||
Using Xcode
|
||||
|
||||
- Open **ios/jitsi-meet-react.xcworkspace** in Xcode. Make sure it's the
|
||||
workspace file!
|
||||
|
||||
- Select your device from the top bar and hit the "play" button.
|
||||
|
||||
When the app is launched from Xcode the Debug console will show the output
|
||||
logs the application creates.
|
||||
|
||||
|
||||
3. Other remarks
|
||||
|
||||
It's likely you'll need to change the bundle ID for deploying to a device
|
||||
because the default bundle ID points to the application signed by Atlassian.
|
||||
|
||||
This can be changed in the "General" tab. Under "Identity" set
|
||||
"Bundle Identifier" to a different value, and adjust the "Team" in the
|
||||
"Signing" section to match your own.
|
||||
|
||||
|
||||
## Android
|
||||
|
||||
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
|
||||
|
||||
The app can be built using the CLI utility as follows:
|
||||
|
||||
```bash
|
||||
react-native run-android
|
||||
```
|
||||
|
||||
It will be launched on the connected Android device.
|
||||
|
||||
|
||||
## Debugging
|
||||
|
||||
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
|
||||
is being interpreted by Chrome's V8 engine, instead of JSCore which
|
||||
React Native uses. It's important to keep this in mind due to potential
|
||||
differences in supported JavaScript features.
|
||||
|
||||
|
||||
[Android Studio]: https://developer.android.com/studio/index.html
|
||||
[debugging]: https://facebook.github.io/react-native/docs/debugging.html
|
||||
[React Native]: https://facebook.github.io/react-native/
|
||||
[React Native dependencies]: https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies
|
||||
6
flow-typed/npm/flow-bin_v0.x.x.js
vendored
Normal file
6
flow-typed/npm/flow-bin_v0.x.x.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583
|
||||
// flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x
|
||||
|
||||
declare module "flow-bin" {
|
||||
declare module.exports: string;
|
||||
}
|
||||
89
flow-typed/npm/react-redux_v5.x.x.js
vendored
Normal file
89
flow-typed/npm/react-redux_v5.x.x.js
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// flow-typed signature: 0ed284c5a2e97a9e3c0e87af3dedc09d
|
||||
// flow-typed version: bdf1e66252/react-redux_v5.x.x/flow_>=v0.30.x
|
||||
|
||||
import type { Dispatch, Store } from 'redux'
|
||||
|
||||
declare module 'react-redux' {
|
||||
|
||||
/*
|
||||
|
||||
S = State
|
||||
A = Action
|
||||
OP = OwnProps
|
||||
SP = StateProps
|
||||
DP = DispatchProps
|
||||
|
||||
*/
|
||||
|
||||
declare type MapStateToProps<S, OP: Object, SP: Object> = (state: S, ownProps: OP) => SP | MapStateToProps<S, OP, SP>;
|
||||
|
||||
declare type MapDispatchToProps<A, OP: Object, DP: Object> = ((dispatch: Dispatch<A>, ownProps: OP) => DP) | DP;
|
||||
|
||||
declare type MergeProps<SP, DP: Object, OP: Object, P: Object> = (stateProps: SP, dispatchProps: DP, ownProps: OP) => P;
|
||||
|
||||
declare type StatelessComponent<P> = (props: P) => ?React$Element<any>;
|
||||
|
||||
declare class ConnectedComponent<OP, P, Def, St> extends React$Component<void, OP, void> {
|
||||
static WrappedComponent: Class<React$Component<Def, P, St>>;
|
||||
getWrappedInstance(): React$Component<Def, P, St>;
|
||||
static defaultProps: void;
|
||||
props: OP;
|
||||
state: void;
|
||||
}
|
||||
|
||||
declare type ConnectedComponentClass<OP, P, Def, St> = Class<ConnectedComponent<OP, P, Def, St>>;
|
||||
|
||||
declare type Connector<OP, P> = {
|
||||
(component: StatelessComponent<P>): ConnectedComponentClass<OP, P, void, void>;
|
||||
<Def, St>(component: Class<React$Component<Def, P, St>>): ConnectedComponentClass<OP, P, Def, St>;
|
||||
};
|
||||
|
||||
declare class Provider<S, A> extends React$Component<void, { store: Store<S, A>, children?: any }, void> { }
|
||||
|
||||
declare type ConnectOptions = {
|
||||
pure?: boolean,
|
||||
withRef?: boolean
|
||||
};
|
||||
|
||||
declare type Null = null | void;
|
||||
|
||||
declare function connect<A, OP>(
|
||||
...rest: Array<void> // <= workaround for https://github.com/facebook/flow/issues/2360
|
||||
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
|
||||
|
||||
declare function connect<A, OP>(
|
||||
mapStateToProps: Null,
|
||||
mapDispatchToProps: Null,
|
||||
mergeProps: Null,
|
||||
options: ConnectOptions
|
||||
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
|
||||
|
||||
declare function connect<S, A, OP, SP>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: Null,
|
||||
mergeProps: Null,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>;
|
||||
|
||||
declare function connect<A, OP, DP>(
|
||||
mapStateToProps: Null,
|
||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
||||
mergeProps: Null,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, $Supertype<DP & OP>>;
|
||||
|
||||
declare function connect<S, A, OP, SP, DP>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
||||
mergeProps: Null,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, $Supertype<SP & DP & OP>>;
|
||||
|
||||
declare function connect<S, A, OP, SP, DP, P>(
|
||||
mapStateToProps: MapStateToProps<S, OP, SP>,
|
||||
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
|
||||
mergeProps: MergeProps<SP, DP, OP, P>,
|
||||
options?: ConnectOptions
|
||||
): Connector<OP, P>;
|
||||
|
||||
}
|
||||
56
flow-typed/npm/redux_v3.x.x.js
vendored
Normal file
56
flow-typed/npm/redux_v3.x.x.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// flow-typed signature: ba132c96664f1a05288f3eb2272a3c35
|
||||
// flow-typed version: c4bbd91cfc/redux_v3.x.x/flow_>=v0.33.x
|
||||
|
||||
declare module 'redux' {
|
||||
|
||||
/*
|
||||
|
||||
S = State
|
||||
A = Action
|
||||
|
||||
*/
|
||||
|
||||
declare type Dispatch<A: { type: $Subtype<string> }> = (action: A) => A;
|
||||
|
||||
declare type MiddlewareAPI<S, A> = {
|
||||
dispatch: Dispatch<A>;
|
||||
getState(): S;
|
||||
};
|
||||
|
||||
declare type Store<S, A> = {
|
||||
// rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages)
|
||||
dispatch: Dispatch<A>;
|
||||
getState(): S;
|
||||
subscribe(listener: () => void): () => void;
|
||||
replaceReducer(nextReducer: Reducer<S, A>): void
|
||||
};
|
||||
|
||||
declare type Reducer<S, A> = (state: S, action: A) => S;
|
||||
|
||||
declare type Middleware<S, A> =
|
||||
(api: MiddlewareAPI<S, A>) =>
|
||||
(next: Dispatch<A>) => Dispatch<A>;
|
||||
|
||||
declare type StoreCreator<S, A> = {
|
||||
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
|
||||
(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
|
||||
};
|
||||
|
||||
declare type StoreEnhancer<S, A> = (next: StoreCreator<S, A>) => StoreCreator<S, A>;
|
||||
|
||||
declare function createStore<S, A>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
|
||||
declare function createStore<S, A>(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
|
||||
|
||||
declare function applyMiddleware<S, A>(...middlewares: Array<Middleware<S, A>>): StoreEnhancer<S, A>;
|
||||
|
||||
declare type ActionCreator<A, B> = (...args: Array<B>) => A;
|
||||
declare type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any> };
|
||||
|
||||
declare function bindActionCreators<A, C: ActionCreator<A, any>>(actionCreator: C, dispatch: Dispatch<A>): C;
|
||||
declare function bindActionCreators<A, K, C: ActionCreators<K, A>>(actionCreators: C, dispatch: Dispatch<A>): C;
|
||||
|
||||
declare function combineReducers<O: Object, A>(reducers: O): Reducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||
|
||||
declare function compose<S, A>(...fns: Array<StoreEnhancer<S, A>>): Function;
|
||||
|
||||
}
|
||||
BIN
fonts/jitsi.eot
BIN
fonts/jitsi.eot
Binary file not shown.
@@ -14,6 +14,7 @@
|
||||
<glyph unicode="" glyph-name="connection-lost" horiz-adv-x="1414" d="M0 299.153h196.337v-187.951h-196.337v187.951zM271.842 480.372h196.337v-369.169h-196.337v369.169zM543.656 661.562h196.337v-550.36h-196.337v550.36zM815.47 842.766v-731.564h119.56c-14.589 33.025-23.125 71.503-23.232 111.943 0.132 86.42 38.697 163.851 99.656 216.468l0.348 403.153h-196.332zM1087.292 1024v-533.672c28.874 10.572 62.222 16.73 97.009 16.825 35.717-0.129 69.823-6.614 101.322-18.371l-1.999 535.218h-196.332zM1192.868 439.852c-0.009 0-0.020 0-0.031 0-122.247 0-221.351-98.447-221.372-219.896 0-0.007 0-0.014 0-0.021 0-121.467 99.111-219.935 221.372-219.935 0.011 0 0.021 0 0.032 0 122.248 0.014 221.345 98.477 221.345 219.935 0 0.007 0 0.013 0 0.020-0.021 121.441-99.11 219.883-221.345 219.897zM1194.706 372.607c87.601-0.006 158.614-69.787 158.614-155.866 0-0.006 0-0.012 0-0.019-0.022-86.062-71.026-155.822-158.614-155.828-87.588 0.006-158.593 69.766-158.615 155.826 0 0.007 0 0.014 0 0.020 0 86.079 71.013 155.86 158.613 155.866zM1286.795 355.682l48.348-52.528-236.375-217.567-48.348 52.528 236.375 217.567z" />
|
||||
<glyph unicode="" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
|
||||
<glyph unicode="" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />
|
||||
<glyph unicode="" glyph-name="kick" d="M512 810l284-426h-568zM214 298h596v-84h-596v84z" />
|
||||
<glyph unicode="" glyph-name="hangup" d="M512 640c-68 0-134-10-196-30v-132c0-16-10-34-24-40-42-20-80-46-114-78-8-8-18-12-30-12s-22 4-30 12l-106 106c-8 8-12 18-12 30s4 22 12 30c130 124 306 200 500 200s370-76 500-200c8-8 12-18 12-30s-4-22-12-30l-106-106c-8-8-18-12-30-12s-22 4-30 12c-34 32-72 58-114 78-14 6-24 20-24 38v132c-62 20-128 32-196 32z" />
|
||||
<glyph unicode="" glyph-name="chat" d="M854 342v512h-684v-598l86 86h598zM854 938c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
BIN
fonts/jitsi.ttf
BIN
fonts/jitsi.ttf
Binary file not shown.
BIN
fonts/jitsi.woff
BIN
fonts/jitsi.woff
Binary file not shown.
@@ -1,6 +1,35 @@
|
||||
{
|
||||
"IcoMoonType": "selection",
|
||||
"icons": [
|
||||
{
|
||||
"icon": {
|
||||
"paths": [
|
||||
"M756.704 395.862l267.296-202.213v635.075l-267.296-202.213v191.923c0 12.085-11.296 21.863-25.216 21.863h-706.272c-13.92 0-25.216-9.777-25.216-21.863v-612.25c0-12.085 11.296-21.863 25.216-21.863h706.272c13.92 0 25.216 9.777 25.216 21.863v189.679zM371.338 647.772c47.817 0 86.529-40.232 86.529-89.811v-184.835c0-49.651-38.713-89.883-86.529-89.883-47.788 0-86.515 40.232-86.515 89.883v184.835c0 49.579 38.756 89.811 86.515 89.811v0zM356.754 709.93v32.78h33.718v-33.412c73.858-9.606 131.235-73.73 131.235-151.351v-88.232h-30.636v88.232c0 67.57-53.696 122.534-119.734 122.534-66.024 0-119.691-54.964-119.691-122.534v-88.232h-30.636v88.232c0 79.215 59.674 144.502 135.744 151.969v0.014z"
|
||||
],
|
||||
"attrs": [
|
||||
{}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"grid": 0,
|
||||
"tags": [
|
||||
"Combined Shape"
|
||||
]
|
||||
},
|
||||
"attrs": [
|
||||
{}
|
||||
],
|
||||
"properties": {
|
||||
"order": 109,
|
||||
"id": 0,
|
||||
"name": "mic-camera-combined",
|
||||
"prevSize": 32,
|
||||
"code": 59651
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 0
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
"paths": [
|
||||
@@ -26,8 +55,8 @@
|
||||
"prevSize": 32,
|
||||
"code": 59677
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 0
|
||||
},
|
||||
{
|
||||
@@ -55,8 +84,8 @@
|
||||
"prevSize": 32,
|
||||
"code": 59676
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 1
|
||||
},
|
||||
{
|
||||
@@ -81,9 +110,9 @@
|
||||
"code": 59649,
|
||||
"name": "avatar"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 12
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 2
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -107,9 +136,9 @@
|
||||
"code": 59653,
|
||||
"name": "hangup"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 123
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 3
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -133,9 +162,9 @@
|
||||
"code": 59654,
|
||||
"name": "chat"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 149
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 4
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -159,9 +188,9 @@
|
||||
"code": 59650,
|
||||
"name": "download"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 165
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 5
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -185,9 +214,9 @@
|
||||
"code": 59655,
|
||||
"name": "edit"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 186
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 6
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -211,9 +240,9 @@
|
||||
"code": 59656,
|
||||
"name": "share-doc"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 207
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 7
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -237,9 +266,9 @@
|
||||
"code": 59657,
|
||||
"name": "telephone"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 216
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 8
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -263,9 +292,9 @@
|
||||
"code": 59652,
|
||||
"name": "kick"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 243
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 9
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -289,9 +318,9 @@
|
||||
"code": 59679,
|
||||
"name": "menu-up"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 257
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 10
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -315,9 +344,9 @@
|
||||
"code": 59680,
|
||||
"name": "menu-down"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 258
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 11
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -341,9 +370,9 @@
|
||||
"code": 59659,
|
||||
"name": "full-screen"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 351
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 12
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -367,9 +396,9 @@
|
||||
"code": 59660,
|
||||
"name": "exit-full-screen"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 352
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 13
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -393,9 +422,9 @@
|
||||
"code": 59658,
|
||||
"name": "star-full"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 364
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 14
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -419,9 +448,9 @@
|
||||
"code": 59661,
|
||||
"name": "security"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 474
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 15
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -445,9 +474,9 @@
|
||||
"code": 59662,
|
||||
"name": "security-locked"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 475
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 16
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -471,9 +500,9 @@
|
||||
"code": 59663,
|
||||
"name": "reload"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 483
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 17
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -497,9 +526,9 @@
|
||||
"code": 59664,
|
||||
"name": "microphone"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 493
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 18
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -523,9 +552,9 @@
|
||||
"code": 59665,
|
||||
"name": "mic-empty"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 494
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 19
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -549,9 +578,9 @@
|
||||
"code": 59666,
|
||||
"name": "mic-disabled"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 495
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 20
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -575,9 +604,9 @@
|
||||
"code": 59678,
|
||||
"name": "raised-hand"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 540
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 21
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -601,9 +630,9 @@
|
||||
"code": 59675,
|
||||
"name": "contactList"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 550
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 22
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -627,9 +656,9 @@
|
||||
"code": 59667,
|
||||
"name": "link"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 560
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 23
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -653,9 +682,9 @@
|
||||
"code": 59668,
|
||||
"name": "shared-video"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 591
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 24
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -679,9 +708,9 @@
|
||||
"code": 59669,
|
||||
"name": "settings"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 666
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 25
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -705,9 +734,9 @@
|
||||
"code": 59670,
|
||||
"name": "star"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 718
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 26
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -731,9 +760,9 @@
|
||||
"code": 59681,
|
||||
"name": "switch-camera"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 742
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 27
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -757,9 +786,9 @@
|
||||
"code": 59671,
|
||||
"name": "share-desktop"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 784
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 28
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -783,9 +812,9 @@
|
||||
"code": 59672,
|
||||
"name": "camera"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 799
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 29
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -809,9 +838,9 @@
|
||||
"code": 59673,
|
||||
"name": "camera-disabled"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 800
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 30
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -835,9 +864,9 @@
|
||||
"code": 59674,
|
||||
"name": "volume"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 822
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 31
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -885,7 +914,7 @@
|
||||
},
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 0
|
||||
"iconIdx": 32
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -956,7 +985,7 @@
|
||||
},
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 4
|
||||
"iconIdx": 33
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -983,7 +1012,7 @@
|
||||
},
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 12
|
||||
"iconIdx": 34
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -1011,7 +1040,7 @@
|
||||
},
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 13
|
||||
"iconIdx": 35
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
@@ -1039,7 +1068,7 @@
|
||||
},
|
||||
"setIdx": 1,
|
||||
"setId": 1,
|
||||
"iconIdx": 22
|
||||
"iconIdx": 36
|
||||
}
|
||||
],
|
||||
"height": 1024,
|
||||
|
||||
182
images/logo-blue.svg
Normal file
182
images/logo-blue.svg
Normal file
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 744.09448819 1052.3622047"
|
||||
id="svg3526"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:export-filename="/Users/ystamcheva/Dropbox/Designs/appLogo.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:docname="logo-blue.svg">
|
||||
<defs
|
||||
id="defs3528" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.49497475"
|
||||
inkscape:cx="817.30793"
|
||||
inkscape:cy="496.00851"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="851"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3531">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g4181">
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g33">
|
||||
<path
|
||||
d="m 257.311,591.057 c 27.544,0 85.707,-16.445 124.179,-27.332 5.595,-1.575 10.81,-3.049 15.549,-4.371 0.767,-0.211 1.51,-0.403 2.213,-0.579 -2.161,-2.139 -5.755,-5.387 -11.612,-10.295 -25.628,-17.369 -49.827,-25.456 -76.146,-25.456 -5.741,0 -11.707,0.352 -18.208,1.088 -22.283,2.535 -40.848,7.845 -49.767,10.39 -4.521,1.296 -5.883,1.683 -7.292,1.683 -2.688,0 -4.997,-1.599 -5.9,-4.069 -0.904,-2.483 -0.13,-5.223 1.969,-6.981 l 0.127,-0.102 c 15.379,-12.883 44.032,-36.866 98.39,-47.582 9.428,-1.853 19.514,-2.796 29.968,-2.796 24.334,0 49.53,5.026 74.869,14.925 34.511,13.474 58.094,30.771 77.062,44.67 10.211,7.489 19.03,13.959 26.705,17.516 1.961,0.912 2.979,1.169 3.453,1.236 0.349,-0.452 1.106,-1.7 2.219,-4.974 0.298,-0.867 2.453,-10.019 -13.007,-62.071 -8.985,-30.217 -19.822,-61.077 -25.465,-74.778 -10.916,-26.509 -8.237,-45.296 -4.877,-56.284 -9.248,3.399 -18.701,8.688 -28.646,15.993 l -0.62,0.458 c -4.969,3.684 -10.031,7.853 -15.482,12.725 -32.074,28.718 -56.104,43.69 -71.455,44.504 l -0.423,0.021 -0.421,-0.036 c -13.524,-1.148 -34.019,-20.834 -42.403,-30.801 -1.743,-1.169 -3.729,-1.699 -6.35,-1.699 -2.632,0 -5.583,0.553 -8.438,1.095 -2.077,0.394 -4.218,0.795 -6.341,1.01 -6.767,0.679 -16.252,2.867 -25.406,4.974 -4.413,1.014 -8.967,2.063 -13.13,2.922 -0.079,0.013 -1.866,0.382 -5.06,1.224 -22.624,6.693 -39.673,14.372 -48.012,21.628 -0.091,0.079 -0.36,0.288 -0.789,0.603 -5.64,4.009 -19.199,15.447 -23.29,34.907 l -0.043,0.162 c -8.541,35.837 4.408,80.28 21.615,105.666 8.093,11.932 16.814,19.376 23.944,20.42 1.775,0.252 3.905,0.386 6.321,0.386 z"
|
||||
id="path35"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g37">
|
||||
<path
|
||||
d="m 383.729,400.995 c 0.549,0.108 1.191,0.162 1.9,0.162 14.785,0 47.804,-21.408 53.912,-31.205 l 0.486,-0.78 0.694,-0.611 c 2.083,-2.056 8.099,-12.885 11.019,-19.367 -31.312,-9.394 -34.767,-26.347 -37.821,-41.41 -0.355,-1.749 -0.667,-3.324 -0.946,-4.732 -0.357,-1.842 -0.731,-3.713 -1.052,-5.159 -46.646,15.471 -60.905,24.154 -68.687,30.611 -4.027,3.345 -6.398,12.858 5.215,39.189 5.932,13.422 26.386,31.591 35.28,33.302 z"
|
||||
id="path39"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path43"
|
||||
d="m 183.03568,710.19014 c -5.799,-6.834 -8.258,-15.447 -7.293,-25.624 4.105,-49.397 -1.525,-61.33 -4.132,-64.162 -0.629,-0.685 -0.969,-0.685 -1.238,-0.685 -0.101,0 -0.195,0.006 -0.296,0.016 -4.84,1.157 -37.441,23.198 -44.638,89.005 -3.471,31.758 2.611,72.542 7.794,97.348 4.165,-14.646 10.742,-30.779 23.483,-47.384 11.862,-15.444 24.801,-27.623 40.852,-38.298 -4.99,-2.075 -10.346,-5.274 -14.532,-10.216 z" />
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g45">
|
||||
<path
|
||||
d="m 485.028,154.141 c -3.896,25.701 -10.239,50.115 -22.077,75.883 12.904,-14.609 20.445,-30.481 22.971,-48.296 1.051,-7.38 2.045,-14.439 -0.894,-27.587 z"
|
||||
id="path47"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g49">
|
||||
<path
|
||||
d="m 413.102,273.797 c 23.135,-20.915 37.22,-55.455 43.078,-75.971 -20.149,19.407 -44.636,29.82 -60.351,36.512 -5.412,2.308 -10.08,4.295 -12.878,5.926 -1.178,0.685 -2.367,1.374 -3.571,2.069 -9.533,5.515 -23.924,13.85 -26.022,18.987 l -0.06,0.167 -0.078,0.165 c -6.529,13.72 -10.208,34.352 -11.387,46.184 15.135,-9.242 30.738,-15.41 43.699,-20.529 12.03,-4.753 22.432,-8.863 27.57,-13.51 z"
|
||||
id="path51"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g53">
|
||||
<path
|
||||
d="m 436.439,291.877 c -0.141,0.357 -0.292,0.695 -0.455,1.017 -3.833,11.143 1.446,26.3 11.227,32.017 2.602,1.522 5.132,2.452 7.559,2.772 0.334,0.014 0.666,0.027 1.001,0.027 7.601,0 13.801,-5.56 18.4,-16.519 2.896,-8.34 3.308,-18.23 1.125,-27.158 -1.696,-6.936 -6.084,-15.215 -8.88,-19.343 -5.219,3.582 -15.533,11.462 -22.615,17.716 -4.946,4.777 -6.733,7.785 -7.362,9.471 z"
|
||||
id="path55"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g57">
|
||||
<path
|
||||
d="m 501.845,575.103 c 8.403,-2.29 15.076,-4.165 19.998,-5.623 -10.137,-7.061 -21.871,-15.846 -37.823,-28.253 -39.096,-30.404 -81.019,-45.826 -124.587,-45.826 -23.861,0 -44.647,4.592 -61.098,10.151 4.101,-0.255 8.271,-0.377 12.554,-0.377 5.088,0 10.42,0.179 15.842,0.541 16.949,1.136 60.616,8.845 100.106,55.931 7.956,9.469 16.507,17.307 40.828,17.307 8.679,0 18.796,-0.967 30.913,-2.959 0.749,-0.209 1.882,-0.518 3.267,-0.892 z"
|
||||
id="path59"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g61">
|
||||
<path
|
||||
d="m 557.268,369.949 c -7.755,-12.043 -17.498,-19.524 -25.41,-19.524 -1.464,0 -2.862,0.258 -4.154,0.765 -4.239,1.672 -10.952,21.042 -7.979,35.126 2.023,9.582 13.67,41.96 19.262,57.52 2.142,5.958 3.18,8.869 3.527,9.951 0.275,0.853 0.67,2.077 1.17,3.621 4.517,13.765 16.111,49.145 19.562,77.793 7.175,-30.554 11.239,-67.36 9.647,-111.409 -0.723,-20.199 -6.274,-39.323 -15.625,-53.843 z"
|
||||
id="path63"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g65">
|
||||
<path
|
||||
d="m 412.08,575.289 c -0.153,-0.2 -0.3,-0.397 -0.445,-0.585 -0.614,0.1 -1.616,0.319 -3.185,0.776 l -0.657,0.197 c -8.011,2.95 -22.707,7.908 -39.694,13.64 -20.387,6.87 -43.477,14.659 -62.808,21.595 -24.596,9.165 -32.572,12.781 -35.073,14.048 -0.454,1.218 -0.963,2.772 -1.53,4.486 -5.817,17.705 -19.139,58.23 -84.831,86.562 13.568,13.744 43.101,38.415 101.24,38.415 5.035,0 10.258,-0.188 15.494,-0.566 43.896,-3.121 85.158,-22.544 116.206,-54.673 28.233,-29.21 44.259,-65.641 44.507,-100.76 -6.871,-0.571 -18.519,-2.281 -29.301,-7.4 -0.125,-0.061 -12.447,-6.002 -19.923,-15.735 z"
|
||||
id="path67"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g69">
|
||||
<path
|
||||
d="m 162.104,639.109 c -0.122,10.334 -1.489,20.245 -2.82,29.907 -0.716,5.216 -1.464,10.615 -2.014,16.041 -0.746,10.914 1.612,14.717 2.659,15.829 0.571,0.629 1.513,1.346 3.536,1.346 1.558,0 3.418,-0.432 5.383,-1.251 19.507,-8.176 38.032,-22.367 46.937,-30.243 -13.668,-6.095 -34.689,-19.26 -53.681,-31.629 z"
|
||||
id="path71"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g73">
|
||||
<path
|
||||
d="m 484.26,598.224 c -0.552,7.258 -1.737,20.949 -3.631,31.378 -2.295,12.629 -6.095,23.31 -8.305,28.889 3.945,3.648 7.878,7.228 10.429,9.488 10.265,-6.718 43.961,-32.297 67.208,-90.368 -7.447,5.03 -17.906,9.456 -31.465,13.332 -13.797,3.929 -27.204,6.229 -34.236,7.281 z"
|
||||
id="path75"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#17a0db;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(43.272677,-6.8248629)"
|
||||
id="g85"
|
||||
style="fill:#17a0db;fill-opacity:1">
|
||||
<path
|
||||
style="fill:#17a0db;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path87"
|
||||
d="M 627.562,350.519 C 613.5,321.124 593.893,306.283 580.351,297.677 568.965,290.444 555.872,285.188 541.339,282 c -1.622,-10.158 -4.397,-20.542 -8.198,-30.646 24.507,-36.531 30.407,-77.605 17.008,-119.213 C 539.858,100.151 531.868,79.524 524.996,67.213 510.15,40.585 489.58,34.997 474.936,34.997 c -15.09,0 -29.538,6.412 -39.667,17.61 -10.37,11.462 -15.213,26.462 -13.634,42.228 1.349,13.446 -2.178,37.872 -4.519,46.594 -0.04,0.117 -4.202,11.776 -35.168,26.784 -0.746,0.268 -2.332,0.811 -4.773,1.629 -17.812,5.965 -50.913,17.062 -72.963,46.219 -16.847,20.407 -20.985,40.629 -25.766,64.036 -2.858,13.955 -5.846,32.187 -5.105,53.745 -55.35,12.291 -95.226,37.338 -118.609,74.54 -24.203,38.52 -28.402,86.272 -12.468,141.993 l 0.14,0.414 c 0.292,1.014 0.6,2.024 0.921,3.03 -2.718,-0.466 -5.465,-0.858 -8.285,-1.169 -2.469,-0.284 -5.015,-0.42 -7.54,-0.42 -27.636,0 -57.043,17.371 -78.666,46.474 -16.427,22.098 -36.156,61.131 -36.852,121.593 -0.523,44.905 4.279,86.306 14.283,123.054 7.461,27.381 15.784,44.202 18.979,50.09 l 67.793,127.079 31.06,-140.731 c 10.6,-47.935 21.066,-68.283 34.571,-81.732 31.425,18.938 68.541,28.901 107.941,28.901 43.919,0 89.715,-12.667 128.934,-35.662 25.477,-14.954 47.193,-33.324 64.629,-54.658 0.236,0 0.469,0 0.704,0 l 1.857,-0.038 c 10.782,-0.365 25.522,-5.697 40.434,-14.63 12.421,-7.433 31.147,-21.108 49.946,-44.064 18.945,-23.155 34.402,-51.324 45.926,-83.731 13.5,-37.939 21.717,-82.115 24.404,-131.272 3.253,-45.723 -2.078,-83.533 -15.881,-112.384 z m -31.124,109.427 c -2.415,44.805 -9.745,84.66 -21.764,118.441 -9.713,27.302 -22.502,50.739 -38.005,69.69 -26.696,32.611 -52.783,41.355 -55.551,41.465 l -0.22,0 c -2.528,0 -4.012,-1.032 -11.095,-5.988 -1.979,-1.379 -4.969,-3.467 -7.436,-5.075 -14.813,28.811 -39.145,53.701 -70.659,72.185 -32.098,18.824 -69.432,29.202 -105.1,29.202 -42.352,0 -79.532,-13.979 -107.842,-40.493 -38.621,24.556 -61.833,45.044 -80.652,130.273 l -3.562,16.157 -7.787,-14.59 C 84.8,867.621 78.058,854.32 71.708,830.982 62.852,798.444 58.598,761.384 59.071,720.842 c 0.944,-80.909 44.373,-121.518 68.427,-121.518 0.792,0 1.578,0.039 2.328,0.128 22.8,2.551 37.699,12.402 64.745,30.291 2.796,1.853 5.74,3.8 8.843,5.838 9.69,6.36 23.387,14.125 26.835,14.791 6.562,-0.381 12.986,-15.079 14.853,-28.713 0.114,-0.829 0.226,-1.598 0.334,-2.315 0.147,-1.612 0.227,-3.03 0.27,-4.194 -1.144,-0.399 -2.333,-0.869 -3.547,-1.403 l -0.27,-0.091 c -17.012,-5.857 -41.868,-34.625 -54.378,-76.385 -12.081,-42.21 -9.691,-77.122 7.099,-103.83 27.221,-43.328 86.307,-53.515 105.849,-56.861 6.109,-1.214 12.498,-2.351 18.999,-3.378 3.035,-0.762 5.11,-1.399 6.449,-1.978 0.58,-0.403 0.835,-0.833 0.439,-2.403 l 0.53,-0.148 -0.513,0.115 c -0.237,-1.065 -0.565,-2.311 -0.941,-3.753 -0.521,-1.997 -1.103,-4.256 -1.705,-6.936 -6.05,-27.141 -2.962,-49.884 0.863,-68.559 4.297,-21.019 6.678,-32.656 16.605,-44.279 13.152,-18.103 36.803,-26.025 50.953,-30.77 3.948,-1.322 7.359,-2.462 9.331,-3.412 43.344,-20.789 57.145,-42.646 61.091,-57.318 3.127,-11.642 8.084,-42.253 5.931,-63.63 -0.239,-2.425 0.326,-4.421 1.695,-5.935 1.215,-1.341 2.942,-2.104 4.748,-2.104 4.061,0 9.623,0 30.377,64.478 10.949,33.996 2.785,65.868 -24.244,94.74 -0.347,0.375 -0.7,0.742 -1.04,1.095 -0.738,0.76 -1.848,1.909 -1.999,2.326 0.006,0 -0.048,1.042 1.755,4.031 11.425,18.864 17.633,42.323 15.832,59.763 -0.429,4.062 -1.206,7.971 -1.879,11.411 -0.4,1.968 -0.879,4.377 -1.126,6.241 0.111,0 0.226,0 0.347,0 3.088,-0.327 7.867,-0.7 13.628,-0.7 13.556,0 32.969,2.077 48.503,11.951 9.382,5.952 21.255,15.137 29.981,33.404 10.281,21.472 14.096,51.453 11.369,89.114 z" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
style="fill:#ffffff"
|
||||
d=""
|
||||
id="path3618"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
@@ -2,6 +2,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!--#include virtual="base.html" -->
|
||||
<script>
|
||||
window.indexLoadedTime = window.performance.now();
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBundleURLProvider.h"
|
||||
#import "RCTLinkingManager.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
/**
|
||||
* A <tt>RCTFatalHandler</tt> implementation which swallows JavaScript errors.
|
||||
|
||||
134
ios/app/AudioMode.m
Normal file
134
ios/app/AudioMode.m
Normal file
@@ -0,0 +1,134 @@
|
||||
#import "RCTBridgeModule.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
@interface AudioMode : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@implementation AudioMode {
|
||||
NSString *_category;
|
||||
NSString *_mode;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
typedef enum {
|
||||
kAudioModeDefault,
|
||||
kAudioModeAudioCall,
|
||||
kAudioModeVideoCall
|
||||
} JitsiMeetAudioMode;
|
||||
|
||||
- (NSDictionary *)constantsToExport {
|
||||
return @{
|
||||
@"AUDIO_CALL" : [NSNumber numberWithInt: kAudioModeAudioCall],
|
||||
@"DEFAULT" : [NSNumber numberWithInt: kAudioModeDefault],
|
||||
@"VIDEO_CALL" : [NSNumber numberWithInt: kAudioModeVideoCall]
|
||||
};
|
||||
};
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_category = nil;
|
||||
_mode = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue {
|
||||
// Make sure all our methods run in the main thread. The route change
|
||||
// notification runs there so this will make sure it will only be fired
|
||||
// after our changes have been applied (when we cause them, that is).
|
||||
return dispatch_get_main_queue();
|
||||
}
|
||||
|
||||
- (void)routeChanged:(NSNotification*)notification {
|
||||
NSInteger reason
|
||||
= [[notification.userInfo
|
||||
valueForKey:AVAudioSessionRouteChangeReasonKey]
|
||||
integerValue];
|
||||
|
||||
switch (reason) {
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange:
|
||||
// The category has changed. Check if it's the one we want and adjust as
|
||||
// needed.
|
||||
[self setCategory:_category mode:_mode error:nil];
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)setCategory:(NSString *)category
|
||||
mode:(NSString *)mode
|
||||
error:(NSError * _Nullable *)outError {
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
|
||||
if (session.category != category
|
||||
&& ![session setCategory:category error:outError]) {
|
||||
RCTLogError(@"Failed to (re)apply specified AVAudioSession category!");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (session.mode != mode && ![session setMode:mode error:outError]) {
|
||||
RCTLogError(@"Failed to (re)apply specified AVAudioSession mode!");
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setMode:(int)mode
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject) {
|
||||
NSString *avCategory;
|
||||
NSString *avMode;
|
||||
NSError *error;
|
||||
|
||||
switch (mode) {
|
||||
case kAudioModeAudioCall:
|
||||
avCategory = AVAudioSessionCategoryPlayAndRecord;
|
||||
avMode = AVAudioSessionModeVoiceChat;
|
||||
break;
|
||||
case kAudioModeDefault:
|
||||
avCategory = AVAudioSessionCategorySoloAmbient;
|
||||
avMode = AVAudioSessionModeDefault;
|
||||
break;
|
||||
case kAudioModeVideoCall:
|
||||
avCategory = AVAudioSessionCategoryPlayAndRecord;
|
||||
avMode = AVAudioSessionModeVideoChat;
|
||||
break;
|
||||
default:
|
||||
reject(@"setMode", @"Invalid mode", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (![self setCategory:avCategory mode:avMode error:&error] || error) {
|
||||
reject(@"setMode", error.localizedDescription, error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Even though the specified category and mode were successfully set, the
|
||||
// AVAudioSession is a singleton and other parts of the application such as
|
||||
// WebRTC may undo the settings. Make sure that the settings are reapplied
|
||||
// upon undoes.
|
||||
if (!_category || !_mode) {
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(routeChanged:)
|
||||
name:AVAudioSessionRouteChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
// Save the desired/specified category and mode so that they may be
|
||||
// reapplied (upon undoes as described above).
|
||||
_category = avCategory;
|
||||
_mode = avMode;
|
||||
|
||||
resolve(nil);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -17,9 +17,22 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1</string>
|
||||
<string>1.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>org.jitsi.meet</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>org.jitsi.meet</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
@@ -43,11 +56,11 @@
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string></string>
|
||||
<string>Participate in conferences with video.</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string></string>
|
||||
<string>Participate in conferences with audio.</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>jitsi.ttf</string>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#import "RCTBridgeModule.h"
|
||||
|
||||
@interface POSIX : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
@@ -1,10 +1,13 @@
|
||||
#import "POSIX.h"
|
||||
#import "RCTBridgeModule.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@interface POSIX : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@implementation POSIX
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
<key>com.apple.developer.associated-domains</key>
|
||||
<array>
|
||||
<string>applinks:beta.meet.jit.si</string>
|
||||
<string>applinks:beta.hipchat.me</string>
|
||||
<string>applinks:chaos.hipchat.me</string>
|
||||
<string>applinks:enso.me</string>
|
||||
<string>applinks:hipchat.me</string>
|
||||
<string>applinks:meet.jit.si</string>
|
||||
</array>
|
||||
</dict>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
@@ -23,6 +24,7 @@
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
@@ -112,6 +114,62 @@
|
||||
remoteGlobalIDString = 5DBEB1501B18CEA900B34395;
|
||||
remoteInfo = RNVectorIcons;
|
||||
};
|
||||
3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3C059A1DE3340900C268FA;
|
||||
remoteInfo = yoga;
|
||||
};
|
||||
3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3C06751DE3340C00C268FA;
|
||||
remoteInfo = "yoga-tvOS";
|
||||
};
|
||||
3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;
|
||||
remoteInfo = cxxreact;
|
||||
};
|
||||
3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;
|
||||
remoteInfo = "cxxreact-tvOS";
|
||||
};
|
||||
3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4;
|
||||
remoteInfo = jschelpers;
|
||||
};
|
||||
3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4;
|
||||
remoteInfo = "jschelpers-tvOS";
|
||||
};
|
||||
5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTAnimation;
|
||||
};
|
||||
5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
|
||||
remoteInfo = "RCTAnimation-tvOS";
|
||||
};
|
||||
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
|
||||
@@ -205,6 +263,7 @@
|
||||
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>"; };
|
||||
0B42DFAD1E2FD90700111B12 /* AudioMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AudioMode.m; path = app/AudioMode.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>"; };
|
||||
@@ -219,11 +278,11 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
821D8ABD506944B4BDBB069B /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
B30EF2301DC0ED7C00690F45 /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
|
||||
B3A9D0231E0481E10009343D /* POSIX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = POSIX.h; path = app/POSIX.h; sourceTree = "<group>"; };
|
||||
B3A9D0241E0481E10009343D /* POSIX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = POSIX.m; path = app/POSIX.m; sourceTree = "<group>"; };
|
||||
B3B083EB1D4955FF0069CEE7 /* jitsi-meet-react.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "jitsi-meet-react.entitlements"; sourceTree = "<group>"; };
|
||||
B96AF9B6FBC0453798399985 /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = "<group>"; };
|
||||
@@ -258,6 +317,7 @@
|
||||
BF96438E1C34FBE100B0BBDF /* VideoToolbox.framework in Frameworks */,
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
|
||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
|
||||
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
|
||||
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
|
||||
@@ -348,12 +408,12 @@
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
0B42DFAD1E2FD90700111B12 /* AudioMode.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
B3A9D0231E0481E10009343D /* POSIX.h */,
|
||||
B3A9D0241E0481E10009343D /* POSIX.m */,
|
||||
);
|
||||
name = app;
|
||||
@@ -363,7 +423,13 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
146834041AC3E56700842450 /* libReact.a */,
|
||||
B3BA19EF1DC6B37B00BCD481 /* libReact-tvOS.a */,
|
||||
B3BA19EF1DC6B37B00BCD481 /* libReact.a */,
|
||||
3DAD3EA51DF850E9000B6D8A /* libyoga.a */,
|
||||
3DAD3EA71DF850E9000B6D8A /* libyoga.a */,
|
||||
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,
|
||||
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
|
||||
3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
|
||||
3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -376,6 +442,15 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5E91572E1DD0AC6500FF2AA8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6956B374CC3C453DB7B8E82D /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -397,10 +472,12 @@
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */,
|
||||
BF96438F1C34FBEB00B0BBDF /* libc.tbd */,
|
||||
BF9643911C34FBF100B0BBDF /* libsqlite3.tbd */,
|
||||
BF9643931C34FBF900B0BBDF /* libstdc++.tbd */,
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
|
||||
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
|
||||
@@ -412,7 +489,6 @@
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */,
|
||||
22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */,
|
||||
5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -500,7 +576,7 @@
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0800;
|
||||
LastUpgradeCheck = 0820;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
@@ -533,6 +609,10 @@
|
||||
ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */;
|
||||
ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
|
||||
@@ -656,6 +736,62 @@
|
||||
remoteRef = 26D58A061D0B42EE00FC396B /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libyoga.a;
|
||||
remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libyoga.a;
|
||||
remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libcxxreact.a;
|
||||
remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libcxxreact.a;
|
||||
remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libjschelpers.a;
|
||||
remoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libjschelpers.a;
|
||||
remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTAnimation.a;
|
||||
remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTAnimation-tvOS.a";
|
||||
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
@@ -712,10 +848,10 @@
|
||||
remoteRef = B3BA19EA1DC6B37B00BCD481 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
B3BA19EF1DC6B37B00BCD481 /* libReact-tvOS.a */ = {
|
||||
B3BA19EF1DC6B37B00BCD481 /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libReact-tvOS.a";
|
||||
path = libReact.a;
|
||||
remoteRef = B3BA19EE1DC6B37B00BCD481 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
@@ -778,6 +914,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B3A9D0251E0481E10009343D /* POSIX.m in Sources */,
|
||||
0B42DFAE1E2FD90700111B12 /* AudioMode.m in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
@@ -832,7 +969,6 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeet.ios;
|
||||
PRODUCT_NAME = "jitsi-meet-react";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -869,7 +1005,6 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeet.ios;
|
||||
PRODUCT_NAME = "jitsi-meet-react";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -886,15 +1021,19 @@
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
@@ -934,8 +1073,10 @@
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
@@ -943,6 +1084,7 @@
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0820"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
|
||||
BuildableName = "libReact.a"
|
||||
BlueprintName = "React"
|
||||
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
"en": "Английски",
|
||||
"bg": "Български",
|
||||
"de": "Немски",
|
||||
"es": "",
|
||||
"es": "Испански",
|
||||
"fr": "Френски",
|
||||
"hy": "",
|
||||
"hy": "Арменски",
|
||||
"it": "Италиански",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "Словашки",
|
||||
"sl": "Словенски",
|
||||
"sv": "Шведски",
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
"en": "Inglés",
|
||||
"bg": "Búlgaro",
|
||||
"de": "Alemán",
|
||||
"es": "",
|
||||
"es": "Español",
|
||||
"fr": "Francés",
|
||||
"hy": "",
|
||||
"hy": "Armenio",
|
||||
"it": "Italiano",
|
||||
"oc": "",
|
||||
"ptBR": "",
|
||||
"oc": "Occitano",
|
||||
"pl": "Polaco",
|
||||
"ptBR": "Portugués (Brasil)",
|
||||
"ru": "Ruso",
|
||||
"sk": "Eslovaco",
|
||||
"sl": "Esloveno",
|
||||
"sv": "Sueco",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "Arménien",
|
||||
"it": "Italien",
|
||||
"oc": "Occitan",
|
||||
"pl": "Polonais",
|
||||
"ptBR": "Portugais (Brésil)",
|
||||
"ru": "Russe",
|
||||
"sk": "Slovaque",
|
||||
"sl": "Slovène",
|
||||
"sv": "Suédois",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "",
|
||||
"it": "Italiano",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "Slovacco",
|
||||
"sl": "Sloveno",
|
||||
"sv": "",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "Ormiański",
|
||||
"it": "Włoski",
|
||||
"oc": "Prowansalski",
|
||||
"pl": "Polski",
|
||||
"ptBR": "portugalski (brazylijski)",
|
||||
"ru": "Rosyjski",
|
||||
"sk": "Słowacki",
|
||||
"sl": "Słoweński",
|
||||
"sv": "Szwedzki",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "",
|
||||
"it": "Taliančina",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "Slovenčina",
|
||||
"sl": "Slovinčina",
|
||||
"sv": "",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "",
|
||||
"it": "Italjanščina",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "",
|
||||
"sl": "Slovenščina",
|
||||
"sv": "",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "",
|
||||
"it": "Italienska",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "Slovakiska",
|
||||
"sl": "Slovenska",
|
||||
"sv": "",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"hy": "",
|
||||
"it": "",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sk": "",
|
||||
"sl": "",
|
||||
"sv": "",
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "СПИСЪК С КОНТАКТИ",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Настройки на връзката",
|
||||
"poweredby": "powered by",
|
||||
"downloadlogs": "Изтегли логовете",
|
||||
"feedback": "Кажете ни как върви",
|
||||
"roomUrlDefaultMsg": "Конференцията се създава...",
|
||||
"participant": "Участник",
|
||||
"inviteUrlDefaultMsg": "Конференцията се създава...",
|
||||
"me": "аз",
|
||||
"speaker": "Говорител",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "Яна Розова",
|
||||
"defaultLink": "например __url__",
|
||||
"calling": "Обаждане към __name__ ...",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
@@ -23,17 +25,18 @@
|
||||
"nwjsGrantPermissions": ""
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "Клавишни комбинации:",
|
||||
"raiseHand": "Вдигни ръка.",
|
||||
"pushToTalk": "Push to talk.",
|
||||
"toggleScreensharing": "Смяна между камера и споделен екран.",
|
||||
"toggleFilmstrip": "Показване/скриване на лентата с видеата.",
|
||||
"toggleShortcuts": "Показване/скриване на това меню.",
|
||||
"focusLocal": "Фокусиране върху нашето видео.",
|
||||
"focusRemote": "Фокусиране върху видео на участник.",
|
||||
"toggleChat": "Отваряне/скриване на чат панела.",
|
||||
"mute": "Спиране/пускане на микрофона.",
|
||||
"videoMute": "Спиране/пускане на нашето видео."
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "Влез",
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Научете повече за своите потребители като интегрирате лесно Piwik, Google Analytics и други статистики за изполването."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Включи / Изключи микрофона",
|
||||
"videomute": "Включи / Изключи камерата",
|
||||
"videomute": "",
|
||||
"authenticate": "Идентификация",
|
||||
"lock": "Заключи / отключи стаята",
|
||||
"invite": "Покани други",
|
||||
"chat": "Отвори / затвори чат",
|
||||
"etherpad": "Покажи споделения документ",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "Сподели YouTube видео",
|
||||
"sharescreen": "Сподели екрана",
|
||||
"fullscreen": "Влез / Излез от Пълен екран",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Обади се на SIP номер",
|
||||
"Settings": "Настройки",
|
||||
"hangup": "Затвори",
|
||||
"hangup": "",
|
||||
"login": "Влез",
|
||||
"logout": "Изход",
|
||||
"dialpad": "Цифров панел",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "Споделеното видео е заглуено,<br/>, за да можете да говорите.",
|
||||
"micMutedPopup": "Микрофонът е заглушен, за да<br/>не пречи на YouTube видеото.",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "Не се говори по време на филм!",
|
||||
"cameraDisabled": "Не е налична камера",
|
||||
"micDisabled": "Не е наличен микрофон"
|
||||
"micDisabled": "Не е наличен микрофон",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Отвори / затвори чат",
|
||||
"filmstrip": "Покажи / скрий лентата с видеа",
|
||||
"contactlist": "Отвори / затвори контакт листа"
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,23 +123,33 @@
|
||||
"messagebox": "Въведете текст..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "НАСТРОЙКИ",
|
||||
"title": "Настройки",
|
||||
"update": "Актуализиране",
|
||||
"name": "Име",
|
||||
"startAudioMuted": "Започни без аудио",
|
||||
"startVideoMuted": "Започни без видео",
|
||||
"selectCamera": "Избери камера",
|
||||
"selectMic": "Избери микрофон",
|
||||
"selectAudioOutput": "Избери аудио изход",
|
||||
"followMe": "Включи \"следвай ме\"",
|
||||
"startAudioMuted": "",
|
||||
"startVideoMuted": "",
|
||||
"selectCamera": "",
|
||||
"selectMic": "",
|
||||
"selectAudioOutput": "",
|
||||
"followMe": "",
|
||||
"noDevice": "Няма",
|
||||
"noPermission": "Не е разрешен достъп до устройството",
|
||||
"avatarUrl": "Адрес на аватар"
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Натиснете за да<br/>промените името",
|
||||
"moderator": "Създателя на<br/>конференцията",
|
||||
"videomute": "Учасника е спрял<br/>камерата си.",
|
||||
"videomute": "",
|
||||
"mute": "Учасника е с изключен микрофон",
|
||||
"kick": "Изгони",
|
||||
"muted": "Изключен микрофон",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": "Огледално"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Дебит:",
|
||||
"packetloss": "Загуба на пакети:",
|
||||
"resolution": "Резолюция:",
|
||||
@@ -165,34 +191,49 @@
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Бяхте изгонен от срещата!",
|
||||
"popupError": "Навигаторът ви блокира попъите. Молим ви да премахнете забраната и да опитате отново.",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Стаята е защитена с парола. Само собственикът може да я променя или премахва.",
|
||||
"passwordError2": "Стаята ви не е защитена с парола. Собственикът би могъл да добави парола.",
|
||||
"connectError": "Опа! Нещо се обърка и не успяхме да се свържем с конференцията.",
|
||||
"connectErrorWithMsg": "Опа! Нещо се обърка и не успяхме да се свържем с конференцията: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Свързване",
|
||||
"copy": "",
|
||||
"error": "Грешка",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Възникна грешка при опит да бъде намерено разширението за споделяне на екран.",
|
||||
"failtoinstall": "Неуспешна инсталация на разширението за споделяне на екрана.",
|
||||
"failedpermissions": "Неуспешен опит за получаване на права за използване на микрофон и/или камера.",
|
||||
"bridgeUnavailable": "Jitsi Videobridge не е наличен. Моля опитайте пак!",
|
||||
"jicofoUnavailable": "Jitsi Videobridge не е наличен. Моля опитайте пак!",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "Конференцията е пълна. Моля, опитайте по-късно!",
|
||||
"lockTitle": "Неуспешно заключване",
|
||||
"lockMessage": "Неуспешно заключване на конференцията.",
|
||||
"warning": "Внимание",
|
||||
"passwordNotSupported": "В момента не поддържаме стаи с пароли.",
|
||||
"sorry": "Съжаляваме",
|
||||
"internalError": "Вътрешна грешка [setRemoteDescription]",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "Неуспешен опит за смяна на видеото.",
|
||||
"SLDFailure": "Опа! Нещо се обърка и не успяхме да спрем микрофона! (SLD Failure)",
|
||||
"SRDFailure": "Опа! Нещо се обърка и не успяхме да спрем камерата! (SRD Failure)",
|
||||
"oops": "Опа!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Възникна грешка",
|
||||
"passwordRequired": "Изисква се парола",
|
||||
"Ok": "ОК",
|
||||
"done": "",
|
||||
"Remove": "DELETE DELETE DELETE DELETE DELETE DELETE DELETE DELETE DELETE DELETE ",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "Сподели видео",
|
||||
"shareVideoLinkError": "Моля въведете правилен Prezi линк.",
|
||||
"removeSharedVideoTitle": "Край на споделянето на видео",
|
||||
@@ -202,6 +243,7 @@
|
||||
"WaitForHostMsg": "<b>__room__ </b> още не е започнал. Ако вие сте домакина моля идентифицирайте се. В противен случай ще изчакаме домакина.",
|
||||
"IamHost": "Аз съм домакина",
|
||||
"Cancel": "Отказ",
|
||||
"Submit": "",
|
||||
"retry": "Повторен опит",
|
||||
"logoutTitle": "Изход",
|
||||
"logoutQuestion": "Сигурни ли сте, че искате да излезете и да прекъснете конференцията?",
|
||||
@@ -216,26 +258,29 @@
|
||||
"sipMsg": "Въведете SIP номер",
|
||||
"passwordCheck": "Сигурни ли сте, че искате да махнете паролата?",
|
||||
"passwordMsg": "Въведете парола, за да заключите стаята",
|
||||
"Invite": "Покани",
|
||||
"shareLink": "Сподели този линк с всеки, който искаш да поканиш",
|
||||
"shareLink": "",
|
||||
"settings1": "Конфигурирай конференцията",
|
||||
"settings2": "Участниците се присъединиха с изключен микрофон.",
|
||||
"settings3": "Изисквай имена<br/><br/>Въведете парола за да заключите стаята:",
|
||||
"yourPassword": "вашата парола",
|
||||
"yourPassword": "",
|
||||
"Back": "Назад",
|
||||
"serviceUnavailable": "Услугата не е налична",
|
||||
"gracefulShutdown": "Услугата временно не е достъпна поради профилактика. Моля опитайте по-късно.",
|
||||
"Yes": "Да",
|
||||
"reservationError": "Грешка в системата за резервации",
|
||||
"reservationErrorMsg": "Грешка номер: __code__, съобщение: __msg__",
|
||||
"password": "парола",
|
||||
"password": "",
|
||||
"userPassword": "потребителска парола",
|
||||
"token": "код за достъп",
|
||||
"tokenAuthFailed": "Неуспешна XMPP автентикация: невалиден тоукън",
|
||||
"displayNameRequired": "Въведете името си:",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "Въведете името си:",
|
||||
"extensionRequired": "Изисква се разширение: ",
|
||||
"firefoxExtensionPrompt": "За да споделите екрана си, трябва да инсталирате Firefox разширение. <a href='__url__'>свалете го тук</a> и пробвайте пак!",
|
||||
"feedbackQuestion": "Как мина разговора?",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "Благодарим, че използвахте __appName__!",
|
||||
"sorryFeedback": "Много съжаляваме! Бихте ли ни казали повече?",
|
||||
"liveStreaming": "Пряко предаване",
|
||||
@@ -246,6 +291,7 @@
|
||||
"stopLiveStreaming": "Край на прякото предаване",
|
||||
"stopRecording": "Край на записа",
|
||||
"doNotShowWarningAgain": "Занапред не ме предупреждавай пак",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "Достъпът е отказан",
|
||||
"screenSharingPermissionDeniedError": "Не сте дали права за споделяне на екран",
|
||||
"micErrorPresent": "Грешка при достъп до микрофона",
|
||||
@@ -253,12 +299,20 @@
|
||||
"cameraUnsupportedResolutionError": "Камерата ви не поддържа тази резолюция",
|
||||
"cameraUnknownError": "Невъзможен достъп до камерата по неясна причина.",
|
||||
"cameraPermissionDeniedError": "",
|
||||
"cameraNotFoundError": "Указаната камера не е намерена.",
|
||||
"cameraNotFoundError": "",
|
||||
"cameraConstraintFailedError": "Камерата ви не задоволява зададените условия.",
|
||||
"micUnknownError": "Не възможен достъп до микрофона по неясна причина.",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "Микрофонът не задоволява зададените условия.",
|
||||
"micConstraintFailedError": "Микрофонът не задоволява зададените условия."
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": "Микрофонът не задоволява зададените условия.",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Изключи микрофона"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
@@ -302,7 +356,7 @@
|
||||
"on": "Запис",
|
||||
"off": "Записът спрян",
|
||||
"failedToStart": "Неуспешен опит за записване",
|
||||
"buttonTooltip": "Пускане / спиране на запис",
|
||||
"buttonTooltip": "",
|
||||
"error": "Грешка при опит за запис. Моля опитайте отново.",
|
||||
"unavailable": "Записите са временно невъзможни. Моля опитайте по-късно."
|
||||
},
|
||||
@@ -312,7 +366,7 @@
|
||||
"off": "Край на прякото предаване",
|
||||
"unavailable": "Услугата за пряко предаване е временно недостъпна. Опитайте по-късно.",
|
||||
"failedToStart": "Неуспешен опит за пряко предаване",
|
||||
"buttonTooltip": "Начало / край на пряко предаване",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "Моля попълнете името на потока, за да можем да започнем прякото предаване.",
|
||||
"error": "Неуспешно пряко предаване. Опитайте пак.",
|
||||
"busy": "Всички записвачки са временно заети. Опитайте отново по-късно."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"contactlist": "Teilnehmer (__pcount__)",
|
||||
"addParticipants": "",
|
||||
"addParticipants": "Link teilen",
|
||||
"roomLocked": "Teilnehmer müssen ein Passwort eingeben",
|
||||
"roomUnlocked": "Jeder mit Zugriff auf den Link kann beitreten",
|
||||
"passwordSetRemotely": "von einem anderen Teilnehmer gesetzt",
|
||||
|
||||
@@ -1,59 +1,62 @@
|
||||
{
|
||||
"contactlist": "LISTA DE CONTACTOS",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Ajustes de la conexión",
|
||||
"poweredby": "impulsado por",
|
||||
"downloadlogs": "Descargar logs",
|
||||
"poweredby": "potenciado por",
|
||||
"feedback": "Danos tu opinión",
|
||||
"roomUrlDefaultMsg": "Tu conferencia está siendo creada...",
|
||||
"participant": "Participante",
|
||||
"inviteUrlDefaultMsg": "Tu conferencia está siendo creada...",
|
||||
"me": "yo",
|
||||
"speaker": "Orador",
|
||||
"raisedHand": "",
|
||||
"raisedHand": "Desea hablar",
|
||||
"defaultNickname": "ej. Juana Rosas",
|
||||
"defaultLink": "ej. __url__",
|
||||
"calling": "Llamando __nombre__ ...",
|
||||
"callingName": "__name__",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
"androidGrantPermissions": "",
|
||||
"firefoxGrantPermissions": "",
|
||||
"operaGrantPermissions": "",
|
||||
"iexplorerGrantPermissions": "",
|
||||
"safariGrantPermissions": "",
|
||||
"nwjsGrantPermissions": ""
|
||||
"react-nativeGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i> Permitir </i></b>",
|
||||
"chromeGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i> Permitir </i></b>",
|
||||
"androidGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i> Permitir </i></b>",
|
||||
"firefoxGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i>Compartir Dispositivo seleccionado</i></b>",
|
||||
"operaGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i> Permitir </i></b>",
|
||||
"iexplorerGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i>OK</i></b>",
|
||||
"safariGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono presionando el botón <b><i>OK</i></b>",
|
||||
"nwjsGrantPermissions": "Por favor, conceda permisos para utilizar su cámara y micrófono"
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "Atajos de teclado:",
|
||||
"raiseHand": "Levantar la mano.",
|
||||
"pushToTalk": "Presione para hablar.",
|
||||
"toggleScreensharing": "Cambiar entre cámara y compartir pantalla.",
|
||||
"toggleFilmstrip": "Mostrar u ocultar película.",
|
||||
"toggleShortcuts": "Muestra u oculta este menú de ayuda.",
|
||||
"focusLocal": "Enfocar el video local.",
|
||||
"focusRemote": "Enfocarse en uno de los videos remotos.",
|
||||
"toggleChat": "Abrir o cerrar panel de charlas.",
|
||||
"mute": "Activar o desactivar micrófono.",
|
||||
"videoMute": "Detener o iniciar el video local."
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "IR",
|
||||
"roomname": "Introduzca un nombre de sala:",
|
||||
"roomname": "Introduzca un nombre de sala",
|
||||
"disable": "No mostrar esta página otra vez",
|
||||
"feature1": {
|
||||
"title": "Sencillo de usar",
|
||||
"content": "No se requiere descargar nada. __app__ funciona directamente con tu navegador. Solo comparte el URL de tu conferencia con otros para comenzar."
|
||||
"content": "No se requiere descargar nada. __app__ funciona directamente con su navegador. Solo comparta el URL de su conferencia con otros para comenzar."
|
||||
},
|
||||
"feature2": {
|
||||
"title": "Bajo Ancho de Banda",
|
||||
"content": "Las Videoconferencias con múltiples participantes funcionan con tan solo 128 Kbps. Conferencias para compartir pantalla y audio son posibles con mucho menos."
|
||||
"title": "Bajo consumo de Ancho de Banda",
|
||||
"content": "Las Videoconferencias con múltiples participantes funcionan con tan solo 128 Kbps. Conferencias para compartir pantalla y solo audio son posibles con mucho menos."
|
||||
},
|
||||
"feature3": {
|
||||
"title": "Código abierto",
|
||||
"content": "__app__ está licenciado bajo la licencia Apache. Eres libre de descargar, usar, modificar, y compartirlo conforme a esta licencia libre."
|
||||
"content": "__app__ está licenciado bajo la Licencia Apache. Eres libre de descargar, usar, modificar, y compartirlo de acuerdo a esta licencia."
|
||||
},
|
||||
"feature4": {
|
||||
"title": "Usuarios ilimitados",
|
||||
"content": "No hay restricciones artificiales en el número de usuarios o participantes de la conferencia. La capacidad del servidor y ancho de banda son los únicos factores limitantes."
|
||||
"content": "No hay restricciones artificiales en el número de usuarios o participantes de la conferencia. La capacidad del servidor y del ancho de banda son los únicos factores limitantes."
|
||||
},
|
||||
"feature5": {
|
||||
"title": "Compartir pantalla",
|
||||
@@ -72,59 +75,81 @@
|
||||
"content": "Aprenda de sus usuarios a través de una fácil integración con Piwik, Google Analytics, y otros sistemas de seguimiento y análisis de uso."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Activar / Desactivar Silencio",
|
||||
"videomute": "Iniciar / detener cámara",
|
||||
"videomute": "",
|
||||
"authenticate": "Autenticar",
|
||||
"lock": "Bloquear / desbloquear sala",
|
||||
"invite": "Invitar a otros",
|
||||
"chat": "Abrir / cerrar chat",
|
||||
"etherpad": "Compartir documento",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "Compartir un vídeo de YouTube",
|
||||
"sharescreen": "Compartir pantalla",
|
||||
"fullscreen": "Entrar / Salir de Pantalla completa",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Llamar a un número SIP",
|
||||
"Settings": "Ajustes",
|
||||
"hangup": "Colgar",
|
||||
"hangup": "",
|
||||
"login": "Inicio de sesión",
|
||||
"logout": "Cerrar sesión",
|
||||
"dialpad": "Mostrar teclado de llamada",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "Su vídeo compartido ha sido silenciado<br/>para que pueda hablar con otros participantes.",
|
||||
"micMutedPopup": "Su micrófono ha sido silenciado para que<br/>pueda disfrutar completamente de compartir su vídeo.",
|
||||
"micMutedPopup": "Su micrófono ha sido silenciado para que<br/>pueda disfrutar completamente de su vídeo compartido.",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "No puede silenciar su micrófono mientras el vídeo compartido está activo.",
|
||||
"cameraDisabled": "Cámara no disponible",
|
||||
"micDisabled": "Micrófono no disponible"
|
||||
"micDisabled": "Micrófono no disponible",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Abrir / cerrar chat",
|
||||
"filmstrip": "Mostrar / ocultar film",
|
||||
"contactlist": "Abrir / cerrar lista de contactos"
|
||||
"chat": "Abrir / cerrar sala de charlas",
|
||||
"filmstrip": "Mostrar / ocultar videos",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
"title": "Indique un nombre en la caja inferior",
|
||||
"popover": "Seleccione un nombre"
|
||||
"title": "Introduzca un apodo en la caja inferior",
|
||||
"popover": "Seleccione un apodo"
|
||||
},
|
||||
"messagebox": "Introduzca texto..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "CONFIGURAR",
|
||||
"title": "Ajustes",
|
||||
"update": "Actualizar",
|
||||
"name": "Nombre",
|
||||
"startAudioMuted": "Iniciar sin audio",
|
||||
"startVideoMuted": "Iniciar sin vídeo",
|
||||
"selectCamera": "Seleccionar cámara",
|
||||
"selectMic": "Seleccionar micrófono",
|
||||
"selectAudioOutput": "Selecciona salida de audio",
|
||||
"followMe": "Habilitar sígueme",
|
||||
"startAudioMuted": "Todos inician en silencio",
|
||||
"startVideoMuted": "Todos inician ocultos",
|
||||
"selectCamera": "Cámara",
|
||||
"selectMic": "Micrófono",
|
||||
"selectAudioOutput": "Salida de audio",
|
||||
"followMe": "Todos me siguen",
|
||||
"noDevice": "Ninguno",
|
||||
"noPermission": "Permiso para usar el dispositivo no permitido",
|
||||
"avatarUrl": "URL del Avatar"
|
||||
"cameraAndMic": "Cámara y micrófono",
|
||||
"moderator": "MODERADOR",
|
||||
"password": "ESTABLECER CONTRASEÑA",
|
||||
"audioVideo": "AUDIO Y VIDEO",
|
||||
"setPasswordLabel": "Bloquear su cuarto con contraseña"
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "Establecer nombre a mostrar",
|
||||
"setEmailLabel": "Establecer su gravatar",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Click para editar tu <br/>nombre",
|
||||
"editnickname": "Presione para editar tu <br/>nombre",
|
||||
"moderator": "El propietario de<br/>esta conferencia",
|
||||
"videomute": "Participante ha<br/>detenido la cámara.",
|
||||
"videomute": "Participante a<br/>detenido la cámara",
|
||||
"mute": "Participante está silenciado",
|
||||
"kick": "Expulsar",
|
||||
"muted": "Silenciado",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": "Voltear"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Tasa de bits:",
|
||||
"packetloss": "Pérdida de paquetes:",
|
||||
"resolution": "Resolución:",
|
||||
@@ -148,63 +174,79 @@
|
||||
"remoteaddress_plural": "Direcciones remotas:",
|
||||
"transport": "Transporte:",
|
||||
"bandwidth": "Ancho de banda estimado:",
|
||||
"na": "Volver aquí para ver información de la conexión, una vez que se inicia la conferencia"
|
||||
"na": "Una vez que se inicia la conferencia, volver aquí para ver información de la conexión"
|
||||
},
|
||||
"notify": {
|
||||
"disconnected": "desconectado",
|
||||
"moderator": "¡Otorgados derechos de moderador! ",
|
||||
"moderator": "¡Se otorgaron privilegios de moderador!",
|
||||
"connected": "conectado",
|
||||
"somebody": "Alguien",
|
||||
"me": "Yo",
|
||||
"focus": "Foco de conferencia",
|
||||
"focus": "Enfocar conferencia",
|
||||
"focusFail": "__component__ no disponible - reintentar en __ms__ seg",
|
||||
"grantedTo": "¡Derechos de moderador otorgados a __to__!",
|
||||
"grantedToUnknown": "¡Derechos de moderador otorgados a $t(somebody)!",
|
||||
"grantedTo": "¡Se otorgaron privilegios de moderador a __to__!",
|
||||
"grantedToUnknown": "¡Se otorgaron privilegios de moderador a $t(somebody)!",
|
||||
"muted": "Has iniciado la conversación silenciado.",
|
||||
"mutedTitle": "¡Estás silenciado!",
|
||||
"raisedHand": ""
|
||||
"raisedHand": "Desearía hablar."
|
||||
},
|
||||
"dialog": {
|
||||
"kickMessage": "¡Auch! ¡Haz sido expulsado de la reunión!",
|
||||
"add": "",
|
||||
"kickMessage": "¡Ouch! ¡Has sido expulsado de la reunión!",
|
||||
"popupError": "Su navegador está bloqueando las ventanas emergentes de este sitio. Por favor, activa las ventanas emergentes en la configuración de seguridad del navegador y vuelva a intentarlo.",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Esta conversación está protegida con una contraseña. Sólo el propietario de la conferencia puede establecer una contraseña.",
|
||||
"passwordError2": "Esta conversación no está protegida con una contraseña. Sólo el propietario de la conferencia puede establecer una contraseña.",
|
||||
"connectError": "¡Uups! Algo salió mal y no pudimos conectarnos a la conferencia.",
|
||||
"connectErrorWithMsg": "¡Uups! Algo salió mal y no pudimos conectarnos a la conferencia: __msg__",
|
||||
"connectError": "¡Oops! Algo salio mal y no fue posible conectarnos a la conferencia.",
|
||||
"connectErrorWithMsg": "¡Oops! Algo salio mal y no fue posible conectarnos a la conferencia: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Conectando",
|
||||
"copy": "Copiar",
|
||||
"error": "Error",
|
||||
"detectext": "Error al tratar de detectar la extensión de compartir escritorio.",
|
||||
"failtoinstall": "Fallo al instalar la extensión de compartir escritorio",
|
||||
"failedpermissions": "Fallo al obtener permisos para utilizar el micrófono y/o cámara de tu equipo.",
|
||||
"bridgeUnavailable": "Videobridge Jitsi no está actualmente disponible. ¡Por favor inténtelo más tarde!",
|
||||
"jicofoUnavailable": "Jicofo no está disponible actualmente. ¡Por favor inténtelo más tarde!",
|
||||
"maxUsersLimitReached": "El número máximo de participantes en la conferencia ha sido alcanzado. La conferencia está llena. ¡Por favor intente nuevamente más tarde!",
|
||||
"lockTitle": "El número máximo de participantes en la conferencia ha sido alcanzado. La conferencia está llena. ¡Por favor intente nuevamente más tarde!",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Error al tratar de detectar la extensión para compartir escritorio.",
|
||||
"failtoinstall": "Falla al instalar la extensión para compartir escritorio",
|
||||
"failedpermissions": "Falla al obtener permisos para utilizar el micrófono y/o cámara de su equipo.",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "La conferencia está llena. El número máximo de participantes de la conferencia se ha alcanzado. ¡Por favor intente más tarde!",
|
||||
"lockTitle": "El bloqueo falló",
|
||||
"lockMessage": "No se pudo bloquear la conferencia.",
|
||||
"warning": "Advertencia",
|
||||
"passwordNotSupported": "No se soportan contraseñas para la sala. ",
|
||||
"sorry": "¡Perdón!",
|
||||
"internalError": "Error interno de la aplicación [setRemoteDescription]",
|
||||
"unableToSwitch": "No se puede activar transmisión de video",
|
||||
"SLDFailure": "¡Ups! Algo salió mal y no se logró silenciar! (Falla de SLD)",
|
||||
"SRDFailure": "¡Ups! ¡Algo salió mal y no se logró detener el video! (Falla SRD)",
|
||||
"oops": "¡Ups!",
|
||||
"warning": "Aviso",
|
||||
"passwordNotSupported": "No se soportan contraseñas para la sala.",
|
||||
"internalErrorTitle": "Error interno",
|
||||
"internalError": "¡Uups! Ocurrió algo incorrecto. Ocurrió el siguiente error: [setRemoteDescription]",
|
||||
"unableToSwitch": "No se puede cambiar secuencia de video.",
|
||||
"SLDFailure": "¡Oops! Algo salio mal y no se logró silenciar! (Falla de SLD)",
|
||||
"SRDFailure": "¡Oops! ¡Algo salio mal y no se logró detener el video! (Falla de SRD)",
|
||||
"oops": "¡Oops!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Hubo algún tipo de error",
|
||||
"passwordRequired": "Se necesita contraseña",
|
||||
"passwordRequired": "Se requiere una contraseña",
|
||||
"Ok": "Aceptar",
|
||||
"done": "",
|
||||
"Remove": "Eliminar",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "Compartir un vídeo",
|
||||
"shareVideoLinkError": "Por favor introduzca un enlace correcto de Youtube.",
|
||||
"removeSharedVideoTitle": "Eliminar video compartido",
|
||||
"removeSharedVideoMsg": "¿Estas seguro que deseas eliminar tu vídeo compartido?",
|
||||
"alreadySharedVideoMsg": "Otro participante esta ahora mismo compartiendo el vídeo. Esta conferencia permite sólo compartir un único vídeo a la vez.",
|
||||
"WaitingForHost": "Esperando al anfitrión...",
|
||||
"removeSharedVideoMsg": "¿Está seguro que desea eliminar su vídeo compartido?",
|
||||
"alreadySharedVideoMsg": "Otro participante está compartiendo el vídeo en este momento. Esta conferencia permite sólo compartir un vídeo a la vez.",
|
||||
"WaitingForHost": "Esperando al anfitrión ...",
|
||||
"WaitForHostMsg": "La conferencia <b>__room__ </b> aún no inicia. Si usted es el anfitrión, por favor autentíquese. De lo contrario, por favor espere a que el anfitrión llegue.",
|
||||
"IamHost": "Yo soy el anfitrión",
|
||||
"Cancel": "Cancelar",
|
||||
"Submit": "",
|
||||
"retry": "Reintentar",
|
||||
"logoutTitle": "Cerrar sesión",
|
||||
"logoutQuestion": "¿Está seguro que quiere salir y detener la conferencia?",
|
||||
"logoutQuestion": "¿Está seguro que desea salir y detener la conferencia?",
|
||||
"sessTerminated": "Sesión finalizada",
|
||||
"hungUp": "Colgaste",
|
||||
"joinAgain": "Unirse de nuevo",
|
||||
@@ -214,30 +256,33 @@
|
||||
"recordingToken": "Introduzca el token de grabación",
|
||||
"Dial": "Marcar",
|
||||
"sipMsg": "Introduzca número SIP",
|
||||
"passwordCheck": "¿Realmente quieres eliminar tu contraseña?",
|
||||
"passwordMsg": "Indica una contraseña para bloquear tu sala",
|
||||
"Invite": "Invitar",
|
||||
"shareLink": "Comparte este enlace con las personas que deseas invitar",
|
||||
"passwordCheck": "¿Realmente desea eliminar su contraseña?",
|
||||
"passwordMsg": "Indique una contraseña para bloquear su sala",
|
||||
"shareLink": "",
|
||||
"settings1": "Configure su conferencia",
|
||||
"settings2": "Los participantes se unieron silenciados",
|
||||
"settings3": "Solicita nombres <br/> <br/>Establecer una contraseña para bloquear la sala:",
|
||||
"yourPassword": "tu contraseña",
|
||||
"Back": "Atrás",
|
||||
"settings3": "Solicitar apodos<br/><br/>Establecer una contraseña para bloquear la sala:",
|
||||
"yourPassword": "Introducir la nueva contraseña",
|
||||
"Back": "Anterior",
|
||||
"serviceUnavailable": "Servicio no disponible",
|
||||
"gracefulShutdown": "Nuestro servicio está detenido por mantenimiento. Por favor, inténtelo de nuevo más tarde.",
|
||||
"gracefulShutdown": "Nuestro servicio se encuentra en mantenimiento. Por favor, intente más tarde.",
|
||||
"Yes": "Sí",
|
||||
"reservationError": "Error de sistema de reservación",
|
||||
"reservationError": "Error del sistema de reservación",
|
||||
"reservationErrorMsg": "Código de error: __code__, message: __msg__",
|
||||
"password": "contraseña",
|
||||
"userPassword": "contraseña de usuario",
|
||||
"password": "Introducir contraseña",
|
||||
"userPassword": "contraseña del usuario",
|
||||
"token": "token",
|
||||
"tokenAuthFailed": "Error al autenticar con el servidor XMPP: token inválido",
|
||||
"displayNameRequired": "Por favor escriba su nombre",
|
||||
"extensionRequired": "Extensión requerida",
|
||||
"firefoxExtensionPrompt": "Es necesario instalar una extensión para Firefox con el fin de utilizar la pantalla compartida. Por favor, inténtelo de nuevo después de que lo obtenga de aquí <a href='__url__'> </a>!",
|
||||
"feedbackQuestion": "¿Como fue su llamada?",
|
||||
"thankYou": "Gracias por usar __appName__!",
|
||||
"sorryFeedback": " Sentimos escuchar eso. ¿Quieres decirnos algo más?",
|
||||
"tokenAuthFailedTitle": "Problema de autenticación",
|
||||
"tokenAuthFailed": "Lo siento, usted no tiene permiso para unirse a este llamada.",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "Por favor escriba su nombre",
|
||||
"extensionRequired": "Extensión requerida:",
|
||||
"firefoxExtensionPrompt": "Necesita instalar una extensión para Firefox para poder utilizar la pantalla compartida. Por favor intente de nuevo, después de <a href='__url__'>obtenerla de aquí</a>!",
|
||||
"rateExperience": "Por favor, califique la experiencia de su reunión.",
|
||||
"feedbackHelp": "Su retroalimentación nos ayuda a mejorar nuestra experiencia de video.",
|
||||
"feedbackQuestion": "¡Comente sobre su llamada!",
|
||||
"thankYou": "¡Gracias por usar __appName__!",
|
||||
"sorryFeedback": "Lamentamos escuchar eso. ¿Quiere decirnos algo más?",
|
||||
"liveStreaming": "Emisión en Directo",
|
||||
"streamKey": "Nombre/clave de emisión",
|
||||
"startLiveStreaming": "Comenzar streaming en tiempo real",
|
||||
@@ -246,52 +291,61 @@
|
||||
"stopLiveStreaming": "Parar retransmisión en directo",
|
||||
"stopRecording": "Parar grabación",
|
||||
"doNotShowWarningAgain": "No volver a mostrar esta advertencia",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "Permiso Denegado",
|
||||
"screenSharingPermissionDeniedError": "No ha otorgado permiso para compartir su pantalla.",
|
||||
"micErrorPresent": "Hubo un error conectando su micrófono.",
|
||||
"cameraErrorPresent": "Hubo un error conectando su cámara.",
|
||||
"cameraUnsupportedResolutionError": "Su cámara no soporta la resolución de video.",
|
||||
"cameraUnknownError": "No se puede usar su cámara por motivos desconocidos.",
|
||||
"cameraPermissionDeniedError": "",
|
||||
"cameraPermissionDeniedError": "No ha otorgado permisos para usar su cámara. Puede unirse a la conferencia, pero no lo podrán ver. Utilice el botón en la barra de dirección para solucionar esto.",
|
||||
"cameraNotFoundError": "No se encontró la cámara.",
|
||||
"cameraConstraintFailedError": "Su cámara no cumple los requerimientos.",
|
||||
"micUnknownError": "No se puede usar su micrófono por motivos desconocidos.",
|
||||
"micPermissionDeniedError": "",
|
||||
"micPermissionDeniedError": "No ha otorgado permisos para usar su micrófono. Puede unirse a la conferencia, pero no lo podrán escuchar. Utilice el botón en la barra de dirección para solucionar esto.",
|
||||
"micNotFoundError": "No se encontró el micrófono.",
|
||||
"micConstraintFailedError": "Su micrófono no cumple los requerimientos."
|
||||
"micConstraintFailedError": "Su micrófono no cumple los requerimientos.",
|
||||
"micNotSendingData": "No fué posible acceder a su micrófono. Por favor, seleccione otro dispositivo del menú de configuración o intente reiniciando la aplicación.",
|
||||
"cameraNotSendingData": "No fué posible acceder a su cámara. Por favor, revise si otra aplicación está usando el dispositivo, seleccione otro dispositivo del menú de configuración o intente reiniciando la aplicación.",
|
||||
"goToStore": "Ir al webstore",
|
||||
"externalInstallationTitle": "Extensión requerida",
|
||||
"externalInstallationMsg": "Necesita instalar nuestra extensión para compartir escritorio.",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Silenciar"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
"Esta conferencia está protegida con contraseña. Utiliza el siguiente pin cuando te unas: ",
|
||||
"Esta conferencia está protegida con contraseña. Utiliza el siguiente pin cuando te unas:",
|
||||
"",
|
||||
"",
|
||||
"__sharedKey__",
|
||||
"",
|
||||
""
|
||||
],
|
||||
"subject": "Invitación a a __appName__ (__conferenceName__)",
|
||||
"subject": "Invitación a __appName__ (__conferenceName__)",
|
||||
"body": [
|
||||
"Ey allí, quiero invitarte a una a conferencia __appName__ que acabo de crear.",
|
||||
"Hola, quiero invitarte a una a conferencia __appName__ que acabo de crear.",
|
||||
"",
|
||||
"",
|
||||
"Por favor pica en la liga siguiente para unirte a la conferencia.",
|
||||
"Por favor presiona el siguiente enlace para unirte a la conferencia.",
|
||||
"",
|
||||
"",
|
||||
"__roomUrl__",
|
||||
"",
|
||||
"",
|
||||
"__sharedKeyText__",
|
||||
"Nota que __appName__ es soportada solo por __supportedBrowsers__, por lo que debes usar uno de esos navegadores.",
|
||||
" Nota que __appName__ es soportada solo por __supportedBrowsers__, por lo que debes usar uno de esos navegadores.",
|
||||
"",
|
||||
"",
|
||||
"Talk to you in a sec!"
|
||||
"¡Hablamos en un segundo!"
|
||||
],
|
||||
"and": "y"
|
||||
},
|
||||
"connection": {
|
||||
"ERROR": "Error",
|
||||
"CONNECTING": "Conectando",
|
||||
"RECONNECTING": "Ocurrió un problema en la red. Reconectando ...",
|
||||
"RECONNECTING": "Ocurrió un problema en la red. Reconectando...",
|
||||
"CONNFAIL": "Conexión fallida",
|
||||
"AUTHENTICATING": "Autenticando",
|
||||
"AUTHFAIL": "Falló la autenticación",
|
||||
@@ -303,20 +357,20 @@
|
||||
"recording": {
|
||||
"pending": "La grabación esta esperando la entrada de un participante...",
|
||||
"on": "Grabando",
|
||||
"off": "Grabación parada",
|
||||
"off": "Grabación detenida",
|
||||
"failedToStart": "No se pudo iniciar la grabación",
|
||||
"buttonTooltip": "Iniciar / parar grabación",
|
||||
"buttonTooltip": "",
|
||||
"error": "Falla de grabación. Vuelva a intentarlo.",
|
||||
"unavailable": "El servicio de grabación no está disponible. Inténtelo más tarde."
|
||||
},
|
||||
"liveStreaming": {
|
||||
"pending": "Iniciando Emisión en Directo",
|
||||
"pending": "Iniciando Emisión en Directo...",
|
||||
"on": "Emisión en Directo",
|
||||
"off": "Emisión en Directo Detenida",
|
||||
"unavailable": "El servicio de emisión en directo no está disponible actualmente. Por favor inténtelo de nuevo más tarde.",
|
||||
"failedToStart": "La emisión en Directo falló al iniciar",
|
||||
"buttonTooltip": "Iniciar / parar emisión en directo",
|
||||
"streamIdRequired": "Por favor introduzca el id de emisión para poder lanzar la emisión en directo",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "Por favor introduzca el identificador de emisión para poder iniciar la emisión en directo",
|
||||
"error": "Falló el video en vivo. Por favor, vuelva a intentarlo.",
|
||||
"busy": "Todos los grabadores están ocupados. Por favor intente más tarde."
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "Liste de contacts",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Paramètres de connexion",
|
||||
"poweredby": "Produit par",
|
||||
"downloadlogs": "Téléchargement des logs",
|
||||
"feedback": "Donnez-nous votre avis",
|
||||
"roomUrlDefaultMsg": "Votre conférence est en cours de création...",
|
||||
"participant": "Participant",
|
||||
"inviteUrlDefaultMsg": "Votre conférence est en cours de création...",
|
||||
"me": "moi",
|
||||
"speaker": "Haut-parleur",
|
||||
"raisedHand": "Aimerais prendre la parole",
|
||||
"defaultNickname": "ex. Jean Dupont",
|
||||
"defaultLink": "ex. __url__",
|
||||
"calling": "Appel __nom__ ...",
|
||||
"callingName": "__name__",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "Merci d'autoriser le partage de votre camera et microphone en appuyant sur le bouton <b><i>Autoriser</i></b>",
|
||||
"chromeGrantPermissions": "Merci d'autoriser le partage de votre camera et microphone en appuyant sur le bouton <b><i>Autoriser</i></b>",
|
||||
@@ -23,17 +25,18 @@
|
||||
"nwjsGrantPermissions": "Merci d'autoriser le partage de votre camera et microphone"
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "Raccourcis clavier :",
|
||||
"raiseHand": "Demander la parole.",
|
||||
"pushToTalk": "Appuyer pour parler.",
|
||||
"toggleScreensharing": "Basculer entre la caméra et le partage d'écran.",
|
||||
"toggleFilmstrip": "Afficher ou masquer les vidéos miniatures.",
|
||||
"toggleShortcuts": "Afficher ou masquer ce menu d'aide.",
|
||||
"focusLocal": "Focus sur la vidéo locale.",
|
||||
"focusRemote": "Focus sur l'une des vidéos distantes.",
|
||||
"toggleChat": "Ouvrir ou fermer le panneau de conversation.",
|
||||
"mute": "Activer ou désactiver le microphone.",
|
||||
"videoMute": "Arrêter ou démarrer la vidéo locale."
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "Créer",
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Apprenez plus au sujet de vos utilisateurs avec une intégration facile de Piwik, Google Analytics et d'autres systèmes de statistiques et supervision d'utilisation."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Muet / Actif",
|
||||
"videomute": "Démarrer / Arrêter la caméra",
|
||||
"videomute": "",
|
||||
"authenticate": "Authentifiez-vous",
|
||||
"lock": "Verrouiller / déverrouiller la salle",
|
||||
"invite": "Inviter des participants",
|
||||
"chat": "Ouvrir / fermer le chat",
|
||||
"etherpad": "Document partagé",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "Partager une vidéo Youtube",
|
||||
"sharescreen": "Partager mon écran",
|
||||
"fullscreen": "Activer / Désactiver le plein écran",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Appeler un numéro SIP",
|
||||
"Settings": "Paramètres",
|
||||
"hangup": "Raccrocher",
|
||||
"hangup": "",
|
||||
"login": "Connexion",
|
||||
"logout": "Déconnexion",
|
||||
"dialpad": "Afficher le clavier de numérotation",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "Votre vidéo a été mise en muet<br/>pour que vous puissiez parler aux autres participants.",
|
||||
"micMutedPopup": "Votre microphone a été désactivé afin que vous<br/>puissiez profiter pleinement de votre vidéo partagée.",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "Vous ne pouvez pas réactiver votre microphone pendant que la vidéo partagée est activée.",
|
||||
"cameraDisabled": "La camera n'est pas disponible",
|
||||
"micDisabled": "Le microphone n'est pas disponible"
|
||||
"micDisabled": "Le microphone n'est pas disponible",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Ouvrir / fermer le chat",
|
||||
"filmstrip": "Montrer / cacher ma vidéo miniature",
|
||||
"contactlist": "Ouvrir / fermer ma liste de contacts"
|
||||
"filmstrip": "Afficher / cacher les vidéos",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,23 +123,33 @@
|
||||
"messagebox": "Saisissez votre texte..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "PARAMÈTRES",
|
||||
"title": "Paramètres",
|
||||
"update": "Mise à jour",
|
||||
"name": "Nom",
|
||||
"startAudioMuted": "Démarrer sans son",
|
||||
"startVideoMuted": "Démarrer sans vidéo",
|
||||
"selectCamera": "Sélectionnez une caméra",
|
||||
"selectMic": "Sélectionnez un microphone",
|
||||
"selectAudioOutput": "Sélectionner la sortie audio",
|
||||
"followMe": "Activer \"me suivre\"",
|
||||
"startAudioMuted": "Tout le monde commence en muet",
|
||||
"startVideoMuted": "Tout le monde commence masqué",
|
||||
"selectCamera": "Caméra",
|
||||
"selectMic": "Microphone",
|
||||
"selectAudioOutput": "Sortie audio",
|
||||
"followMe": "Tout le monde me suit",
|
||||
"noDevice": "Aucun",
|
||||
"noPermission": "L'autorisation d'utiliser l'appareil n'a pas été accordé",
|
||||
"avatarUrl": "URL de l'avatar"
|
||||
"cameraAndMic": "Caméra et microphone",
|
||||
"moderator": "MODÉRATEUR",
|
||||
"password": "DÉFINIR UN MOT DE PASSE",
|
||||
"audioVideo": "AUDIO ET VIDÉO",
|
||||
"setPasswordLabel": "Verrouiller votre salle avec un mot de passe."
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "Choisissez un pseudo",
|
||||
"setEmailLabel": "Définir votre courriel Gravatar",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Cliquez pour modifier<br/>votre nom",
|
||||
"moderator": "Le propriétaire de<br/>cette conférence",
|
||||
"videomute": "Un participant a<br/>arrêté sa caméra.",
|
||||
"videomute": "Un participant a<br/>arrêté sa caméra",
|
||||
"mute": "Un participant a coupé son micro",
|
||||
"kick": "Exclure",
|
||||
"muted": "Muet",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": "Retourner"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Débit :",
|
||||
"packetloss": "Perte de paquets :",
|
||||
"resolution": "Résolution :",
|
||||
@@ -165,34 +191,49 @@
|
||||
"raisedHand": "Aimerais prendre la parole."
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Oups! Vous avez été renvoyé de la réunion !",
|
||||
"popupError": "Votre navigateur bloque les fenêtres popup de ce site. Merci d'activer les popups dans les paramètres de sécurité de votre navigateur et d'essayer à nouveau.",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Cette conversation est actuellement protégée par un mot de passe. Seul le propriétaire de la conférence peut définir un mot de passe.",
|
||||
"passwordError2": "Cette conversation n'est actuellement pas protégé par un mot de passe. Seul le propriétaire de la conférence peut définir un mot de passe.",
|
||||
"connectError": "Oups! Un problème est survenu et la connexion à la conférence est impossible.",
|
||||
"connectErrorWithMsg": "Oups! Un problème est survenu et la connexion à la conférence est impossible: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Connexion en cours",
|
||||
"copy": "Copier",
|
||||
"error": "Erreur",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Une erreur est survenue pendant la détection de l'extension de partage d'écran.",
|
||||
"failtoinstall": "Échec de l'installation de l'extension de partage d'écran",
|
||||
"failedpermissions": "Échec d'obtention des permissions pour utiliser le micro et/ou la caméra.",
|
||||
"bridgeUnavailable": "Le pont de visioconférence Jitsi est indisponible pour le moment. Réessayez plus tard !",
|
||||
"jicofoUnavailable": "Le pont de visioconférence Jitsi est indisponible pour le moment. Réessayez plus tard !",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "La limite pour le nombre maximum de participants à la conférence a été atteinte. La conférence est pleine. Veuillez réessayer plus tard !",
|
||||
"lockTitle": "Échec du verrouillage",
|
||||
"lockMessage": "Impossible de verrouiller la conférence.",
|
||||
"warning": "Avertissement",
|
||||
"passwordNotSupported": "Les mots de passe de conférence ne sont pas supportés.",
|
||||
"sorry": "Désolé",
|
||||
"internalError": "Une erreur interne de l'application est survenue [setRemoteDescription]",
|
||||
"internalErrorTitle": "Erreur interne",
|
||||
"internalError": "Oups ! Quelque chose s'est mal passé. L'erreur suivante est apparue : [setRemoteDescription]",
|
||||
"unableToSwitch": "Impossible de changer le flux vidéo.",
|
||||
"SLDFailure": "Oups! Un problème est survenu et le micro n'a pas été coupé! (Échec SLD)",
|
||||
"SRDFailure": "Oups! Un problème est survenu et la caméra n'a pas été coupée! (Échec SRD)",
|
||||
"oops": "Oups !",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Une erreur est survenue",
|
||||
"passwordRequired": "Mot de passe requis",
|
||||
"Ok": "Ok",
|
||||
"done": "",
|
||||
"Remove": "Supprimer",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "Partager une vidéo",
|
||||
"shareVideoLinkError": "Fournissez s'il vous plaît un lien Youtube fonctionnel.",
|
||||
"removeSharedVideoTitle": "Supprimer la vidéo partagée",
|
||||
@@ -202,6 +243,7 @@
|
||||
"WaitForHostMsg": "La conférence <b>__room__</b> n'a pas encore commencé. Si vous êtes l'hôte, merci de vous authentifier. Sinon, merci d'attendre que l'hôte arrive.",
|
||||
"IamHost": "Je suis l’hôte",
|
||||
"Cancel": "Annuler",
|
||||
"Submit": "",
|
||||
"retry": "Réessayer",
|
||||
"logoutTitle": "Déconnexion",
|
||||
"logoutQuestion": "Voulez-vous vraiment vous déconnecter et arrêter la conférence ?",
|
||||
@@ -216,26 +258,29 @@
|
||||
"sipMsg": "Saisissez un numéro SIP",
|
||||
"passwordCheck": "Voulez-vous vraiment supprimer votre mot de passe ?",
|
||||
"passwordMsg": "Saisissez un mot de passe pour verrouiller la conférence",
|
||||
"Invite": "Inviter",
|
||||
"shareLink": "Partagez ce lien avec toutes les personnes que vous voulez inviter",
|
||||
"shareLink": "",
|
||||
"settings1": "Configurez votre conférence",
|
||||
"settings2": "Les participants rejoignent la conférence en étant muets",
|
||||
"settings3": "Pseudonymes requis<br/><br/>Saisissez un mot de passe pour verrouiller la conférence :",
|
||||
"yourPassword": "votre mot de passe",
|
||||
"yourPassword": "Saisissez un nouveau mot de passe",
|
||||
"Back": "Retour",
|
||||
"serviceUnavailable": "Service indisponible",
|
||||
"gracefulShutdown": "Le service est actuellement en maintenance. Réessayez plus tard.",
|
||||
"Yes": "Oui",
|
||||
"reservationError": "Erreur du système de réservation",
|
||||
"reservationErrorMsg": "Code d'erreur: __code__, message: __msg__",
|
||||
"password": "mot de passe",
|
||||
"password": "Saisir le mot de passe",
|
||||
"userPassword": "mot de passe utilisateur",
|
||||
"token": "jeton",
|
||||
"tokenAuthFailed": "Échec de l'authentification avec le serveur XMPP : jeton non valide",
|
||||
"displayNameRequired": "Veuillez saisir votre nom",
|
||||
"tokenAuthFailedTitle": "Échec de l'authentification",
|
||||
"tokenAuthFailed": "Désolé, vous n'êtes pas autorisé à rejoindre cette conversation.",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "Veuillez saisir votre nom",
|
||||
"extensionRequired": "Extension requise :",
|
||||
"firefoxExtensionPrompt": "Vous devez installer une extension Firefox pour utiliser le partage d'écran. Merci d'essayer de nouveau après l'installation <a href='__url__'>depuis ce lien</a> !",
|
||||
"feedbackQuestion": "Comment était votre conférence ?",
|
||||
"rateExperience": "Veuillez évaluer votre réunion.",
|
||||
"feedbackHelp": "Vos retours nous permettrons d'améliorer notre expérience vidéo.",
|
||||
"feedbackQuestion": "Informez-nous à propos de votre appel !",
|
||||
"thankYou": "Merci d'avoir utilisé __appName__ !",
|
||||
"sorryFeedback": "Nous sommes désolés d'apprendre cela. Voulez-vous nous en dire plus ?",
|
||||
"liveStreaming": "Direct",
|
||||
@@ -246,6 +291,7 @@
|
||||
"stopLiveStreaming": "Arrêter le direct",
|
||||
"stopRecording": "Arrêter l'enregistrement",
|
||||
"doNotShowWarningAgain": "Ne plus afficher cet avertissement",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "Permission refusée",
|
||||
"screenSharingPermissionDeniedError": "Vous n'avez pas autorisé le partage de votre écran.",
|
||||
"micErrorPresent": "Une erreur est survenue lors de la connexion à votre microphone.",
|
||||
@@ -253,12 +299,20 @@
|
||||
"cameraUnsupportedResolutionError": "Votre appareil ne prend pas en charge la résolution vidéo requise.",
|
||||
"cameraUnknownError": "Vous ne pouvez pas utiliser la caméra pour une raison inconnue.",
|
||||
"cameraPermissionDeniedError": "Vous n'avez pas autorisé l'utilisation de votre caméra. Vous pouvez toujours participer à la conférence, mais les autres ne vont pas vous voir. Utilisez le bouton de la caméra dans la barre d'adresse pour résoudre ce problème.",
|
||||
"cameraNotFoundError": "La caméra demandée n'a pas été trouvée.",
|
||||
"cameraNotFoundError": "La caméra n'a pas été trouvée",
|
||||
"cameraConstraintFailedError": "Votre caméra ne satisfait pas certaines des contraintes nécessaires.",
|
||||
"micUnknownError": "Vous ne pouvez pas utiliser le microphone pour une raison inconnue.",
|
||||
"micPermissionDeniedError": "Vous n'avez pas autorisé l'utilisation de votre microphone. Vous pouvez toujours participer à la conférence, mais les autres ne vont pas vous entendre. Utilisez le bouton du microphone dans la barre d'adresse pour résoudre ce problème.",
|
||||
"micNotFoundError": "Le microphone demandé n'a pas été trouvé.",
|
||||
"micConstraintFailedError": "Votre microphone ne satisfait pas certaines des contraintes nécessaires."
|
||||
"micNotFoundError": "Le microphone n'a pas été détecté.",
|
||||
"micConstraintFailedError": "Votre microphone ne satisfait pas certaines des contraintes nécessaires.",
|
||||
"micNotSendingData": "Nous ne pouvons pas accéder à votre microphone. Veuillez sélectionner un autre périphérique dans le menu des paramètres ou essayez de redémarrer l'application.",
|
||||
"cameraNotSendingData": "Nous ne pouvons pas accéder à votre caméra. Vérifiez si une autre application utilise ce périphérique, sélectionnez un autre périphérique dans le menu des paramètres ou essayez de redémarrer l'application.",
|
||||
"goToStore": "Aller sur le webstore",
|
||||
"externalInstallationTitle": "Extension requise : ",
|
||||
"externalInstallationMsg": "Vous devez installer notre extension de partage de bureau.",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Couper le son"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
@@ -305,7 +359,7 @@
|
||||
"on": "Enregistrement",
|
||||
"off": "Enregistrement arrêter",
|
||||
"failedToStart": "L'enregistrement n'as pas réussi à démarrer",
|
||||
"buttonTooltip": "Démarrer / arrêter l'enregistrement",
|
||||
"buttonTooltip": "",
|
||||
"error": "Échec de l'enregistrement. Veuillez réessayer.",
|
||||
"unavailable": "Le service d'enregistrement est actuellement indisponible. Veuillez réessayer plus tard."
|
||||
},
|
||||
@@ -315,7 +369,7 @@
|
||||
"off": "Le direct a été arrêter",
|
||||
"unavailable": "Le direct est temporairement indisponible. Veuillez réessayer plus tard.",
|
||||
"failedToStart": "Le direct n'as pas réussi à démarrer",
|
||||
"buttonTooltip": "Démarrer / arrêter le direct",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "Merci de renseigner le stream id pour lancer le direct.",
|
||||
"error": "La retransmission en direct a échoué. Veuillez réessayer.",
|
||||
"busy": "Tous les enregistreurs sont actuellement occupés. Veuillez réessayer plus tard."
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
{
|
||||
"contactlist": "Զանգ",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Միացման կարգավորումներ",
|
||||
"poweredby": "Հիմնված է",
|
||||
"feedback": "Հայտնեք ձեր կարծիքը",
|
||||
"roomUrlDefaultMsg": "Ձեր կոնֆերանսը այժմ ստեղծվում է...",
|
||||
"inviteUrlDefaultMsg": "Ձեր կոնֆերանսը այժմ ստեղծվում է...",
|
||||
"me": "ես",
|
||||
"speaker": "Հռետոր",
|
||||
"raisedHand": "Ցանկանում է խոսել",
|
||||
@@ -11,27 +15,28 @@
|
||||
"defaultLink": "օրինակ՝ __url__",
|
||||
"callingName": "__անուն__",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
"androidGrantPermissions": "",
|
||||
"react-nativeGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i>ընդունել</ i> </ b> կոճակը",
|
||||
"chromeGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i>ընդունել</ i> </ b> կոճակը",
|
||||
"androidGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i>ընդունել</ i> </ b> կոճակը",
|
||||
"firefoxGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i> տարածել նշված սարքը </ i> </ b> կոճակը",
|
||||
"operaGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i>ընդունել</ i> </ b> կոճակը",
|
||||
"iexplorerGrantPermissions": "",
|
||||
"iexplorerGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i>Այո</ i> </ b> կոճակը",
|
||||
"safariGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ <b> <i>Այո</ i> </ b> կոճակը",
|
||||
"nwjsGrantPermissions": "Խնդրում ենք տրամադրել տեսախցիկը և խոսափողը օգտագործելու թույլտվություններ"
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "Ստեղնաշարի դյուրանցումներ (shortcuts)",
|
||||
"raiseHand": "Բարձրացրեք Ձեր ձեռքը",
|
||||
"pushToTalk": "Սեղմեք խոսելու համար",
|
||||
"toggleScreensharing": "Անցնել ֆոտոխցիկի և էկրանի փոխանակման միջև",
|
||||
"toggleFilmstrip": "Ցույց տալ կամ թաքցնել տեսանյութերը",
|
||||
"toggleShortcuts": "Ցույց տալ կամ թաքցնել այս օգնության մենյուն",
|
||||
"focusLocal": "Կենտրոնանալ տեղական տեսանյութի վրա",
|
||||
"focusRemote": "Կենտրոնանալ տեղական տեսանյութի վրա",
|
||||
"toggleChat": "Բացել կամ փակել չատի պանելը",
|
||||
"mute": "Անջատել կամ միացնել խոսափողը",
|
||||
"videoMute": "Կանգնեցնել կամ սկսել տեղական տեսանյութը"
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "ՄՈՒՏՔ",
|
||||
@@ -70,35 +75,45 @@
|
||||
"content": "Օգտագործման վիճակագրություն կարելի է ստանալ հեշտ ինտեգրվող Piwik, Google Analytics կամ այլ մոնիտորինգի համակարգերի միջոցով:"
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Ձայնը Միացնել/Անջատել ",
|
||||
"videomute": "Տեսախցիկը Միացնել/Անջատել ",
|
||||
"videomute": "",
|
||||
"authenticate": "Վավերացում",
|
||||
"lock": "Փակել/բացել սենյակը",
|
||||
"invite": "Հրավիրել ուրիշներին",
|
||||
"chat": "Բացել/փակել չատը",
|
||||
"etherpad": "Համատեղ փաստաթուղթ",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "Կիսվել YouTube-ի նյութով",
|
||||
"sharescreen": "Ցուցադրել էկրանը",
|
||||
"fullscreen": "Ամբողջ Էկրանի ռեժիմը միացնել/անջատել",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Զանգել SIP համարով",
|
||||
"Settings": "Կարգավորումներ",
|
||||
"hangup": "Անջատել",
|
||||
"hangup": "",
|
||||
"login": "Մուտք",
|
||||
"logout": "Ելք",
|
||||
"dialpad": "Ցույց տալ թվաշարը",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "Ձեր ցուցադրված տեսանյութի ձայնը անջատված է, այնպես որ <br />, կարող եք խոսել մյուս մասնակիցների հետ:",
|
||||
"micMutedPopup": "Ձեր խոսափողը անջատված է՝<br/> կարող եք լիովին վայելել ձեր ցուցադրված տեսանյութը:",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "Դուք չեք կարող միացնել ձայնը, քանի դեռ միանցված է ցուցադրվող տեսանյութը:",
|
||||
"cameraDisabled": "Տեսախցիկը հասանելի չէ",
|
||||
"micDisabled": "Խոսափողը հասանելի չէ",
|
||||
"filmstrip": "",
|
||||
"raiseHand": "Բարձրացրեք ձեռքը խոսելու համար"
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Բացել/փակել չատը",
|
||||
"filmstrip": "Ցույց տալ/թաքցնել տեսանյութները",
|
||||
"contactlist": "Բացել/փակել կոնտակտների ցուցակը"
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -126,9 +141,10 @@
|
||||
"setPasswordLabel": "Փակել սենյակը գաղտնաբառով"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Էջ",
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "Դնել Ձեր երևացող անունը",
|
||||
"setEmailLabel": "Սահմանեք Ձեր gravatar էլ.փոստը"
|
||||
"setEmailLabel": "Սահմանեք Ձեր gravatar էլ.փոստը",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Սեղմեք Ձեր անունը <br/>փոխելու համար",
|
||||
@@ -141,6 +157,7 @@
|
||||
"flip": "Շրջել"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Բիթրեյթ",
|
||||
"packetloss": "Փաթեթների կորուստ՝",
|
||||
"resolution": "Որակ՝",
|
||||
@@ -170,20 +187,30 @@
|
||||
"raisedHand": "Ցանկանում է խոսել"
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Վա՜յ: Ձեզ դուրս հանեցին հանդիպումից:",
|
||||
"popupError": "Ձեր բրաուզերը արգելափակել է թռուցիկ(popup) պատուհանները այս կայքում: Խնդրում ենք միացրեք թռուցիկները Ձեր բրաուզերի անվտանգության կարգավորումներում և կրկին փորձեք:",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Այս խոսակցությունը այս պահին պաշտպանված է գաղտնաբառով:Միայն կոնֆերանսի սեփականատերը կարող է սահմանել գաղտնաբառ:",
|
||||
"passwordError2": "Այս խոսակցությունը այս պահին պաշտպանված չէ գաղտնաբառով:Միայն կոնֆերանսի սեփականատերը կարող է սահմանել գաղտնաբառ:",
|
||||
"connectError": "Ու՜պս! Ինչոր բան այն չէ և մենք չկարողացանք միանալ կոնֆերանսին:",
|
||||
"connectErrorWithMsg": "Ու՜պս! Ինչոր բան այն չէ և մենք չկարողացանք միանալ կոնֆերանսին: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Միանում է...",
|
||||
"copy": "Պատճենել",
|
||||
"error": "Սխալ",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Սխալ, երբ փորձում է հայտնաբերել էկրանի ցուցադրման ընդլայնումը:",
|
||||
"failtoinstall": "Չհաջողվեց տեղադրել էկրանի ցուցադրման ընդլայնումը",
|
||||
"failedpermissions": "Չհաջողվեց ստանալ թույլտվություն օգտագործելու տեղի խոսափողը և/ կամ տեսախցիկը:",
|
||||
"bridgeUnavailable": "Jitsi Videobridge-ը ներկայումս անհասանելի է: Խնդրում ենք փորձեք մի փոքր ուշ!",
|
||||
"jicofoUnavailable": "Jicofo ներկայումս անհասանելի է: Խնդրում ենք փորձեք ավելի ուշ:",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "Մասնակիցների առավելագույն թիվը արդեն լրացել է: Մասնակիցները արդեն հավաքվել են: Խնդրում ենք փորձեք ավելի ուշ:",
|
||||
"lockTitle": "Փակումը ձախողվեց",
|
||||
"lockMessage": "Ձախողվեց արգելափակել կոնֆերանսը:",
|
||||
@@ -195,10 +222,14 @@
|
||||
"SLDFailure": "Ու՜պս: Ինչ-որ բան գնաց սխալ, և մենք չկարողացանք անջատել ձայնը (SLD Failure)",
|
||||
"SRDFailure": "Ու՜պս: Ինչ-որ բան գնաց սխալ, և մենք չկարողացանք անջատել տեսահոսքը (SRD Failure)",
|
||||
"oops": "Ու՜պս:",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Առկա էր որոշակի սխալ",
|
||||
"passwordRequired": "Պահանջվում է գաղտնաբառ",
|
||||
"Ok": "Ok",
|
||||
"done": "",
|
||||
"Remove": "Հեռացնել",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "Տարածել տեսանյութը",
|
||||
"shareVideoLinkError": "Խնդրում ենք ներկայացնել ճիշտ Youtube հղում:",
|
||||
"removeSharedVideoTitle": "Հեռացնել տարածված տեսանյութը",
|
||||
@@ -208,6 +239,7 @@
|
||||
"WaitForHostMsg": "Կոնֆերանսը <b> __ root__ </ b> դեռ չի սկսվել. Եթե դուք են հյուրընկալող եք ապա խնդրում ենք հաստատել իսկությունը: Հակառակ դեպքում, խնդրում ենք սպասել հյուրընկալող կժամանի.",
|
||||
"IamHost": "Ես եմ ընդունողը",
|
||||
"Cancel": "Չեղարկել",
|
||||
"Submit": "",
|
||||
"retry": "Կրկին փորձել",
|
||||
"logoutTitle": "Ելք",
|
||||
"logoutQuestion": "Համոզված եք, որ ցանկանում եք դուրս գալ, եւ դադարեցնել կոնֆերանսը:",
|
||||
@@ -222,7 +254,7 @@
|
||||
"sipMsg": "Նշեք SIP համարը",
|
||||
"passwordCheck": "Դուք վստա՞հ էք որ ցանկանում էք ջնջել Ձեր գաղտնաբառը։",
|
||||
"passwordMsg": "Սահմանել գաղտնաբառ ձեր սենյակը կողպելու համար",
|
||||
"shareLink": "Պատճենել և կիսվել այս հղումով",
|
||||
"shareLink": "",
|
||||
"settings1": "Կարգավորել Ձեր կոնֆերանսը",
|
||||
"settings2": "Մասնակիցները միացան անջատվախ ձայնով",
|
||||
"settings3": "Պահանջվում է մականունը<br/><br/>Դրեք գաղտնաբառ Ձեր սենյակը արգելափակելու համար",
|
||||
@@ -238,7 +270,8 @@
|
||||
"token": "սիմվոլ",
|
||||
"tokenAuthFailedTitle": "Վավերացումը չի ստացվել",
|
||||
"tokenAuthFailed": "Ներողություն,Դուք ընդունված չեք այս զանգին միանալու համար",
|
||||
"displayNameRequired": "Խնդրում ենք մուտքագրել Ձեր ցուցադրման անունը",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "Խնդրում ենք մուտքագրել Ձեր ցուցադրման անունը",
|
||||
"extensionRequired": "Ընդլայնում է պահանջվում:",
|
||||
"firefoxExtensionPrompt": "Դուք պետք է տեղադրեք Firefox ընդլայնում, որպեսզի օգտագործել էկրանի փոխանակման ռեժիմը: Խնդրում ենք փորձեք կրկին՝ այն <a href='__url__'> այստեղից ձեռք բերելուց հետո</a>:",
|
||||
"rateExperience": "Խնդրում ենք ներկայացրեք Ձեր հանդիպման փորձը",
|
||||
@@ -254,6 +287,7 @@
|
||||
"stopLiveStreaming": "Կանգնացնել ուղիղ հեռարձակումը:",
|
||||
"stopRecording": "Կանգնացնել ձայնագրումը",
|
||||
"doNotShowWarningAgain": "Այլևս ցույց չտալ այս նախազգուշական էջը",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "Թույլատվությունը արգելված է",
|
||||
"screenSharingPermissionDeniedError": "Դուք չունեք թույլտվություն կիսվել Ձեր էկրանով",
|
||||
"micErrorPresent": "Տեղի է ունեցել սխալ Ձեր խոսափողին միանալիս",
|
||||
@@ -271,7 +305,10 @@
|
||||
"cameraNotSendingData": "Մենք չեն կարողանում միանալ Ձեր տեսախցիկին: Խնդրում ենք ստուգեք թե արդյոք մեկ ուրիշ սարք չի օգտագործում այն կամ ընտրեք մեկ այլ սարք կարգավորումների ցանկից կամ փորձեք վերսկսել ծրագիրը:",
|
||||
"goToStore": "Գնալ դեպի վեբ խանութ",
|
||||
"externalInstallationTitle": "Ընդլայնում է պահանջվում:",
|
||||
"externalInstallationMsg": "Չհաջողվեց տեղադրել էկրանի ցուցադրման ընդլայնումը"
|
||||
"externalInstallationMsg": "Չհաջողվեց տեղադրել էկրանի ցուցադրման ընդլայնումը",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Անջատել ձայնը"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
@@ -314,7 +351,7 @@
|
||||
"on": "Գրանցում",
|
||||
"off": "Ձայնագրությունը կանգնացված է",
|
||||
"failedToStart": "Ձայնագրությունը ստացվեց սկսել",
|
||||
"buttonTooltip": "Սկսել / կանգնացնել ձայնագրությունը",
|
||||
"buttonTooltip": "",
|
||||
"error": "Ձայնագրությյունը չստացվեց: Փորձեք կրկին",
|
||||
"unavailable": "Ձայնագրության ծառայությունը ներկայումս անհասանելի է: Խնդրում եմ փորձեք մի փոքր ուշ:"
|
||||
},
|
||||
@@ -324,7 +361,7 @@
|
||||
"off": "Ուղիղ Հեռարձակումը կանգնեցված է",
|
||||
"unavailable": "Ուղիղ հեռարձակման ծառայությունը ներկայումս հասանելի չէ: Խնդրում եք փորձեք ավելի ուշ:",
|
||||
"failedToStart": "Ուղիղ հեռարձակումը չստացվեց սկսել",
|
||||
"buttonTooltip": "Սկսել / կանգնեցնել ուղիղ հեռարձակումը",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "Խնդրում ենք լրացնել հոսքի ID-ն, որպեսզի կսկսի հեռարձակումը:",
|
||||
"error": "Ուղիղ հեռարձակումը չստացվեց: Փորձեք կրկին",
|
||||
"busy": "Բոլոր ձայնագրիչները ներկայումս զբաղված են: Խնդրում ենք փորձեք մի փոքր ուշ:"
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "LISTA CONTATTI",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Impostazioni Connessione",
|
||||
"poweredby": "powered by",
|
||||
"downloadlogs": "Scarica logs",
|
||||
"feedback": "",
|
||||
"roomUrlDefaultMsg": "La tua conferenza sta per essere creata...",
|
||||
"participant": "Partecipante",
|
||||
"inviteUrlDefaultMsg": "La tua conferenza sta per essere creata...",
|
||||
"me": "io",
|
||||
"speaker": "Relatore",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "es. __url__",
|
||||
"calling": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
@@ -33,6 +35,7 @@
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Impara come i tuoi utenti lo utilizzano con la facile integrazione con PiWik, Google Analytics, e altri sistemi di statistica e monitor dell'utilizzo."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Microfono Attiva / Disattiva",
|
||||
"videomute": "Abilita / Disabilita video",
|
||||
"videomute": "",
|
||||
"authenticate": "Autenticazione",
|
||||
"lock": "Blocca / Sblocca Stanza",
|
||||
"invite": "Invita altri",
|
||||
"chat": "Apri / Chiudi chat",
|
||||
"etherpad": "Documento condiviso",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "Condividi schermo",
|
||||
"fullscreen": "Entra / Esci da schermo intero",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Chiama numero SIP",
|
||||
"Settings": "Impostazioni",
|
||||
"hangup": "Termina",
|
||||
"hangup": "",
|
||||
"login": "Login",
|
||||
"logout": "Logout",
|
||||
"dialpad": "Mostra il tastierino",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": ""
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Apri / Chiudi chat",
|
||||
"filmstrip": "Mostra / Nascondi miniature",
|
||||
"contactlist": "Apri / Chiudi la lista contatti"
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,7 +123,7 @@
|
||||
"messagebox": "Inserisci testo..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "IMPOSTAZIONI",
|
||||
"title": "Impostazioni",
|
||||
"update": "Aggiorna",
|
||||
"name": "Nome",
|
||||
"startAudioMuted": "",
|
||||
@@ -119,12 +134,22 @@
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"avatarUrl": ""
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Clicca per modificare il tuo<br/>nome visualizzato",
|
||||
"moderator": "Il proprietario<br/>della conferenza",
|
||||
"videomute": "Il partecipante ha<br/>fermato il video.",
|
||||
"videomute": "",
|
||||
"mute": "Il partecipante è in muto",
|
||||
"kick": "Espelli",
|
||||
"muted": "Audio disattivato",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Bitrate:",
|
||||
"packetloss": "Perdita pacchetti:",
|
||||
"resolution": "Risoluzione:",
|
||||
@@ -165,43 +191,59 @@
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Accidenti! Sei stato espulso dalla conferenza !",
|
||||
"popupError": "",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "",
|
||||
"passwordError2": "",
|
||||
"connectError": "Oops! Qualcosa è andato storto e non ti puoi collegare alla conferenza.",
|
||||
"connectErrorWithMsg": "Oops! Qualcosa è andato storto e non ti puoi collegare alla conferenza: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Connessione",
|
||||
"copy": "",
|
||||
"error": "Errore",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Errore durante il rilevamento dell'estensione per il desktopsharing.",
|
||||
"failtoinstall": "Impossibile installare l'estensione per il desktop sharing",
|
||||
"failedpermissions": "Impossibile ottenere i permessi per usare il microfono e/o il video locale.",
|
||||
"bridgeUnavailable": "Il Videobridge non è al momento disponibile. Si prega di riprovare più tardi!",
|
||||
"jicofoUnavailable": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "Blocco fallito",
|
||||
"lockMessage": "",
|
||||
"lockMessage": "Impossibile bloccare la conferenza.",
|
||||
"warning": "Attenzione",
|
||||
"passwordNotSupported": "Le password sulla stanza non sono al momento supportate.",
|
||||
"sorry": "Spiacente",
|
||||
"internalError": "Errore interno dell'applicazione [setRemoteDescription]",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "Impossibile cambiare lo stream video.",
|
||||
"SLDFailure": "Oops! Qualcosa è andato storto e non è possibile silenziare il microfono! (Errore SLD)",
|
||||
"SRDFailure": "Oops! Qualcosa è andato storto e non è possibile fermare il video! (Errore SRD)",
|
||||
"oops": "Oops!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "C'è stato qualche tipo di errore",
|
||||
"passwordRequired": "Richiesta password ",
|
||||
"Ok": "Ok",
|
||||
"done": "",
|
||||
"Remove": "Rimuovi",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"shareVideoLinkError": "Fornire un link Prezi esatto.",
|
||||
"removeSharedVideoTitle": "",
|
||||
"removeSharedVideoMsg": "",
|
||||
"removeSharedVideoMsg": "Sei sicuro di voler rimuovere il tuo Prezi?",
|
||||
"alreadySharedVideoMsg": "",
|
||||
"WaitingForHost": "In attesa dell'organizzatore ...",
|
||||
"WaitForHostMsg": "La conferenza <b>__room__ </b> non è ancora iniziata. Se sei l'organizzatore sei pregato di autenticarti, altrimenti ti preghiamo di attendere l'arrivo dell'organizzatore.",
|
||||
"IamHost": "Sono l'organizzatore",
|
||||
"Cancel": "Annulla",
|
||||
"Submit": "",
|
||||
"retry": "Riprova",
|
||||
"logoutTitle": "Logout",
|
||||
"logoutQuestion": "Vuoi disconnetterti e interrompere la conferenza ?",
|
||||
@@ -216,25 +258,28 @@
|
||||
"sipMsg": "Inserire numero SIP",
|
||||
"passwordCheck": "Confermi la rimozione della password?",
|
||||
"passwordMsg": "Imposta una password per bloccare la stanza",
|
||||
"Invite": "Invita",
|
||||
"shareLink": "Condividi questo link con tutte le persone che vuoi invitare",
|
||||
"shareLink": "",
|
||||
"settings1": "Configura la tua conferenza",
|
||||
"settings2": "Partecipanti connessi in muto",
|
||||
"settings3": "Richiedi nicknames<br/><br/>Imposta una password per bloccare la tua stanza:",
|
||||
"yourPassword": "la tua password",
|
||||
"yourPassword": "",
|
||||
"Back": "Indietro",
|
||||
"serviceUnavailable": "Servizio non disponibile",
|
||||
"gracefulShutdown": "Il nostro servizio è al momento spento per manutenzione. Si prega di riprovare più tardi.",
|
||||
"Yes": "Sì",
|
||||
"reservationError": "Errore di sistema in prenotazione",
|
||||
"reservationErrorMsg": "Codice di errore: __code__, messaggio: __msg__",
|
||||
"password": "password",
|
||||
"password": "",
|
||||
"userPassword": "password utente",
|
||||
"token": "token",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "Per favore, inserisci il tuo nome utente:",
|
||||
"extensionRequired": "",
|
||||
"firefoxExtensionPrompt": "",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "",
|
||||
"sorryFeedback": "",
|
||||
@@ -246,6 +291,7 @@
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
@@ -258,8 +304,17 @@
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": ""
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Disattiva audio"
|
||||
},
|
||||
"\u0005dialog": {},
|
||||
"email": {
|
||||
"sharedKey": "",
|
||||
"subject": "Invito su __appName__ (__conferenceName__)",
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
{
|
||||
"contactlist": "Al telefòn",
|
||||
"contactlist": "Participants (__pcount__)",
|
||||
"addParticipants": "Partejatz lo ligam",
|
||||
"roomLocked": "Los qu'apèlan devon picar un senhal",
|
||||
"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",
|
||||
"roomUrlDefaultMsg": "Vòstra conferéncia es en cors de creacion...",
|
||||
"inviteUrlDefaultMsg": "Vòstra conferéncia es en cors de creacion...",
|
||||
"me": "ieu",
|
||||
"speaker": "Nautparlaire",
|
||||
"raisedHand": "Volriatz charrar",
|
||||
@@ -22,16 +26,17 @@
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "Acorchis de clavièr",
|
||||
"raiseHand": "Demandar a parlar.",
|
||||
"raiseHand": "Demandar o pas la paraula",
|
||||
"pushToTalk": "Butar per parlar",
|
||||
"toggleScreensharing": "Caplevar entre camerà e partatge d'ecran",
|
||||
"toggleFilmstrip": "Mostrar o escondre la vidèo",
|
||||
"toggleShortcuts": "Afichar o amagar aiceste menú d'ajuda",
|
||||
"focusLocal": "Focus sus la vidèo locala.",
|
||||
"focusRemote": "Focus sus una de las vidèas aluènhadas.",
|
||||
"toggleChat": "Dubrir o tampar lo panèl de conversacion.",
|
||||
"mute": "Activar o desactivar lo microfòn.",
|
||||
"videoMute": "Arrestar o lançar la vidèo locala."
|
||||
"focusLocal": "Centrar sus vòstra vidèo",
|
||||
"focusRemote": "Centrar sus la vidèo de qualqu'un mai",
|
||||
"toggleChat": "Dubrir o tampar lo panèl de conversacion",
|
||||
"mute": "Activar o desactivar lo microfòn",
|
||||
"fullScreen": "Activar / Desactivar l'ecran complet",
|
||||
"videoMute": "Aviar o arrestar vòstra camerà"
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "Crear",
|
||||
@@ -70,35 +75,45 @@
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
"title": "__app__ a besonh d'utilizar vòstre microfòn e camerà."
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "Vòstra conferéncia vidèo es estada arrestada perque vòstre ordinador se botèt en velha.",
|
||||
"rejoinKeyTitle": "Tornar participar"
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Mut / Actiu",
|
||||
"videomute": "Aviar / Arrestar la camèra",
|
||||
"videomute": "Aviar / Arrestar la camerà",
|
||||
"authenticate": "Autentificatz-vos",
|
||||
"lock": "Verrolhar / desverrolhar la sala",
|
||||
"invite": "Convidar de participants",
|
||||
"chat": "Dobrir / tampar lo chat",
|
||||
"etherpad": "Document partejat",
|
||||
"invite": "Partejatz lo ligam",
|
||||
"chat": "Dobrir / tampar la conversacion",
|
||||
"etherpad": "Dobrir / Tampar los documents partejats",
|
||||
"sharedvideo": "Partejar una vidèo Youtube",
|
||||
"sharescreen": "Partejar mon ecran",
|
||||
"fullscreen": "Activar / Désactivar l'ecran complet",
|
||||
"sharescreen": "Aviar / Arrestar lo partatge d'ecran",
|
||||
"fullscreen": "Activar / Desactivar l'ecran complet",
|
||||
"sip": "Sonar un numèro SIP",
|
||||
"Settings": "Paramètres",
|
||||
"hangup": "Tornar penjar",
|
||||
"hangup": "Quitar",
|
||||
"login": "Connexion",
|
||||
"logout": "Desconnexion",
|
||||
"dialpad": "Afichar lo clavièr de numerotacion",
|
||||
"dialpad": "Dubrir / Tampar lo clavièr",
|
||||
"sharedVideoMutedPopup": "Vòstra vidèo es estada mesa en mut<br/>per que poscatz parlar als autres participants.",
|
||||
"micMutedPopup": "Vòstre microfòn es estat desactivat per fin que <br/>poscatz profeitar plenament de vòstra vidèo partejada.",
|
||||
"talkWhileMutedPopup": "Ensajatz de parlar ? Vòstre microfòn es copat.",
|
||||
"unableToUnmutePopup": "Podètz pas reactivar vòstre microfòn pendent que la vidèo partejada es activada.",
|
||||
"cameraDisabled": "La camerà es pas disponibla",
|
||||
"micDisabled": "Lo microfòn es pas disponible",
|
||||
"filmstrip": "",
|
||||
"raiseHand": "Demandar la paraula"
|
||||
"filmstrip": "Mostrar / escondre vidèos",
|
||||
"profile": "Modificar vòstre perfil",
|
||||
"raiseHand": "Demandar / Demandar pas mai la paraula"
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Dobrir / tampar lo chat",
|
||||
"filmstrip": "Mostrar / escondre vidèos",
|
||||
"contactlist": "Dobrir / tampar ma lista de contactes"
|
||||
"contactlist": "Veire e convidar de participants"
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -126,9 +141,10 @@
|
||||
"setPasswordLabel": "Verrolhar vòstra sala amb un senhal"
|
||||
},
|
||||
"profile": {
|
||||
"title": "PERFIL",
|
||||
"title": "Perfil",
|
||||
"setDisplayNameLabel": "Causissètz vòstra nom",
|
||||
"setEmailLabel": "Definir vòstre corrièl per gravatar"
|
||||
"setEmailLabel": "Definir vòstre corrièl per gravatar",
|
||||
"setEmailInput": "Picatz lo corrièl"
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Clicatz per modificar<br/>vòstre nom",
|
||||
@@ -141,6 +157,7 @@
|
||||
"flip": "Revirar"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "Donadas de connexion",
|
||||
"bitrate": "Debit :",
|
||||
"packetloss": "Pèrda de paquets :",
|
||||
"resolution": "Resolucion :",
|
||||
@@ -174,20 +191,30 @@
|
||||
"raisedHand": "Volriá parlar."
|
||||
},
|
||||
"dialog": {
|
||||
"add": "Apondre",
|
||||
"kickMessage": "Ops! Sètz estat bandit de la reünion !",
|
||||
"popupError": "Vòstre navigador blòca las fenèstras popup d'aqueste site. Mercé d'activar las popups dins los paramètres de seguretat de vòstre navigador e d'ensajar tornamai.",
|
||||
"passwordErrorTitle": "Error de senhal",
|
||||
"passwordError": "Aquesta conversacion es actualament protegida per un senhal. Sol lo proprietari de la conferéncia pòt definir un senhal.",
|
||||
"passwordError2": "Actualament, aquesta conversacion es pas protegida per un senhal. Sol lo proprietari de la conferéncia pòt definir un senhal.",
|
||||
"connectError": "Ops! Quicòm a trucat e la connexion a la conferéncia es impossibla.",
|
||||
"connectErrorWithMsg": "Ops! Quicòm a trucat e la connexion a la conferéncia es impossibla: __msg__",
|
||||
"incorrectPassword": "Lo senhal es incorrècte",
|
||||
"connecting": "Connexion en cors",
|
||||
"copy": "Copiar",
|
||||
"error": "Error",
|
||||
"roomLocked": "Aquesta conversacion es verrolhada. Lo nòu-venguts devon aver lo ligam e lo senhal per participar.",
|
||||
"addPassword": "Apondre un senhal",
|
||||
"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.",
|
||||
"bridgeUnavailable": "Lo pont de visioconferéncia Jitsi es indisponible pel moment. Ensajatz tornamai pus tard !",
|
||||
"jicofoUnavailable": "Lo pont de visioconferéncia Jitsi es indisponible pel moment. Ensajatz tornamai pus tard !",
|
||||
"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.",
|
||||
"conferenceDisconnectMsg": "Se tòrna connectar dins...",
|
||||
"reconnectNow": "Es a se tornar connectar ara",
|
||||
"conferenceReloadTimeLeft": "__seconds__ segondas.",
|
||||
"maxUsersLimitReached": "Lo limit pel nombre maximum de participants a la conferéncia es estat atent. La conferéncia es plena. Ensajatz tornamai pus tard !",
|
||||
"lockTitle": "Fracàs del verrolhatge",
|
||||
"lockMessage": "Impossible de verrolhar la conferéncia.",
|
||||
@@ -199,10 +226,14 @@
|
||||
"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)",
|
||||
"oops": "Ops !",
|
||||
"currentPassword": "L'actual senhal es",
|
||||
"passwordLabel": "Senhal",
|
||||
"defaultError": "Una error s'es produita",
|
||||
"passwordRequired": "Senhal requesit",
|
||||
"Ok": "D'acòrdi",
|
||||
"done": "Acabat",
|
||||
"Remove": "Suprimir",
|
||||
"removePassword": "Levar lo senhal",
|
||||
"shareVideoTitle": "Partejar una vidèo",
|
||||
"shareVideoLinkError": "Se vos plai, provesissètz un ligam Youtube foncional.",
|
||||
"removeSharedVideoTitle": "Suprimir la vidèo partejada",
|
||||
@@ -212,6 +243,7 @@
|
||||
"WaitForHostMsg": "La conferéncia <b> __ room__ </b> es pas encara començat. Se sètz l'òste, mercé de vos autentificar. Siquenon, mercé d'esperar que l'òste arribe.",
|
||||
"IamHost": "Soi l’òste",
|
||||
"Cancel": "Anullar",
|
||||
"Submit": "Validar",
|
||||
"retry": "Ensajar tornamai",
|
||||
"logoutTitle": "Desconnexion",
|
||||
"logoutQuestion": "Sètz segur que vos volètz desconnectar e arrestar la conferéncia ?",
|
||||
@@ -226,7 +258,7 @@
|
||||
"sipMsg": "Sasissètz un numèro SIP",
|
||||
"passwordCheck": "Sètz segur que volètz suprimir vòstre senhal ?",
|
||||
"passwordMsg": "Sasissètz un senhal per verrolhar la conferéncia",
|
||||
"shareLink": "Copiatz e partejatz aqueste ligam",
|
||||
"shareLink": "Partejatz lo ligam de la conversacion",
|
||||
"settings1": "Configuratz vòstra conferéncia",
|
||||
"settings2": "Los participants rejonhon la conferéncia en essent muts",
|
||||
"settings3": "Escaisses requesits<br/><br/>Sasissètz un senhal per verrolhar la conferéncia :",
|
||||
@@ -242,7 +274,8 @@
|
||||
"token": "geton",
|
||||
"tokenAuthFailedTitle": "Fracàs de l'autentificacion",
|
||||
"tokenAuthFailed": "O planhèm, sètz pas autorizat a rejónher l'apèl.",
|
||||
"displayNameRequired": "Sasissètz vòstre nom",
|
||||
"displayNameRequired": "Un nom d'afichatge es necessari",
|
||||
"enterDisplayName": "Sasissètz vòstre nom",
|
||||
"extensionRequired": "Extension requesida :",
|
||||
"firefoxExtensionPrompt": "Vos cal installar una extension Firefox per utilizar lo partiment d'ecran. Mercé ensajar tornamai aprèp l'installacion <a href='__url__'>dempuèi aqueste ligam</a> !",
|
||||
"rateExperience": "Mercés de donar una nota à vòstra experiéncia.",
|
||||
@@ -258,6 +291,7 @@
|
||||
"stopLiveStreaming": "Arrestar lo dirècte",
|
||||
"stopRecording": "Arrestar l'enregistrament",
|
||||
"doNotShowWarningAgain": "Afichar pas mai aqueste avertiment",
|
||||
"doNotShowMessageAgain": "Afichar pas mai aqueste messatge",
|
||||
"permissionDenied": "Permission Refusada",
|
||||
"screenSharingPermissionDeniedError": "Vos cal autorizar lo partatge de vòstre ecran.",
|
||||
"micErrorPresent": "I a agut una error pendent la connexion al microfòn.",
|
||||
@@ -273,9 +307,12 @@
|
||||
"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.",
|
||||
"goToStore": "Anatz sul webstore",
|
||||
"goToStore": "Anar sul webstore",
|
||||
"externalInstallationTitle": "Extension requesida :",
|
||||
"externalInstallationMsg": "Avètz d'installar nòstra extension de partiment d'ecran."
|
||||
"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"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
{
|
||||
"contactlist": "w trakcie rozmowy",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "ustawienia połączenia",
|
||||
"poweredby": "Uruchomiono",
|
||||
"feedback": "jaka jest twoja opinia ?",
|
||||
"roomUrlDefaultMsg": "otwarto twoją konferencję",
|
||||
"inviteUrlDefaultMsg": "otwarto twoją konferencję",
|
||||
"me": "to ja",
|
||||
"speaker": "głośnik",
|
||||
"raisedHand": "Chcesz się odezwać ?",
|
||||
@@ -11,27 +15,28 @@
|
||||
"defaultLink": "np. _url_",
|
||||
"callingName": "_nazwa_",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
"androidGrantPermissions": "",
|
||||
"react-nativeGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>Allow</i></b> przycisk",
|
||||
"chromeGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>Allow</i></b> przycisk",
|
||||
"androidGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>Allow</i></b> przycisk",
|
||||
"firefoxGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>Share Selected Device</i></b> przycisk",
|
||||
"operaGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>Allow</i></b> przycisk",
|
||||
"iexplorerGrantPermissions": "",
|
||||
"iexplorerGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>OK</i></b> przycisk",
|
||||
"safariGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu naciskając <b><i>OK</i></b> przycisk",
|
||||
"nwjsGrantPermissions": "wyraź zgodę na użycie kamery i mikrofonu"
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"keyboardShortcuts": "Skróty klawiaturowe:",
|
||||
"raiseHand": "Unieś rękę.",
|
||||
"pushToTalk": "naciśnij i mów",
|
||||
"toggleScreensharing": "Przełączanie pomiędzy kamerą i wspóldzieleniem ekranu",
|
||||
"toggleFilmstrip": "Pokaż lub ukryj klipy wideo",
|
||||
"toggleShortcuts": "Pokaż lub ukryj pasek pomocy.",
|
||||
"focusLocal": "Przełącz na lokalne wideo.",
|
||||
"focusRemote": "Przełącz na któreś ze zdalnych wideo.",
|
||||
"toggleChat": "Otwórz lub zamknij panel czat.",
|
||||
"mute": "Wyłącz lub włącz mikrofon.",
|
||||
"videoMute": "Start lub stop lokalne wideo."
|
||||
"keyboardShortcuts": "",
|
||||
"raiseHand": "",
|
||||
"pushToTalk": "",
|
||||
"toggleScreensharing": "",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleShortcuts": "",
|
||||
"focusLocal": "",
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
"go": "IDŹ",
|
||||
@@ -70,35 +75,45 @@
|
||||
"content": "Analizuj uczestników konferencji z łatwościa integrując dane z Piwik i Google Analitics i innymi systemami monitorującymi."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Wycisz / Pogłośnij",
|
||||
"videomute": "Kamera start / stop ",
|
||||
"videomute": "",
|
||||
"authenticate": "Uwierzytelnianie",
|
||||
"lock": "Zamknij / Otwórz salę",
|
||||
"invite": "Zaproś innych",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "Udostępniaj dokument",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "Udostępniaj wideo w Youtube",
|
||||
"sharescreen": "Udostępnij ekran",
|
||||
"fullscreen": "Otwórz / Zamknij pełny ekran",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Wykręć numer SIP",
|
||||
"Settings": "",
|
||||
"hangup": "Rozłącz",
|
||||
"Settings": "Ustawienia",
|
||||
"hangup": "",
|
||||
"login": "Zaloguj",
|
||||
"logout": "",
|
||||
"dialpad": "Wyświetl panel wybierania",
|
||||
"logout": "Wyloguj",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "Współdzielone wideo zostało wyciszone i <br/> możesz zacząć rozmawiać z innymi.",
|
||||
"micMutedPopup": "Mikrofon został wyłączony i <br/> możesz spokojnie konsumować współdzielone wideo",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "Nie możesz pogłośnić audio podczas współużytkowania wideo",
|
||||
"cameraDisabled": "Kamera nie jest dostępna",
|
||||
"micDisabled": "Mikrofon nie jest dostępny",
|
||||
"filmstrip": "",
|
||||
"raiseHand": "Podnieś rękę chcąc zabrać głos"
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Otwórz / Zamknij Czat",
|
||||
"filmstrip": "Pokaż / Ukryj klipy wideo",
|
||||
"contactlist": "Otwórz / Zamknij spis kontaktów"
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -126,21 +141,23 @@
|
||||
"setPasswordLabel": "Zamknij salę konferencyjną z hasłem"
|
||||
},
|
||||
"profile": {
|
||||
"title": "PROFIL",
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "Podaj swoją wyświetlaną nazwę",
|
||||
"setEmailLabel": "Ustaw email swojego gravatara"
|
||||
"setEmailLabel": "Ustaw email swojego gravatara",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Kliknij <br/>celem edycji swojej nazwy",
|
||||
"moderator": "Gospodarz <br/>tej konferencji",
|
||||
"videomute": "Uczestnik <br/>wyłączyl kamerę",
|
||||
"mute": "Uczestnik ma wyciszone audio",
|
||||
"kick": "Kick out",
|
||||
"kick": "Spadaj!",
|
||||
"muted": "Wyciszony",
|
||||
"domute": "Wyciszenie",
|
||||
"flip": "Odwrócenie"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Szybkość transmisji:",
|
||||
"packetloss": "Strata pakietów:",
|
||||
"resolution": "Rozdzielczość:",
|
||||
@@ -178,20 +195,30 @@
|
||||
"raisedHand": "Możesz mówić."
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Ocho! Zostałeś wyproszony z konferencji!",
|
||||
"popupError": "Twoja przeglądarka blokuje wyskakujące okienka z tej witryny. Proszę, zmień w ustawieniach przeglądarki.",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Ta konwersacja aktualnie jest zabezpieczona hasłem. Tylko gospodarz konferencji może zakładać hasło.",
|
||||
"passwordError2": "Ta rozmowa nie jest zabezpieczona hasłem. Tylko gospodarz konferencji może ustanowić hasło zabezpieczające.",
|
||||
"connectError": "Ocho! Cos poszło nie tak, nie można podłaczyć się do tej konferencji.",
|
||||
"connectErrorWithMsg": "Ocho! Coś poszło nie tak i nie można podłączyć się do tej konferencji:_msg_",
|
||||
"connecting": "",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Nawiązywanie połączenia",
|
||||
"copy": "Kopiuj",
|
||||
"error": "",
|
||||
"error": "Błąd",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Błąd podczas rozpoznania rozszerzenia wspóldzielenia ekranu.",
|
||||
"failtoinstall": "Instalacja współdzielenia ekranu nie powiodła się.",
|
||||
"failedpermissions": "Brak akceptacji dla użycia kamery i mikrofonu",
|
||||
"bridgeUnavailable": "Jitsi Videobridge aktualnie jest niedostępne. Proszę, spróbuj później!",
|
||||
"jicofoUnavailable": "Jicofo jest aktualnie niedostępne. Proszę, spróbuj później!",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "Osiągnięto max liczbę uczestników konferencji. Proszę spróbuj później! ",
|
||||
"lockTitle": "Nie powiodło się zabezpieczenie konferencji",
|
||||
"lockMessage": "Zabezpieczenie konferencji nie powiodło się.",
|
||||
@@ -203,10 +230,14 @@
|
||||
"SLDFailure": "Ocho! Coś poszło nie tak i nie można wyciszyć! (SLD Failure)",
|
||||
"SRDFailure": "Ocho! Coś poszło nie tak i nie można zatrzymać wideo! (SRD Failure)",
|
||||
"oops": "Ups",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Wystąpił jakiś błąd",
|
||||
"passwordRequired": "Wymagane hasło",
|
||||
"Ok": "Ok",
|
||||
"done": "",
|
||||
"Remove": "Usuń",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "Współdziel wideo",
|
||||
"shareVideoLinkError": "Podaj proszę prawidłowy link youtube.",
|
||||
"removeSharedVideoTitle": "Usuń wideo współdzielone",
|
||||
@@ -216,6 +247,7 @@
|
||||
"WaitForHostMsg": "Konferencja <b>_room_</b> jeszcze nie wystartowała. Jeśli jesteś gospodarzem podaj dane autentykacji. Jeśli nie czekaj na gospodarza.",
|
||||
"IamHost": "Jestem gospodarzem",
|
||||
"Cancel": "Anuluj",
|
||||
"Submit": "",
|
||||
"retry": "Ponów",
|
||||
"logoutTitle": "Wyloguj",
|
||||
"logoutQuestion": "Na pewno chcesz się wylogować i zakończyć konferencję?",
|
||||
@@ -224,13 +256,13 @@
|
||||
"joinAgain": "Ponownie przystąp",
|
||||
"Share": "Współdziel",
|
||||
"Save": "Zapisz",
|
||||
"recording": "",
|
||||
"recording": "Nagrywanie",
|
||||
"recordingToken": "Proszę podać token nagrywania",
|
||||
"Dial": "Dzwoń",
|
||||
"sipMsg": "Podaj numer SIP",
|
||||
"passwordCheck": "Czy na pewno chcesz usunąć swoje hasło ?",
|
||||
"passwordMsg": "Podaj hasło aby zabezpieczyć salę konferencyjną",
|
||||
"shareLink": "Skopiuj i udostępnij ten link",
|
||||
"shareLink": "",
|
||||
"settings1": "Skonfiguruj swoją konferencję",
|
||||
"settings2": "Wyciszenie współuczestników",
|
||||
"settings3": "Wymagane nicki <br/><br/>Wprowadź hasło dla zabezpieczenia sali konferencyjnej:",
|
||||
@@ -246,7 +278,8 @@
|
||||
"token": "token",
|
||||
"tokenAuthFailedTitle": "Problem uwierzytelnienia",
|
||||
"tokenAuthFailed": "Przepraszam, ale nie jesteś upoważniony do uczestnictwa w tym połączeniu",
|
||||
"displayNameRequired": "Wprowadź swoją nazwę użytkownika",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "Wprowadź swoją nazwę użytkownika",
|
||||
"extensionRequired": "Wymagane jest rozszerzenie:",
|
||||
"firefoxExtensionPrompt": "Potrzebujesz zainstalować rozszerzenie firefox aby móc współdzielić ekran. Spróbuj ponownie później <a href='__url__'>weź z</a>!",
|
||||
"rateExperience": "Oceń proszę swoje doświadczenia z konferencji.",
|
||||
@@ -254,7 +287,7 @@
|
||||
"feedbackQuestion": "Powiedz nam o twoim połączeniu!",
|
||||
"thankYou": "Dziękujemy Ci za używanie _appName_!",
|
||||
"sorryFeedback": "Przykro nam to słyszeć. Czy możesz powiedzieć więcej na ten temat?",
|
||||
"liveStreaming": "",
|
||||
"liveStreaming": "Strumień live",
|
||||
"streamKey": "Nazwa strumienia/klucz",
|
||||
"startLiveStreaming": "Uruchom strumień live",
|
||||
"stopStreamingWarning": "Czy jesteś pewny, że chcesz zatrzymać ten strumień live?",
|
||||
@@ -262,6 +295,7 @@
|
||||
"stopLiveStreaming": "Zatrzymaj transmisję live",
|
||||
"stopRecording": "Zatrzymaj nagrywanie",
|
||||
"doNotShowWarningAgain": "Nie pokazuj tego ostrzeżenia ponownie",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "Brak uprawnień",
|
||||
"screenSharingPermissionDeniedError": "Nie posiadasz uprawnień do współdzielenia ekranu.",
|
||||
"micErrorPresent": "Wystąpił błąd w dostępie do mikrofonu.",
|
||||
@@ -279,7 +313,10 @@
|
||||
"cameraNotSendingData": "Nie możemy mieć dostępu do twojej kamery. Sprawdź czy inna aplikacja nie używa twojej kamery, wybierz inne urządzenie lub ponownie uruchom aplikację.",
|
||||
"goToStore": "Idź do sklepu",
|
||||
"externalInstallationTitle": "Wymagane rozszerzenie",
|
||||
"externalInstallationMsg": "Zainstaluj rozszerzenie naszego współdzielenia ekranu."
|
||||
"externalInstallationMsg": "Zainstaluj rozszerzenie naszego współdzielenia ekranu.",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Wyciszenie"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
@@ -326,7 +363,7 @@
|
||||
"on": "Nagrywanie",
|
||||
"off": "Nagrywanie zatrzymane",
|
||||
"failedToStart": "Nagrywanie nie jest możliwe",
|
||||
"buttonTooltip": "Nagrywanie start / stop",
|
||||
"buttonTooltip": "",
|
||||
"error": "Nagranie się nie powiodło. Proszę, spróbuj ponownie.",
|
||||
"unavailable": "Serwis nagrywania jest aktualnie niedostępny. Proszę, spróbować później."
|
||||
},
|
||||
@@ -336,7 +373,7 @@
|
||||
"off": "Strumieniowanie live zastopowane",
|
||||
"unavailable": "Strumieniowanie live aktualnie jest niedostepne. Proszę spróbować później.",
|
||||
"failedToStart": "Strumieniowanie live nie powiodło się",
|
||||
"buttonTooltip": "Strumieniowanie live start / stop",
|
||||
"buttonTooltip": "",
|
||||
"streamIdRequired": "Proszę podaj id strumieniowania aby uruchomić live.",
|
||||
"error": "Strumieniowanie live nie powiodło się. Spróbuj później.",
|
||||
"busy": "Wszystkie nagrywarki są zajęte. Proszę, sprawdź ponownie później."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"contactlist": "Participantes (__pcount__)",
|
||||
"addParticipants": "",
|
||||
"addParticipants": "Compartilhar o link",
|
||||
"roomLocked": "Visitantes precisam digitar uma senha",
|
||||
"roomUnlocked": "Qualquer um com o link pode entrar",
|
||||
"passwordSetRemotely": "Definido por outro participante",
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "ZOZNAM KONTAKTOV",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Nastavenie spojenia",
|
||||
"poweredby": "založené na",
|
||||
"downloadlogs": "Stiahnúť logy",
|
||||
"feedback": "",
|
||||
"roomUrlDefaultMsg": "Vaša konferencia bola práve vytvorená...",
|
||||
"participant": "Účastník",
|
||||
"inviteUrlDefaultMsg": "Vaša konferencia bola práve vytvorená...",
|
||||
"me": "ja",
|
||||
"speaker": "Rečník",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "napr. __url__",
|
||||
"calling": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
@@ -33,6 +35,7 @@
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Zistite o Vašich uživateľoch viac ľahko cez integráciu s Piwik, Google Analytics a inych monitorovacích a štatistických nástrojov."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Vypnúť / Zapnúť mikrofón",
|
||||
"videomute": "Vypnúť / Zapnúť kameru",
|
||||
"videomute": "",
|
||||
"authenticate": "Overiť",
|
||||
"lock": "Zamknúť / Odomknúť miestnosť",
|
||||
"invite": "Pozvať ďalšich",
|
||||
"chat": "Otvoriť / zatvoriť chat",
|
||||
"etherpad": "Zdieľať dokument",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "Zdieľať prac. plochu",
|
||||
"fullscreen": "Zapnúť / Vypnúť plnú obrazovku",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Zavolať SIP číslo",
|
||||
"Settings": "Nastavenia",
|
||||
"hangup": "Zložiť",
|
||||
"hangup": "",
|
||||
"login": "Prihlásiť",
|
||||
"logout": "Odhlásiť",
|
||||
"dialpad": "Zobraziť číselník",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": ""
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Otvoriť / zatvoriť chat",
|
||||
"filmstrip": "Zobraziť / skryť účastníkov",
|
||||
"contactlist": "Otvoriť / zatvoriť zoznam kontaktov"
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,7 +123,7 @@
|
||||
"messagebox": "Napíšte text..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "NASTAVENIA",
|
||||
"title": "Nastavenia",
|
||||
"update": "Nastaviť",
|
||||
"name": "Meno",
|
||||
"startAudioMuted": "",
|
||||
@@ -119,12 +134,22 @@
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"avatarUrl": ""
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Kliknite pre zmenu<br/>Vášho mena",
|
||||
"moderator": "Majiteľ tejto<br/>konferencie",
|
||||
"videomute": "Učastník s<br/>vypnutou kamerou",
|
||||
"videomute": "",
|
||||
"mute": "Učastník s<br/>vypnutým mikrofónom",
|
||||
"kick": "Vyhodiť",
|
||||
"muted": "Vypnutý mikrofón",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Prenos. rýchlosť",
|
||||
"packetloss": "Strata packetov:",
|
||||
"resolution": "Rozlíšenie:",
|
||||
@@ -169,34 +195,49 @@
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Boli ste vyhodený z konferencie!",
|
||||
"popupError": "Váš prehliadač blokuje vyskakovacie okná pre túto stránku. Prosím, povoľte si vyskakovacie okná a skúste to znova.",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Táto diskusia je momentálne zabezpečená heslom. Iba majiteľ tejto konferencie može nastaviť heslo.",
|
||||
"passwordError2": "Táto diskusia nie je momentálne zabezpečená heslom. Iba majiteľ tejto konferencie može nastaviť heslo.",
|
||||
"connectError": "Oops! Niečo je zle a nemožem sa pripojiť do konferencie.",
|
||||
"connectErrorWithMsg": "Oops! Niečo je zle a nemožem sa pripojiť do konferencie. Správa: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Pripájam",
|
||||
"copy": "",
|
||||
"error": "Chyba",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Chyba pri pokuse najsť rozšírenie pre zdieľanie prac. plochy",
|
||||
"failtoinstall": "Zlyhanie pri inštalácií rozšírenia pre zdieľanie prac. plochy",
|
||||
"failedpermissions": "Zlyhanie pri pokuse získať prístup k lokálnemu mikrofonu alebo kamere.",
|
||||
"bridgeUnavailable": "Jitsi Videobridge je momentálne nedostupné. Prosím, skúste neskor!",
|
||||
"jicofoUnavailable": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "Zabezpečenie zlyhalo",
|
||||
"lockMessage": "Zlyhanie pri pokuse o zabezpečenie konferencie.",
|
||||
"warning": "Upozornenie",
|
||||
"passwordNotSupported": "Heslá pre miestnosti nie sú momentálne podporované.",
|
||||
"sorry": "Prepáčte",
|
||||
"internalError": "Vnútorná aplikačná chyba [setRemoteDescription]",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "Nie je možne prepnúť video stream.",
|
||||
"SLDFailure": "Oops! Niečo sa stalo a nie je možne vypnúť mikrofón! (Chyba SLD)",
|
||||
"SRDFailure": "Oops! Niečo sa stalo a nie je možne vypnúť kameru! (Chyba SLD)",
|
||||
"oops": "Oops!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Nastala neznáma chyba",
|
||||
"passwordRequired": "Je potrebné heslo",
|
||||
"Ok": "Ok",
|
||||
"done": "",
|
||||
"Remove": "Odstrániť",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"removeSharedVideoTitle": "",
|
||||
@@ -206,6 +247,7 @@
|
||||
"WaitForHostMsg": "Konferencia <b>__room__ </b> ešte nezačala. Ak ste hostiteľ Vy, overte sa. Inak čakajte kým sa prihlási hostiteľ.",
|
||||
"IamHost": "Ja som hostiteľ",
|
||||
"Cancel": "Zrušiť",
|
||||
"Submit": "",
|
||||
"retry": "Skúsiť znova",
|
||||
"logoutTitle": "Odhlásiť",
|
||||
"logoutQuestion": "Ste si istý, že sa chcete odhlásiť a skončit konferenciu?",
|
||||
@@ -220,25 +262,28 @@
|
||||
"sipMsg": "Vložte SIP číslo",
|
||||
"passwordCheck": "Ste si istý, že chcete odstrániť heslo?",
|
||||
"passwordMsg": "Zadajte heslo pre zabezpečenie miestnosti",
|
||||
"Invite": "Pozvať",
|
||||
"shareLink": "Zdieľajte tento odkaz s každým koho chcete pozvať",
|
||||
"shareLink": "",
|
||||
"settings1": "Nastavte Vašu konferenciu",
|
||||
"settings2": "Učastníkov pripájať stíšených",
|
||||
"settings3": "Vyžaduj meno<br/><br/>Zadaj heslo pre zabezpečenie miestnosti:",
|
||||
"yourPassword": "Vaše heslo",
|
||||
"yourPassword": "",
|
||||
"Back": "Späť",
|
||||
"serviceUnavailable": "Služba nedostupná",
|
||||
"gracefulShutdown": "Naša služba je momentálne vypnutá pre údržbu. Skúste to neskor.",
|
||||
"Yes": "Áno",
|
||||
"reservationError": "Systemová chyba rezervácie",
|
||||
"reservationErrorMsg": "Chyba: __code__, správa: __msg__",
|
||||
"password": "heslo",
|
||||
"password": "",
|
||||
"userPassword": "uživateľské heslo",
|
||||
"token": "token",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "",
|
||||
"extensionRequired": "Potrebné rozšírenie:",
|
||||
"firefoxExtensionPrompt": "Potrebujete nainštalovať rozšírenie do Firefoxu pre možnosť zdieľať prac. plochu. Prosím, skúste znovu po nainštalovaní z: <a href='__url__'>",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "",
|
||||
"sorryFeedback": "",
|
||||
@@ -250,6 +295,7 @@
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
@@ -262,7 +308,15 @@
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": ""
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Vypnút mikrofón"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": [
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "STIKI",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Nastavitve povezave",
|
||||
"poweredby": "poganja",
|
||||
"downloadlogs": "Shrani zapis",
|
||||
"feedback": "",
|
||||
"roomUrlDefaultMsg": "Ustvarjanje vaše konference ...",
|
||||
"participant": "Udeleženec",
|
||||
"inviteUrlDefaultMsg": "Ustvarjanje vaše konference ...",
|
||||
"me": "jaz",
|
||||
"speaker": "Govornik",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "npr. __url__",
|
||||
"calling": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
@@ -33,6 +35,7 @@
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Spoznajte svoje uporabnike z enostavno integracijo v Piwik, Google Analytics ter druge sisteme za nadzor uporabe in statistiko."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Utišaj / Povrni glasnost",
|
||||
"videomute": "Zaženi / Ustavi kamero",
|
||||
"videomute": "",
|
||||
"authenticate": "Overi",
|
||||
"lock": "Zakleni / Odkleni sobo",
|
||||
"invite": "Povabite ostale",
|
||||
"chat": "Odpri / zapri klepetalnico",
|
||||
"etherpad": "Dokument v skupni rabi",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "Zaslon v souporabi",
|
||||
"fullscreen": "Vklopi / Izklopi celozaslonski način",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Pokliči številko SIP",
|
||||
"Settings": "Nastavitve",
|
||||
"hangup": "Odloži",
|
||||
"hangup": "",
|
||||
"login": "Prijava",
|
||||
"logout": "Odjava",
|
||||
"dialpad": "Pokaži številčnico",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": ""
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Odpri / zapri klepetalnico",
|
||||
"filmstrip": "Pokaži / Skrij filmski trak",
|
||||
"contactlist": "Odpri / Zapri stike"
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,7 +123,7 @@
|
||||
"messagebox": "Vnesite besedilo ..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "NASTAVITVE",
|
||||
"title": "Nastavitve",
|
||||
"update": "Posodobi",
|
||||
"name": "Ime",
|
||||
"startAudioMuted": "",
|
||||
@@ -119,12 +134,22 @@
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"avatarUrl": ""
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Kliknite, da spremenite<br/>svoje ime",
|
||||
"moderator": "Lastnik<br/>konference",
|
||||
"videomute": "Udeleženec je<br/>izključil kamero.",
|
||||
"videomute": "",
|
||||
"mute": "Udeleženec je utišan",
|
||||
"kick": "Izženi",
|
||||
"muted": "Utišan",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Bitna hitrost:",
|
||||
"packetloss": "Izgubljeni paketi:",
|
||||
"resolution": "Ločljivost:",
|
||||
@@ -173,34 +199,49 @@
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Ojej! Izgnali so vas iz srečanja!",
|
||||
"popupError": "",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "",
|
||||
"passwordError2": "",
|
||||
"connectError": "Ups! Nekaj je narobe in se ni bilo mogoče povezati s konferenco.",
|
||||
"connectErrorWithMsg": "Ups! Nekaj je narobe in se ni bilo mogoče povezati s konferenco: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Povezovanje",
|
||||
"copy": "",
|
||||
"error": "Napaka",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Napaka pri zaznavanju razširitve za skupno uporabo namizja.",
|
||||
"failtoinstall": "Razširitve za skupno uporabo namizja ni bilo mogoče namestiti",
|
||||
"failedpermissions": "Ni bilo mogoče pridobiti dovoljenja za uporabo lokalnega mikrofona ali kamere.",
|
||||
"bridgeUnavailable": "Jitsi Videobridge trenutno ni na razpolago. Prosim poskusite kasneje!",
|
||||
"jicofoUnavailable": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "Zaklepanje ni uspelo",
|
||||
"lockMessage": "",
|
||||
"warning": "Opozorilo",
|
||||
"passwordNotSupported": "Trenutno ni mogoče zakleniti sobe z geslom.",
|
||||
"sorry": "Oprostite",
|
||||
"internalError": "Notranja napaka [setRemoteDescription]",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "Ni mogoče preklopiti video pretoka.",
|
||||
"SLDFailure": "Ups! Nekaj je narobe in zvoka se ne da utišati! (Napaka SLD)",
|
||||
"SRDFailure": "Ups! Nekaj je narobe in slike ni mogoče ustaviti! (Napaka SRD)",
|
||||
"oops": "Ups!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Prišlo je do neke napake",
|
||||
"passwordRequired": "Potrebno je geslo",
|
||||
"Ok": "V redu",
|
||||
"done": "",
|
||||
"Remove": "Odstrani",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"removeSharedVideoTitle": "",
|
||||
@@ -210,6 +251,7 @@
|
||||
"WaitForHostMsg": "Ta konferenca <b>__room__ </b> se še ni začela. V primeru, da ste vi gostitelj se prosim overite. Drugače počakajte prosim na prihod gostitelja.",
|
||||
"IamHost": "Jaz sem gostitelj",
|
||||
"Cancel": "Prekliči",
|
||||
"Submit": "",
|
||||
"retry": "Poskusi ponovno",
|
||||
"logoutTitle": "Odjava",
|
||||
"logoutQuestion": "Ali se res želite odjaviti in prekiniti konferenco?",
|
||||
@@ -224,25 +266,28 @@
|
||||
"sipMsg": "Vnesite številko SIP",
|
||||
"passwordCheck": "Ali res želite odstraniti geslo?",
|
||||
"passwordMsg": "Nastavite geslo za zaklepanje sobe",
|
||||
"Invite": "Povabi",
|
||||
"shareLink": "To povezavo pošljite vsem, ki jih želite povabiti",
|
||||
"shareLink": "",
|
||||
"settings1": "Nastavite svojo konferenco",
|
||||
"settings2": "Utišaj udeležence ob pristopu",
|
||||
"settings3": "Zahtevaj vzdevke<br/><br/>Nastavi geslo za zaklep sobe:",
|
||||
"yourPassword": "vaše geslo",
|
||||
"yourPassword": "",
|
||||
"Back": "Nazaj",
|
||||
"serviceUnavailable": "Storitev ni na voljo",
|
||||
"gracefulShutdown": "Storitev trenutno ni na voljo zaradi vzdrževanja. Poskusite ponovno kasneje.",
|
||||
"Yes": "Da",
|
||||
"reservationError": "Napaka v sistemu rezervacije",
|
||||
"reservationErrorMsg": "Koda napake: __code__, sporočilo: __msg__",
|
||||
"password": "geslo",
|
||||
"password": "",
|
||||
"userPassword": "uporabniško geslo",
|
||||
"token": "žeton",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "",
|
||||
"extensionRequired": "",
|
||||
"firefoxExtensionPrompt": "",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "",
|
||||
"sorryFeedback": "",
|
||||
@@ -254,6 +299,7 @@
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
@@ -266,7 +312,15 @@
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": ""
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Utišaj"
|
||||
},
|
||||
"email": {
|
||||
"sharedKey": "",
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "KONTAKTLISTA",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Anslutningsinställningar",
|
||||
"poweredby": "drivs av",
|
||||
"downloadlogs": "Hämta loggar",
|
||||
"feedback": "Ge oss din feedback",
|
||||
"roomUrlDefaultMsg": "Din konferens håller på att skapas...",
|
||||
"participant": "Deltagare",
|
||||
"inviteUrlDefaultMsg": "Din konferens håller på att skapas...",
|
||||
"me": "jag",
|
||||
"speaker": "Talare",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "t ex. __url__",
|
||||
"calling": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
@@ -33,6 +35,7 @@
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Studera användningsmönster genom enkel integration med Piwik, Google Analytics och andra monitorerings- och statistiksystem."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Slå av/på ljud",
|
||||
"videomute": "Starta / stoppa kamera",
|
||||
"videomute": "",
|
||||
"authenticate": "Autentisera",
|
||||
"lock": "Lås / lås upp rum",
|
||||
"invite": "Bjud in andra",
|
||||
"chat": "Öppna / stäng chat",
|
||||
"etherpad": "Delat dokument",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "Dela skärm",
|
||||
"fullscreen": "Aktivera / avaktivera helskärm",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "Ring SIP-nummer",
|
||||
"Settings": "Inställningar",
|
||||
"hangup": "Lägg på",
|
||||
"hangup": "",
|
||||
"login": "Logga in",
|
||||
"logout": "Logga ut",
|
||||
"dialpad": "Visa knappsats",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": ""
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Öppna / stäng chat",
|
||||
"filmstrip": "Visa / dölj filmremsa",
|
||||
"contactlist": "Öppna / stäng kontaktlista"
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,7 +123,7 @@
|
||||
"messagebox": "Skriv text..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "INSTÄLLNINGAR",
|
||||
"title": "Inställningar",
|
||||
"update": "Uppdatera",
|
||||
"name": "Namn",
|
||||
"startAudioMuted": "",
|
||||
@@ -119,12 +134,22 @@
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"avatarUrl": ""
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Klicka här för att <br/>redigera namn",
|
||||
"moderator": "Ägaren av den<br/>här konferensen",
|
||||
"videomute": "Deltagaren har<br/>stoppat kameran.",
|
||||
"videomute": "",
|
||||
"mute": "Deltagaren har avstängd mikrofon",
|
||||
"kick": "Sparka ut",
|
||||
"muted": "Tystad",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Bithastighet:",
|
||||
"packetloss": "Paketförluster:",
|
||||
"resolution": "Upplösning:",
|
||||
@@ -165,34 +191,49 @@
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Aj! Du har sparkats ur mötet!",
|
||||
"popupError": "Din webbläsare blockerar popup-fönster från den här webbplatsen. Vänligen aktivera popups i din webbläsares säkerhetsinställningar och försök igen.",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "Den här konversationen är för närvarande skyddad av lösenord. Bara ägaren till konferensen kan sätta ett lösenord.",
|
||||
"passwordError2": "Den här konversationen är för närvarande inte skyddad av ett lösenord. Bara ägaren till konferensen kan sätta ett lösenord.",
|
||||
"connectError": "Ojdå! Något gick fel och vi kunde inte ansluta till konferensen.",
|
||||
"connectErrorWithMsg": "Ojdå! Något gick fel och vi kunde inte ansluta till konferensen: __msg__",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "Ansluter",
|
||||
"copy": "",
|
||||
"error": "Fel",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Fel när skrivbordsdelnings-tillägget försökte hittas.",
|
||||
"failtoinstall": "Misslyckades att installera skrivbordsdelnings-tillägget",
|
||||
"failedpermissions": "Misslyckades med att få tillåtelse att använda lokal mikrofon och/eller kamera.",
|
||||
"bridgeUnavailable": "Jitsi Videobridge är för tillfället inte tillgänglig. Vänligen försök senare!",
|
||||
"jicofoUnavailable": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "Låsning misslyckades",
|
||||
"lockMessage": "Misslyckades att låsa konferensen.",
|
||||
"warning": "Varning",
|
||||
"passwordNotSupported": "Rumslösenord stöds inte för tillfället.",
|
||||
"sorry": "Tyvärr",
|
||||
"internalError": "Internt applikationsfel [setRemoteDescription]",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "Kunde inte byta videoström.",
|
||||
"SLDFailure": "Ojdå! Något gick fel och vi kunde inte stänga av mikrofonen! (SLD Failure)",
|
||||
"SRDFailure": "Ojdå! Något gick fel och vi kunde inte stänga av videokameran! (SRD Failure)",
|
||||
"oops": "Ojdå!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Det uppstod någon typ av fel",
|
||||
"passwordRequired": "Lösenord krävs",
|
||||
"Ok": "Ok",
|
||||
"done": "",
|
||||
"Remove": "Ta bort",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"removeSharedVideoTitle": "",
|
||||
@@ -202,6 +243,7 @@
|
||||
"WaitForHostMsg": "Konferensen <b>__room__</b> har inte startat än. Om du är värd för konferensen, vänligen logga in. Annars, vänta kvar på att konferensvärden kommer.",
|
||||
"IamHost": "Jag är värd",
|
||||
"Cancel": "Avbryt",
|
||||
"Submit": "",
|
||||
"retry": "Försök igen",
|
||||
"logoutTitle": "Logga ut",
|
||||
"logoutQuestion": "Är du säker på att du vill logga ut och stoppa konferensen?",
|
||||
@@ -216,26 +258,29 @@
|
||||
"sipMsg": "Skriv in SIP-nummer",
|
||||
"passwordCheck": "Är du säker på att du vill ta bort ditt lösenord?",
|
||||
"passwordMsg": "Sätt ett lösenord för att låsa ditt rum",
|
||||
"Invite": "Bjud in",
|
||||
"shareLink": "Dela den här länken med alla du vill bjuda in",
|
||||
"shareLink": "",
|
||||
"settings1": "Anpassa din konferens",
|
||||
"settings2": "Deltagare går med med mikrofonen avstängd",
|
||||
"settings3": "Kräver användarnamn<br/><br/>Sätt ett lösenord för att låsa ditt rum:",
|
||||
"yourPassword": "ditt lösenord",
|
||||
"yourPassword": "",
|
||||
"Back": "Tillbaka",
|
||||
"serviceUnavailable": "Tjänsten otillgänglig",
|
||||
"gracefulShutdown": "Vår tjänst är för tillfället nedstängd för underhåll. Vänligen försök senare.",
|
||||
"Yes": "Ja",
|
||||
"reservationError": "Fel i reservationssystemet",
|
||||
"reservationErrorMsg": "Felkod: __code__, meddelande: __msg__",
|
||||
"password": "lösenord",
|
||||
"password": "",
|
||||
"userPassword": "användarlösenord",
|
||||
"token": "token",
|
||||
"tokenAuthFailed": "Misslyckades att autentisera mot XMPP-server: ogiltig token",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "",
|
||||
"extensionRequired": "Tillägg krävs:",
|
||||
"firefoxExtensionPrompt": "Du behöver installera ett Firefox-tillägg för att kunna använda skärmdelning. Vänligen försök igen efter att du <a href='__url__'>hämtat det här</a>!",
|
||||
"feedbackQuestion": "Hur upplevde du samtalet?",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "Tack för att du använder __appName__!",
|
||||
"sorryFeedback": "Tråkigt att du känner så. Vill du berätta mer?",
|
||||
"liveStreaming": "",
|
||||
@@ -246,6 +291,7 @@
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
@@ -258,7 +304,15 @@
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": ""
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Tysta"
|
||||
},
|
||||
"\u0005dialog": {},
|
||||
"email": {
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"contactlist": "KİŞİ LİSTESİ",
|
||||
"contactlist": "",
|
||||
"addParticipants": "",
|
||||
"roomLocked": "",
|
||||
"roomUnlocked": "",
|
||||
"passwordSetRemotely": "",
|
||||
"connectionsettings": "Bağlantı Ayarları",
|
||||
"poweredby": "Gücünün kaynağı",
|
||||
"downloadlogs": "Günlükleri indir",
|
||||
"feedback": "",
|
||||
"roomUrlDefaultMsg": "",
|
||||
"participant": "",
|
||||
"inviteUrlDefaultMsg": "",
|
||||
"me": "",
|
||||
"speaker": "",
|
||||
"raisedHand": "",
|
||||
"defaultNickname": "",
|
||||
"defaultLink": "",
|
||||
"calling": "",
|
||||
"callingName": "",
|
||||
"userMedia": {
|
||||
"react-nativeGrantPermissions": "",
|
||||
"chromeGrantPermissions": "",
|
||||
@@ -33,6 +35,7 @@
|
||||
"focusRemote": "",
|
||||
"toggleChat": "",
|
||||
"mute": "",
|
||||
"fullScreen": "",
|
||||
"videoMute": ""
|
||||
},
|
||||
"welcomepage": {
|
||||
@@ -72,33 +75,45 @@
|
||||
"content": "Piwik, Google Analytics ve diğer kullanım izleme ve istatistik sistemleri ile kolay tümleştirmeyle kullanıcılar hakkında bilgi edinin."
|
||||
}
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": "",
|
||||
"title": ""
|
||||
},
|
||||
"suspendedoverlay": {
|
||||
"title": "",
|
||||
"rejoinKeyTitle": ""
|
||||
},
|
||||
"toolbar": {
|
||||
"mute": "Sessiz / Sesli",
|
||||
"videomute": "Kamera başlat / durdur",
|
||||
"videomute": "",
|
||||
"authenticate": "Kimlik doğrula",
|
||||
"lock": "Odayı kilitle / kilit aç",
|
||||
"invite": "Arkadaşlarını davet et",
|
||||
"chat": "Sohbeti aç / kapa",
|
||||
"etherpad": "Paylaşımlı belge",
|
||||
"lock": "",
|
||||
"invite": "",
|
||||
"chat": "",
|
||||
"etherpad": "",
|
||||
"sharedvideo": "",
|
||||
"sharescreen": "Ekran paylaş",
|
||||
"fullscreen": "Tam Ekrana Gir / Çık",
|
||||
"sharescreen": "",
|
||||
"fullscreen": "",
|
||||
"sip": "SIP numara ara",
|
||||
"Settings": "Ayarlar",
|
||||
"hangup": "Kapat",
|
||||
"hangup": "",
|
||||
"login": "Oturum aç",
|
||||
"logout": "Oturum kapat",
|
||||
"dialpad": "",
|
||||
"sharedVideoMutedPopup": "",
|
||||
"micMutedPopup": "",
|
||||
"talkWhileMutedPopup": "",
|
||||
"unableToUnmutePopup": "",
|
||||
"cameraDisabled": "",
|
||||
"micDisabled": ""
|
||||
"micDisabled": "",
|
||||
"filmstrip": "",
|
||||
"profile": "",
|
||||
"raiseHand": ""
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Sohbeti aç / kapa",
|
||||
"filmstrip": "Film şeridini göster / gizle",
|
||||
"contactlist": "Kişi listesi aç / kapa"
|
||||
"filmstrip": "",
|
||||
"contactlist": ""
|
||||
},
|
||||
"chat": {
|
||||
"nickname": {
|
||||
@@ -108,7 +123,7 @@
|
||||
"messagebox": "Metin girin..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "AYARLAR",
|
||||
"title": "Ayarlar",
|
||||
"update": "Güncelle",
|
||||
"name": "Ad",
|
||||
"startAudioMuted": "",
|
||||
@@ -119,12 +134,22 @@
|
||||
"followMe": "",
|
||||
"noDevice": "",
|
||||
"noPermission": "",
|
||||
"avatarUrl": ""
|
||||
"cameraAndMic": "",
|
||||
"moderator": "",
|
||||
"password": "",
|
||||
"audioVideo": "",
|
||||
"setPasswordLabel": ""
|
||||
},
|
||||
"profile": {
|
||||
"title": "",
|
||||
"setDisplayNameLabel": "",
|
||||
"setEmailLabel": "",
|
||||
"setEmailInput": ""
|
||||
},
|
||||
"videothumbnail": {
|
||||
"editnickname": "Görünür adınızı değiştirmek<br/>için tıkla",
|
||||
"moderator": "Bu görüşmenin<br/>sahibi",
|
||||
"videomute": "Katılımcı<br/>kamera durdurdu.",
|
||||
"videomute": "",
|
||||
"mute": "Katılımcı sessiz",
|
||||
"kick": "Kovuldu",
|
||||
"muted": "Sessiz",
|
||||
@@ -132,6 +157,7 @@
|
||||
"flip": ""
|
||||
},
|
||||
"connectionindicator": {
|
||||
"header": "",
|
||||
"bitrate": "Bit hızı:",
|
||||
"packetloss": "Paket kaybı:",
|
||||
"resolution": "Çözünürlük:",
|
||||
@@ -161,34 +187,49 @@
|
||||
"raisedHand": ""
|
||||
},
|
||||
"dialog": {
|
||||
"add": "",
|
||||
"kickMessage": "Ahhh! Görüşmeden, kavuldun!",
|
||||
"popupError": "",
|
||||
"passwordErrorTitle": "",
|
||||
"passwordError": "",
|
||||
"passwordError2": "",
|
||||
"connectError": "Amanin boo! Birşeyler ters gitti ve görüşmeye bağlanamadık.",
|
||||
"connectErrorWithMsg": "Amanin boo! Birşeyler ters gitti ve görüşmeye bağlanamadık.",
|
||||
"incorrectPassword": "",
|
||||
"connecting": "",
|
||||
"copy": "",
|
||||
"error": "Hata",
|
||||
"roomLocked": "",
|
||||
"addPassword": "",
|
||||
"createPassword": "",
|
||||
"detectext": "Ekran paylaşımı eklentisi tespit edilirken hata.",
|
||||
"failtoinstall": "Masaüstü paylaşım eklentisi yüklenemedi",
|
||||
"failedpermissions": "Yerel mikrofon ve/veya kamerayı kullanmak için izinler alınamadı.",
|
||||
"bridgeUnavailable": "Jitsi Videobridge şu anda kullanılamıyor. Daha sonra tekrar deneyiniz!",
|
||||
"jicofoUnavailable": "",
|
||||
"conferenceReloadTitle": "",
|
||||
"conferenceReloadMsg": "",
|
||||
"conferenceDisconnectTitle": "",
|
||||
"conferenceDisconnectMsg": "",
|
||||
"reconnectNow": "",
|
||||
"conferenceReloadTimeLeft": "",
|
||||
"maxUsersLimitReached": "",
|
||||
"lockTitle": "Kilitlenemedi",
|
||||
"lockMessage": "Görüşme kilitlenemedi.",
|
||||
"warning": "Uyarı",
|
||||
"passwordNotSupported": "Oda parolaları şu anda desteklenmemekte.",
|
||||
"sorry": "Üzgünüz",
|
||||
"internalError": "İç uygulama hatası [setRemoteDescription]",
|
||||
"internalErrorTitle": "",
|
||||
"internalError": "",
|
||||
"unableToSwitch": "Video akışı açılamıyor.",
|
||||
"SLDFailure": "Amanin boo! Birşeyler ters gitti ve sessize alamadık! (SLD Başarısız)",
|
||||
"SRDFailure": "Amanin boo! Birşeyler ters gitti ve videoyu durduramadık! (SRD Başarısız)",
|
||||
"oops": "Amanin boo!",
|
||||
"currentPassword": "",
|
||||
"passwordLabel": "",
|
||||
"defaultError": "Bir tür hata var",
|
||||
"passwordRequired": "Parola gerekli",
|
||||
"Ok": "Tamam",
|
||||
"done": "",
|
||||
"Remove": "Kaldır",
|
||||
"removePassword": "",
|
||||
"shareVideoTitle": "",
|
||||
"shareVideoLinkError": "",
|
||||
"removeSharedVideoTitle": "",
|
||||
@@ -198,6 +239,7 @@
|
||||
"WaitForHostMsg": "",
|
||||
"IamHost": "",
|
||||
"Cancel": "İptal",
|
||||
"Submit": "",
|
||||
"retry": "",
|
||||
"logoutTitle": "Oturum kapat",
|
||||
"logoutQuestion": "Oturumu ve görüşmeyi sonlandırmak istediğinizden emin misiniz?",
|
||||
@@ -212,12 +254,11 @@
|
||||
"sipMsg": "SIP numarası gir",
|
||||
"passwordCheck": "Parolanızı kaldırmak istediğinizden emin misiniz?",
|
||||
"passwordMsg": "Odanızı kilitlemek için bir parola koyun",
|
||||
"Invite": "Davet et",
|
||||
"shareLink": "Davet etmek istediğiniz herkesle bu bağlantıyı paylaşın",
|
||||
"shareLink": "",
|
||||
"settings1": "Görüşmenizi yapılandır",
|
||||
"settings2": "Katılımcılar sessiz katılsın",
|
||||
"settings3": "Takma adlar gerekli<br/><br/>Odanızı kitlemek için bir parola ayarlayın:",
|
||||
"yourPassword": "parolanız",
|
||||
"yourPassword": "",
|
||||
"Back": "Geri",
|
||||
"serviceUnavailable": "Hizmet kullanım dışı",
|
||||
"gracefulShutdown": "Hizmetimiz bakıp için durduruldu. Daha sonra tekrar deneyiniz.",
|
||||
@@ -227,10 +268,14 @@
|
||||
"password": "",
|
||||
"userPassword": "parolanız",
|
||||
"token": "",
|
||||
"tokenAuthFailedTitle": "",
|
||||
"tokenAuthFailed": "",
|
||||
"displayNameRequired": "",
|
||||
"enterDisplayName": "",
|
||||
"extensionRequired": "",
|
||||
"firefoxExtensionPrompt": "",
|
||||
"rateExperience": "",
|
||||
"feedbackHelp": "",
|
||||
"feedbackQuestion": "",
|
||||
"thankYou": "",
|
||||
"sorryFeedback": "",
|
||||
@@ -242,6 +287,7 @@
|
||||
"stopLiveStreaming": "",
|
||||
"stopRecording": "",
|
||||
"doNotShowWarningAgain": "",
|
||||
"doNotShowMessageAgain": "",
|
||||
"permissionDenied": "",
|
||||
"screenSharingPermissionDeniedError": "",
|
||||
"micErrorPresent": "",
|
||||
@@ -254,7 +300,15 @@
|
||||
"micUnknownError": "",
|
||||
"micPermissionDeniedError": "",
|
||||
"micNotFoundError": "",
|
||||
"micConstraintFailedError": ""
|
||||
"micConstraintFailedError": "",
|
||||
"micNotSendingData": "",
|
||||
"cameraNotSendingData": "",
|
||||
"goToStore": "",
|
||||
"externalInstallationTitle": "",
|
||||
"externalInstallationMsg": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantBody": "",
|
||||
"muteParticipantButton": "Sustur"
|
||||
},
|
||||
"\u0005dialog": {},
|
||||
"email": {
|
||||
|
||||
@@ -156,8 +156,8 @@
|
||||
"kick": "Kick out",
|
||||
"muted": "Muted",
|
||||
"domute": "Mute",
|
||||
"flip": "Flip"
|
||||
|
||||
"flip": "Flip",
|
||||
"remoteControl": "Remote control"
|
||||
},
|
||||
"connectionindicator":
|
||||
{
|
||||
@@ -316,7 +316,12 @@
|
||||
"externalInstallationMsg": "You need to install our desktop sharing extension.",
|
||||
"muteParticipantTitle": "Mute this participant?",
|
||||
"muteParticipantBody": "You won't be able to unmute them, but they can unmute themselves at any time.",
|
||||
"muteParticipantButton": "Mute"
|
||||
"muteParticipantButton": "Mute",
|
||||
"remoteControlTitle": "Remote Control",
|
||||
"remoteControlDeniedMessage": "__user__ rejected your remote control request!",
|
||||
"remoteControlAllowedMessage": "__user__ accepted your remote control request!",
|
||||
"remoteControlErrorMessage": "An error occurred while trying to request remote control permissions from __user__!",
|
||||
"remoteControlStopMessage": "The remote control session ended!"
|
||||
},
|
||||
"email":
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* global APP, getConfigParamsFromUrl */
|
||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
|
||||
/**
|
||||
* Implements API class that communicates with external api class
|
||||
@@ -56,38 +55,15 @@ function initCommands() {
|
||||
APP.conference.toggleScreenSharing.bind(APP.conference),
|
||||
"video-hangup": () => APP.conference.hangup(),
|
||||
"email": APP.conference.changeLocalEmail,
|
||||
"avatar-url": APP.conference.changeLocalAvatarUrl
|
||||
"avatar-url": APP.conference.changeLocalAvatarUrl,
|
||||
"remote-control-event": event =>
|
||||
APP.remoteControl.onRemoteControlAPIEvent(event)
|
||||
};
|
||||
Object.keys(commands).forEach(function (key) {
|
||||
postis.listen(key, args => commands[key](...args));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps the supported events and their status
|
||||
* (true it the event is enabled and false if it is disabled)
|
||||
* @type {{
|
||||
* incoming-message: boolean,
|
||||
* outgoing-message: boolean,
|
||||
* display-name-change: boolean,
|
||||
* participant-left: boolean,
|
||||
* participant-joined: boolean,
|
||||
* video-conference-left: boolean,
|
||||
* video-conference-joined: boolean
|
||||
* }}
|
||||
*/
|
||||
const events = {
|
||||
"incoming-message": false,
|
||||
"outgoing-message":false,
|
||||
"display-name-change": false,
|
||||
"participant-joined": false,
|
||||
"participant-left": false,
|
||||
"video-conference-joined": false,
|
||||
"video-conference-left": false,
|
||||
"video-ready-to-close": false
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends message to the external application.
|
||||
* @param message {object}
|
||||
@@ -95,27 +71,19 @@ const events = {
|
||||
* @param params {object} the object that will be sent as JSON string
|
||||
*/
|
||||
function sendMessage(message) {
|
||||
if(enabled)
|
||||
if(enabled) {
|
||||
postis.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the API should be enabled or not.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isEnabled () {
|
||||
function shouldBeEnabled () {
|
||||
return (typeof jitsi_meet_external_api_id === "number");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the event is enabled ot not.
|
||||
* @param name the name of the event.
|
||||
* @returns {*}
|
||||
*/
|
||||
function isEventEnabled (name) {
|
||||
return events[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends event object to the external application that has been subscribed
|
||||
* for that event.
|
||||
@@ -123,29 +91,18 @@ function isEventEnabled (name) {
|
||||
* @param object data associated with the event
|
||||
*/
|
||||
function triggerEvent (name, object) {
|
||||
if(isEventEnabled(name))
|
||||
if(enabled) {
|
||||
sendMessage({method: name, params: object});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles system messages. (for example: enable/disable events)
|
||||
* @param message {object} the message
|
||||
*/
|
||||
function onSystemMessage(message) {
|
||||
switch (message.type) {
|
||||
case "eventStatus":
|
||||
if(!message.name || !message.value) {
|
||||
logger.warn("Unknown system message format", message);
|
||||
break;
|
||||
}
|
||||
events[message.name] = message.value;
|
||||
break;
|
||||
default:
|
||||
logger.warn("Unknown system message type", message);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
class API {
|
||||
/**
|
||||
* Constructs new instance
|
||||
* @constructor
|
||||
*/
|
||||
constructor() { }
|
||||
|
||||
/**
|
||||
* Initializes the APIConnector. Setups message event listeners that will
|
||||
* receive information from external applications that embed Jitsi Meet.
|
||||
@@ -153,17 +110,23 @@ export default {
|
||||
* is initialized.
|
||||
* @param options {object}
|
||||
* @param forceEnable {boolean} if true the module will be enabled.
|
||||
* @param enabledEvents {array} array of events that should be enabled.
|
||||
*/
|
||||
init (options = {}) {
|
||||
if(!isEnabled() && !options.forceEnable)
|
||||
if(!shouldBeEnabled() && !options.forceEnable)
|
||||
return;
|
||||
|
||||
enabled = true;
|
||||
if(options.enabledEvents)
|
||||
options.enabledEvents.forEach(function (eventName) {
|
||||
events[eventName] = true;
|
||||
});
|
||||
|
||||
if(!postis) {
|
||||
this._initPostis();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* initializes postis library.
|
||||
* @private
|
||||
*/
|
||||
_initPostis() {
|
||||
let postisOptions = {
|
||||
window: target
|
||||
};
|
||||
@@ -171,9 +134,8 @@ export default {
|
||||
postisOptions.scope
|
||||
= "jitsi_meet_external_api_" + jitsi_meet_external_api_id;
|
||||
postis = postisInit(postisOptions);
|
||||
postis.listen("jitsiSystemMessage", onSystemMessage);
|
||||
initCommands();
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that message was sent.
|
||||
@@ -181,7 +143,7 @@ export default {
|
||||
*/
|
||||
notifySendingChatMessage (body) {
|
||||
triggerEvent("outgoing-message", {"message": body});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -200,7 +162,7 @@ export default {
|
||||
"incoming-message",
|
||||
{"from": id, "nick": nick, "message": body, "stamp": ts}
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -209,7 +171,7 @@ export default {
|
||||
*/
|
||||
notifyUserJoined (id) {
|
||||
triggerEvent("participant-joined", {id});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -218,7 +180,7 @@ export default {
|
||||
*/
|
||||
notifyUserLeft (id) {
|
||||
triggerEvent("participant-left", {id});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -228,7 +190,7 @@ export default {
|
||||
*/
|
||||
notifyDisplayNameChanged (id, displayName) {
|
||||
triggerEvent("display-name-change", {id, displayname: displayName});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -238,7 +200,7 @@ export default {
|
||||
*/
|
||||
notifyConferenceJoined (room) {
|
||||
triggerEvent("video-conference-joined", {roomName: room});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -248,7 +210,7 @@ export default {
|
||||
*/
|
||||
notifyConferenceLeft (room) {
|
||||
triggerEvent("video-conference-left", {roomName: room});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that
|
||||
@@ -256,13 +218,23 @@ export default {
|
||||
*/
|
||||
notifyReadyToClose () {
|
||||
triggerEvent("video-ready-to-close", {});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends remote control event.
|
||||
* @param {RemoteControlEvent} event the remote control event.
|
||||
*/
|
||||
sendRemoteControlEvent(event) {
|
||||
sendMessage({method: "remote-control-event", params: event});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listeners.
|
||||
*/
|
||||
dispose: function () {
|
||||
dispose () {
|
||||
if(enabled)
|
||||
postis.destroy();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default new API();
|
||||
|
||||
58
modules/API/external/external_api.js
vendored
58
modules/API/external/external_api.js
vendored
@@ -69,20 +69,15 @@ function sendMessage(postis, object) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends message for event enable/disable status change.
|
||||
* @param postis {Postis object} the postis instance that is going to be used.
|
||||
* @param event {string} the name of the event
|
||||
* @param status {boolean} true - enabled; false - disabled;
|
||||
* Adds given number to the numberOfParticipants property of given APIInstance.
|
||||
* @param {JitsiMeetExternalAPI} APIInstance the instance of the
|
||||
* JitsiMeetExternalAPI
|
||||
* @param {int} number - the number of participants to be added to
|
||||
* numberOfParticipants property (this parameter can be negative number if the
|
||||
* numberOfParticipants should be decreased).
|
||||
*/
|
||||
function changeEventStatus(postis, event, status) {
|
||||
if(!(event in events)) {
|
||||
logger.error("Not supported event name.");
|
||||
return;
|
||||
}
|
||||
sendMessage(postis, {
|
||||
method: "jitsiSystemMessage",
|
||||
params: {type: "eventStatus", name: events[event], value: status}
|
||||
});
|
||||
function changeParticipantNumber(APIInstance, number) {
|
||||
APIInstance.numberOfParticipants += number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,8 +88,10 @@ function changeEventStatus(postis, event, status) {
|
||||
* @param width width of the iframe
|
||||
* @param height height of the iframe
|
||||
* @param parent_node the node that will contain the iframe
|
||||
* @param filmStripOnly if the value is true only the small videos will be
|
||||
* visible.
|
||||
* @param configOverwrite object containing configuration options defined in
|
||||
* config.js to be overridden.
|
||||
* @param interfaceConfigOverwrite object containing configuration options
|
||||
* defined in interface_config.js to be overridden.
|
||||
* @param noSsl if the value is true https won't be used
|
||||
* @constructor
|
||||
*/
|
||||
@@ -161,6 +158,12 @@ function JitsiMeetExternalAPI(domain, room_name, width, height, parentNode,
|
||||
|
||||
this.eventHandlers = {};
|
||||
|
||||
// Map<{string} event_name, {boolean} postis_listener_added>
|
||||
this.postisListeners = {};
|
||||
|
||||
this.numberOfParticipants = 1;
|
||||
this._setupListeners();
|
||||
|
||||
id++;
|
||||
}
|
||||
|
||||
@@ -313,14 +316,15 @@ JitsiMeetExternalAPI.prototype.addEventListener = function(event, listener) {
|
||||
}
|
||||
// We cannot remove listeners from postis that's why we are handling the
|
||||
// callback that way.
|
||||
if(!(event in this.eventHandlers))
|
||||
if(!this.postisListeners[event]) {
|
||||
this.postis.listen(events[event], function(data) {
|
||||
if((event in this.eventHandlers) &&
|
||||
typeof this.eventHandlers[event] === "function")
|
||||
this.eventHandlers[event].call(null, data);
|
||||
}.bind(this));
|
||||
this.postisListeners[event] = true;
|
||||
}
|
||||
this.eventHandlers[event] = listener;
|
||||
changeEventStatus(this.postis, event, true);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -334,7 +338,6 @@ JitsiMeetExternalAPI.prototype.removeEventListener = function(event) {
|
||||
return;
|
||||
}
|
||||
delete this.eventHandlers[event];
|
||||
changeEventStatus(this.postis, event, false);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -346,6 +349,25 @@ JitsiMeetExternalAPI.prototype.removeEventListeners = function(events) {
|
||||
this.removeEventListener(events[i]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the number of participants in the conference.
|
||||
* NOTE: the local participant is included.
|
||||
* @returns {int} the number of participants in the conference.
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.getNumberOfParticipants = function() {
|
||||
return this.numberOfParticipants;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setups listeners that are used internally for JitsiMeetExternalAPI.
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype._setupListeners = function() {
|
||||
this.postis.listen("participant-joined",
|
||||
changeParticipantNumber.bind(null, this, 1));
|
||||
this.postis.listen("participant-left",
|
||||
changeParticipantNumber.bind(null, this, -1));
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the listeners and removes the Jitsi Meet frame.
|
||||
*/
|
||||
|
||||
@@ -1441,4 +1441,11 @@ UI.hideUserMediaPermissionsGuidanceOverlay = function () {
|
||||
GumPermissionsOverlay.hide();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles user's features changes.
|
||||
*/
|
||||
UI.onUserFeaturesChanged = function (user) {
|
||||
VideoLayout.onUserFeaturesChanged(user);
|
||||
};
|
||||
|
||||
module.exports = UI;
|
||||
|
||||
@@ -54,7 +54,7 @@ const IndicatorFontSizes = {
|
||||
/**
|
||||
* Returns the available video width.
|
||||
*/
|
||||
getAvailableVideoWidth: function () {
|
||||
getAvailableVideoWidth() {
|
||||
return window.innerWidth;
|
||||
},
|
||||
|
||||
@@ -70,7 +70,7 @@ const IndicatorFontSizes = {
|
||||
*
|
||||
* @param el the element
|
||||
*/
|
||||
getTextWidth: function (el) {
|
||||
getTextWidth(el) {
|
||||
return (el.clientWidth + 1);
|
||||
},
|
||||
|
||||
@@ -79,7 +79,7 @@ const IndicatorFontSizes = {
|
||||
*
|
||||
* @param el the element
|
||||
*/
|
||||
getTextHeight: function (el) {
|
||||
getTextHeight(el) {
|
||||
return (el.clientHeight + 1);
|
||||
},
|
||||
|
||||
@@ -88,14 +88,14 @@ const IndicatorFontSizes = {
|
||||
*
|
||||
* @param id the identifier of the audio element.
|
||||
*/
|
||||
playSoundNotification: function (id) {
|
||||
playSoundNotification(id) {
|
||||
document.getElementById(id).play();
|
||||
},
|
||||
|
||||
/**
|
||||
* Escapes the given text.
|
||||
*/
|
||||
escapeHtml: function (unsafeText) {
|
||||
escapeHtml(unsafeText) {
|
||||
return $('<div/>').text(unsafeText).html();
|
||||
},
|
||||
|
||||
@@ -105,11 +105,11 @@ const IndicatorFontSizes = {
|
||||
* @param {string} safe string which contains escaped html
|
||||
* @returns {string} unescaped html string.
|
||||
*/
|
||||
unescapeHtml: function (safe) {
|
||||
unescapeHtml(safe) {
|
||||
return $('<div />').html(safe).text();
|
||||
},
|
||||
|
||||
imageToGrayScale: function (canvas) {
|
||||
imageToGrayScale(canvas) {
|
||||
var context = canvas.getContext('2d');
|
||||
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||
var pixels = imgData.data;
|
||||
@@ -156,7 +156,7 @@ const IndicatorFontSizes = {
|
||||
* @param key the tooltip data-i18n key
|
||||
* @param position the position of the tooltip in relation to the element
|
||||
*/
|
||||
setTooltip: function (element, key, position) {
|
||||
setTooltip(element, key, position) {
|
||||
if (element !== null) {
|
||||
element.setAttribute('data-tooltip', TOOLTIP_POSITIONS[position]);
|
||||
element.setAttribute('data-i18n', '[content]' + key);
|
||||
@@ -170,7 +170,7 @@ const IndicatorFontSizes = {
|
||||
*
|
||||
* @param element the element to remove the tooltip from
|
||||
*/
|
||||
removeTooltip: function (element) {
|
||||
removeTooltip(element) {
|
||||
element.removeAttribute('data-tooltip', '');
|
||||
element.removeAttribute('data-i18n','');
|
||||
element.removeAttribute('content','');
|
||||
@@ -183,7 +183,7 @@ const IndicatorFontSizes = {
|
||||
* @returns {string|*}
|
||||
* @private
|
||||
*/
|
||||
_getTooltipText: function (element) {
|
||||
_getTooltipText(element) {
|
||||
let title = element.getAttribute('content');
|
||||
let shortcut = element.getAttribute('shortcut');
|
||||
if(shortcut) {
|
||||
@@ -198,7 +198,7 @@ const IndicatorFontSizes = {
|
||||
* @param container the container to which new child element will be added
|
||||
* @param newChild the new element that will be inserted into the container
|
||||
*/
|
||||
prependChild: function (container, newChild) {
|
||||
prependChild(container, newChild) {
|
||||
var firstChild = container.childNodes[0];
|
||||
if (firstChild) {
|
||||
container.insertBefore(newChild, firstChild);
|
||||
@@ -214,7 +214,7 @@ const IndicatorFontSizes = {
|
||||
* @returns {boolean} {true} to indicate that the given toolbar button
|
||||
* is enabled, {false} - otherwise
|
||||
*/
|
||||
isButtonEnabled: function (name) {
|
||||
isButtonEnabled(name) {
|
||||
return interfaceConfig.TOOLBAR_BUTTONS.indexOf(name) !== -1
|
||||
|| interfaceConfig.MAIN_TOOLBAR_BUTTONS.indexOf(name) !== -1;
|
||||
},
|
||||
@@ -226,7 +226,7 @@ const IndicatorFontSizes = {
|
||||
* @returns {boolean} {true} to indicate that the given setting section
|
||||
* is enabled, {false} - otherwise
|
||||
*/
|
||||
isSettingEnabled: function (name) {
|
||||
isSettingEnabled(name) {
|
||||
return interfaceConfig.SETTINGS_SECTIONS.indexOf(name) !== -1;
|
||||
},
|
||||
|
||||
@@ -235,7 +235,7 @@ const IndicatorFontSizes = {
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAuthenticationEnabled: function() {
|
||||
isAuthenticationEnabled() {
|
||||
return interfaceConfig.AUTHENTICATION_ENABLE;
|
||||
},
|
||||
|
||||
@@ -303,7 +303,7 @@ const IndicatorFontSizes = {
|
||||
}
|
||||
},
|
||||
|
||||
hideDisabledButtons: function (mappings) {
|
||||
hideDisabledButtons(mappings) {
|
||||
var selector = Object.keys(mappings)
|
||||
.map(function (buttonName) {
|
||||
return UIUtil.isButtonEnabled(buttonName)
|
||||
@@ -313,7 +313,7 @@ const IndicatorFontSizes = {
|
||||
$(selector).hide();
|
||||
},
|
||||
|
||||
redirect (url) {
|
||||
redirect(url) {
|
||||
window.location.href = url;
|
||||
},
|
||||
|
||||
@@ -368,7 +368,7 @@ const IndicatorFontSizes = {
|
||||
* @param {Object} attrs object with properties
|
||||
* @returns {String} string of html element attributes
|
||||
*/
|
||||
attrsToString: function (attrs) {
|
||||
attrsToString(attrs) {
|
||||
return Object.keys(attrs).map(
|
||||
key => ` ${key}="${attrs[key]}"`
|
||||
).join(' ');
|
||||
|
||||
@@ -64,7 +64,7 @@ ConnectionIndicator.getStringFromArray = function (array) {
|
||||
ConnectionIndicator.prototype.generateText = function () {
|
||||
var downloadBitrate, uploadBitrate, packetLoss, i;
|
||||
|
||||
if(this.bitrate === null) {
|
||||
if(!this.bitrate) {
|
||||
downloadBitrate = "N/A";
|
||||
uploadBitrate = "N/A";
|
||||
}
|
||||
@@ -75,7 +75,7 @@ ConnectionIndicator.prototype.generateText = function () {
|
||||
this.bitrate.upload? this.bitrate.upload + " Kbps" : "N/A";
|
||||
}
|
||||
|
||||
if(this.packetLoss === null) {
|
||||
if(!this.packetLoss) {
|
||||
packetLoss = "N/A";
|
||||
} else {
|
||||
|
||||
@@ -132,7 +132,7 @@ ConnectionIndicator.prototype.generateText = function () {
|
||||
|
||||
if (this.showMoreValue) {
|
||||
var downloadBandwidth, uploadBandwidth, transport;
|
||||
if (this.bandwidth === null) {
|
||||
if (!this.bandwidth) {
|
||||
downloadBandwidth = "N/A";
|
||||
uploadBandwidth = "N/A";
|
||||
} else {
|
||||
@@ -341,7 +341,7 @@ ConnectionIndicator.prototype.updateConnectionStatusIndicator
|
||||
*/
|
||||
ConnectionIndicator.prototype.updateConnectionQuality =
|
||||
function (percent, object) {
|
||||
if (percent === null) {
|
||||
if (!percent) {
|
||||
this.connectionIndicatorContainer.style.display = "none";
|
||||
this.popover.forceHide();
|
||||
return;
|
||||
|
||||
@@ -3,6 +3,7 @@ const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
|
||||
import Avatar from "../avatar/Avatar";
|
||||
import {createDeferred} from '../../util/helpers';
|
||||
import UIEvents from "../../../service/UI/UIEvents";
|
||||
import UIUtil from "../util/UIUtil";
|
||||
import {VideoContainer, VIDEO_CONTAINER_TYPE} from "./VideoContainer";
|
||||
|
||||
@@ -19,8 +20,11 @@ export default class LargeVideoManager {
|
||||
* @type {Object.<string, LargeContainer>}
|
||||
*/
|
||||
this.containers = {};
|
||||
this.eventEmitter = emitter;
|
||||
|
||||
this.state = VIDEO_CONTAINER_TYPE;
|
||||
// FIXME: We are passing resizeContainer as parameter which is calling
|
||||
// Container.resize. Probably there's better way to implement this.
|
||||
this.videoContainer = new VideoContainer(
|
||||
() => this.resizeContainer(VIDEO_CONTAINER_TYPE), emitter);
|
||||
this.addContainer(VIDEO_CONTAINER_TYPE, this.videoContainer);
|
||||
@@ -164,6 +168,7 @@ export default class LargeVideoManager {
|
||||
// after everything is done check again if there are any pending
|
||||
// new streams.
|
||||
this.updateInProcess = false;
|
||||
this.eventEmitter.emit(UIEvents.LARGE_VIDEO_ID_CHANGED, this.id);
|
||||
this.scheduleLargeVideoUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ function RemoteVideo(user, VideoLayout, emitter) {
|
||||
this.videoSpanId = `participant_${this.id}`;
|
||||
SmallVideo.call(this, VideoLayout);
|
||||
this.hasRemoteVideoMenu = false;
|
||||
this._supportsRemoteControl = false;
|
||||
this.addRemoteVideoContainer();
|
||||
this.connectionIndicator = new ConnectionIndicator(this, this.id);
|
||||
this.setDisplayName();
|
||||
@@ -64,7 +65,7 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
|
||||
|
||||
this.initBrowserSpecificProperties();
|
||||
|
||||
if (APP.conference.isModerator) {
|
||||
if (APP.conference.isModerator || this._supportsRemoteControl) {
|
||||
this.addRemoteVideoMenu();
|
||||
}
|
||||
|
||||
@@ -106,14 +107,6 @@ RemoteVideo.prototype._initPopupMenu = function (popupMenuElement) {
|
||||
// call the original show, passing its actual this
|
||||
origShowFunc.call(this.popover);
|
||||
}.bind(this);
|
||||
|
||||
// override popover hide method so we can cleanup click handlers
|
||||
let origHideFunc = this.popover.forceHide;
|
||||
this.popover.forceHide = function () {
|
||||
$(document).off("click", '#mutelink_' + this.id);
|
||||
$(document).off("click", '#ejectlink_' + this.id);
|
||||
origHideFunc.call(this.popover);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -139,38 +132,68 @@ RemoteVideo.prototype._generatePopupContent = function () {
|
||||
let popupmenuElement = document.createElement('ul');
|
||||
popupmenuElement.className = 'popupmenu';
|
||||
popupmenuElement.id = `remote_popupmenu_${this.id}`;
|
||||
let menuItems = [];
|
||||
|
||||
let muteTranslationKey;
|
||||
let muteClassName;
|
||||
if (this.isAudioMuted) {
|
||||
muteTranslationKey = 'videothumbnail.muted';
|
||||
muteClassName = 'mutelink disabled';
|
||||
} else {
|
||||
muteTranslationKey = 'videothumbnail.domute';
|
||||
muteClassName = 'mutelink';
|
||||
if(APP.conference.isModerator) {
|
||||
let muteTranslationKey;
|
||||
let muteClassName;
|
||||
if (this.isAudioMuted) {
|
||||
muteTranslationKey = 'videothumbnail.muted';
|
||||
muteClassName = 'mutelink disabled';
|
||||
} else {
|
||||
muteTranslationKey = 'videothumbnail.domute';
|
||||
muteClassName = 'mutelink';
|
||||
}
|
||||
|
||||
let muteHandler = this._muteHandler.bind(this);
|
||||
let kickHandler = this._kickHandler.bind(this);
|
||||
|
||||
menuItems = [
|
||||
{
|
||||
id: 'mutelink_' + this.id,
|
||||
handler: muteHandler,
|
||||
icon: 'icon-mic-disabled',
|
||||
className: muteClassName,
|
||||
data: {
|
||||
i18n: muteTranslationKey
|
||||
}
|
||||
}, {
|
||||
id: 'ejectlink_' + this.id,
|
||||
handler: kickHandler,
|
||||
icon: 'icon-kick',
|
||||
data: {
|
||||
i18n: 'videothumbnail.kick'
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
let muteHandler = this._muteHandler.bind(this);
|
||||
let kickHandler = this._kickHandler.bind(this);
|
||||
|
||||
let menuItems = [
|
||||
{
|
||||
id: 'mutelink_' + this.id,
|
||||
handler: muteHandler,
|
||||
icon: 'icon-mic-disabled',
|
||||
className: muteClassName,
|
||||
data: {
|
||||
i18n: muteTranslationKey
|
||||
}
|
||||
}, {
|
||||
id: 'ejectlink_' + this.id,
|
||||
handler: kickHandler,
|
||||
icon: 'icon-kick',
|
||||
data: {
|
||||
i18n: 'videothumbnail.kick'
|
||||
}
|
||||
if(this._supportsRemoteControl) {
|
||||
let icon, handler, className;
|
||||
if(APP.remoteControl.controller.getRequestedParticipant()
|
||||
=== this.id) {
|
||||
handler = () => {};
|
||||
className = "requestRemoteControlLink disabled";
|
||||
icon = "remote-control-spinner fa fa-spinner fa-spin";
|
||||
} else if(!APP.remoteControl.controller.isStarted()) {
|
||||
handler = this._requestRemoteControlPermissions.bind(this);
|
||||
icon = "fa fa-play";
|
||||
className = "requestRemoteControlLink";
|
||||
} else {
|
||||
handler = this._stopRemoteControl.bind(this);
|
||||
icon = "fa fa-stop";
|
||||
className = "requestRemoteControlLink";
|
||||
}
|
||||
];
|
||||
menuItems.push({
|
||||
id: 'remoteControl_' + this.id,
|
||||
handler,
|
||||
icon,
|
||||
className,
|
||||
data: {
|
||||
i18n: 'videothumbnail.remoteControl'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
menuItems.forEach(el => {
|
||||
let menuItem = this._generatePopupMenuItem(el);
|
||||
@@ -182,6 +205,76 @@ RemoteVideo.prototype._generatePopupContent = function () {
|
||||
return popupmenuElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the remote control supported value and initializes or updates the menu
|
||||
* depending on the remote control is supported or not.
|
||||
* @param {boolean} isSupported
|
||||
*/
|
||||
RemoteVideo.prototype.setRemoteControlSupport = function(isSupported = false) {
|
||||
if(this._supportsRemoteControl === isSupported) {
|
||||
return;
|
||||
}
|
||||
this._supportsRemoteControl = isSupported;
|
||||
if(!isSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this.hasRemoteVideoMenu) {
|
||||
//create menu
|
||||
this.addRemoteVideoMenu();
|
||||
} else {
|
||||
//update the content
|
||||
this.updateRemoteVideoMenu(this.isAudioMuted, true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests permissions for remote control session.
|
||||
*/
|
||||
RemoteVideo.prototype._requestRemoteControlPermissions = function () {
|
||||
APP.remoteControl.controller.requestPermissions(
|
||||
this.id, this.VideoLayout.getLargeVideoWrapper()).then(result => {
|
||||
if(result === null) {
|
||||
return;
|
||||
}
|
||||
this.updateRemoteVideoMenu(this.isAudioMuted, true);
|
||||
APP.UI.messageHandler.openMessageDialog(
|
||||
"dialog.remoteControlTitle",
|
||||
(result === false) ? "dialog.remoteControlDeniedMessage"
|
||||
: "dialog.remoteControlAllowedMessage",
|
||||
{user: this.user.getDisplayName()
|
||||
|| interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME}
|
||||
);
|
||||
if(result === true) {//the remote control permissions has been granted
|
||||
// pin the controlled participant
|
||||
let pinnedId = this.VideoLayout.getPinnedId();
|
||||
if(pinnedId !== this.id) {
|
||||
this.VideoLayout.handleVideoThumbClicked(this.id);
|
||||
}
|
||||
}
|
||||
}, error => {
|
||||
logger.error(error);
|
||||
this.updateRemoteVideoMenu(this.isAudioMuted, true);
|
||||
APP.UI.messageHandler.openMessageDialog(
|
||||
"dialog.remoteControlTitle",
|
||||
"dialog.remoteControlErrorMessage",
|
||||
{user: this.user.getDisplayName()
|
||||
|| interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME}
|
||||
);
|
||||
});
|
||||
this.updateRemoteVideoMenu(this.isAudioMuted, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Stops remote control session.
|
||||
*/
|
||||
RemoteVideo.prototype._stopRemoteControl = function () {
|
||||
// send message about stopping
|
||||
APP.remoteControl.controller.stop();
|
||||
this.updateRemoteVideoMenu(this.isAudioMuted, true);
|
||||
};
|
||||
|
||||
RemoteVideo.prototype._muteHandler = function () {
|
||||
if (this.isAudioMuted)
|
||||
return;
|
||||
@@ -244,8 +337,7 @@ RemoteVideo.prototype._generatePopupMenuItem = function (opts = {}) {
|
||||
linkItem.appendChild(textContent);
|
||||
linkItem.id = id;
|
||||
|
||||
// Delegate event to the document.
|
||||
$(document).on("click", `#${id}`, handler);
|
||||
linkItem.onclick = handler;
|
||||
menuItem.appendChild(linkItem);
|
||||
|
||||
return menuItem;
|
||||
|
||||
@@ -164,12 +164,20 @@ export class VideoContainer extends LargeContainer {
|
||||
return getStreamOwnerId(this.stream);
|
||||
}
|
||||
|
||||
constructor (onPlay, emitter) {
|
||||
/**
|
||||
* Creates new VideoContainer instance.
|
||||
* @param resizeContainer {Function} function that takes care of the size
|
||||
* of the video container.
|
||||
* @param emitter {EventEmitter} the event emitter that will be used by
|
||||
* this instance.
|
||||
*/
|
||||
constructor (resizeContainer, emitter) {
|
||||
super();
|
||||
this.stream = null;
|
||||
this.videoType = null;
|
||||
this.localFlipX = true;
|
||||
this.emitter = emitter;
|
||||
this.resizeContainer = resizeContainer;
|
||||
|
||||
this.isVisible = false;
|
||||
|
||||
@@ -199,8 +207,8 @@ export class VideoContainer extends LargeContainer {
|
||||
this.avatarHeight = $("#dominantSpeakerAvatar").height();
|
||||
|
||||
var onPlayCallback = function (event) {
|
||||
if (typeof onPlay === 'function') {
|
||||
onPlay(event);
|
||||
if (typeof resizeContainer === 'function') {
|
||||
resizeContainer(event);
|
||||
}
|
||||
this.wasVideoRendered = true;
|
||||
}.bind(this);
|
||||
@@ -336,8 +344,14 @@ export class VideoContainer extends LargeContainer {
|
||||
* @param {string} videoType video type
|
||||
*/
|
||||
setStream (stream, videoType) {
|
||||
|
||||
if (this.stream === stream) {
|
||||
// Handles the use case for the remote participants when the
|
||||
// videoType is received with delay after turning on/off the
|
||||
// desktop sharing.
|
||||
if(this.videoType !== videoType) {
|
||||
this.videoType = videoType;
|
||||
this.resizeContainer();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// The stream has changed, so the image will be lost on detach
|
||||
@@ -361,6 +375,9 @@ export class VideoContainer extends LargeContainer {
|
||||
this.$video.css({
|
||||
transform: flipX ? 'scaleX(-1)' : 'none'
|
||||
});
|
||||
|
||||
// Reset the large video background depending on the stream.
|
||||
this.setLargeVideoBackground(this.avatarDisplayed);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,8 +412,7 @@ export class VideoContainer extends LargeContainer {
|
||||
// default background set.
|
||||
// In order to fix this code we need to introduce video background or
|
||||
// find a workaround for the video flickering.
|
||||
$("#largeVideoContainer").css("background",
|
||||
(show) ? interfaceConfig.DEFAULT_BACKGROUND : "#000");
|
||||
this.setLargeVideoBackground(show);
|
||||
|
||||
this.$avatar.css("visibility", show ? "visible" : "hidden");
|
||||
this.avatarDisplayed = show;
|
||||
@@ -465,4 +481,19 @@ export class VideoContainer extends LargeContainer {
|
||||
stayOnStage () {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the large video container background depending on the container
|
||||
* type and the parameter indicating if an avatar is currently shown on
|
||||
* large.
|
||||
*
|
||||
* @param {boolean} isAvatar - Indicates if the avatar is currently shown
|
||||
* on the large video.
|
||||
* @returns {void}
|
||||
*/
|
||||
setLargeVideoBackground (isAvatar) {
|
||||
$("#largeVideoContainer").css("background",
|
||||
(this.videoType === VIDEO_CONTAINER_TYPE && !isAvatar)
|
||||
? "#000" : interfaceConfig.DEFAULT_BACKGROUND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +406,7 @@ var VideoLayout = {
|
||||
remoteVideo = smallVideo;
|
||||
else
|
||||
remoteVideo = new RemoteVideo(user, VideoLayout, eventEmitter);
|
||||
this._setRemoteControlProperties(user, remoteVideo);
|
||||
this.addRemoteVideoContainer(id, remoteVideo);
|
||||
},
|
||||
|
||||
@@ -1158,12 +1159,44 @@ var VideoLayout = {
|
||||
* Sets the flipX state of the local video.
|
||||
* @param {boolean} true for flipped otherwise false;
|
||||
*/
|
||||
setLocalFlipX: function (val) {
|
||||
setLocalFlipX (val) {
|
||||
this.localFlipX = val;
|
||||
|
||||
},
|
||||
|
||||
getEventEmitter: () => {return eventEmitter;}
|
||||
getEventEmitter() {return eventEmitter;},
|
||||
|
||||
/**
|
||||
* Handles user's features changes.
|
||||
*/
|
||||
onUserFeaturesChanged (user) {
|
||||
let video = this.getSmallVideo(user.getId());
|
||||
|
||||
if (!video) {
|
||||
return;
|
||||
}
|
||||
this._setRemoteControlProperties(user, video);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the remote control properties (checks whether remote control
|
||||
* is supported and executes remoteVideo.setRemoteControlSupport).
|
||||
* @param {JitsiParticipant} user the user that will be checked for remote
|
||||
* control support.
|
||||
* @param {RemoteVideo} remoteVideo the remoteVideo on which the properties
|
||||
* will be set.
|
||||
*/
|
||||
_setRemoteControlProperties (user, remoteVideo) {
|
||||
APP.remoteControl.checkUserRemoteControlSupport(user).then(result =>
|
||||
remoteVideo.setRemoteControlSupport(result));
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the wrapper jquery selector for the largeVideo
|
||||
* @returns {JQuerySelector} the wrapper jquery selector for the largeVideo
|
||||
*/
|
||||
getLargeVideoWrapper() {
|
||||
return this.getCurrentlyOnLargeContainer().$wrapper;
|
||||
}
|
||||
};
|
||||
|
||||
export default VideoLayout;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
|
||||
import { redirect } from '../util/helpers';
|
||||
import { replace } from '../util/helpers';
|
||||
|
||||
/**
|
||||
* The modules stores information about the URL used to start the conference and
|
||||
@@ -68,6 +68,6 @@ export default class ConferenceUrl {
|
||||
*/
|
||||
reload() {
|
||||
logger.info("Reloading the conference using URL: " + this.originalURL);
|
||||
redirect(this.originalURL);
|
||||
replace(this.originalURL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,12 @@ function showKeyboardShortcutsPanel(show) {
|
||||
*/
|
||||
let _shortcuts = {};
|
||||
|
||||
/**
|
||||
* True if the keyboard shortcuts are enabled and false if not.
|
||||
* @type {boolean}
|
||||
*/
|
||||
let enabled = true;
|
||||
|
||||
/**
|
||||
* Maps keycode to character, id of popover for given function and function.
|
||||
*/
|
||||
@@ -74,6 +80,9 @@ var KeyboardShortcut = {
|
||||
|
||||
var self = this;
|
||||
window.onkeyup = function(e) {
|
||||
if(!enabled) {
|
||||
return;
|
||||
}
|
||||
var key = self._getKeyboardKey(e).toUpperCase();
|
||||
var num = parseInt(key, 10);
|
||||
if(!($(":focus").is("input[type=text]") ||
|
||||
@@ -93,6 +102,9 @@ var KeyboardShortcut = {
|
||||
};
|
||||
|
||||
window.onkeydown = function(e) {
|
||||
if(!enabled) {
|
||||
return;
|
||||
}
|
||||
if(!($(":focus").is("input[type=text]") ||
|
||||
$(":focus").is("input[type=password]") ||
|
||||
$(":focus").is("textarea"))) {
|
||||
@@ -105,6 +117,14 @@ var KeyboardShortcut = {
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables/Disables the keyboard shortcuts.
|
||||
* @param {boolean} value - the new value.
|
||||
*/
|
||||
enable: function (value) {
|
||||
enabled = value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a new shortcut.
|
||||
*
|
||||
|
||||
163
modules/keycode/keycode.js
Normal file
163
modules/keycode/keycode.js
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Enumerates the supported keys.
|
||||
* NOTE: The maps represents physical keys on the keyboard, not chars.
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const KEYS = {
|
||||
BACKSPACE: "backspace" ,
|
||||
DELETE : "delete",
|
||||
RETURN : "enter",
|
||||
TAB : "tab",
|
||||
ESCAPE : "escape",
|
||||
UP : "up",
|
||||
DOWN : "down",
|
||||
RIGHT : "right",
|
||||
LEFT : "left",
|
||||
HOME : "home",
|
||||
END : "end",
|
||||
PAGEUP : "pageup",
|
||||
PAGEDOWN : "pagedown",
|
||||
|
||||
F1 : "f1",
|
||||
F2 : "f2",
|
||||
F3 : "f3",
|
||||
F4 : "f4",
|
||||
F5 : "f5",
|
||||
F6 : "f6",
|
||||
F7 : "f7",
|
||||
F8 : "f8",
|
||||
F9 : "f9",
|
||||
F10 : "f10",
|
||||
F11 : "f11",
|
||||
F12 : "f12",
|
||||
META : "command",
|
||||
CMD_L: "command",
|
||||
CMD_R: "command",
|
||||
ALT : "alt",
|
||||
CONTROL : "control",
|
||||
SHIFT : "shift",
|
||||
CAPS_LOCK: "caps_lock", //not supported by robotjs
|
||||
SPACE : "space",
|
||||
PRINTSCREEN : "printscreen",
|
||||
INSERT : "insert",
|
||||
|
||||
NUMPAD_0 : "numpad_0",
|
||||
NUMPAD_1 : "numpad_1",
|
||||
NUMPAD_2 : "numpad_2",
|
||||
NUMPAD_3 : "numpad_3",
|
||||
NUMPAD_4 : "numpad_4",
|
||||
NUMPAD_5 : "numpad_5",
|
||||
NUMPAD_6 : "numpad_6",
|
||||
NUMPAD_7 : "numpad_7",
|
||||
NUMPAD_8 : "numpad_8",
|
||||
NUMPAD_9 : "numpad_9",
|
||||
|
||||
COMMA: ",",
|
||||
|
||||
PERIOD: ".",
|
||||
SEMICOLON: ";",
|
||||
QUOTE: "'",
|
||||
BRACKET_LEFT: "[",
|
||||
BRACKET_RIGHT: "]",
|
||||
BACKQUOTE: "`",
|
||||
BACKSLASH: "\\",
|
||||
MINUS: "-",
|
||||
EQUAL: "=",
|
||||
SLASH: "/"
|
||||
};
|
||||
|
||||
/**
|
||||
* Mapping between the key codes and keys deined in KEYS.
|
||||
* The mappings are based on
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Specifications
|
||||
*/
|
||||
let keyCodeToKey = {
|
||||
8: KEYS.BACKSPACE,
|
||||
9: KEYS.TAB,
|
||||
13: KEYS.RETURN,
|
||||
16: KEYS.SHIFT,
|
||||
17: KEYS.CONTROL,
|
||||
18: KEYS.ALT,
|
||||
20: KEYS.CAPS_LOCK,
|
||||
27: KEYS.ESCAPE,
|
||||
32: KEYS.SPACE,
|
||||
33: KEYS.PAGEUP,
|
||||
34: KEYS.PAGEDOWN,
|
||||
35: KEYS.END,
|
||||
36: KEYS.HOME,
|
||||
37: KEYS.LEFT,
|
||||
38: KEYS.UP,
|
||||
39: KEYS.RIGHT,
|
||||
40: KEYS.DOWN,
|
||||
42: KEYS.PRINTSCREEN,
|
||||
44: KEYS.PRINTSCREEN,
|
||||
45: KEYS.INSERT,
|
||||
46: KEYS.DELETE,
|
||||
59: KEYS.SEMICOLON,
|
||||
61: KEYS.EQUAL,
|
||||
91: KEYS.CMD_L,
|
||||
92: KEYS.CMD_R,
|
||||
93: KEYS.CMD_R,
|
||||
96: KEYS.NUMPAD_0,
|
||||
97: KEYS.NUMPAD_1,
|
||||
98: KEYS.NUMPAD_2,
|
||||
99: KEYS.NUMPAD_3,
|
||||
100: KEYS.NUMPAD_4,
|
||||
101: KEYS.NUMPAD_5,
|
||||
102: KEYS.NUMPAD_6,
|
||||
103: KEYS.NUMPAD_7,
|
||||
104: KEYS.NUMPAD_8,
|
||||
105: KEYS.NUMPAD_9,
|
||||
112: KEYS.F1,
|
||||
113: KEYS.F2,
|
||||
114: KEYS.F3,
|
||||
115: KEYS.F4,
|
||||
116: KEYS.F5,
|
||||
117: KEYS.F6,
|
||||
118: KEYS.F7,
|
||||
119: KEYS.F8,
|
||||
120: KEYS.F9,
|
||||
121: KEYS.F10,
|
||||
122: KEYS.F11,
|
||||
123: KEYS.F12,
|
||||
124: KEYS.PRINTSCREEN,
|
||||
173: KEYS.MINUS,
|
||||
186: KEYS.SEMICOLON,
|
||||
187: KEYS.EQUAL,
|
||||
188: KEYS.COMMA,
|
||||
189: KEYS.MINUS,
|
||||
190: KEYS.PERIOD,
|
||||
191: KEYS.SLASH,
|
||||
192: KEYS.BACKQUOTE,
|
||||
219: KEYS.BRACKET_LEFT,
|
||||
220: KEYS.BACKSLASH,
|
||||
221: KEYS.BRACKET_RIGHT,
|
||||
222: KEYS.QUOTE,
|
||||
224: KEYS.META,
|
||||
229: KEYS.SEMICOLON
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate codes for digit keys (0-9)
|
||||
*/
|
||||
for(let i = 0; i < 10; i++) {
|
||||
keyCodeToKey[i + 48] = `${i}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate codes for letter keys (a-z)
|
||||
*/
|
||||
for(let i = 0; i < 26; i++) {
|
||||
let keyCode = i + 65;
|
||||
keyCodeToKey[keyCode] = String.fromCharCode(keyCode).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns key associated with the keyCode from the passed event.
|
||||
* @param {KeyboardEvent} event the event
|
||||
* @returns {KEYS} the key on the keyboard.
|
||||
*/
|
||||
export function keyboardEventToKey(event) {
|
||||
return keyCodeToKey[event.which];
|
||||
}
|
||||
374
modules/remotecontrol/Controller.js
Normal file
374
modules/remotecontrol/Controller.js
Normal file
@@ -0,0 +1,374 @@
|
||||
/* global $, JitsiMeetJS, APP */
|
||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
import * as KeyCodes from "../keycode/keycode";
|
||||
import {EVENT_TYPES, REMOTE_CONTROL_EVENT_TYPE, PERMISSIONS_ACTIONS}
|
||||
from "../../service/remotecontrol/Constants";
|
||||
import RemoteControlParticipant from "./RemoteControlParticipant";
|
||||
import UIEvents from "../../service/UI/UIEvents";
|
||||
|
||||
const ConferenceEvents = JitsiMeetJS.events.conference;
|
||||
|
||||
/**
|
||||
* Extract the keyboard key from the keyboard event.
|
||||
* @param event {KeyboardEvent} the event.
|
||||
* @returns {KEYS} the key that is pressed or undefined.
|
||||
*/
|
||||
function getKey(event) {
|
||||
return KeyCodes.keyboardEventToKey(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the modifiers from the keyboard event.
|
||||
* @param event {KeyboardEvent} the event.
|
||||
* @returns {Array} with possible values: "shift", "control", "alt", "command".
|
||||
*/
|
||||
function getModifiers(event) {
|
||||
let modifiers = [];
|
||||
if(event.shiftKey) {
|
||||
modifiers.push("shift");
|
||||
}
|
||||
|
||||
if(event.ctrlKey) {
|
||||
modifiers.push("control");
|
||||
}
|
||||
|
||||
|
||||
if(event.altKey) {
|
||||
modifiers.push("alt");
|
||||
}
|
||||
|
||||
if(event.metaKey) {
|
||||
modifiers.push("command");
|
||||
}
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents the controller party for a remote controller session.
|
||||
* It listens for mouse and keyboard events and sends them to the receiver
|
||||
* party of the remote control session.
|
||||
*/
|
||||
export default class Controller extends RemoteControlParticipant {
|
||||
/**
|
||||
* Creates new instance.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.isCollectingEvents = false;
|
||||
this.controlledParticipant = null;
|
||||
this.requestedParticipant = null;
|
||||
this._stopListener = this._handleRemoteControlStoppedEvent.bind(this);
|
||||
this._userLeftListener = this._onUserLeft.bind(this);
|
||||
this._largeVideoChangedListener
|
||||
= this._onLargeVideoIdChanged.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests permissions from the remote control receiver side.
|
||||
* @param {string} userId the user id of the participant that will be
|
||||
* requested.
|
||||
* @param {JQuerySelector} eventCaptureArea the area that is going to be
|
||||
* used mouse and keyboard event capture.
|
||||
* @returns {Promise<boolean>} - resolve values:
|
||||
* true - accept
|
||||
* false - deny
|
||||
* null - the participant has left.
|
||||
*/
|
||||
requestPermissions(userId, eventCaptureArea) {
|
||||
if(!this.enabled) {
|
||||
return Promise.reject(new Error("Remote control is disabled!"));
|
||||
}
|
||||
this.area = eventCaptureArea;// $("#largeVideoWrapper")
|
||||
logger.log("Requsting remote control permissions from: " + userId);
|
||||
return new Promise((resolve, reject) => {
|
||||
const clearRequest = () => {
|
||||
this.requestedParticipant = null;
|
||||
APP.conference.removeConferenceListener(
|
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
permissionsReplyListener);
|
||||
APP.conference.removeConferenceListener(
|
||||
ConferenceEvents.USER_LEFT,
|
||||
onUserLeft);
|
||||
};
|
||||
const permissionsReplyListener = (participant, event) => {
|
||||
let result = null;
|
||||
try {
|
||||
result = this._handleReply(participant, event);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
if(result !== null) {
|
||||
clearRequest();
|
||||
resolve(result);
|
||||
}
|
||||
};
|
||||
const onUserLeft = (id) => {
|
||||
if(id === this.requestedParticipant) {
|
||||
clearRequest();
|
||||
resolve(null);
|
||||
}
|
||||
};
|
||||
APP.conference.addConferenceListener(
|
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
permissionsReplyListener);
|
||||
APP.conference.addConferenceListener(ConferenceEvents.USER_LEFT,
|
||||
onUserLeft);
|
||||
this.requestedParticipant = userId;
|
||||
this._sendRemoteControlEvent(userId, {
|
||||
type: EVENT_TYPES.permissions,
|
||||
action: PERMISSIONS_ACTIONS.request
|
||||
}, e => {
|
||||
clearRequest();
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the reply of the permissions request.
|
||||
* @param {JitsiParticipant} participant the participant that has sent the
|
||||
* reply
|
||||
* @param {RemoteControlEvent} event the remote control event.
|
||||
*/
|
||||
_handleReply(participant, event) {
|
||||
const remoteControlEvent = event.event;
|
||||
const userId = participant.getId();
|
||||
if(this.enabled && event.type === REMOTE_CONTROL_EVENT_TYPE
|
||||
&& remoteControlEvent.type === EVENT_TYPES.permissions
|
||||
&& userId === this.requestedParticipant) {
|
||||
if(remoteControlEvent.action !== PERMISSIONS_ACTIONS.grant) {
|
||||
this.area = null;
|
||||
}
|
||||
switch(remoteControlEvent.action) {
|
||||
case PERMISSIONS_ACTIONS.grant: {
|
||||
this.controlledParticipant = userId;
|
||||
logger.log("Remote control permissions granted to: "
|
||||
+ userId);
|
||||
this._start();
|
||||
return true;
|
||||
}
|
||||
case PERMISSIONS_ACTIONS.deny:
|
||||
return false;
|
||||
case PERMISSIONS_ACTIONS.error:
|
||||
throw new Error("Error occurred on receiver side");
|
||||
default:
|
||||
throw new Error("Unknown reply received!");
|
||||
}
|
||||
} else {
|
||||
//different message type or another user -> ignoring the message
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles remote control stopped.
|
||||
* @param {JitsiParticipant} participant the participant that has sent the
|
||||
* event
|
||||
* @param {Object} event EndpointMessage event from the data channels.
|
||||
* @property {string} type property. The function process only events of
|
||||
* type REMOTE_CONTROL_EVENT_TYPE
|
||||
* @property {RemoteControlEvent} event - the remote control event.
|
||||
*/
|
||||
_handleRemoteControlStoppedEvent(participant, event) {
|
||||
if(this.enabled && event.type === REMOTE_CONTROL_EVENT_TYPE
|
||||
&& event.event.type === EVENT_TYPES.stop
|
||||
&& participant.getId() === this.controlledParticipant) {
|
||||
this._stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts processing the mouse and keyboard events. Sets conference
|
||||
* listeners. Disables keyboard events.
|
||||
*/
|
||||
_start() {
|
||||
logger.log("Starting remote control controller.");
|
||||
APP.UI.addListener(UIEvents.LARGE_VIDEO_ID_CHANGED,
|
||||
this._largeVideoChangedListener);
|
||||
APP.conference.addConferenceListener(
|
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
this._stopListener);
|
||||
APP.conference.addConferenceListener(ConferenceEvents.USER_LEFT,
|
||||
this._userLeftListener);
|
||||
this.resume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the keyboatd shortcuts. Starts collecting remote control
|
||||
* events.
|
||||
*
|
||||
* It can be used to resume an active remote control session wchich was
|
||||
* paused with this.pause().
|
||||
*/
|
||||
resume() {
|
||||
if(!this.enabled || this.isCollectingEvents) {
|
||||
return;
|
||||
}
|
||||
logger.log("Resuming remote control controller.");
|
||||
this.isCollectingEvents = true;
|
||||
APP.keyboardshortcut.enable(false);
|
||||
this.area.mousemove(event => {
|
||||
const position = this.area.position();
|
||||
this._sendRemoteControlEvent(this.controlledParticipant, {
|
||||
type: EVENT_TYPES.mousemove,
|
||||
x: (event.pageX - position.left)/this.area.width(),
|
||||
y: (event.pageY - position.top)/this.area.height()
|
||||
});
|
||||
});
|
||||
this.area.mousedown(this._onMouseClickHandler.bind(this,
|
||||
EVENT_TYPES.mousedown));
|
||||
this.area.mouseup(this._onMouseClickHandler.bind(this,
|
||||
EVENT_TYPES.mouseup));
|
||||
this.area.dblclick(
|
||||
this._onMouseClickHandler.bind(this, EVENT_TYPES.mousedblclick));
|
||||
this.area.contextmenu(() => false);
|
||||
this.area[0].onmousewheel = event => {
|
||||
this._sendRemoteControlEvent(this.controlledParticipant, {
|
||||
type: EVENT_TYPES.mousescroll,
|
||||
x: event.deltaX,
|
||||
y: event.deltaY
|
||||
});
|
||||
};
|
||||
$(window).keydown(this._onKeyPessHandler.bind(this,
|
||||
EVENT_TYPES.keydown));
|
||||
$(window).keyup(this._onKeyPessHandler.bind(this, EVENT_TYPES.keyup));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops processing the mouse and keyboard events. Removes added listeners.
|
||||
* Enables the keyboard shortcuts. Displays dialog to notify the user that
|
||||
* remote control session has ended.
|
||||
*/
|
||||
_stop() {
|
||||
if(!this.controlledParticipant) {
|
||||
return;
|
||||
}
|
||||
logger.log("Stopping remote control controller.");
|
||||
APP.UI.removeListener(UIEvents.LARGE_VIDEO_ID_CHANGED,
|
||||
this._largeVideoChangedListener);
|
||||
APP.conference.removeConferenceListener(
|
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
this._stopListener);
|
||||
APP.conference.removeConferenceListener(ConferenceEvents.USER_LEFT,
|
||||
this._userLeftListener);
|
||||
this.controlledParticipant = null;
|
||||
this.pause();
|
||||
this.area = null;
|
||||
APP.UI.messageHandler.openMessageDialog(
|
||||
"dialog.remoteControlTitle",
|
||||
"dialog.remoteControlStopMessage"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes this._stop() mehtod:
|
||||
* Stops processing the mouse and keyboard events. Removes added listeners.
|
||||
* Enables the keyboard shortcuts. Displays dialog to notify the user that
|
||||
* remote control session has ended.
|
||||
*
|
||||
* In addition:
|
||||
* Sends stop message to the controlled participant.
|
||||
*/
|
||||
stop() {
|
||||
if(!this.controlledParticipant) {
|
||||
return;
|
||||
}
|
||||
this._sendRemoteControlEvent(this.controlledParticipant, {
|
||||
type: EVENT_TYPES.stop
|
||||
});
|
||||
this._stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses the collecting of events and enables the keyboard shortcus. But
|
||||
* it doesn't removes any other listeners. Basically the remote control
|
||||
* session will be still active after this.pause(), but no events from the
|
||||
* controller side will be captured and sent.
|
||||
*
|
||||
* You can resume the collecting of the events with this.resume().
|
||||
*/
|
||||
pause() {
|
||||
if(!this.controlledParticipant) {
|
||||
return;
|
||||
}
|
||||
logger.log("Pausing remote control controller.");
|
||||
this.isCollectingEvents = false;
|
||||
APP.keyboardshortcut.enable(true);
|
||||
this.area.off( "mousemove" );
|
||||
this.area.off( "mousedown" );
|
||||
this.area.off( "mouseup" );
|
||||
this.area.off( "contextmenu" );
|
||||
this.area.off( "dblclick" );
|
||||
$(window).off( "keydown");
|
||||
$(window).off( "keyup");
|
||||
this.area[0].onmousewheel = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for mouse click events.
|
||||
* @param {String} type the type of event ("mousedown"/"mouseup")
|
||||
* @param {Event} event the mouse event.
|
||||
*/
|
||||
_onMouseClickHandler(type, event) {
|
||||
this._sendRemoteControlEvent(this.controlledParticipant, {
|
||||
type: type,
|
||||
button: event.which
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the remote control session is started.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isStarted() {
|
||||
return this.controlledParticipant !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the requested participant
|
||||
* @returns {string} this.requestedParticipant.
|
||||
* NOTE: This id should be the result of JitsiParticipant.getId() call.
|
||||
*/
|
||||
getRequestedParticipant() {
|
||||
return this.requestedParticipant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for key press events.
|
||||
* @param {String} type the type of event ("keydown"/"keyup")
|
||||
* @param {Event} event the key event.
|
||||
*/
|
||||
_onKeyPessHandler(type, event) {
|
||||
this._sendRemoteControlEvent(this.controlledParticipant, {
|
||||
type: type,
|
||||
key: getKey(event),
|
||||
modifiers: getModifiers(event),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the stop method if the other side have left.
|
||||
* @param {string} id - the user id for the participant that have left
|
||||
*/
|
||||
_onUserLeft(id) {
|
||||
if(this.controlledParticipant === id) {
|
||||
this._stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changes of the participant displayed on the large video.
|
||||
* @param {string} id - the user id for the participant that is displayed.
|
||||
*/
|
||||
_onLargeVideoIdChanged(id) {
|
||||
if (!this.controlledParticipant) {
|
||||
return;
|
||||
}
|
||||
if(this.controlledParticipant == id) {
|
||||
this.resume();
|
||||
} else {
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
192
modules/remotecontrol/Receiver.js
Normal file
192
modules/remotecontrol/Receiver.js
Normal file
@@ -0,0 +1,192 @@
|
||||
/* global APP, JitsiMeetJS, interfaceConfig */
|
||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
import {DISCO_REMOTE_CONTROL_FEATURE, REMOTE_CONTROL_EVENT_TYPE, EVENT_TYPES,
|
||||
PERMISSIONS_ACTIONS} from "../../service/remotecontrol/Constants";
|
||||
import RemoteControlParticipant from "./RemoteControlParticipant";
|
||||
import * as JitsiMeetConferenceEvents from '../../ConferenceEvents';
|
||||
|
||||
const ConferenceEvents = JitsiMeetJS.events.conference;
|
||||
|
||||
/**
|
||||
* This class represents the receiver party for a remote controller session.
|
||||
* It handles "remote-control-event" events and sends them to the
|
||||
* API module. From there the events can be received from wrapper application
|
||||
* and executed.
|
||||
*/
|
||||
export default class Receiver extends RemoteControlParticipant {
|
||||
/**
|
||||
* Creates new instance.
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.controller = null;
|
||||
this._remoteControlEventsListener
|
||||
= this._onRemoteControlEvent.bind(this);
|
||||
this._userLeftListener = this._onUserLeft.bind(this);
|
||||
this._hangupListener = this._onHangup.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables / Disables the remote control
|
||||
* @param {boolean} enabled the new state.
|
||||
*/
|
||||
enable(enabled) {
|
||||
if(this.enabled === enabled) {
|
||||
return;
|
||||
}
|
||||
this.enabled = enabled;
|
||||
if(enabled === true) {
|
||||
logger.log("Remote control receiver enabled.");
|
||||
// Announce remote control support.
|
||||
APP.connection.addFeature(DISCO_REMOTE_CONTROL_FEATURE, true);
|
||||
APP.conference.addConferenceListener(
|
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
this._remoteControlEventsListener);
|
||||
APP.conference.addListener(JitsiMeetConferenceEvents.BEFORE_HANGUP,
|
||||
this._hangupListener);
|
||||
} else {
|
||||
logger.log("Remote control receiver disabled.");
|
||||
this._stop(true);
|
||||
APP.connection.removeFeature(DISCO_REMOTE_CONTROL_FEATURE);
|
||||
APP.conference.removeConferenceListener(
|
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
this._remoteControlEventsListener);
|
||||
APP.conference.removeListener(
|
||||
JitsiMeetConferenceEvents.BEFORE_HANGUP,
|
||||
this._hangupListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED
|
||||
* events. Sends stop message to the wrapper application. Optionally
|
||||
* displays dialog for informing the user that remote control session
|
||||
* ended.
|
||||
* @param {boolean} dontShowDialog - if true the dialog won't be displayed.
|
||||
*/
|
||||
_stop(dontShowDialog = false) {
|
||||
if(!this.controller) {
|
||||
return;
|
||||
}
|
||||
logger.log("Remote control receiver stop.");
|
||||
this.controller = null;
|
||||
APP.conference.removeConferenceListener(ConferenceEvents.USER_LEFT,
|
||||
this._userLeftListener);
|
||||
APP.API.sendRemoteControlEvent({
|
||||
type: EVENT_TYPES.stop
|
||||
});
|
||||
if(!dontShowDialog) {
|
||||
APP.UI.messageHandler.openMessageDialog(
|
||||
"dialog.remoteControlTitle",
|
||||
"dialog.remoteControlStopMessage"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls this._stop() and sends stop message to the controller participant
|
||||
*/
|
||||
stop() {
|
||||
if(!this.controller) {
|
||||
return;
|
||||
}
|
||||
this._sendRemoteControlEvent(this.controller, {
|
||||
type: EVENT_TYPES.stop
|
||||
});
|
||||
this._stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for data channel EndpointMessage events. Handles only events of
|
||||
* type remote control. Sends "remote-control-event" events to the API
|
||||
* module.
|
||||
* @param {JitsiParticipant} participant the controller participant
|
||||
* @param {Object} event EndpointMessage event from the data channels.
|
||||
* @property {string} type property. The function process only events of
|
||||
* type REMOTE_CONTROL_EVENT_TYPE
|
||||
* @property {RemoteControlEvent} event - the remote control event.
|
||||
*/
|
||||
_onRemoteControlEvent(participant, event) {
|
||||
if(this.enabled && event.type === REMOTE_CONTROL_EVENT_TYPE) {
|
||||
const remoteControlEvent = event.event;
|
||||
if(this.controller === null
|
||||
&& remoteControlEvent.type === EVENT_TYPES.permissions
|
||||
&& remoteControlEvent.action === PERMISSIONS_ACTIONS.request) {
|
||||
remoteControlEvent.userId = participant.getId();
|
||||
remoteControlEvent.userJID = participant.getJid();
|
||||
remoteControlEvent.displayName = participant.getDisplayName()
|
||||
|| interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME;
|
||||
remoteControlEvent.screenSharing
|
||||
= APP.conference.isSharingScreen;
|
||||
} else if(this.controller !== participant.getId()) {
|
||||
return;
|
||||
} else if(remoteControlEvent.type === EVENT_TYPES.stop) {
|
||||
this._stop();
|
||||
return;
|
||||
}
|
||||
APP.API.sendRemoteControlEvent(remoteControlEvent);
|
||||
} else if(event.type === REMOTE_CONTROL_EVENT_TYPE) {
|
||||
logger.log("Remote control event is ignored because remote "
|
||||
+ "control is disabled", event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles remote control permission events received from the API module.
|
||||
* @param {String} userId the user id of the participant related to the
|
||||
* event.
|
||||
* @param {PERMISSIONS_ACTIONS} action the action related to the event.
|
||||
*/
|
||||
_onRemoteControlPermissionsEvent(userId, action) {
|
||||
if(action === PERMISSIONS_ACTIONS.grant) {
|
||||
APP.conference.addConferenceListener(ConferenceEvents.USER_LEFT,
|
||||
this._userLeftListener);
|
||||
this.controller = userId;
|
||||
logger.log("Remote control permissions granted to: " + userId);
|
||||
if(!APP.conference.isSharingScreen) {
|
||||
APP.conference.toggleScreenSharing();
|
||||
APP.conference.screenSharingPromise.then(() => {
|
||||
if(APP.conference.isSharingScreen) {
|
||||
this._sendRemoteControlEvent(userId, {
|
||||
type: EVENT_TYPES.permissions,
|
||||
action: action
|
||||
});
|
||||
} else {
|
||||
this._sendRemoteControlEvent(userId, {
|
||||
type: EVENT_TYPES.permissions,
|
||||
action: PERMISSIONS_ACTIONS.error
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
this._sendRemoteControlEvent(userId, {
|
||||
type: EVENT_TYPES.permissions,
|
||||
action: PERMISSIONS_ACTIONS.error
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._sendRemoteControlEvent(userId, {
|
||||
type: EVENT_TYPES.permissions,
|
||||
action: action
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the stop method if the other side have left.
|
||||
* @param {string} id - the user id for the participant that have left
|
||||
*/
|
||||
_onUserLeft(id) {
|
||||
if(this.controller === id) {
|
||||
this._stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles hangup events. Disables the receiver.
|
||||
*/
|
||||
_onHangup() {
|
||||
this.enable(false);
|
||||
}
|
||||
}
|
||||
89
modules/remotecontrol/RemoteControl.js
Normal file
89
modules/remotecontrol/RemoteControl.js
Normal file
@@ -0,0 +1,89 @@
|
||||
/* global APP, config */
|
||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
import Controller from "./Controller";
|
||||
import Receiver from "./Receiver";
|
||||
import {EVENT_TYPES, DISCO_REMOTE_CONTROL_FEATURE}
|
||||
from "../../service/remotecontrol/Constants";
|
||||
|
||||
/**
|
||||
* Implements the remote control functionality.
|
||||
*/
|
||||
class RemoteControl {
|
||||
/**
|
||||
* Constructs new instance. Creates controller and receiver properties.
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
this.controller = new Controller();
|
||||
this.receiver = new Receiver();
|
||||
this.enabled = false;
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the remote control - checks if the remote control should be
|
||||
* enabled or not, initializes the API module.
|
||||
*/
|
||||
init() {
|
||||
if(config.disableRemoteControl || this.initialized
|
||||
|| !APP.conference.isDesktopSharingEnabled) {
|
||||
return;
|
||||
}
|
||||
logger.log("Initializing remote control.");
|
||||
this.initialized = true;
|
||||
APP.API.init({
|
||||
forceEnable: true,
|
||||
});
|
||||
this.controller.enable(true);
|
||||
if(this.enabled) { // supported message came before init.
|
||||
this._onRemoteControlSupported();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles remote control events from the API module. Currently only events
|
||||
* with type = EVENT_TYPES.supported or EVENT_TYPES.permissions
|
||||
* @param {RemoteControlEvent} event the remote control event.
|
||||
*/
|
||||
onRemoteControlAPIEvent(event) {
|
||||
switch(event.type) {
|
||||
case EVENT_TYPES.supported:
|
||||
this._onRemoteControlSupported();
|
||||
break;
|
||||
case EVENT_TYPES.permissions:
|
||||
this.receiver._onRemoteControlPermissionsEvent(
|
||||
event.userId, event.action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles API event for support for executing remote control events into
|
||||
* the wrapper application.
|
||||
*/
|
||||
_onRemoteControlSupported() {
|
||||
logger.log("Remote Control supported.");
|
||||
if(!config.disableRemoteControl) {
|
||||
this.enabled = true;
|
||||
if(this.initialized) {
|
||||
this.receiver.enable(true);
|
||||
}
|
||||
} else {
|
||||
logger.log("Remote Control disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the passed user supports remote control or not
|
||||
* @param {JitsiParticipant} user the user to be tested
|
||||
* @returns {Promise<boolean>} the promise will be resolved with true if
|
||||
* the user supports remote control and with false if not.
|
||||
*/
|
||||
checkUserRemoteControlSupport(user) {
|
||||
return user.getFeatures().then(features =>
|
||||
features.has(DISCO_REMOTE_CONTROL_FEATURE), () => false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default new RemoteControl();
|
||||
42
modules/remotecontrol/RemoteControlParticipant.js
Normal file
42
modules/remotecontrol/RemoteControlParticipant.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/* global APP */
|
||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
import {REMOTE_CONTROL_EVENT_TYPE}
|
||||
from "../../service/remotecontrol/Constants";
|
||||
|
||||
export default class RemoteControlParticipant {
|
||||
/**
|
||||
* Creates new instance.
|
||||
*/
|
||||
constructor() {
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables / Disables the remote control
|
||||
* @param {boolean} enabled the new state.
|
||||
*/
|
||||
enable(enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends remote control event to other participant trough data channel.
|
||||
* @param {RemoteControlEvent} event the remote control event.
|
||||
* @param {Function} onDataChannelFail handler for data channel failure.
|
||||
*/
|
||||
_sendRemoteControlEvent(to, event, onDataChannelFail = () => {}) {
|
||||
if(!this.enabled || !to) {
|
||||
logger.warn("Remote control: Skip sending remote control event."
|
||||
+ " Params:", this.enable, to);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
APP.conference.sendEndpointMessage(to,
|
||||
{type: REMOTE_CONTROL_EVENT_TYPE, event});
|
||||
} catch (e) {
|
||||
logger.error("Failed to send EndpointMessage via the datachannels",
|
||||
e);
|
||||
onDataChannelFail(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,12 +73,6 @@ class TokenData{
|
||||
|
||||
this.jwt = jwt;
|
||||
|
||||
//External API settings
|
||||
this.externalAPISettings = {
|
||||
forceEnable: true,
|
||||
enabledEvents: ["video-conference-joined", "video-conference-left",
|
||||
"video-ready-to-close"]
|
||||
};
|
||||
this._decode();
|
||||
// Use JWT param as token if there is not other token set and if the
|
||||
// iss field is not anonymous. If you want to pass data with JWT token
|
||||
|
||||
@@ -2,12 +2,13 @@ const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||
|
||||
/**
|
||||
* Create deferred object.
|
||||
*
|
||||
* @returns {{promise, resolve, reject}}
|
||||
*/
|
||||
export function createDeferred () {
|
||||
let deferred = {};
|
||||
export function createDeferred() {
|
||||
const deferred = {};
|
||||
|
||||
deferred.promise = new Promise(function (resolve, reject) {
|
||||
deferred.promise = new Promise((resolve, reject) => {
|
||||
deferred.resolve = resolve;
|
||||
deferred.reject = reject;
|
||||
});
|
||||
@@ -18,63 +19,58 @@ export function createDeferred () {
|
||||
/**
|
||||
* Reload page.
|
||||
*/
|
||||
export function reload () {
|
||||
export function reload() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to new URL.
|
||||
* Redirects to a specific new URL by replacing the current location (in the
|
||||
* history).
|
||||
*
|
||||
* @param {string} url the URL pointing to the location where the user should
|
||||
* be redirected to.
|
||||
*/
|
||||
export function redirect (url) {
|
||||
export function replace(url) {
|
||||
window.location.replace(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the error and reports it to the global error handler.
|
||||
*
|
||||
* @param e {Error} the error
|
||||
* @param msg {string} [optional] the message printed in addition to the error
|
||||
*/
|
||||
export function reportError (e, msg = "") {
|
||||
export function reportError(e, msg = "") {
|
||||
logger.error(msg, e);
|
||||
if(window.onerror)
|
||||
window.onerror(msg, null, null,
|
||||
null, e);
|
||||
window.onerror && window.onerror(msg, null, null, null, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a debounced function that delays invoking func until after wait
|
||||
* milliseconds have elapsed since the last time the debounced
|
||||
* function was invoked
|
||||
* milliseconds have elapsed since the last time the debounced function was
|
||||
* invoked.
|
||||
*
|
||||
* @param fn
|
||||
* @param wait
|
||||
* @param options
|
||||
* @returns {function(...[*])}
|
||||
*/
|
||||
export function debounce(fn, wait = 0, options = {}) {
|
||||
let leading = options.leading || false;
|
||||
let trailing = true;
|
||||
let isCalled = false;
|
||||
|
||||
if (typeof options.trailing !== 'undefined') {
|
||||
trailing = options.trailing;
|
||||
}
|
||||
const leading = options.leading || false;
|
||||
const trailing
|
||||
= (typeof options.trailing === 'undefined') || options.trailing;
|
||||
let called = false;
|
||||
|
||||
return (...args) => {
|
||||
if(!isCalled) {
|
||||
if (leading) {
|
||||
fn(...args);
|
||||
}
|
||||
if (!called) {
|
||||
leading && fn(...args);
|
||||
|
||||
setTimeout(() => {
|
||||
isCalled = false;
|
||||
if (trailing) {
|
||||
fn(...args);
|
||||
}
|
||||
called = false;
|
||||
trailing && fn(...args);
|
||||
}, wait);
|
||||
|
||||
isCalled = true;
|
||||
called = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
18
package.json
18
package.json
@@ -34,10 +34,11 @@
|
||||
"postis": "^2.2.0",
|
||||
"react": "15.4.2",
|
||||
"react-dom": "15.4.2",
|
||||
"react-native": "0.39.2",
|
||||
"react-native-keep-awake": "^1.0.7",
|
||||
"react-native": "0.41.2",
|
||||
"react-native-immersive": "0.0.4",
|
||||
"react-native-keep-awake": "^2.0.2",
|
||||
"react-native-prompt": "^1.0.0",
|
||||
"react-native-vector-icons": "^3.0.0",
|
||||
"react-native-vector-icons": "^4.0.0",
|
||||
"react-native-webrtc": "jitsi/react-native-webrtc",
|
||||
"react-redux": "^5.0.2",
|
||||
"redux": "^3.5.2",
|
||||
@@ -57,14 +58,17 @@
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"babel-preset-stage-1": "^6.16.0",
|
||||
"clean-css": "*",
|
||||
"clean-css": "^3.0.0",
|
||||
"css-loader": "*",
|
||||
"eslint": "^3.13.1",
|
||||
"eslint": "^3.15.0",
|
||||
"eslint-plugin-flowtype": "^2.30.0",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jsdoc": "*",
|
||||
"eslint-plugin-react": "*",
|
||||
"eslint-plugin-react-native": "^2.2.1",
|
||||
"expose-loader": "*",
|
||||
"file-loader": "*",
|
||||
"file-loader": "^0.10.0",
|
||||
"flow-bin": "^0.37.0",
|
||||
"haste-resolver-webpack-plugin": "^0.2.2",
|
||||
"imports-loader": "*",
|
||||
"jshint": "2.9.4",
|
||||
@@ -78,7 +82,7 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"lint": "jshint . && eslint .",
|
||||
"lint": "jshint . && eslint . && flow",
|
||||
"validate": "npm ls"
|
||||
},
|
||||
"pre-commit": [
|
||||
|
||||
13
prosody-plugins/mod_muc_allowners.lua
Normal file
13
prosody-plugins/mod_muc_allowners.lua
Normal file
@@ -0,0 +1,13 @@
|
||||
-- Copyright (c) 2015 &yet <https://andyet.com>
|
||||
-- https://github.com/otalk/mod_muc_allowners/blob/9a86266a25ed32ade150742cc79f5a1669765a8f/mod_muc_allowners.lua
|
||||
--
|
||||
-- Used under the terms of the MIT License
|
||||
-- https://github.com/otalk/mod_muc_allowners/blob/9a86266a25ed32ade150742cc79f5a1669765a8f/LICENSE
|
||||
|
||||
local muc_service = module:depends("muc");
|
||||
local room_mt = muc_service.room_mt;
|
||||
|
||||
|
||||
room_mt.get_affiliation = function (room, jid)
|
||||
return "owner";
|
||||
end
|
||||
21
prosody-plugins/muc_owner_allow_kick.patch
Normal file
21
prosody-plugins/muc_owner_allow_kick.patch
Normal file
@@ -0,0 +1,21 @@
|
||||
--- muc.lib.lua 2016-10-26 18:26:53.432377291 +0000
|
||||
+++ muc.lib.lua 2016-10-26 18:41:40.754426072 +0000
|
||||
@@ -1256,15 +1256,16 @@
|
||||
if actor == true then
|
||||
actor = nil -- So we can pass it safely to 'publicise_occupant_status' below
|
||||
else
|
||||
+ local actor_affiliation = self:get_affiliation(actor);
|
||||
+
|
||||
-- Can't do anything to other owners or admins
|
||||
local occupant_affiliation = self:get_affiliation(occupant.bare_jid);
|
||||
- if occupant_affiliation == "owner" or occupant_affiliation == "admin" then
|
||||
+ if (occupant_affiliation == "owner" and actor_affiliation ~= "owner") or (occupant_affiliation == "admin" and actor_affiliation ~= "admin" and actor_affiliation ~= "owner") then
|
||||
return nil, "cancel", "not-allowed";
|
||||
end
|
||||
|
||||
-- If you are trying to give or take moderator role you need to be an owner or admin
|
||||
if occupant.role == "moderator" or role == "moderator" then
|
||||
- local actor_affiliation = self:get_affiliation(actor);
|
||||
if actor_affiliation ~= "owner" and actor_affiliation ~= "admin" then
|
||||
return nil, "cancel", "not-allowed";
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user