mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-04 05:42:28 +00:00
Compare commits
85 Commits
android-sd
...
3686
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b9e156c5d | ||
|
|
9265e1ffec | ||
|
|
d11735b04c | ||
|
|
d33b700477 | ||
|
|
97d75c2cb9 | ||
|
|
287115f4c3 | ||
|
|
63a221212b | ||
|
|
6a916fd0e1 | ||
|
|
220691d61d | ||
|
|
5cafc4bcbd | ||
|
|
b3a78dc2e6 | ||
|
|
bebc6eabe5 | ||
|
|
26dc6a4ac2 | ||
|
|
ff2626723a | ||
|
|
72bb897269 | ||
|
|
f46387a226 | ||
|
|
a4cbbccb2a | ||
|
|
3e1a008399 | ||
|
|
7e70a8c1de | ||
|
|
8efee04a10 | ||
|
|
a35099f949 | ||
|
|
8be02f9ca1 | ||
|
|
3c25a4c08c | ||
|
|
5ade0cad8b | ||
|
|
0fa6ffc439 | ||
|
|
c2ed296178 | ||
|
|
febd12b871 | ||
|
|
0a06e256b7 | ||
|
|
f295f60bea | ||
|
|
4a8f787519 | ||
|
|
d85b869934 | ||
|
|
35130f0736 | ||
|
|
1feff9709c | ||
|
|
1010f53a84 | ||
|
|
f7a526f488 | ||
|
|
245eb89b85 | ||
|
|
99de9d0bfa | ||
|
|
98698ba89a | ||
|
|
19d1e3829d | ||
|
|
612586ed1f | ||
|
|
2609e43f29 | ||
|
|
c5cd4f534c | ||
|
|
6e10ca5dd2 | ||
|
|
0fff1c3534 | ||
|
|
42271b1b89 | ||
|
|
f270b50972 | ||
|
|
ab4b6be9d7 | ||
|
|
c45ee0230f | ||
|
|
d210f2f2e7 | ||
|
|
13d78d6b49 | ||
|
|
34a71042c6 | ||
|
|
47ecf7d035 | ||
|
|
bbe8c52778 | ||
|
|
2011421e9d | ||
|
|
ce55952ca9 | ||
|
|
f93482e815 | ||
|
|
761ac6a730 | ||
|
|
11d3a343e5 | ||
|
|
9666bf836e | ||
|
|
a6d3b09796 | ||
|
|
bb0036fdab | ||
|
|
8dc0f30a49 | ||
|
|
1aed08f460 | ||
|
|
afccf6f06d | ||
|
|
5cd351a46f | ||
|
|
51f257e894 | ||
|
|
ac06892bb4 | ||
|
|
fd8473cb52 | ||
|
|
3f40257f89 | ||
|
|
14509adff2 | ||
|
|
c472537ecf | ||
|
|
d40fce741a | ||
|
|
944e8f8353 | ||
|
|
7d972a50f2 | ||
|
|
92e7be34e3 | ||
|
|
f5dba929a5 | ||
|
|
64d2885233 | ||
|
|
4ce65ae7a7 | ||
|
|
07bf95f838 | ||
|
|
3469d5dc4f | ||
|
|
8c0f942ae1 | ||
|
|
b8aa74f212 | ||
|
|
2a7c6681ad | ||
|
|
324a9eba91 | ||
|
|
fb1ed22c6c |
@@ -11,6 +11,9 @@ node_modules/react-native/Libraries/react-native/React.js
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
node_modules/react-native/Libraries/react-native/React.js
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
|
||||
; Ignore polyfills
|
||||
node_modules/react-native/Libraries/polyfills/.*
|
||||
|
||||
@@ -112,4 +115,4 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.98.0
|
||||
^0.104.0
|
||||
|
||||
11
.github/ISSUE_TEMPLATE/4-security-issues.md
vendored
Normal file
11
.github/ISSUE_TEMPLATE/4-security-issues.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Security issues
|
||||
about: Please email security@jitsi.org
|
||||
|
||||
---
|
||||
|
||||
We take security very seriously and develop all Jitsi projects to be secure and safe.
|
||||
|
||||
If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
|
||||
|
||||
We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.
|
||||
@@ -1,4 +1,4 @@
|
||||
osx_image: xcode10.2
|
||||
osx_image: xcode11.1
|
||||
language: objective-c
|
||||
script:
|
||||
- "./ios/travis-ci/build-ipa.sh"
|
||||
|
||||
12
Makefile
12
Makefile
@@ -3,6 +3,7 @@ CLEANCSS = ./node_modules/.bin/cleancss
|
||||
DEPLOY_DIR = libs
|
||||
LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet/
|
||||
LIBFLAC_DIR = node_modules/libflacjs/dist/min/
|
||||
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist/
|
||||
NODE_SASS = ./node_modules/.bin/node-sass
|
||||
NPM = npm
|
||||
OUTPUT_DIR = .
|
||||
@@ -20,7 +21,7 @@ compile:
|
||||
clean:
|
||||
rm -fr $(BUILD_DIR)
|
||||
|
||||
deploy: deploy-init deploy-appbundle deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
|
||||
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
|
||||
|
||||
deploy-init:
|
||||
rm -fr $(DEPLOY_DIR)
|
||||
@@ -47,6 +48,8 @@ deploy-appbundle:
|
||||
$(BUILD_DIR)/analytics-ga.min.map \
|
||||
$(BUILD_DIR)/video-blur-effect.min.js \
|
||||
$(BUILD_DIR)/video-blur-effect.min.map \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.js \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.map \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-lib-jitsi-meet:
|
||||
@@ -63,6 +66,11 @@ deploy-libflac:
|
||||
$(LIBFLAC_DIR)/libflac4-1.3.2.min.js.mem \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-rnnoise-binary:
|
||||
cp \
|
||||
$(RNNOISE_WASM_DIR)/rnnoise.wasm \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-css:
|
||||
$(NODE_SASS) $(STYLES_MAIN) $(STYLES_BUNDLE) && \
|
||||
$(CLEANCSS) $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
|
||||
@@ -71,7 +79,7 @@ deploy-css:
|
||||
deploy-local:
|
||||
([ ! -x deploy-local.sh ] || ./deploy-local.sh)
|
||||
|
||||
dev: deploy-init deploy-css deploy-lib-jitsi-meet deploy-libflac
|
||||
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac
|
||||
$(WEBPACK_DEV_SERVER)
|
||||
|
||||
source-package:
|
||||
|
||||
90
README.md
90
README.md
@@ -31,82 +31,9 @@ You can get our mobile versions from here:
|
||||
* [Android](https://play.google.com/store/apps/details?id=org.jitsi.meet)
|
||||
* [iOS](https://itunes.apple.com/us/app/jitsi-meet/id1165103905)
|
||||
|
||||
## Building the sources
|
||||
## Development
|
||||
|
||||
Node.js >= 10 and npm >= 6 are required.
|
||||
|
||||
On Debian/Ubuntu systems, the required packages can be installed with:
|
||||
```
|
||||
sudo apt-get install npm nodejs
|
||||
cd jitsi-meet
|
||||
npm install
|
||||
```
|
||||
|
||||
To build the Jitsi Meet application, just type
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
### 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
|
||||
"lib-jitsi-meet": "jitsi/lib-jitsi-meet",
|
||||
```
|
||||
|
||||
To work with local copy you must change the path to:
|
||||
```json
|
||||
"lib-jitsi-meet": "file:///Users/name/local-lib-jitsi-meet-copy",
|
||||
```
|
||||
|
||||
To make the project you must force it to take the sources as 'npm update':
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make
|
||||
```
|
||||
|
||||
Or if you are making only changes to the library:
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make deploy-lib-jitsi-meet
|
||||
```
|
||||
|
||||
Alternative way is to use [npm link](https://docs.npmjs.com/cli/link).
|
||||
It allows to link `lib-jitsi-meet` dependency to local source in few steps:
|
||||
|
||||
```bash
|
||||
cd lib-jitsi-meet
|
||||
|
||||
#### create global symlink for lib-jitsi-meet package
|
||||
npm link
|
||||
|
||||
cd ../jitsi-meet
|
||||
|
||||
#### create symlink from the local node_modules folder to the global lib-jitsi-meet symlink
|
||||
npm link lib-jitsi-meet
|
||||
```
|
||||
|
||||
After changes in local `lib-jitsi-meet` repository, you can rebuild it with `npm run install` and your `jitsi-meet` repository will use that modified library.
|
||||
Note: when using node version 4.x, the make file of jitsi-meet do npm update which will delete the link. It is no longer the case with version 6.x.
|
||||
|
||||
If you do not want to use local repository anymore you should run
|
||||
```bash
|
||||
cd jitsi-meet
|
||||
npm unlink lib-jitsi-meet
|
||||
npm install
|
||||
```
|
||||
### Running with webpack-dev-server for development
|
||||
|
||||
Use it at the CLI, type
|
||||
```
|
||||
make dev
|
||||
```
|
||||
|
||||
By default the backend deployment used is `beta.meet.jit.si`. You can point the Jitsi-Meet app at a different backend by using a proxy server. To do this, set the WEBPACK_DEV_SERVER_PROXY_TARGET variable:
|
||||
```
|
||||
export WEBPACK_DEV_SERVER_PROXY_TARGET=https://your-example-server.com
|
||||
make dev
|
||||
```
|
||||
|
||||
The app should be running at https://localhost:8080/
|
||||
For web development see [here](doc/development.md), and for mobile see [here](doc/mobile.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -118,7 +45,8 @@ see our [guidelines for contributing](CONTRIBUTING.md).
|
||||
Jitsi Meet provides a very flexible way of embedding in external applications by using the [Jitsi Meet API](doc/api.md).
|
||||
|
||||
## Security
|
||||
WebRTC does not provide a way of conducting multi-party conversations with end-to-end encryption.
|
||||
|
||||
WebRTC does not (yet) provide a way of conducting multi-party conversations with end-to-end encryption.
|
||||
Unless you consistently compare DTLS fingerprints with your peers vocally, the same goes for one-to-one calls.
|
||||
As a result, your stream is encrypted on the network but decrypted on the machine that hosts the bridge when using Jitsi Meet.
|
||||
|
||||
@@ -130,9 +58,13 @@ Jitsi Meet in terms of security.
|
||||
The [meet.jit.si](https://meet.jit.si) service is maintained by the Jitsi team
|
||||
at [8x8](https://8x8.com).
|
||||
|
||||
## Mobile app
|
||||
Jitsi Meet is also available as a React Native app for Android and iOS.
|
||||
Instructions on how to build it can be found [here](doc/mobile.md).
|
||||
## Security issues
|
||||
|
||||
We take security very seriously and develop all Jitsi projects to be secure and safe.
|
||||
|
||||
If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
|
||||
|
||||
**We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.**
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
appVersion=19.3.0
|
||||
sdkVersion=2.3.0
|
||||
appVersion=19.4.0
|
||||
sdkVersion=2.4.0
|
||||
|
||||
@@ -10,7 +10,7 @@ MVN_HTTP=0
|
||||
DEFAULT_SDK_VERSION=$(grep sdkVersion ${THIS_DIR}/../gradle.properties | cut -d"=" -f2)
|
||||
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
|
||||
RN_VERSION=$(jq -r '.dependencies."react-native"' ${THIS_DIR}/../../package.json)
|
||||
JSC_VERSION="r"$(jq -r '.dependencies."jsc-android"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -d . -f 1)
|
||||
JSC_VERSION="r"$(jq -r '.dependencies."jsc-android"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -d . -f 1 | cut -c 2-)
|
||||
DO_GIT_TAG=${GIT_TAG:-0}
|
||||
|
||||
if [[ $THE_MVN_REPO == http* ]]; then
|
||||
|
||||
@@ -45,6 +45,7 @@ dependencies {
|
||||
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
implementation 'com.squareup.duktape:duktape-android:1.3.0'
|
||||
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
implementation 'com.amplitude:android-sdk:2.14.1'
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.squareup.duktape.Duktape;
|
||||
|
||||
@ReactModule(name = JavaScriptSandboxModule.NAME)
|
||||
class JavaScriptSandboxModule extends ReactContextBaseJavaModule {
|
||||
public static final String NAME = "JavaScriptSandbox";
|
||||
|
||||
public JavaScriptSandboxModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given code in a Duktape VM.
|
||||
* @param code - The code that needs to evaluated.
|
||||
* @param promise - Resolved with the output in case of success or rejected with an exception
|
||||
* in case of failure.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void evaluate(String code, Promise promise) {
|
||||
Duktape vm = Duktape.create();
|
||||
try {
|
||||
Object res = vm.evaluate(code);
|
||||
promise.resolve(res.toString());
|
||||
} catch (Throwable tr) {
|
||||
promise.reject(tr);
|
||||
} finally {
|
||||
vm.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,9 @@ public class JitsiMeet {
|
||||
}
|
||||
|
||||
public static void setDefaultConferenceOptions(JitsiMeetConferenceOptions options) {
|
||||
if (options != null && options.getRoom() != null) {
|
||||
throw new RuntimeException("'room' must be null in the default conference options");
|
||||
}
|
||||
defaultConferenceOptions = options;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class JitsiMeetActivityDelegate {
|
||||
// https://github.com/facebook/react-native/blob/df4e67fe75d781d1eb264128cadf079989542755/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java#L512
|
||||
// Why this happens is a mystery wrapped in an enigma.
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (activity == reactContext.getCurrentActivity()) {
|
||||
if (reactContext != null && activity == reactContext.getCurrentActivity()) {
|
||||
reactInstanceManager.onHostPause(activity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,46 @@ public class JitsiMeetConferenceOptions implements Parcelable {
|
||||
*/
|
||||
private JitsiMeetUserInfo userInfo;
|
||||
|
||||
public URL getServerURL() {
|
||||
return serverURL;
|
||||
}
|
||||
|
||||
public String getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public Bundle getColorScheme() {
|
||||
return colorScheme;
|
||||
}
|
||||
|
||||
public Bundle getFeatureFlags() {
|
||||
return featureFlags;
|
||||
}
|
||||
|
||||
public boolean getAudioMuted() {
|
||||
return audioMuted;
|
||||
}
|
||||
|
||||
public boolean getAudioOnly() {
|
||||
return audioOnly;
|
||||
}
|
||||
|
||||
public boolean getVideoMuted() {
|
||||
return videoMuted;
|
||||
}
|
||||
|
||||
public JitsiMeetUserInfo getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used to build the immutable {@link JitsiMeetConferenceOptions} object.
|
||||
*/
|
||||
|
||||
@@ -87,7 +87,7 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
final String action = intent.getAction();
|
||||
if (action.equals(Actions.START)) {
|
||||
if (Actions.START.equals(action)) {
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification();
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
@@ -96,7 +96,7 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
JitsiMeetLogger.i(TAG + " Service started");
|
||||
}
|
||||
} else if (action.equals(Actions.HANGUP)) {
|
||||
} else if (Actions.HANGUP.equals(action)) {
|
||||
JitsiMeetLogger.i(TAG + " Hangup requested");
|
||||
// Abort all ongoing calls
|
||||
if (AudioModeModule.useConnectionService()) {
|
||||
|
||||
@@ -144,9 +144,10 @@ class RNConnectionService
|
||||
* @param callUUID - the call's UUID.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void reportConnectedOutgoingCall(String callUUID) {
|
||||
public void reportConnectedOutgoingCall(String callUUID, Promise promise) {
|
||||
JitsiMeetLogger.d(TAG + " reportConnectedOutgoingCall " + callUUID);
|
||||
ConnectionService.setConnectionActive(callUUID);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -67,6 +67,7 @@ class ReactInstanceManagerHolder {
|
||||
new AudioModeModule(reactContext),
|
||||
new DropboxModule(reactContext),
|
||||
new ExternalAPIModule(reactContext),
|
||||
new JavaScriptSandboxModule(reactContext),
|
||||
new LocaleDetector(reactContext),
|
||||
new LogBridgeModule(reactContext),
|
||||
new PictureInPictureModule(reactContext),
|
||||
|
||||
@@ -43,7 +43,7 @@ public class NAT64AddrInfoModule
|
||||
* The host for which the module wil try to resolve both IPv4 and IPv6
|
||||
* addresses in order to figure out the NAT64 prefix.
|
||||
*/
|
||||
private final static String HOST = "nat64.jitsi.net";
|
||||
private final static String HOST = "ipv4only.arpa";
|
||||
|
||||
/**
|
||||
* How long is the {@link NAT64AddrInfo} instance valid.
|
||||
|
||||
@@ -10,7 +10,7 @@ project(':react-native-community-async-storage').projectDir = new File(rootProje
|
||||
include ':react-native-community_netinfo'
|
||||
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-signin/android')
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-keep-awake'
|
||||
|
||||
@@ -104,7 +104,6 @@ import {
|
||||
trackRemoved
|
||||
} from './react/features/base/tracks';
|
||||
import { getJitsiMeetGlobalNS } from './react/features/base/util';
|
||||
import { addMessage } from './react/features/chat';
|
||||
import { showDesktopPicker } from './react/features/desktop-picker';
|
||||
import { appendSuffix } from './react/features/display-name';
|
||||
import {
|
||||
@@ -114,7 +113,6 @@ import {
|
||||
import { mediaPermissionPromptVisibilityChanged } from './react/features/overlay';
|
||||
import { suspendDetected } from './react/features/power-monitor';
|
||||
import { setSharedVideoStatus } from './react/features/shared-video';
|
||||
import { isButtonEnabled } from './react/features/toolbox';
|
||||
import { endpointMessageReceived } from './react/features/subtitles';
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
@@ -244,8 +242,6 @@ class ConferenceConnector {
|
||||
this._handleConferenceJoined.bind(this));
|
||||
room.on(JitsiConferenceEvents.CONFERENCE_FAILED,
|
||||
this._onConferenceFailed.bind(this));
|
||||
room.on(JitsiConferenceEvents.CONFERENCE_ERROR,
|
||||
this._onConferenceError.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,31 +344,6 @@ class ConferenceConnector {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_onConferenceError(err, ...params) {
|
||||
logger.error('CONFERENCE Error:', err, params);
|
||||
switch (err) {
|
||||
case JitsiConferenceErrors.CHAT_ERROR:
|
||||
logger.error('Chat error.', err);
|
||||
if (isButtonEnabled('chat') && !interfaceConfig.filmStripOnly) {
|
||||
const [ code, msg ] = params;
|
||||
|
||||
APP.store.dispatch(addMessage({
|
||||
hasRead: true,
|
||||
error: code,
|
||||
message: msg,
|
||||
messageType: 'error',
|
||||
timestamp: Date.now()
|
||||
}));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.error('Unknown error.', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
24
config.js
24
config.js
@@ -1,16 +1,6 @@
|
||||
/* eslint-disable no-unused-vars, no-var */
|
||||
|
||||
var config = {
|
||||
// Configuration
|
||||
//
|
||||
|
||||
// Alternative location for the configuration.
|
||||
// configLocation: './config.json',
|
||||
|
||||
// Custom function which given the URL path should return a room name.
|
||||
// getroomnode: function (path) { return 'someprefixpossiblybasedonpath'; },
|
||||
|
||||
|
||||
// Connection
|
||||
//
|
||||
|
||||
@@ -60,6 +50,10 @@ var config = {
|
||||
|
||||
// Enables the test specific features consumed by jitsi-meet-torture
|
||||
// testMode: false
|
||||
|
||||
// Disables the auto-play behavior of *all* newly created video element.
|
||||
// This is useful when the client runs on a host with limited resources.
|
||||
// noAutoPlayVideo: false
|
||||
},
|
||||
|
||||
// Disables ICE/UDP by filtering out local and remote UDP candidates in
|
||||
@@ -425,6 +419,16 @@ var config = {
|
||||
// the menu has option to flip the locally seen video for local presentations
|
||||
// disableLocalVideoFlip: false
|
||||
|
||||
// Deployment specific URLs.
|
||||
// deploymentUrls: {
|
||||
// // If specified a 'Help' button will be displayed in the overflow menu with a link to the specified URL for
|
||||
// // user documentation.
|
||||
// userDocumentationURL: 'https://docs.example.com/video-meetings.html',
|
||||
// // If specified a 'Download our apps' button will be displayed in the overflow menu with a link
|
||||
// // to the specified URL for an app download page.
|
||||
// downloadAppsUrl: 'https://docs.example.com/our-apps.html'
|
||||
// }
|
||||
|
||||
// List of undocumented settings used in jitsi-meet
|
||||
/**
|
||||
_immediateReloadThreshold
|
||||
|
||||
@@ -33,7 +33,7 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
.jitsi-icon svg {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
#chat-recipient {
|
||||
align-items: center;
|
||||
background-color: $chatPrivateMessageBackgroundColor;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-weight: 100;
|
||||
padding: 10px;
|
||||
|
||||
span {
|
||||
color: white;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
div {
|
||||
svg {
|
||||
cursor: pointer;
|
||||
fill: white
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
background-color: $chatHeaderBackgroundColor;
|
||||
height: 70px;
|
||||
@@ -111,6 +133,7 @@
|
||||
#chat-input {
|
||||
border-top: 1px solid $chatInputSeparatorColor;
|
||||
display: flex;
|
||||
padding: 5px 10px;
|
||||
|
||||
* {
|
||||
background-color: transparent;
|
||||
@@ -131,8 +154,7 @@
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
line-height: 30px;
|
||||
padding: 5px;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
@@ -162,6 +184,7 @@
|
||||
.display-name {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
@@ -175,7 +198,6 @@
|
||||
color: white;
|
||||
margin-top: 3px;
|
||||
max-width: 100%;
|
||||
padding-bottom: 3px;
|
||||
position: relative;
|
||||
|
||||
&.localuser {
|
||||
@@ -196,6 +218,15 @@
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.privatemessagenotice {
|
||||
font-size: 11px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.messagecontent {
|
||||
margin: 5px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.smiley {
|
||||
@@ -228,6 +259,7 @@
|
||||
.smileys-panel {
|
||||
bottom: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(0, 0, 0, .6) !important;
|
||||
height: auto;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
@@ -270,10 +302,6 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#usermsg::-webkit-input-placeholder {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
#usermsg::-webkit-scrollbar-track-piece {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
@@ -288,6 +316,10 @@
|
||||
.chatmessage {
|
||||
background-color: $chatLocalMessageBackgroundColor;
|
||||
border-radius: 6px 0px 6px 6px;
|
||||
|
||||
&.privatemessage {
|
||||
background-color: $chatPrivateMessageBackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
.display-name {
|
||||
@@ -301,8 +333,9 @@
|
||||
|
||||
&.error {
|
||||
.chatmessage {
|
||||
background-color: $defaultWarningColor;
|
||||
border-radius: 0px;
|
||||
color: red;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.display-name {
|
||||
@@ -312,6 +345,25 @@
|
||||
|
||||
.chatmessage-wrapper {
|
||||
max-width: 100%;
|
||||
|
||||
.replywrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.messageactions {
|
||||
align-self: stretch;
|
||||
border-left: 1px solid $chatActionsSeparatorColor;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 5px;
|
||||
|
||||
.toolbox-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chatmessage {
|
||||
@@ -320,6 +372,9 @@
|
||||
display: inline-block;
|
||||
margin-top: 3px;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
|
||||
&.privatemessage {
|
||||
background-color: $chatPrivateMessageBackgroundColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
css/_mini_toolbox.scss
Normal file
66
css/_mini_toolbox.scss
Normal file
@@ -0,0 +1,66 @@
|
||||
.filmstrip-toolbox,
|
||||
.always-on-top-toolbox {
|
||||
background-color: $newToolbarBackgroundColor;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
z-index: $toolbarZ;
|
||||
|
||||
.toolbox-icon {
|
||||
cursor: pointer;
|
||||
padding: 7px;
|
||||
|
||||
&.toggled {
|
||||
background: $AOTToolbarButtonToggleColor;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.always-on-top-toolbox {
|
||||
flex-direction: row;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.toolbox-button {
|
||||
&:first-child {
|
||||
.toolbox-icon {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
svg {
|
||||
fill: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.toolbox-icon {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filmstrip-toolbox {
|
||||
flex-direction: column;
|
||||
|
||||
.toolbox-button {
|
||||
&:nth-child(1) {
|
||||
svg {
|
||||
fill: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
min-width: 75px;
|
||||
text-align: left;
|
||||
padding: 0px;
|
||||
width: 150px;
|
||||
width: 180px;
|
||||
white-space: nowrap;
|
||||
|
||||
&__item {
|
||||
@@ -87,6 +87,7 @@
|
||||
display: inline-block;
|
||||
min-width: 20px;
|
||||
height: 100%;
|
||||
padding-right: 10px;
|
||||
|
||||
> * {
|
||||
@include absoluteAligning();
|
||||
|
||||
@@ -270,89 +270,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.always-on-top-toolbox,
|
||||
.filmstrip-toolbox {
|
||||
background-color: $newToolbarBackgroundColor;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: $toolbarZ;
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
|
||||
i:hover {
|
||||
background-color: $AOTToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
i.toggled {
|
||||
background: $AOTToolbarButtonToggleColor;
|
||||
}
|
||||
|
||||
i.toggled:hover:not(.disabled) {
|
||||
background-color: $AOTToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
.toolbox-button {
|
||||
color: $toolbarButtonColor;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.always-on-top-toolbox {
|
||||
flex-direction: row;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
transform: translateX(-50%);
|
||||
z-index: $toolbarZ;
|
||||
|
||||
i {
|
||||
font-size: $newToolbarFontSize;
|
||||
height: $newToolbarSize;
|
||||
line-height: $newToolbarSize;
|
||||
width: $newToolbarSize;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
.toolbox-button:first-child i {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
.toolbox-button:last-child i {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.filmstrip-toolbox {
|
||||
i {
|
||||
font-size: 1.9em;
|
||||
height: 37px;
|
||||
line-height: 37px;
|
||||
width: 37px;
|
||||
}
|
||||
|
||||
.toolbox-button:first-child i {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
.toolbox-button:last-child i {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* START of fade in animation for main toolbar
|
||||
*/
|
||||
|
||||
@@ -28,6 +28,7 @@ $defaultColor: #F1F1F1;
|
||||
$defaultSideBarFontColor: #44A5FF;
|
||||
$defaultSemiDarkColor: #ACACAC;
|
||||
$defaultDarkColor: #2b3d5c;
|
||||
$defaultWarningColor: rgb(215, 121, 118);
|
||||
|
||||
/**
|
||||
* Toolbar
|
||||
@@ -85,10 +86,12 @@ $modalTextColor: #333;
|
||||
/**
|
||||
* Chat
|
||||
*/
|
||||
$chatActionsSeparatorColor: rgb(173, 105, 112);
|
||||
$chatHeaderBackgroundColor: rgba(42, 58, 75, 0.9);
|
||||
$chatInputSeparatorColor: #A4B8D1;
|
||||
$chatLocalMessageBackgroundColor: rgba(26, 108, 180, 1);
|
||||
$chatRemoteMessageBackgroundColor: rgba(240, 243, 247, 0.15);
|
||||
$chatLocalMessageBackgroundColor: rgb(4, 98, 178);
|
||||
$chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
|
||||
$chatRemoteMessageBackgroundColor: rgb(86, 101, 114);
|
||||
$sidebarWidth: 375px;
|
||||
|
||||
/**
|
||||
@@ -163,9 +166,45 @@ $watermarkHeight: 74px;
|
||||
*/
|
||||
$welcomePageDescriptionColor: #fff;
|
||||
$welcomePageFontFamily: inherit;
|
||||
$welcomePageHeaderBackground: linear-gradient(-90deg, #1251AE 0%, #0074FF 50%, #1251AE 100%);
|
||||
$welcomePageBackground: linear-gradient(-90deg, #1251AE 0%, #0074FF 50%, #1251AE 100%);
|
||||
$welcomePageTitleColor: #fff;
|
||||
|
||||
$welcomePageHeaderBackground: none;
|
||||
$welcomePageHeaderBackgroundSmall: none;
|
||||
$welcomePageHeaderBackgroundPosition: none;
|
||||
$welcomePageHeaderBackgroundRepeat: none;
|
||||
$welcomePageHeaderBackgroundSize: none;
|
||||
$welcomePageHeaderPaddingBottom: 0px;
|
||||
|
||||
$welcomePageHeaderTextMarginTop: 35px;
|
||||
$welcomePageHeaderTextMarginBottom: 35px;
|
||||
|
||||
$welcomePageHeaderTextTitleMarginBottom: 16px;
|
||||
|
||||
$welcomePageHeaderTextDescriptionDisplay: inherit;
|
||||
|
||||
$welcomePageEnterRoomWidth: 680px;
|
||||
$welcomePageEnterRoomPadding: 25px 30px;
|
||||
$welcomePageEnterRoomBorderRadius: 0px;
|
||||
|
||||
$welcomePageEnterRoomInputContainerPadding: 0 8px 5px 0px;
|
||||
$welcomePageEnterRoomInputContainerBorderWidth: 0px 0px 2px 0px;
|
||||
$welcomePageEnterRoomInputContainerBorderStyle: solid;
|
||||
$welcomePageEnterRoomInputContainerBorderImage: linear-gradient(to right, #dee1e6, #fff) 1;
|
||||
|
||||
$welcomePageEnterRoomTitleDisplay: inherit;
|
||||
|
||||
$welcomePageTabContainerDisplay: flex;
|
||||
$welcomePageTabContentDisplay: inherit;
|
||||
$welcomePageTabButtonsDisplay: flex;
|
||||
$welcomePageTabDisplay: block;
|
||||
|
||||
$welcomePageButtonWidth: 51px;
|
||||
$welcomePageButtonHeight: 35px;
|
||||
$welcomePageButtonFontWeight: inherit;
|
||||
$welcomePageButtonBorderRadius: 4px;
|
||||
$welcomePageButtonLineHeight: 35px;
|
||||
|
||||
/**
|
||||
* Deep-linking page variables.
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ body.welcome-page {
|
||||
}
|
||||
|
||||
.welcome {
|
||||
background-image: $welcomePageHeaderBackground;
|
||||
background-image: $welcomePageBackground;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family: $welcomePageFontFamily;
|
||||
@@ -13,6 +13,11 @@ body.welcome-page {
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
background-image: $welcomePageHeaderBackground;
|
||||
background-position: $welcomePageHeaderBackgroundPosition;
|
||||
background-repeat: $welcomePageHeaderBackgroundRepeat;
|
||||
background-size: $welcomePageHeaderBackgroundSize;
|
||||
padding-bottom: $welcomePageHeaderPaddingBottom;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -24,8 +29,8 @@ body.welcome-page {
|
||||
.header-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: $watermarkHeight + 35;
|
||||
margin-bottom: 35px;
|
||||
margin-top: $watermarkHeight + $welcomePageHeaderTextMarginTop;
|
||||
margin-bottom: $welcomePageHeaderTextMarginBottom;
|
||||
max-width: calc(100% - 40px);
|
||||
width: 650px;
|
||||
z-index: $zindex2;
|
||||
@@ -36,10 +41,11 @@ body.welcome-page {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.18;
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: $welcomePageHeaderTextTitleMarginBottom;
|
||||
}
|
||||
|
||||
.header-text-description {
|
||||
display: $welcomePageHeaderTextDescriptionDisplay;
|
||||
color: $welcomePageDescriptionColor;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
@@ -51,23 +57,24 @@ body.welcome-page {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: calc(100% - 40px);
|
||||
width: 680px;
|
||||
width: $welcomePageEnterRoomWidth;
|
||||
z-index: $zindex2;
|
||||
background-color: #fff;
|
||||
padding: 25px 30px;
|
||||
padding: $welcomePageEnterRoomPadding;
|
||||
border-radius: $welcomePageEnterRoomBorderRadius;
|
||||
|
||||
.enter-room-input-container {
|
||||
width: 100%;
|
||||
padding-right: 8px;
|
||||
padding-bottom: 5px;
|
||||
padding: $welcomePageEnterRoomInputContainerPadding;
|
||||
text-align: left;
|
||||
color: #253858;
|
||||
height: fit-content;
|
||||
border-width: 0px 0px 2px 0px;
|
||||
border-style: solid;
|
||||
border-image: linear-gradient(to right, #dee1e6, #fff) 1;
|
||||
border-width: $welcomePageEnterRoomInputContainerBorderWidth;
|
||||
border-style: $welcomePageEnterRoomInputContainerBorderStyle;
|
||||
border-image: $welcomePageEnterRoomInputContainerBorderImage;
|
||||
|
||||
.enter-room-title {
|
||||
display: $welcomePageEnterRoomTitleDisplay;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
padding-bottom: 5px;
|
||||
@@ -94,10 +101,11 @@ body.welcome-page {
|
||||
min-height: 354px;
|
||||
width: 710px;
|
||||
background: #75A7E7;
|
||||
display: flex;
|
||||
display: $welcomePageTabContainerDisplay;
|
||||
flex-direction: column;
|
||||
|
||||
.tab-content{
|
||||
display: $welcomePageTabContentDisplay;
|
||||
margin: 5px 0px;
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
@@ -111,13 +119,14 @@ body.welcome-page {
|
||||
.tab-buttons {
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
display: $welcomePageTabButtonsDisplay;
|
||||
flex-grow: 0;
|
||||
flex-direction: row;
|
||||
min-height: 54px;
|
||||
width: 100%;
|
||||
|
||||
.tab {
|
||||
display: $welcomePageTabDisplay;
|
||||
text-align: center;
|
||||
background: rgba(9,30,66,0.37);
|
||||
height: 55px;
|
||||
@@ -138,15 +147,16 @@ body.welcome-page {
|
||||
}
|
||||
|
||||
.welcome-page-button {
|
||||
width: 51px;
|
||||
height: 35px;
|
||||
width: $welcomePageButtonWidth;
|
||||
height: $welcomePageButtonHeight;
|
||||
font-size: 14px;
|
||||
font-weight: $welcomePageButtonFontWeight;
|
||||
background: #0074E0;
|
||||
border-radius: 4px;
|
||||
border-radius: $welcomePageButtonBorderRadius;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 35px;
|
||||
line-height: $welcomePageButtonLineHeight;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
1
css/_welcome_page_settings_toolbar.scss
Normal file
1
css/_welcome_page_settings_toolbar.scss
Normal file
@@ -0,0 +1 @@
|
||||
/** Insert custom CSS for any additional content in the welcome page settings toolbar **/
|
||||
@@ -32,6 +32,7 @@ $flagsImagePath: "../images/";
|
||||
@import 'overlay/overlay';
|
||||
@import 'inlay';
|
||||
@import 'reload_overlay/reload_overlay';
|
||||
@import 'mini_toolbox';
|
||||
@import 'modals/desktop-picker/desktop-picker';
|
||||
@import 'modals/device-selection/device-selection';
|
||||
@import 'modals/dialog';
|
||||
@@ -51,6 +52,7 @@ $flagsImagePath: "../images/";
|
||||
@import 'ringing/ringing';
|
||||
@import 'welcome_page';
|
||||
@import 'welcome_page_content';
|
||||
@import 'welcome_page_settings_toolbar';
|
||||
@import 'toolbars';
|
||||
@import 'jquery.contextMenu';
|
||||
@import 'keyboard-shortcuts';
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
width: -webkit-max-content;
|
||||
word-break: break-all;
|
||||
max-width: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-dialog-dial-in {
|
||||
@@ -86,6 +88,15 @@
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.info-dialog-url-icon {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
|
||||
svg {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.info-dialog-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
@@ -214,4 +225,10 @@
|
||||
-moz-user-select: text;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
|
||||
.info-dialog-url-text-unselectable {
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,29 +19,37 @@ server {
|
||||
ssl_certificate_key /etc/jitsi/meet/jitsi-meet.example.com.key;
|
||||
|
||||
root /usr/share/jitsi-meet;
|
||||
ssi on;
|
||||
index index.html index.htm;
|
||||
error_page 404 /static/404.html;
|
||||
|
||||
location /config.js {
|
||||
location = /config.js {
|
||||
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
}
|
||||
|
||||
location /external_api.js {
|
||||
location = /external_api.js {
|
||||
alias /usr/share/jitsi-meet/libs/external_api.min.js;
|
||||
}
|
||||
|
||||
location ~ ^/([a-zA-Z0-9=\?]+)$ {
|
||||
rewrite ^/(.*)$ / break;
|
||||
}
|
||||
|
||||
location / {
|
||||
ssi on;
|
||||
#ensure all static content can always be found first
|
||||
location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
|
||||
{
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
alias /usr/share/jitsi-meet/$1/$2;
|
||||
}
|
||||
|
||||
# BOSH
|
||||
location /http-bind {
|
||||
location = /http-bind {
|
||||
proxy_pass http://localhost:5280/http-bind;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
|
||||
location ~ ^/([^?&:’“]+)$ {
|
||||
try_files $uri @root_path;
|
||||
}
|
||||
|
||||
location @root_path {
|
||||
rewrite ^/(.*)$ / break;
|
||||
}
|
||||
}
|
||||
|
||||
78
doc/development.md
Normal file
78
doc/development.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Developing Jitsi Meet
|
||||
|
||||
## Building the sources
|
||||
|
||||
Node.js >= 10 and npm >= 6 are required.
|
||||
|
||||
On Debian/Ubuntu systems, the required packages can be installed with:
|
||||
```
|
||||
sudo apt-get install npm nodejs
|
||||
cd jitsi-meet
|
||||
npm install
|
||||
```
|
||||
|
||||
To build the Jitsi Meet application, just type
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
### 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
|
||||
"lib-jitsi-meet": "jitsi/lib-jitsi-meet",
|
||||
```
|
||||
|
||||
To work with local copy you must change the path to:
|
||||
```json
|
||||
"lib-jitsi-meet": "file:///Users/name/local-lib-jitsi-meet-copy",
|
||||
```
|
||||
|
||||
To make the project you must force it to take the sources as 'npm update':
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make
|
||||
```
|
||||
|
||||
Or if you are making only changes to the library:
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make deploy-lib-jitsi-meet
|
||||
```
|
||||
|
||||
Alternative way is to use [npm link](https://docs.npmjs.com/cli/link).
|
||||
It allows to link `lib-jitsi-meet` dependency to local source in few steps:
|
||||
|
||||
```bash
|
||||
cd lib-jitsi-meet
|
||||
|
||||
#### create global symlink for lib-jitsi-meet package
|
||||
npm link
|
||||
|
||||
cd ../jitsi-meet
|
||||
|
||||
#### create symlink from the local node_modules folder to the global lib-jitsi-meet symlink
|
||||
npm link lib-jitsi-meet
|
||||
```
|
||||
|
||||
After changes in local `lib-jitsi-meet` repository, you can rebuild it with `npm run install` and your `jitsi-meet` repository will use that modified library.
|
||||
Note: when using node version 4.x, the make file of jitsi-meet do npm update which will delete the link. It is no longer the case with version 6.x.
|
||||
|
||||
If you do not want to use local repository anymore you should run
|
||||
```bash
|
||||
cd jitsi-meet
|
||||
npm unlink lib-jitsi-meet
|
||||
npm install
|
||||
```
|
||||
### Running with webpack-dev-server for development
|
||||
|
||||
Use it at the CLI, type
|
||||
```
|
||||
make dev
|
||||
```
|
||||
|
||||
By default the backend deployment used is `beta.meet.jit.si`. You can point the Jitsi-Meet app at a different backend by using a proxy server. To do this, set the WEBPACK_DEV_SERVER_PROXY_TARGET variable:
|
||||
```
|
||||
export WEBPACK_DEV_SERVER_PROXY_TARGET=https://your-example-server.com
|
||||
make dev
|
||||
```
|
||||
|
||||
The app should be running at https://localhost:8080/
|
||||
@@ -148,6 +148,7 @@
|
||||
<!--#include virtual="title.html" -->
|
||||
<!--#include virtual="plugin.head.html" -->
|
||||
<!--#include virtual="static/welcomePageAdditionalContent.html" -->
|
||||
<!--#include virtual="static/settingsToolbarAdditionalContent.html" -->
|
||||
</head>
|
||||
<body>
|
||||
<div id="react"></div>
|
||||
|
||||
@@ -27,6 +27,7 @@ var interfaceConfig = {
|
||||
SHOW_DEEP_LINKING_IMAGE: false,
|
||||
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
|
||||
DISPLAY_WELCOME_PAGE_CONTENT: true,
|
||||
DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT: false,
|
||||
APP_NAME: 'Jitsi Meet',
|
||||
NATIVE_APP_NAME: 'Jitsi Meet',
|
||||
PROVIDER_NAME: 'Jitsi',
|
||||
@@ -50,7 +51,7 @@ var interfaceConfig = {
|
||||
'fodeviceselection', 'hangup', 'profile', 'info', 'chat', 'recording',
|
||||
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
'tileview', 'videobackgroundblur'
|
||||
'tileview', 'videobackgroundblur', 'download', 'help'
|
||||
],
|
||||
|
||||
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ],
|
||||
@@ -221,6 +222,13 @@ var interfaceConfig = {
|
||||
* milliseconds, those notifications should remain displayed.
|
||||
*/
|
||||
// ENFORCE_NOTIFICATION_AUTO_DISMISS_TIMEOUT: 15000,
|
||||
|
||||
// List of undocumented settings
|
||||
/**
|
||||
INDICATOR_FONT_SIZES
|
||||
MOBILE_DYNAMIC_LINK
|
||||
PHONE_NUMBER_REGEX
|
||||
*/
|
||||
};
|
||||
|
||||
/* eslint-enable no-unused-vars, no-var, max-len */
|
||||
|
||||
21
ios/Podfile
21
ios/Podfile
@@ -17,9 +17,20 @@ target 'JitsiMeet' do
|
||||
# React Native and its dependencies
|
||||
#
|
||||
|
||||
pod 'FBLazyVector', :path => '../node_modules/react-native/Libraries/FBLazyVector/'
|
||||
pod 'FBReactNativeSpec', :path => '../node_modules/react-native/Libraries/FBReactNativeSpec/'
|
||||
pod 'RCTRequired', :path => '../node_modules/react-native/Libraries/RCTRequired/'
|
||||
pod 'RCTTypeSafety', :path => '../node_modules/react-native/Libraries/TypeSafety/'
|
||||
pod 'React', :path => '../node_modules/react-native/'
|
||||
pod 'React-Core', :path => '../node_modules/react-native/React'
|
||||
pod 'React-DevSupport', :path => '../node_modules/react-native/React'
|
||||
pod 'ReactCommon', :path => '../node_modules/react-native/ReactCommon', :subspecs => [
|
||||
'turbomodule'
|
||||
]
|
||||
pod 'React-Core', :path => '../node_modules/react-native/', :subspecs => [
|
||||
'CoreModulesHeaders',
|
||||
'DevSupport',
|
||||
'RCTWebSocket'
|
||||
]
|
||||
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
|
||||
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
|
||||
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
|
||||
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
|
||||
@@ -29,13 +40,12 @@ target 'JitsiMeet' do
|
||||
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
|
||||
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
|
||||
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
|
||||
pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'
|
||||
|
||||
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
||||
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
||||
@@ -52,7 +62,7 @@ target 'JitsiMeet' do
|
||||
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
||||
pod 'BVLinearGradient', :path => '../node_modules/react-native-linear-gradient'
|
||||
pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-community/async-storage'
|
||||
pod 'RNGoogleSignin', :path => '../node_modules/react-native-google-signin'
|
||||
pod 'RNGoogleSignin', :path => '../node_modules/@react-native-community/google-signin'
|
||||
pod 'RNSound', :path => '../node_modules/react-native-sound'
|
||||
pod 'RNSVG', :path => '../node_modules/react-native-svg'
|
||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
||||
@@ -71,6 +81,7 @@ post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'YES'
|
||||
config.build_settings['SUPPORTS_MACCATALYST'] = 'NO'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
400
ios/Podfile.lock
400
ios/Podfile.lock
@@ -1,5 +1,10 @@
|
||||
PODS:
|
||||
- Amplitude-iOS (4.0.4)
|
||||
- AppAuth (1.2.0):
|
||||
- AppAuth/Core (= 1.2.0)
|
||||
- AppAuth/ExternalUserAgent (= 1.2.0)
|
||||
- AppAuth/Core (1.2.0)
|
||||
- AppAuth/ExternalUserAgent (1.2.0)
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BVLinearGradient (2.5.6):
|
||||
- React
|
||||
@@ -10,6 +15,14 @@ PODS:
|
||||
- Fabric (~> 1.9.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- Fabric (1.9.0)
|
||||
- FBLazyVector (0.61.1)
|
||||
- FBReactNativeSpec (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.61.1)
|
||||
- RCTTypeSafety (= 0.61.1)
|
||||
- React-Core (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- ReactCommon/turbomodule/core (= 0.61.1)
|
||||
- Firebase/Core (5.18.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (= 5.7.0)
|
||||
@@ -54,18 +67,10 @@ PODS:
|
||||
- GoogleUtilities/Network (~> 5.2)
|
||||
- "GoogleUtilities/NSData+zlib (~> 5.2)"
|
||||
- nanopb (~> 0.3)
|
||||
- GoogleSignIn (4.4.0):
|
||||
- "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)"
|
||||
- "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)"
|
||||
- GoogleSignIn (5.0.1):
|
||||
- AppAuth (~> 1.2)
|
||||
- GTMAppAuth (~> 1.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- GoogleToolboxForMac/DebugUtils (2.2.0):
|
||||
- GoogleToolboxForMac/Defines (= 2.2.0)
|
||||
- GoogleToolboxForMac/Defines (2.2.0)
|
||||
- "GoogleToolboxForMac/NSDictionary+URLArguments (2.2.0)":
|
||||
- GoogleToolboxForMac/DebugUtils (= 2.2.0)
|
||||
- GoogleToolboxForMac/Defines (= 2.2.0)
|
||||
- "GoogleToolboxForMac/NSString+URLArguments (= 2.2.0)"
|
||||
- "GoogleToolboxForMac/NSString+URLArguments (2.2.0)"
|
||||
- GoogleUtilities/AppDelegateSwizzler (5.4.1):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
@@ -84,58 +89,183 @@ PODS:
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (5.4.1):
|
||||
- GoogleUtilities/Logger
|
||||
- GTMSessionFetcher/Core (1.2.1)
|
||||
- GTMAppAuth (1.0.0):
|
||||
- AppAuth/Core (~> 1.0)
|
||||
- GTMSessionFetcher (~> 1.1)
|
||||
- GTMSessionFetcher (1.2.2):
|
||||
- GTMSessionFetcher/Full (= 1.2.2)
|
||||
- GTMSessionFetcher/Core (1.2.2)
|
||||
- GTMSessionFetcher/Full (1.2.2):
|
||||
- GTMSessionFetcher/Core (= 1.2.2)
|
||||
- nanopb (0.3.901):
|
||||
- nanopb/decode (= 0.3.901)
|
||||
- nanopb/encode (= 0.3.901)
|
||||
- nanopb/decode (0.3.901)
|
||||
- nanopb/encode (0.3.901)
|
||||
- ObjectiveDropboxOfficial (3.9.4)
|
||||
- React (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-DevSupport (= 0.60.5)
|
||||
- React-RCTActionSheet (= 0.60.5)
|
||||
- React-RCTAnimation (= 0.60.5)
|
||||
- React-RCTBlob (= 0.60.5)
|
||||
- React-RCTImage (= 0.60.5)
|
||||
- React-RCTLinking (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTSettings (= 0.60.5)
|
||||
- React-RCTText (= 0.60.5)
|
||||
- React-RCTVibration (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-Core (0.60.5):
|
||||
- RCTRequired (0.61.1)
|
||||
- RCTTypeSafety (0.61.1):
|
||||
- FBLazyVector (= 0.61.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-cxxreact (= 0.60.5)
|
||||
- React-jsiexecutor (= 0.60.5)
|
||||
- yoga (= 0.60.5.React)
|
||||
- React-cxxreact (0.60.5):
|
||||
- RCTRequired (= 0.61.1)
|
||||
- React-Core (= 0.61.1)
|
||||
- React (0.61.1):
|
||||
- React-Core (= 0.61.1)
|
||||
- React-Core/DevSupport (= 0.61.1)
|
||||
- React-Core/RCTWebSocket (= 0.61.1)
|
||||
- React-RCTActionSheet (= 0.61.1)
|
||||
- React-RCTAnimation (= 0.61.1)
|
||||
- React-RCTBlob (= 0.61.1)
|
||||
- React-RCTImage (= 0.61.1)
|
||||
- React-RCTLinking (= 0.61.1)
|
||||
- React-RCTNetwork (= 0.61.1)
|
||||
- React-RCTSettings (= 0.61.1)
|
||||
- React-RCTText (= 0.61.1)
|
||||
- React-RCTVibration (= 0.61.1)
|
||||
- React-Core (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.1)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/Default (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.1)
|
||||
- React-Core/RCTWebSocket (= 0.61.1)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- React-jsinspector (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.61.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.1)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsiexecutor (= 0.61.1)
|
||||
- Yoga
|
||||
- React-CoreModules (0.61.1):
|
||||
- FBReactNativeSpec (= 0.61.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.61.1)
|
||||
- React-Core/CoreModulesHeaders (= 0.61.1)
|
||||
- React-RCTImage (= 0.61.1)
|
||||
- ReactCommon/turbomodule/core (= 0.61.1)
|
||||
- React-cxxreact (0.61.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsinspector (= 0.60.5)
|
||||
- React-DevSupport (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-jsi (0.60.5):
|
||||
- React-jsinspector (= 0.61.1)
|
||||
- React-jsi (0.61.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsi/Default (= 0.60.5)
|
||||
- React-jsi/Default (0.60.5):
|
||||
- React-jsi/Default (= 0.61.1)
|
||||
- React-jsi/Default (0.61.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsiexecutor (0.60.5):
|
||||
- React-jsiexecutor (0.61.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.60.5)
|
||||
- React-jsi (= 0.60.5)
|
||||
- React-jsinspector (0.60.5)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-jsinspector (0.61.1)
|
||||
- react-native-background-timer (2.1.1):
|
||||
- React
|
||||
- react-native-calendar-events (1.7.3):
|
||||
@@ -146,35 +276,66 @@ PODS:
|
||||
- React
|
||||
- react-native-webrtc (1.75.0):
|
||||
- React
|
||||
- react-native-webview (5.8.1):
|
||||
- react-native-webview (7.4.1):
|
||||
- React
|
||||
- React-RCTActionSheet (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTAnimation (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTBlob (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-RCTImage (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTLinking (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTSettings (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTText (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTVibration (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTWebSocket (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTActionSheet (0.61.1):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.61.1)
|
||||
- React-RCTAnimation (0.61.1):
|
||||
- React-Core/RCTAnimationHeaders (= 0.61.1)
|
||||
- React-RCTBlob (0.61.1):
|
||||
- React-Core/RCTBlobHeaders (= 0.61.1)
|
||||
- React-Core/RCTWebSocket (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- React-RCTNetwork (= 0.61.1)
|
||||
- React-RCTImage (0.61.1):
|
||||
- React-Core/RCTImageHeaders (= 0.61.1)
|
||||
- React-RCTNetwork (= 0.61.1)
|
||||
- React-RCTLinking (0.61.1):
|
||||
- React-Core/RCTLinkingHeaders (= 0.61.1)
|
||||
- React-RCTNetwork (0.61.1):
|
||||
- React-Core/RCTNetworkHeaders (= 0.61.1)
|
||||
- React-RCTSettings (0.61.1):
|
||||
- React-Core/RCTSettingsHeaders (= 0.61.1)
|
||||
- React-RCTText (0.61.1):
|
||||
- React-Core/RCTTextHeaders (= 0.61.1)
|
||||
- React-RCTVibration (0.61.1):
|
||||
- React-Core/RCTVibrationHeaders (= 0.61.1)
|
||||
- ReactCommon/jscallinvoker (0.61.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- ReactCommon/turbomodule (0.61.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 0.61.1)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- ReactCommon/jscallinvoker (= 0.61.1)
|
||||
- ReactCommon/turbomodule/core (= 0.61.1)
|
||||
- ReactCommon/turbomodule/samples (= 0.61.1)
|
||||
- ReactCommon/turbomodule/core (0.61.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 0.61.1)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- ReactCommon/jscallinvoker (= 0.61.1)
|
||||
- ReactCommon/turbomodule/samples (0.61.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 0.61.1)
|
||||
- React-cxxreact (= 0.61.1)
|
||||
- React-jsi (= 0.61.1)
|
||||
- ReactCommon/jscallinvoker (= 0.61.1)
|
||||
- ReactCommon/turbomodule/core (= 0.61.1)
|
||||
- RNCAsyncStorage (1.3.4):
|
||||
- React
|
||||
- RNGoogleSignin (2.0.0):
|
||||
- GoogleSignIn (~> 4.4.0)
|
||||
- RNGoogleSignin (3.0.1):
|
||||
- GoogleSignIn (~> 5.0.0)
|
||||
- React
|
||||
- RNSound (0.11.0):
|
||||
- React
|
||||
@@ -185,7 +346,7 @@ PODS:
|
||||
- React
|
||||
- RNWatch (0.2.0):
|
||||
- React
|
||||
- yoga (0.60.5.React)
|
||||
- Yoga (1.14.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Amplitude-iOS (~> 4.0.4)
|
||||
@@ -194,15 +355,21 @@ DEPENDENCIES:
|
||||
- Crashlytics (~> 3.12.0)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- Fabric (~> 1.9.0)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector/`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec/`)
|
||||
- Firebase/Core (~> 5.18.0)
|
||||
- Firebase/DynamicLinks (~> 5.18.0)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- ObjectiveDropboxOfficial (~> 3.9.4)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired/`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety/`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-Core (from `../node_modules/react-native/React`)
|
||||
- React-Core/CoreModulesHeaders (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
- React-DevSupport (from `../node_modules/react-native/React`)
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
@@ -221,16 +388,16 @@ DEPENDENCIES:
|
||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`)
|
||||
- ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
|
||||
- RNGoogleSignin (from `../node_modules/react-native-google-signin`)
|
||||
- "RNGoogleSignin (from `../node_modules/@react-native-community/google-signin`)"
|
||||
- RNSound (from `../node_modules/react-native-sound`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- RNWatch (from `../node_modules/react-native-watch-connectivity`)
|
||||
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
https://github.com/CocoaPods/Specs.git:
|
||||
- Amplitude-iOS
|
||||
- boost-for-react-native
|
||||
- CocoaLumberjack
|
||||
@@ -243,30 +410,40 @@ SPEC REPOS:
|
||||
- FirebaseDynamicLinks
|
||||
- FirebaseInstanceID
|
||||
- GoogleAppMeasurement
|
||||
- GoogleSignIn
|
||||
- GoogleToolboxForMac
|
||||
- GoogleUtilities
|
||||
- GTMSessionFetcher
|
||||
- nanopb
|
||||
- ObjectiveDropboxOfficial
|
||||
trunk:
|
||||
- AppAuth
|
||||
- GoogleSignIn
|
||||
- GTMAppAuth
|
||||
- GTMSessionFetcher
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
BVLinearGradient:
|
||||
:path: "../node_modules/react-native-linear-gradient"
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
FBLazyVector:
|
||||
:path: "../node_modules/react-native/Libraries/FBLazyVector/"
|
||||
FBReactNativeSpec:
|
||||
:path: "../node_modules/react-native/Libraries/FBReactNativeSpec/"
|
||||
Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired/"
|
||||
RCTTypeSafety:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety/"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/React"
|
||||
:path: "../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
:path: "../node_modules/react-native/React/CoreModules"
|
||||
React-cxxreact:
|
||||
:path: "../node_modules/react-native/ReactCommon/cxxreact"
|
||||
React-DevSupport:
|
||||
:path: "../node_modules/react-native/React"
|
||||
React-jsi:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsi"
|
||||
React-jsiexecutor:
|
||||
@@ -303,29 +480,32 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/Text"
|
||||
React-RCTVibration:
|
||||
:path: "../node_modules/react-native/Libraries/Vibration"
|
||||
React-RCTWebSocket:
|
||||
:path: "../node_modules/react-native/Libraries/WebSocket"
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-community/async-storage"
|
||||
RNGoogleSignin:
|
||||
:path: "../node_modules/react-native-google-signin"
|
||||
:path: "../node_modules/@react-native-community/google-signin"
|
||||
RNSound:
|
||||
:path: "../node_modules/react-native-sound"
|
||||
RNSVG:
|
||||
:path: "../node_modules/react-native-svg"
|
||||
RNWatch:
|
||||
:path: "../node_modules/react-native-watch-connectivity"
|
||||
yoga:
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Amplitude-iOS: 2ad4d7270c99186236c1272a3a9425463b1ae1a7
|
||||
AppAuth: bce82c76043657c99d91e7882e8a9e1a93650cd4
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
CocoaLumberjack: 2f44e60eb91c176d471fdba43b9e3eae6a721947
|
||||
Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
Fabric: f988e33c97f08930a413e08123064d2e5f68d655
|
||||
FBLazyVector: 0846affdb2924b01093eb696766ecb0104e409e0
|
||||
FBReactNativeSpec: c4cf958af1b97799b524f63a26a1c509c0295b04
|
||||
Firebase: 02f3281965c075426141a0ce1277e9de6649cab9
|
||||
FirebaseAnalytics: 23851fe602c872130a2c5c55040b302120346cc2
|
||||
FirebaseAnalyticsInterop: efbe45c8385ec626e29f9525e5ebd38520dfb6c1
|
||||
@@ -335,42 +515,44 @@ SPEC CHECKSUMS:
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
GoogleAppMeasurement: 6cf307834da065863f9faf4c0de0a936d81dd832
|
||||
GoogleSignIn: 7ff245e1a7b26d379099d3243a562f5747e23d39
|
||||
GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d
|
||||
GoogleSignIn: 3a51b9bb8e48b635fd7f4272cee06ca260345b86
|
||||
GoogleUtilities: 1e25823cbf46540b4284f6ef8e17b3a68ee12bbc
|
||||
GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca
|
||||
GTMAppAuth: 4deac854479704f348309e7b66189e604cf5e01e
|
||||
GTMSessionFetcher: 61bb0f61a4cb560030f1222021178008a5727a23
|
||||
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
|
||||
ObjectiveDropboxOfficial: a5afefc83f6467c42c45f2253f583f2ad1ffc701
|
||||
React: 53c53c4d99097af47cf60594b8706b4e3321e722
|
||||
React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64
|
||||
React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395
|
||||
React-DevSupport: 197fb409737cff2c4f9986e77c220d7452cb9f9f
|
||||
React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2
|
||||
React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30
|
||||
React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4
|
||||
RCTRequired: 53825815218847d3e9c7b6d92ad2d197a926d51e
|
||||
RCTTypeSafety: d886540c518e53064dfa081bf7693fd650699b92
|
||||
React: 5dea58967c421bd1fdf6b94c18b9ed0f5134683c
|
||||
React-Core: b381e65aa0da9b94b9dcdc4a99298075b1c3876c
|
||||
React-CoreModules: 4ed224e29848ba76d26aacb8e3fe85712d3c4fe1
|
||||
React-cxxreact: 52c98f5c1fb4e4d9f4b588742718350a55f4f088
|
||||
React-jsi: 61ff417c95e6c3af50fb96399037e80752fb5ce7
|
||||
React-jsiexecutor: ee45274419eb95614bbbadb98e20684c5f29996e
|
||||
React-jsinspector: 574d597112f9ea3d1b717f6fb62aef764c70dd6f
|
||||
react-native-background-timer: 0d34748e53a972507c66963490c775321a88f6f2
|
||||
react-native-calendar-events: 2fe35a9294af05de0ed819d3a1b5dac048d2c010
|
||||
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
|
||||
react-native-netinfo: 8d8db463bcc5db66a8ac5c48a7d86beb3b92f61a
|
||||
react-native-webrtc: c5e3d631179a933548a8e49bddbd8fad02586095
|
||||
react-native-webview: a95842e3f351a6d2c8bc8bcc9eab689c7e7e5ad4
|
||||
React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90
|
||||
React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e
|
||||
React-RCTBlob: 5e2b55f76e9a1c7ae52b826923502ddc3238df24
|
||||
React-RCTImage: f5f1c50922164e89bdda67bcd0153952a5cfe719
|
||||
React-RCTLinking: d0ecbd791e9ddddc41fa1f66b0255de90e8ee1e9
|
||||
React-RCTNetwork: e26946300b0ab7bb6c4a6348090e93fa21f33a9d
|
||||
React-RCTSettings: d0d37cb521b7470c998595a44f05847777cc3f42
|
||||
React-RCTText: b074d89033583d4f2eb5faf7ea2db3a13c7553a2
|
||||
React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0
|
||||
React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4
|
||||
react-native-webview: 4dbc1d2a4a6b9c5e9e723c62651917aa2b5e579e
|
||||
React-RCTActionSheet: af4d951113b1e068bb30611f91b984a7a73597ff
|
||||
React-RCTAnimation: 4f518d70bb6890b7c3d9d732f84786d6693ca297
|
||||
React-RCTBlob: 072a4888c08de0eef6d04eaa727d25e577e6ff26
|
||||
React-RCTImage: 78c5cdf1b2de6cd3cd650dd741868fad19a35528
|
||||
React-RCTLinking: 486ed1c9a659c7f9fea213868f8930b9a0a79f07
|
||||
React-RCTNetwork: e79599f3160b459da03447e32b8bcca1a0f0f797
|
||||
React-RCTSettings: 48b7c5a64ffe0c54c39d59eb7d9036e72305f95a
|
||||
React-RCTText: 81b62b4e7f11531a5154e4daa5617670d5a2d5de
|
||||
React-RCTVibration: 8be61459e3749d1fb02cf414edd05b3007622882
|
||||
ReactCommon: 4fba5be89efdf0b5720e0adb3d8d7edf6e532db0
|
||||
RNCAsyncStorage: 8e31405a9f12fbf42c2bb330e4560bfd79c18323
|
||||
RNGoogleSignin: d030c6c6591db24c3cee649f64c7babf0a1699a0
|
||||
RNGoogleSignin: 39336070b35fc4cea6a98cf111e00480317be0ae
|
||||
RNSound: c980916b596cc15c8dcd2f6ecd3b13c4881dbe20
|
||||
RNSVG: aac12785382e8fd4f28d072fe640612e34914631
|
||||
RNWatch: 09738b339eceb66e4d80a2371633ca5fb380fa42
|
||||
yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411
|
||||
Yoga: d8c572ddec8d05b7dba08e4e5f1924004a177078
|
||||
|
||||
PODFILE CHECKSUM: 86bb4d2bc94c6c76b971b9a33e5b2ced9bbfb09f
|
||||
PODFILE CHECKSUM: cb84b325b724c6ef7c8b24aa52ca7b6f681a095c
|
||||
|
||||
COCOAPODS: 1.7.2
|
||||
COCOAPODS: 1.8.1
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
@@ -52,8 +50,8 @@
|
||||
ReferencedContainer = "container:app.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -75,8 +73,6 @@
|
||||
ReferencedContainer = "container:app.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>19.3.0</string>
|
||||
<string>19.4.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>19.3.0</string>
|
||||
<string>19.4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>19.3.0</string>
|
||||
<string>19.4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
||||
103
ios/ci/build-ipa.sh
Executable file
103
ios/ci/build-ipa.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Mandatory arguments with no default values provided:
|
||||
# PR_REPO_SLUG - the Github name of the repo to be merged into the origin/master
|
||||
# PR_BRANCH - the branch to be merged, if set to "master" no merge will happen
|
||||
# IPA_DEPLOY_LOCATION - the location understandable by the "scp" command
|
||||
# executed at the end of the script to deploy the output .ipa file
|
||||
# LIB_JITSI_MEET_PKG (optional) - the npm package for lib-jitsi-meet which will
|
||||
# be put in place of the current version in the package.json file.
|
||||
#
|
||||
# Other than that the script requires the following env variables to be set:
|
||||
#
|
||||
# DEPLOY_SSH_CERT_URL - the SSH private key used by the 'scp' command to deploy
|
||||
# the .ipa. It is expected to be encrypted with the $ENCRYPTION_PASSWORD.
|
||||
# ENCRYPTION_PASSWORD - the password used to decrypt certificate/key files used
|
||||
# in the script.
|
||||
# IOS_TEAM_ID - the team ID inserted into build-ipa-.plist.template file in
|
||||
# place of "YOUR_TEAM_ID".
|
||||
|
||||
function echoAndExit1() {
|
||||
echo $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -z $PR_REPO_SLUG ]; then
|
||||
echoAndExit1 "No PR_REPO_SLUG defined"
|
||||
fi
|
||||
if [ -z $PR_BRANCH ]; then
|
||||
echoAndExit1 "No PR_BRANCH defined"
|
||||
fi
|
||||
if [ -z $IPA_DEPLOY_LOCATION ]; then
|
||||
echoAndExit1 "No IPA_DEPLOY_LOCATION defined"
|
||||
fi
|
||||
|
||||
echo "PR_REPO_SLUG=${PR_REPO_SLUG} PR_BRANCH=${PR_BRANCH}"
|
||||
|
||||
# do the marge and git log
|
||||
|
||||
if [ $PR_BRANCH != "master" ]; then
|
||||
echo "Will merge ${PR_REPO_SLUG}/${PR_BRANCH} into master"
|
||||
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
|
||||
git fetch origin master
|
||||
git checkout master
|
||||
git pull https://github.com/${PR_REPO_SLUG}.git $PR_BRANCH --no-edit
|
||||
fi
|
||||
|
||||
# Link this lib-jitsi-meet checkout in jitsi-meet through the package.json
|
||||
if [ ! -z ${LIB_JITSI_MEET_PKG} ];
|
||||
then
|
||||
echo "Adjusting lib-jitsi-meet package in package.json to ${LIB_JITSI_MEET_PKG}"
|
||||
# escape for the sed
|
||||
LIB_JITSI_MEET_PKG=$(echo $LIB_JITSI_MEET_PKG | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')
|
||||
sed -i.bak -e "s/\"lib-jitsi-meet.*/\"lib-jitsi-meet\"\: \"${LIB_JITSI_MEET_PKG}\",/g" package.json
|
||||
echo "Package.json lib-jitsi-meet line:"
|
||||
grep lib-jitsi-meet package.json
|
||||
else
|
||||
echo "LIB_JITSI_MEET_PKG var not set - will not modify the package.json"
|
||||
fi
|
||||
|
||||
git log -20 --graph --pretty=format':%C(yellow)%h%Cblue%d%Creset %s %C(white) %an, %ar%Creset'
|
||||
|
||||
# certificates
|
||||
|
||||
CERT_DIR="ios/ci/certs"
|
||||
|
||||
mkdir -p $CERT_DIR
|
||||
|
||||
curl -L -o ${CERT_DIR}/id_rsa.enc ${DEPLOY_SSH_CERT_URL}
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/id_rsa.enc -d -a -out ${CERT_DIR}/id_rsa
|
||||
chmod 0600 ${CERT_DIR}/id_rsa
|
||||
ssh-add ${CERT_DIR}/id_rsa
|
||||
|
||||
npm install
|
||||
|
||||
# Ever since the Apple Watch app has been added the bitcode for WebRTC needs to be downloaded in order to build successfully
|
||||
./node_modules/react-native-webrtc/tools/downloadBitcode.sh
|
||||
|
||||
cd ios
|
||||
pod install --repo-update --no-ansi
|
||||
cd ..
|
||||
|
||||
mkdir -p /tmp/jitsi-meet/
|
||||
|
||||
xcodebuild archive -quiet -workspace ios/jitsi-meet.xcworkspace -scheme jitsi-meet -configuration Release -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive
|
||||
|
||||
sed -e "s/YOUR_TEAM_ID/${IOS_TEAM_ID}/g" ios/ci/build-ipa.plist.template > ios/ci/build-ipa.plist
|
||||
|
||||
IPA_EXPORT_DIR=/tmp/jitsi-meet/jitsi-meet-ipa
|
||||
|
||||
xcodebuild -quiet -exportArchive -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive -exportPath $IPA_EXPORT_DIR -exportOptionsPlist ios/ci/build-ipa.plist
|
||||
|
||||
echo "Will try deploy the .ipa to: ${IPA_DEPLOY_LOCATION}"
|
||||
|
||||
if [ ! -z ${SCP_PROXY_HOST} ];
|
||||
then
|
||||
scp -o ProxyCommand="ssh -t -A -l %r ${SCP_PROXY_HOST} -o \"StrictHostKeyChecking no\" -o \"BatchMode yes\" -W %h:%p" -o StrictHostKeyChecking=no -o LogLevel=DEBUG "${IPA_EXPORT_DIR}/jitsi-meet.ipa" "${IPA_DEPLOY_LOCATION}"
|
||||
else
|
||||
scp -o StrictHostKeyChecking=no -o LogLevel=DEBUG "${IPA_EXPORT_DIR}/jitsi-meet.ipa" "${IPA_DEPLOY_LOCATION}"
|
||||
fi
|
||||
|
||||
rm -r /tmp/jitsi-meet/
|
||||
rm -r $CERT_DIR
|
||||
100
ios/ci/setup-certificates.sh
Executable file
100
ios/ci/setup-certificates.sh
Executable file
@@ -0,0 +1,100 @@
|
||||
# The script is based on tutorial written by Antonis Tsakiridis published at:
|
||||
# https://medium.com/@atsakiridis/continuous-deployment-for-ios-using-travis-ci-55dcea342d9
|
||||
#
|
||||
# APPLE_CERT_URL - the URL pointing to Apple certificate (set to
|
||||
# http://developer.apple.com/certificationauthority/AppleWWDRCA.cer by default)
|
||||
# DEPLOY_SSH_CERT_URL - the SSH private key used by the 'scp' command to deploy
|
||||
# the .ipa. It is expected to be encrypted with the $ENCRYPTION_PASSWORD.
|
||||
# ENCRYPTION_PASSWORD - the password used to decrypt certificate/key files used
|
||||
# in the script.
|
||||
# IOS_DEV_CERT_KEY_URL - URL pointing to provisioning profile certificate key
|
||||
# file (development-key.p12.enc from the tutorial) encrypted with the
|
||||
# $ENCRYPTION_PASSWORD.
|
||||
# IOS_DEV_CERT_URL - URL pointing to provisioning profile certificate file
|
||||
# (development-cert.cer.enc from the tutorial) encrypted with the
|
||||
# $ENCRYPTION_PASSWORD.
|
||||
# IOS_DEV_PROV_PROFILE_URL - URL pointing to provisioning profile file
|
||||
# (profile-development-olympus.mobileprovision.enc from the tutorial) encrypted
|
||||
# IOS_DEV_WATCH_PROV_PROFILE_URL - URL pointing to watch app provisioning profile file(encrypted).
|
||||
# with the $ENCRYPTION_PASSWORD.
|
||||
# IOS_SIGNING_CERT_PASSWORD - the password to the provisioning profile
|
||||
# certificate key (used to open development-key.p12 from the tutorial).
|
||||
|
||||
function echoAndExit1() {
|
||||
echo $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
CERT_DIR=$1
|
||||
|
||||
if [ -z $CERT_DIR ]; then
|
||||
echoAndExit1 "First argument must be certificates directory"
|
||||
fi
|
||||
|
||||
if [ -z $APPLE_CERT_URL ]; then
|
||||
APPLE_CERT_URL="http://developer.apple.com/certificationauthority/AppleWWDRCA.cer"
|
||||
fi
|
||||
|
||||
if [ -z $DEPLOY_SSH_CERT_URL ]; then
|
||||
echoAndExit1 "DEPLOY_SSH_CERT_URL env var is not defined"
|
||||
fi
|
||||
|
||||
if [ -z $ENCRYPTION_PASSWORD ]; then
|
||||
echoAndExit1 "ENCRYPTION_PASSWORD env var is not defined"
|
||||
fi
|
||||
|
||||
if [ -z $IOS_DEV_CERT_KEY_URL ]; then
|
||||
echoAndExit1 "IOS_DEV_CERT_KEY_URL env var is not defined"
|
||||
fi
|
||||
|
||||
if [ -z $IOS_DEV_CERT_URL ]; then
|
||||
echoAndExit1 "IOS_DEV_CERT_URL env var is not defined"
|
||||
fi
|
||||
|
||||
if [ -z $IOS_DEV_PROV_PROFILE_URL ]; then
|
||||
echoAndExit1 "IOS_DEV_PROV_PROFILE_URL env var is not defined"
|
||||
fi
|
||||
|
||||
if [ -z $IOS_DEV_WATCH_PROV_PROFILE_URL ]; then
|
||||
echoAndExit1 "IOS_DEV_WATCH_PROV_PROFILE_URL env var is not defined"
|
||||
fi
|
||||
|
||||
if [ -z $IOS_SIGNING_CERT_PASSWORD ]; then
|
||||
echoAndExit1 "IOS_SIGNING_CERT_PASSWORD env var is not defined"
|
||||
fi
|
||||
|
||||
# certificates
|
||||
|
||||
curl -L -o ${CERT_DIR}/AppleWWDRCA.cer 'http://developer.apple.com/certificationauthority/AppleWWDRCA.cer'
|
||||
curl -L -o ${CERT_DIR}/dev-cert.cer.enc ${IOS_DEV_CERT_URL}
|
||||
curl -L -o ${CERT_DIR}/dev-key.p12.enc ${IOS_DEV_CERT_KEY_URL}
|
||||
curl -L -o ${CERT_DIR}/dev-profile.mobileprovision.enc ${IOS_DEV_PROV_PROFILE_URL}
|
||||
curl -L -o ${CERT_DIR}/dev-watch-profile.mobileprovision.enc ${IOS_DEV_WATCH_PROV_PROFILE_URL}
|
||||
|
||||
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-cert.cer.enc -d -a -out ${CERT_DIR}/dev-cert.cer
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-key.p12.enc -d -a -out ${CERT_DIR}/dev-key.p12
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-profile.mobileprovision.enc -d -a -out ${CERT_DIR}/dev-profile.mobileprovision
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-watch-profile.mobileprovision.enc -d -a -out ${CERT_DIR}/dev-watch-profile.mobileprovision
|
||||
|
||||
security create-keychain -p $ENCRYPTION_PASSWORD ios-build.keychain
|
||||
security default-keychain -s ios-build.keychain
|
||||
security unlock-keychain -p $ENCRYPTION_PASSWORD ios-build.keychain
|
||||
security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain
|
||||
|
||||
echo "importing Apple cert"
|
||||
security import ${CERT_DIR}/AppleWWDRCA.cer -k ios-build.keychain -A
|
||||
echo "importing dev-cert.cer"
|
||||
security import ${CERT_DIR}/dev-cert.cer -k ios-build.keychain -A
|
||||
echo "importing dev-key.p12"
|
||||
security import ${CERT_DIR}/dev-key.p12 -k ios-build.keychain -P $IOS_SIGNING_CERT_PASSWORD -A
|
||||
|
||||
echo "will set-key-partition-list"
|
||||
# Fix for OS X Sierra that hungs in the codesign step
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k $ENCRYPTION_PASSWORD ios-build.keychain > /dev/null
|
||||
echo "done set-key-partition-list"
|
||||
|
||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
|
||||
cp "${CERT_DIR}/dev-profile.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
cp "${CERT_DIR}/dev-watch-profile.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
@@ -42,6 +42,7 @@
|
||||
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69EFA0B209A0F660027712B /* JMCallKitListener.swift */; };
|
||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425E204EF76800E062DD /* DragGestureController.swift */; };
|
||||
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */; };
|
||||
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
|
||||
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AAC92317FFCD00290BEC /* LogUtils.h */; };
|
||||
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */; };
|
||||
DE762DB422AFDE76000DEBD6 /* JitsiMeetUserInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -104,6 +105,7 @@
|
||||
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
|
||||
C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
|
||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
||||
DE438CD82350934700DD541D /* JavaScriptSandbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JavaScriptSandbox.m; sourceTree = "<group>"; };
|
||||
DE65AAC92317FFCD00290BEC /* LogUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogUtils.h; sourceTree = "<group>"; };
|
||||
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetBaseLogHandler+Private.h"; sourceTree = "<group>"; };
|
||||
DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetUserInfo.h; sourceTree = "<group>"; };
|
||||
@@ -190,6 +192,7 @@
|
||||
A4A934E7212F3AB8001E9388 /* dropbox */,
|
||||
0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */,
|
||||
0BD906E91EC0C00300C8C18E /* Info.plist */,
|
||||
DE438CD82350934700DD541D /* JavaScriptSandbox.m */,
|
||||
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
|
||||
DEFE535821FB311F00011A3A /* JitsiMeet+Private.h */,
|
||||
DEFE535321FB1BF800011A3A /* JitsiMeet.m */,
|
||||
@@ -493,6 +496,7 @@
|
||||
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
|
||||
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
|
||||
DEFE535421FB1BF800011A3A /* JitsiMeet.m in Sources */,
|
||||
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -634,15 +638,18 @@
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeetSDK.ios;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -662,14 +669,17 @@
|
||||
ENABLE_BITCODE = YES;
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeetSDK.ios;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
|
||||
<ActionContent
|
||||
title = "Run Script"
|
||||
scriptText = "exec > /tmp/${PROJECT_NAME}_archive.log 2>&1 UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal if [ "true" == ${ALREADYINVOKED:-false} ] then echo "RECURSION: Detected, stopping" else export ALREADYINVOKED="true" # make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}" echo "Building for iPhoneSimulator" xcodebuild -workspace "${WORKSPACE_PATH}" -scheme "${TARGET_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO ARCHS='i386 x86_64' BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE=bitcode clean build # Step 1. Copy the framework structure (from iphoneos build) to the universal folder echo "Copying to output folder" cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FULL_PRODUCT_NAME}" "${UNIVERSAL_OUTPUTFOLDER}/" # Step 2. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/." if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule" fi # Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory echo "Combining executables" lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${EXECUTABLE_PATH}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${EXECUTABLE_PATH}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${EXECUTABLE_PATH}" # Step 4. Create universal binaries for embedded frameworks #for SUB_FRAMEWORK in $( ls "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks" ); do #BINARY_NAME="${SUB_FRAMEWORK%.*}" #lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${SUB_FRAMEWORK}/${BINARY_NAME}" "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" #done # Step 5. Convenience step to copy the framework to the project's directory echo "Copying to project dir" yes | cp -Rf "${UNIVERSAL_OUTPUTFOLDER}/${FULL_PRODUCT_NAME}" "${PROJECT_DIR}" fi">
|
||||
scriptText = "exec > /tmp/${PROJECT_NAME}_archive.log 2>&1 UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal if [ "true" == ${ALREADYINVOKED:-false} ] then echo "RECURSION: Detected, stopping" else export ALREADYINVOKED="true" # make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}" echo "Building for iPhoneSimulator" xcodebuild -workspace "${WORKSPACE_PATH}" -scheme "${TARGET_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' ONLY_ACTIVE_ARCH=NO ARCHS='i386 x86_64' BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE=bitcode clean build # Step 1. Copy the framework structure (from iphoneos build) to the universal folder echo "Copying to output folder" cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FULL_PRODUCT_NAME}" "${UNIVERSAL_OUTPUTFOLDER}/" # Step 2. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/." if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule" fi # Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory echo "Combining executables" lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${EXECUTABLE_PATH}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${EXECUTABLE_PATH}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${EXECUTABLE_PATH}" # Step 4. Create universal binaries for embedded frameworks #for SUB_FRAMEWORK in $( ls "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks" ); do #BINARY_NAME="${SUB_FRAMEWORK%.*}" #lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${SUB_FRAMEWORK}/${BINARY_NAME}" "${ARCHIVE_PRODUCTS_PATH}${INSTALL_PATH}/${TARGET_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" #done # Step 5. Convenience step to copy the framework to the project's directory echo "Copying to project dir" yes | cp -Rf "${UNIVERSAL_OUTPUTFOLDER}/${FULL_PRODUCT_NAME}" "${PROJECT_DIR}" fi ">
|
||||
<EnvironmentBuildable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.3.0</string>
|
||||
<string>2.4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
55
ios/sdk/src/JavaScriptSandbox.m
Normal file
55
ios/sdk/src/JavaScriptSandbox.m
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@import JavaScriptCore;
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
|
||||
@interface JavaScriptSandbox : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@implementation JavaScriptSandbox
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Exported methods
|
||||
|
||||
RCT_EXPORT_METHOD(evaluate:(NSString *)code
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject) {
|
||||
__block BOOL hasError = NO;
|
||||
JSContext *ctx = [[JSContext alloc] init];
|
||||
ctx.exceptionHandler = ^(JSContext *context, JSValue *exception) {
|
||||
hasError = YES;
|
||||
reject(@"evaluate", [exception toString], nil);
|
||||
};
|
||||
JSValue *ret = [ctx evaluateScript:code];
|
||||
if (!hasError) {
|
||||
NSString *result = [ret toString];
|
||||
if (result == nil) {
|
||||
reject(@"evaluate", @"Error in string coercion", nil);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -37,7 +37,6 @@
|
||||
* List of domains used for universal linking.
|
||||
*/
|
||||
@property (copy, nonatomic, nullable) NSArray<NSString *> *universalLinkDomains;
|
||||
|
||||
/**
|
||||
* Default conference options used for all conferences. These options will be merged
|
||||
* with those passed to JitsiMeetView.join when joining a conference.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#import "ReactUtils.h"
|
||||
|
||||
#import <RNGoogleSignin/RNGoogleSignin.h>
|
||||
#import <WebRTC/RTCLogging.h>
|
||||
|
||||
|
||||
@implementation JitsiMeet {
|
||||
@@ -54,6 +55,11 @@
|
||||
|
||||
// Register a log handler for React.
|
||||
registerReactLogHandler();
|
||||
|
||||
#if 0
|
||||
// Enable WebRTC logs
|
||||
RTCSetMinDebugLogLevel(RTCLoggingSeverityInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -90,8 +96,7 @@
|
||||
|
||||
if ([RNGoogleSignin application:app
|
||||
openURL:url
|
||||
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
|
||||
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]) {
|
||||
options:options]) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -179,6 +184,15 @@
|
||||
return _universalLinkDomains ? _universalLinkDomains : @[];
|
||||
}
|
||||
|
||||
- (void)setDefaultConferenceOptions:(JitsiMeetConferenceOptions *)defaultConferenceOptions {
|
||||
if (defaultConferenceOptions != nil && _defaultConferenceOptions.room != nil) {
|
||||
@throw [NSException exceptionWithName:@"RuntimeError"
|
||||
reason:@"'room' must be null in the default conference options"
|
||||
userInfo:nil];
|
||||
}
|
||||
_defaultConferenceOptions = defaultConferenceOptions;
|
||||
}
|
||||
|
||||
#pragma mark - Private API methods
|
||||
|
||||
- (NSDictionary *)getDefaultProps {
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
*/
|
||||
__attribute__((constructor))
|
||||
static void initializeLogger() {
|
||||
[DDLog addLogger:[DDOSLogger sharedInstance]];
|
||||
NSString *mainBundleId = [NSBundle mainBundle].bundleIdentifier;
|
||||
DDOSLogger *osLogger = [[DDOSLogger alloc] initWithSubsystem:mainBundleId category:@"JitsiMeetSDK"];
|
||||
[DDLog addLogger:osLogger];
|
||||
}
|
||||
|
||||
+ (void)addHandler:(JitsiMeetBaseLogHandler *)handler {
|
||||
|
||||
@@ -37,6 +37,7 @@ set -e
|
||||
# IOS_TEAM_ID - the team ID inserted into build-ipa-.plist.template file in
|
||||
# place of "YOUR_TEAM_ID".
|
||||
|
||||
|
||||
# Travis will not print the last echo if there's no sleep 1
|
||||
function echoSleepAndExit1() {
|
||||
echo $1
|
||||
@@ -57,10 +58,6 @@ if [ -z $IPA_DEPLOY_LOCATION ]; then
|
||||
echoSleepAndExit1 "No IPA_DEPLOY_LOCATION defined"
|
||||
fi
|
||||
|
||||
if [ -z $APPLE_CERT_URL ]; then
|
||||
APPLE_CERT_URL="http://developer.apple.com/certificationauthority/AppleWWDRCA.cer"
|
||||
fi
|
||||
|
||||
echo "PR_REPO_SLUG=${PR_REPO_SLUG} PR_BRANCH=${PR_BRANCH}"
|
||||
|
||||
# do the marge and git log
|
||||
@@ -88,47 +85,17 @@ fi
|
||||
|
||||
git log -20 --graph --pretty=format':%C(yellow)%h%Cblue%d%Creset %s %C(white) %an, %ar%Creset'
|
||||
|
||||
# certificates
|
||||
|
||||
#certificates
|
||||
CERT_DIR="ios/travis-ci/certs"
|
||||
|
||||
mkdir $CERT_DIR
|
||||
mkdir -p $CERT_DIR
|
||||
|
||||
./ios/ci/setup-certificates.sh $CERT_DIR
|
||||
|
||||
curl -L -o ${CERT_DIR}/AppleWWDRCA.cer 'http://developer.apple.com/certificationauthority/AppleWWDRCA.cer'
|
||||
curl -L -o ${CERT_DIR}/dev-cert.cer.enc ${IOS_DEV_CERT_URL}
|
||||
curl -L -o ${CERT_DIR}/dev-key.p12.enc ${IOS_DEV_CERT_KEY_URL}
|
||||
curl -L -o ${CERT_DIR}/dev-profile.mobileprovision.enc ${IOS_DEV_PROV_PROFILE_URL}
|
||||
curl -L -o ${CERT_DIR}/dev-watch-profile.mobileprovision.enc ${IOS_DEV_WATCH_PROV_PROFILE_URL}
|
||||
curl -L -o ${CERT_DIR}/id_rsa.enc ${DEPLOY_SSH_CERT_URL}
|
||||
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-cert.cer.enc -d -a -out ${CERT_DIR}/dev-cert.cer
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-key.p12.enc -d -a -out ${CERT_DIR}/dev-key.p12
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-profile.mobileprovision.enc -d -a -out ${CERT_DIR}/dev-profile.mobileprovision
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/dev-watch-profile.mobileprovision.enc -d -a -out ${CERT_DIR}/dev-watch-profile.mobileprovision
|
||||
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/id_rsa.enc -d -a -out ${CERT_DIR}/id_rsa
|
||||
chmod 0600 ${CERT_DIR}/id_rsa
|
||||
|
||||
security create-keychain -p $ENCRYPTION_PASSWORD ios-build.keychain
|
||||
security default-keychain -s ios-build.keychain
|
||||
security unlock-keychain -p $ENCRYPTION_PASSWORD ios-build.keychain
|
||||
security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain
|
||||
|
||||
echo "importing Apple cert"
|
||||
security import ${CERT_DIR}/AppleWWDRCA.cer -k ios-build.keychain -A
|
||||
echo "importing dev-cert.cer"
|
||||
security import ${CERT_DIR}/dev-cert.cer -k ios-build.keychain -A
|
||||
echo "importing dev-key.p12"
|
||||
security import ${CERT_DIR}/dev-key.p12 -k ios-build.keychain -P $IOS_SIGNING_CERT_PASSWORD -A
|
||||
|
||||
echo "will set-key-partition-list"
|
||||
# Fix for OS X Sierra that hungs in the codesign step
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k $ENCRYPTION_PASSWORD ios-build.keychain > /dev/null
|
||||
echo "done set-key-partition-list"
|
||||
|
||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
|
||||
cp "${CERT_DIR}/dev-profile.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
cp "${CERT_DIR}/dev-watch-profile.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
ssh-add ${CERT_DIR}/id_rsa
|
||||
|
||||
npm install
|
||||
|
||||
@@ -136,24 +103,21 @@ npm install
|
||||
./node_modules/react-native-webrtc/tools/downloadBitcode.sh
|
||||
|
||||
cd ios
|
||||
pod update
|
||||
pod install
|
||||
pod install --repo-update --no-ansi
|
||||
cd ..
|
||||
|
||||
mkdir -p /tmp/jitsi-meet/
|
||||
|
||||
xcodebuild archive -quiet -workspace ios/jitsi-meet.xcworkspace -scheme jitsi-meet -configuration Release -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive
|
||||
|
||||
sed -e "s/YOUR_TEAM_ID/${IOS_TEAM_ID}/g" ios/travis-ci/build-ipa.plist.template > ios/travis-ci/build-ipa.plist
|
||||
sed -e "s/YOUR_TEAM_ID/${IOS_TEAM_ID}/g" ios/ci/build-ipa.plist.template > ios/ci/build-ipa.plist
|
||||
|
||||
IPA_EXPORT_DIR=/tmp/jitsi-meet/jitsi-meet-ipa
|
||||
|
||||
xcodebuild -quiet -exportArchive -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive -exportPath $IPA_EXPORT_DIR -exportOptionsPlist ios/travis-ci/build-ipa.plist
|
||||
xcodebuild -quiet -exportArchive -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive -exportPath $IPA_EXPORT_DIR -exportOptionsPlist ios/ci/build-ipa.plist
|
||||
|
||||
echo "Will try deploy the .ipa to: ${IPA_DEPLOY_LOCATION}"
|
||||
|
||||
ssh-add ${CERT_DIR}/id_rsa
|
||||
|
||||
if [ ! -z ${SCP_PROXY_HOST} ];
|
||||
then
|
||||
scp -o ProxyCommand="ssh -t -A -l %r ${SCP_PROXY_HOST} -o \"StrictHostKeyChecking no\" -o \"BatchMode yes\" -W %h:%p" -o StrictHostKeyChecking=no -o LogLevel=DEBUG "${IPA_EXPORT_DIR}/jitsi-meet.ipa" "${IPA_DEPLOY_LOCATION}"
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
{
|
||||
"en": "Английски",
|
||||
"af": "Африканс",
|
||||
"az": "Азербайджански",
|
||||
"bg": "Български",
|
||||
"ca": "Каталонски",
|
||||
"cs": "Чешки",
|
||||
"de": "Немски",
|
||||
"el": "Гръцки",
|
||||
"enGB": "Английски (Великобритания)",
|
||||
"eo": "Есперанто",
|
||||
"es": "Испански",
|
||||
"esUS": "Испански (Латинска Америка)",
|
||||
"fi": "Фински",
|
||||
"fr": "Френски",
|
||||
"frCA": "Френски (Канада)",
|
||||
"hr": "Хърватски",
|
||||
"hy": "Арменски",
|
||||
"it": "Италиански",
|
||||
"ja": "Японски",
|
||||
"ko": "Корейски",
|
||||
"nb": "Норвежки букмол",
|
||||
"nl": "Нидерландски",
|
||||
"oc": "Окситански",
|
||||
"pl": "Полски",
|
||||
"ptBR": "Португалски (Бразилия)",
|
||||
"ru": "Руски",
|
||||
"sk": "Словашки",
|
||||
"sl": "Словенски",
|
||||
"sv": "Шведски",
|
||||
"tr": "Турски",
|
||||
"vi": "Виетнамски",
|
||||
"zhCN": "Китайски (Китай)"
|
||||
"zhCN": "Китайски (Китай)",
|
||||
"zhTW": "Тайвански"
|
||||
}
|
||||
@@ -1,27 +1,31 @@
|
||||
{
|
||||
"en": "Angol",
|
||||
"af": "",
|
||||
"az": "",
|
||||
"bg": "Bolgár",
|
||||
"cs": "",
|
||||
"de": "Német",
|
||||
"el": "",
|
||||
"eo": "Eszperantó",
|
||||
"es": "Spanyol",
|
||||
"fr": "Francia",
|
||||
"hy": "Örmény",
|
||||
"it": "Olasz",
|
||||
"ja": "",
|
||||
"ko": "",
|
||||
"nb": "Norvég bokmal",
|
||||
"oc": "Okszitán",
|
||||
"pl": "Lengyel",
|
||||
"ptBR": "Portugál (Brazil)",
|
||||
"ru": "Orosz",
|
||||
"sk": "Szlovák",
|
||||
"sl": "Szlovén",
|
||||
"sv": "Svéd",
|
||||
"tr": "Török",
|
||||
"vi": "",
|
||||
"zhCN": "Kínai (Kína)"
|
||||
"en": "angol",
|
||||
"af": "afrikaans",
|
||||
"bg": "bolgár",
|
||||
"ca": "katalán",
|
||||
"cs": "cseh",
|
||||
"de": "német",
|
||||
"el": "görög",
|
||||
"enGB": "angol (Egyesült Királyság)",
|
||||
"eo": "eszperantó",
|
||||
"es": "spanyol",
|
||||
"esUS": "spanyol (Latin-Amerika)",
|
||||
"fi": "finn",
|
||||
"fr": "francia",
|
||||
"frCA": "francia (kanadai)",
|
||||
"hr": "horvát",
|
||||
"hy": "örmény",
|
||||
"it": "olasz",
|
||||
"ja": "japán",
|
||||
"ko": "koreai",
|
||||
"nl": "holland",
|
||||
"oc": "okszitán",
|
||||
"pl": "lengyel",
|
||||
"ptBR": "portugál (Brazil)",
|
||||
"ru": "orosz",
|
||||
"sv": "svéd",
|
||||
"tr": "török",
|
||||
"vi": "vietnámi",
|
||||
"zhCN": "kínai (Kína)",
|
||||
"zhTW": "kínai (Tajvan)"
|
||||
}
|
||||
@@ -2,23 +2,23 @@
|
||||
"en": "Anglés",
|
||||
"af": "Afrikaans",
|
||||
"bg": "Bulgar",
|
||||
"ca": "",
|
||||
"ca": "Catalan",
|
||||
"cs": "Chèc",
|
||||
"de": "Aleman",
|
||||
"el": "Grèc",
|
||||
"enGB": "",
|
||||
"enGB": "Anglés (Reialme Unit)",
|
||||
"eo": "Esperanto",
|
||||
"es": "Castelhan",
|
||||
"esUS": "",
|
||||
"fi": "",
|
||||
"esUS": "Espanhòl (America latina)",
|
||||
"fi": "Finés",
|
||||
"fr": "Francés",
|
||||
"frCA": "",
|
||||
"hr": "",
|
||||
"frCA": "Francés (Canadian)",
|
||||
"hr": "Croat",
|
||||
"hy": "Armenian",
|
||||
"it": "Italian",
|
||||
"ja": "Japonés",
|
||||
"ko": "Corean",
|
||||
"nl": "",
|
||||
"nl": "Neerlandés",
|
||||
"oc": "Occitan",
|
||||
"pl": "Polonés",
|
||||
"ptBR": "Portugués (Brasil)",
|
||||
@@ -27,5 +27,5 @@
|
||||
"tr": "Turc",
|
||||
"vi": "Vietnamian",
|
||||
"zhCN": "Chinés (China)",
|
||||
"zhTW": ""
|
||||
"zhTW": "Chinés (Taiwan)"
|
||||
}
|
||||
@@ -1,27 +1,31 @@
|
||||
{
|
||||
"en": "Anglik",
|
||||
"af": "",
|
||||
"az": "Azerski",
|
||||
"en": "Angielski",
|
||||
"af": "Afrykanerski",
|
||||
"bg": "Bułgarski",
|
||||
"ca": "",
|
||||
"cs": "Czeski",
|
||||
"de": "Niemiecki",
|
||||
"el": "Grecki",
|
||||
"enGB": "",
|
||||
"eo": "Esperanto",
|
||||
"es": "Hiszpański",
|
||||
"esUS": "",
|
||||
"fi": "",
|
||||
"fr": "Francuski",
|
||||
"frCA": "",
|
||||
"hr": "",
|
||||
"hy": "Ormiański",
|
||||
"it": "Włoski",
|
||||
"ja": "Japoński",
|
||||
"ko": "Koreański",
|
||||
"nb": "Norweski Bokmal",
|
||||
"nl": "",
|
||||
"oc": "Oksytański",
|
||||
"pl": "Polski",
|
||||
"ptBR": "portugalski (brazylijski)",
|
||||
"ptBR": "Portugalski (brazylijski)",
|
||||
"ru": "Rosyjski",
|
||||
"sk": "Słowacki",
|
||||
"sl": "Słoweński",
|
||||
"sv": "Szwedzki",
|
||||
"tr": "Turecki",
|
||||
"vi": "Wietnamski",
|
||||
"zhCN": "Chiński (Chiny)"
|
||||
"zhCN": "Chiński (Chiny)",
|
||||
"zhTW": ""
|
||||
}
|
||||
@@ -1,27 +1,31 @@
|
||||
{
|
||||
"en": "Inglês",
|
||||
"af": "Africâner",
|
||||
"az": "Azerbaijanês",
|
||||
"bg": "Búlgaro",
|
||||
"ca": "",
|
||||
"cs": "Checo",
|
||||
"de": "Alemão",
|
||||
"el": "Grego",
|
||||
"enGB": "",
|
||||
"eo": "Esperanto",
|
||||
"es": "Espanhol",
|
||||
"esUS": "",
|
||||
"fi": "",
|
||||
"fr": "Francês",
|
||||
"frCA": "",
|
||||
"hr": "",
|
||||
"hy": "Armênio",
|
||||
"it": "Italiano",
|
||||
"ja": "Japonês",
|
||||
"ko": "Coreano",
|
||||
"nb": "Bokmal norueguês",
|
||||
"nl": "",
|
||||
"oc": "Occitano",
|
||||
"pl": "Polonês",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ru": "Russo",
|
||||
"sk": "Eslovaco",
|
||||
"sl": "Esloveno",
|
||||
"sv": "Sueco",
|
||||
"tr": "Turco",
|
||||
"vi": "Vietnamita",
|
||||
"zhCN": "Chinês (China)"
|
||||
"zhCN": "Chinês (China)",
|
||||
"zhTW": ""
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
"fr": "French",
|
||||
"frCA": "French (Canadian)",
|
||||
"hr": "Croatian",
|
||||
"hu": "Hungarian",
|
||||
"hy": "Armenian",
|
||||
"it": "Italian",
|
||||
"ja": "Japanese",
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"countryNotSupported": "Желаната дестинация не се поддържа.",
|
||||
"countryReminder": "Международно обаждане? Започнете номера с международният код!",
|
||||
"disabled": "Не можете да каните хора.",
|
||||
"failedToAdd": "",
|
||||
"footerText": "Изходящиите разговори не са разрешени.",
|
||||
"failedToAdd": "Неуспешно добавяне на участници",
|
||||
"footerText": "Изходящите разговори не са разрешени.",
|
||||
"loading": "Търсене на хора и телефонни номера.",
|
||||
"loadingNumber": "Валидиране на номера",
|
||||
"loadingPeople": "Търсене на хора",
|
||||
@@ -13,48 +13,49 @@
|
||||
"noValidNumbers": "Моля въведете телефонен номер",
|
||||
"searchNumbers": "Добавяне на номера",
|
||||
"searchPeople": "Търсене на хора",
|
||||
"searchPeopleAndNumbers": "",
|
||||
"telephone": "",
|
||||
"title": ""
|
||||
"searchPeopleAndNumbers": "Търсене на участници или добавяне с телефони номера",
|
||||
"telephone": "Телефон: {{number}}",
|
||||
"title": "Добавяне на участници в срещата"
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "",
|
||||
"bluetooth": "Bluetooth",
|
||||
"headphones": "Слушалки",
|
||||
"phone": "Телефон",
|
||||
"speaker": "Говорещ"
|
||||
"speaker": "Говорещ",
|
||||
"none": "Няма налични устройства за звук"
|
||||
},
|
||||
"audioOnly": {
|
||||
"audioOnly": "Само звук"
|
||||
"audioOnly": "Нисък дебит"
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "",
|
||||
"confirmAddLink": "",
|
||||
"addMeetingURL": "Добавяне на връзка за среща",
|
||||
"confirmAddLink": "Искате ли да добавите връзка към това събитие?",
|
||||
"error": {
|
||||
"appConfiguration": "",
|
||||
"generic": "",
|
||||
"notSignedIn": ""
|
||||
"appConfiguration": "Интеграцията с календара не е настроена.",
|
||||
"generic": "Грешка, моля проверете настройката за календара или го обновете.",
|
||||
"notSignedIn": "Грешка при идентификация за изтегляне на събития. Моля проверете настройките на календара и опитайте отново."
|
||||
},
|
||||
"join": "",
|
||||
"joinTooltip": "",
|
||||
"nextMeeting": "",
|
||||
"noEvents": "",
|
||||
"ongoingMeeting": "",
|
||||
"permissionButton": "",
|
||||
"permissionMessage": "",
|
||||
"refresh": "",
|
||||
"today": ""
|
||||
"join": "Влизане",
|
||||
"joinTooltip": "Влизане в срещата",
|
||||
"nextMeeting": "следваща среща",
|
||||
"noEvents": "Няма насрочени бъдещи събития.",
|
||||
"ongoingMeeting": "настояща среща",
|
||||
"permissionButton": "Отваряне на настройки",
|
||||
"permissionMessage": "За показване на срещите ви е нужно позволение за ползване на календара.",
|
||||
"refresh": "Обновяване на календара",
|
||||
"today": "Днес"
|
||||
},
|
||||
"chat": {
|
||||
"error": "",
|
||||
"messagebox": "",
|
||||
"error": "Грешка: вашето съобщение \"{{originalText}}\" не е бе изпратено. Поради: {{error}}",
|
||||
"messagebox": "Въведете съобщение",
|
||||
"nickname": {
|
||||
"popover": "Избор на име",
|
||||
"title": ""
|
||||
"title": "Въведете име за да обменяте съобщения"
|
||||
},
|
||||
"title": ""
|
||||
"title": "Текстови съобщения"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
"joiningRoom": ""
|
||||
"joiningRoom": "Свързване с вашата среща..."
|
||||
},
|
||||
"connection": {
|
||||
"ATTACHED": "Прикрепен",
|
||||
@@ -72,8 +73,8 @@
|
||||
"address": "Адрес:",
|
||||
"bandwidth": "Предполагаема скорост:",
|
||||
"bitrate": "Скорост:",
|
||||
"bridgeCount": "",
|
||||
"connectedTo": "",
|
||||
"bridgeCount": "Брой сървъри:",
|
||||
"connectedTo": "Свързан към:",
|
||||
"framerate": "Кадри в секунда:",
|
||||
"less": "Скриване",
|
||||
"localaddress": "Локален адрес:",
|
||||
@@ -96,26 +97,25 @@
|
||||
"resolution": "Резолюция:",
|
||||
"status": "Връзка:",
|
||||
"transport": "Транспорт:",
|
||||
"transport_plural": "Транспорти:",
|
||||
"turn": " (обръщане)"
|
||||
"transport_plural": "Транспорти:"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "",
|
||||
"today": "",
|
||||
"yesterday": ""
|
||||
"earlier": "По-рано",
|
||||
"today": "Днес",
|
||||
"yesterday": "Вчера"
|
||||
},
|
||||
"deepLinking": {
|
||||
"appNotInstalled": "",
|
||||
"description": "",
|
||||
"descriptionWithoutWeb": "",
|
||||
"downloadApp": "Сваляне не приложението",
|
||||
"launchWebButton": "",
|
||||
"openApp": "",
|
||||
"title": "",
|
||||
"tryAgainButton": ""
|
||||
"appNotInstalled": "Имате нужда от мобилното приложение {{app}} за влизане в тази среща от телефона.",
|
||||
"description": "Нищо не се случва? Опитахме се да заредим срещата в приложението {{app}}. Пробвайте отново или влезте чрез уеб приложението {{app}}.",
|
||||
"descriptionWithoutWeb": "Нищо не се случва? Опитахме се да заредим срещата в приложението {{app}}.",
|
||||
"downloadApp": "Свалете приложението",
|
||||
"launchWebButton": "Заредете уеб страницата",
|
||||
"openApp": "Продължете към приложението",
|
||||
"title": "Зареждане на срещата в {{app}}...",
|
||||
"tryAgainButton": "Пробвайте отново"
|
||||
},
|
||||
"\u0005deepLinking": {},
|
||||
"defaultLink": "напр. {{url}}",
|
||||
"defaultNickname": "напр. Иван Иванов",
|
||||
"deviceError": {
|
||||
"cameraError": "Камерата е недостъпна",
|
||||
"cameraPermission": "Грешка при получаване на разрешение за достъп до камерата",
|
||||
@@ -126,14 +126,14 @@
|
||||
"noPermission": "Не е получено разрешение",
|
||||
"previewUnavailable": "Няма възможност за преглед",
|
||||
"selectADevice": "Изберете устройство",
|
||||
"testAudio": ""
|
||||
"testAudio": "Пусни пробен звук"
|
||||
},
|
||||
"dialog": {
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Излъчване на живо"
|
||||
},
|
||||
"allow": "Разрешаване",
|
||||
"alreadySharedVideoMsg": "",
|
||||
"alreadySharedVideoMsg": "Друг участник вече е споделил видео. Тази среща позволява само едно споделено видео.",
|
||||
"alreadySharedVideoTitle": "Разрешено е споделянето само на едно видео в даден момент",
|
||||
"applicationWindow": "Прозореца на програмата",
|
||||
"Back": "Назад",
|
||||
@@ -150,8 +150,8 @@
|
||||
"conferenceDisconnectTitle": "Връзката се разпадна.",
|
||||
"conferenceReloadMsg": "Опитваме се да оправим нещата. Повторно свързване след {{seconds}} сек…",
|
||||
"conferenceReloadTitle": "За съжаление, нещо се обърка.",
|
||||
"confirm": "",
|
||||
"confirmNo": "",
|
||||
"confirm": "Потвърждение",
|
||||
"confirmNo": "Не",
|
||||
"confirmYes": "Да",
|
||||
"connectError": "Опа! Нещо се обърка и не успяхме да се свържем с конференцията.",
|
||||
"connectErrorWithMsg": "Опа! Нещо се обърка и не успяхме да се свържем с конференцията: {{msg}}",
|
||||
@@ -159,66 +159,66 @@
|
||||
"contactSupport": "Връзка с отдела по поддръжка",
|
||||
"copy": "Копиране",
|
||||
"dismiss": "Отхвърляне",
|
||||
"displayNameRequired": "",
|
||||
"displayNameRequired": "Здравей! Как се казваш?",
|
||||
"done": "Готово",
|
||||
"enterDisplayName": "",
|
||||
"enterDisplayName": "Моля въведете вашето име",
|
||||
"error": "Грешка",
|
||||
"externalInstallationMsg": "Трябва да инсталирате разширението за споделяне на екрана.",
|
||||
"externalInstallationTitle": "Нужно е разширение",
|
||||
"goToStore": "Към магазина в Интернет",
|
||||
"gracefulShutdown": "Услугата временно не е достъпна поради профилактика. Моля опитайте по-късно.",
|
||||
"IamHost": "Аз съм домакина",
|
||||
"incorrectRoomLockPassword": "",
|
||||
"incorrectRoomLockPassword": "Грешна парола",
|
||||
"incorrectPassword": "Неправилно потребителско име или парола",
|
||||
"inlineInstallationMsg": "Трябва да инсталирате разширението за споделяне на екрана.",
|
||||
"inlineInstallExtension": "Инсталиране сега",
|
||||
"internalError": "Опа! Нещо се обърка. Възникна следната грешка: {{error}}",
|
||||
"internalErrorTitle": "Вътрешна грешка",
|
||||
"kickMessage": "",
|
||||
"kickParticipantButton": "",
|
||||
"kickParticipantDialog": "",
|
||||
"kickParticipantTitle": "",
|
||||
"kickTitle": "",
|
||||
"kickMessage": "Може да се свържете с {{participantDisplayName}} за повече подробности.",
|
||||
"kickParticipantButton": "Изгони",
|
||||
"kickParticipantDialog": "Сигурни ли сте че искате да изгоните участника?",
|
||||
"kickParticipantTitle": "Изгонване на този участник?",
|
||||
"kickTitle": "Ауч! {{participantDisplayName}} ви изгони от тази среща",
|
||||
"liveStreaming": "Излъчване на живо",
|
||||
"liveStreamingDisabledForGuestTooltip": "",
|
||||
"liveStreamingDisabledTooltip": "",
|
||||
"liveStreamingDisabledForGuestTooltip": "Гостите не могат да стартират излъчване на живо.",
|
||||
"liveStreamingDisabledTooltip": "Излъчването на живо е деактивирано.",
|
||||
"lockMessage": "Неуспешно заключване на конференцията.",
|
||||
"lockRoom": "",
|
||||
"lockRoom": "Добавяне $t(lockRoomPasswordUppercase) за срещата",
|
||||
"lockTitle": "Неуспешно заключване",
|
||||
"logoutQuestion": "Сигурни ли сте, че искате да излезете и да прекъснете конференцията?",
|
||||
"logoutTitle": "Изход",
|
||||
"maxUsersLimitReached": "",
|
||||
"maxUsersLimitReachedTitle": "",
|
||||
"maxUsersLimitReached": "Лимитът за максимален брой участници бе достигнат. Капацитета на срещата е запълнен. Моля свържете се с организатора или опитайте по-късно!",
|
||||
"maxUsersLimitReachedTitle": "Достигнат е лимита за максимален брой участници",
|
||||
"micConstraintFailedError": "Микрофонът Ви не покрива някои от изискванията.",
|
||||
"micNotFoundError": "Не е открит микрофон.",
|
||||
"micNotSendingData": "",
|
||||
"micNotSendingDataTitle": "",
|
||||
"micNotSendingData": "Пуснете микрофона си от системните настройки на компютъра ви.",
|
||||
"micNotSendingDataTitle": "Микрофона ви е спрян от системните настройки",
|
||||
"micPermissionDeniedError": "Не сте дали разрешение за използване на микрофона. Ще можете да се присъедините в беседата, но другите няма да Ви чуват. Използвайте бутона с камерата в адресната лента, за да оправите това.",
|
||||
"micUnknownError": "Не възможен достъп до микрофона по неясна причина.",
|
||||
"micUnknownError": "Невъзможен достъп до микрофона по неясна причина.",
|
||||
"muteParticipantBody": "Вие няма да можете да спрете заглушаването на участника, но той ще може да го направи по всяко време.",
|
||||
"muteParticipantButton": "Изключи микрофона",
|
||||
"muteParticipantDialog": "",
|
||||
"muteParticipantTitle": "",
|
||||
"muteParticipantDialog": "Сигурни ли сте че искате да заглушите този участник? Няма да можете да пуснете обратно звука му, но участника ще може да направи това сам.",
|
||||
"muteParticipantTitle": "Спиране звука на участник?",
|
||||
"Ok": "Готово",
|
||||
"passwordLabel": "",
|
||||
"passwordNotSupported": "Задаването на парола за срещата не се поддържа.",
|
||||
"passwordNotSupportedTitle": "",
|
||||
"passwordRequired": "",
|
||||
"passwordLabel": "Парола",
|
||||
"passwordNotSupported": "Задаването на $t(lockRoomPassword) за срещата не се поддържа.",
|
||||
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) не се поддържа",
|
||||
"passwordRequired": "Изисква се $t(lockRoomPassword) ",
|
||||
"popupError": "Браузърът Ви блокира изскачащите прозорци от този уеб сайт. Моля, разрешете изскачащите прозорци от настройките за сигурност на браузъра си и след това опитайте отново.",
|
||||
"popupErrorTitle": "Блокиран изскачащ прозорец",
|
||||
"recording": "Запис",
|
||||
"recordingDisabledForGuestTooltip": "",
|
||||
"recordingDisabledTooltip": "",
|
||||
"recordingDisabledForGuestTooltip": "Гостите не могат да стартират запис",
|
||||
"recordingDisabledTooltip": "Стартирането на запис е спряно",
|
||||
"rejoinNow": "Повторно присъединяване сега",
|
||||
"remoteControlAllowedMessage": "{{user}} прие заявката Ви за отдалечено управление!",
|
||||
"remoteControlDeniedMessage": "{{user}} отказа заявката Ви за отдалечено управление!",
|
||||
"remoteControlErrorMessage": "Възникна грешка при опита за искана на разрешение за отдалечено управление от {{user}}!",
|
||||
"remoteControlErrorMessage": "Възникна грешка при опита за искане на разрешение за отдалечено управление от {{user}}!",
|
||||
"remoteControlRequestMessage": "Ще позволите ли на {{user}} да управлява отдалечено компютъра Ви?",
|
||||
"remoteControlShareScreenWarning": "Ако натиснете „Разрешаване“, ще споделите екрана си!",
|
||||
"remoteControlStopMessage": "Сесията за отдалечено управление приключи!",
|
||||
"remoteControlTitle": "Отдалечено управление на компютъра",
|
||||
"Remove": "Премахване",
|
||||
"removePassword": "",
|
||||
"removePassword": "Премахване на $t(lockRoomPassword)",
|
||||
"removeSharedVideoMsg": "Наистина ли искате да премахнете споделеното си видео?",
|
||||
"removeSharedVideoTitle": "Край на споделянето на видео",
|
||||
"reservationError": "Грешка в системата за резервации",
|
||||
@@ -226,8 +226,8 @@
|
||||
"retry": "Повторен опит",
|
||||
"screenSharingFailedToInstall": "Опа! Разширението за споделяне на екрана не успя да се инсталира.",
|
||||
"screenSharingFailedToInstallTitle": "Разширението за споделяне на екрана не успя да се инсталира",
|
||||
"screenSharingFirefoxPermissionDeniedError": "",
|
||||
"screenSharingFirefoxPermissionDeniedTitle": "",
|
||||
"screenSharingFirefoxPermissionDeniedError": "Нещо се обърка докато се опитвахме да споделим екрана. Моля уверете се че сте дали права за това.",
|
||||
"screenSharingFirefoxPermissionDeniedTitle": "Упс! Не успяхме да стартираме споделянето на екрана!",
|
||||
"screenSharingPermissionDeniedError": "Опа! Нещо се обърка с разрешенията на разширението за споделяне на екрана. Моля, презаредете и опитайте отново.",
|
||||
"serviceUnavailable": "Услугата не е налична",
|
||||
"sessTerminated": "Разговорът приключи",
|
||||
@@ -235,91 +235,86 @@
|
||||
"shareVideoLinkError": "Моля въведете правилна връзка към YouTube.",
|
||||
"shareVideoTitle": "Сподели видео",
|
||||
"shareYourScreen": "Споделяне на екрана",
|
||||
"shareYourScreenDisabled": "",
|
||||
"shareYourScreenDisabledForGuest": "",
|
||||
"shareYourScreenDisabled": "Споделянето на екрана не се поддържа.",
|
||||
"shareYourScreenDisabledForGuest": "Гостите не могат да споделят екрана.",
|
||||
"startLiveStreaming": "Започване на излъчване на живо",
|
||||
"startRecording": "Край на записа",
|
||||
"startRecording": "Стартиране на запис",
|
||||
"startRemoteControlErrorMessage": "Възникна грешка при опита за започване на сесията за отдалечено управление!",
|
||||
"stopLiveStreaming": "Спиране на излъчването на живо",
|
||||
"stopRecording": "Край на записа",
|
||||
"stopRecordingWarning": "Наистина ли искате да спрем записа?",
|
||||
"stopStreamingWarning": "Наистина ли искате да спрете излъчването на живо?",
|
||||
"streamKey": "",
|
||||
"streamKey": "Ключ за излъчване на живо",
|
||||
"Submit": "Изпращане",
|
||||
"thankYou": "Благодарим, че използвахте {{appName}}!",
|
||||
"token": "код за достъп",
|
||||
"tokenAuthFailed": "Съжаляваме, но не можете да се присъедините към този разговор.",
|
||||
"tokenAuthFailedTitle": "Неуспешна идентификация",
|
||||
"transcribing": "",
|
||||
"unlockRoom": "",
|
||||
"transcribing": "Транскрипция",
|
||||
"unlockRoom": "Премахване $t(lockRoomPassword) от срещата",
|
||||
"userPassword": "потребителска парола",
|
||||
"WaitForHostMsg": "",
|
||||
"WaitForHostMsgWOk": "",
|
||||
"WaitForHostMsg": "Конференцията <b>{{room}}</b> все още не е започнала. Ако сте домакинът тогава се идентифицирайте. В противен случай изчакайте докато домакинът пристигне.",
|
||||
"WaitForHostMsgWOk": "Конференцията <b>{{room}}</b> все още не е започнала. Ако сте домакинът тогава натиснете бутона за да се идентифицирате. В противен случай изчакайте докато домакинът пристигне.",
|
||||
"WaitingForHost": "Чакаме домакина ...",
|
||||
"Yes": "Да",
|
||||
"yourEntireScreen": "Целия екран"
|
||||
},
|
||||
"\u0005dialog": {
|
||||
"accessibilityLabel": {}
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "в момента е {{status}}"
|
||||
},
|
||||
"feedback": {
|
||||
"average": "Средно",
|
||||
"bad": "Лошо",
|
||||
"detailsLabel": "",
|
||||
"detailsLabel": "Разкажете ни повече.",
|
||||
"good": "Добра",
|
||||
"rateExperience": "Моля, оценете качеството на срещата.",
|
||||
"veryBad": "Много лошо",
|
||||
"veryGood": "Много добра"
|
||||
},
|
||||
"\u0005feedback": {},
|
||||
"incomingCall": {
|
||||
"answer": "",
|
||||
"audioCallTitle": "",
|
||||
"answer": "Вдигни",
|
||||
"audioCallTitle": "Входящ разговор",
|
||||
"decline": "Отхвърляне",
|
||||
"productLabel": "",
|
||||
"videoCallTitle": ""
|
||||
"productLabel": "от Jitsi Meet",
|
||||
"videoCallTitle": "Входящ видео разговор"
|
||||
},
|
||||
"info": {
|
||||
"accessibilityLabel": "",
|
||||
"addPassword": "",
|
||||
"cancelPassword": "",
|
||||
"conferenceURL": "",
|
||||
"country": "",
|
||||
"dialANumber": "",
|
||||
"dialInConferenceID": "",
|
||||
"dialInNotSupported": "",
|
||||
"dialInNumber": "",
|
||||
"dialInSummaryError": "",
|
||||
"dialInTollFree": "",
|
||||
"genericError": "",
|
||||
"inviteLiveStream": "",
|
||||
"invitePhone": "",
|
||||
"invitePhoneAlternatives": "",
|
||||
"inviteURLFirstPartGeneral": "",
|
||||
"inviteURLFirstPartPersonal": "",
|
||||
"inviteURLSecondPart": "",
|
||||
"liveStreamURL": "Излъчване на живо",
|
||||
"moreNumbers": "",
|
||||
"noNumbers": "",
|
||||
"accessibilityLabel": "Покажи информация",
|
||||
"addPassword": "Добави $t(lockRoomPassword)",
|
||||
"cancelPassword": "Премахни $t(lockRoomPassword)",
|
||||
"conferenceURL": "Връзка:",
|
||||
"country": "Страна",
|
||||
"dialANumber": "За влизане в срещата, наберете един от изброените номера и въведете кода.",
|
||||
"dialInConferenceID": "Код:",
|
||||
"dialInNotSupported": "Съжаляваме, обаждането в момента не се поддържа. ",
|
||||
"dialInNumber": "Тел:",
|
||||
"dialInSummaryError": "Проблем при достъпа на информация за опциите за влизане през телефон. Моля опитайте отново по-късно.",
|
||||
"dialInTollFree": "Безплатен",
|
||||
"genericError": "Упс, нещо се случи.",
|
||||
"inviteLiveStream": "За да видите предаването на живо на срещата, използвйте тази връзка: {{url}}",
|
||||
"invitePhone": "За влизане през телефон, използвайте: {{number}},,{{conferenceID}}#\n",
|
||||
"invitePhoneAlternatives": "Търсене на друг номер за набиране?\nВижте още номера: : {{url}}\n\n\nАко вече сте набрали от телефон в стаята, влезте без да е пуснат звука: {{silentUrl}}",
|
||||
"inviteURLFirstPartGeneral": "Поканени сте да се присъедините към среща.",
|
||||
"inviteURLFirstPartPersonal": "{{name}} ви кани за среща.\n",
|
||||
"inviteURLSecondPart": "\nВлезте в срещата:\n{{url}}\n",
|
||||
"liveStreamURL": "Излъчване на живо:",
|
||||
"moreNumbers": "Повече номера",
|
||||
"noNumbers": "Няма номера за набиране.",
|
||||
"noPassword": "Няма",
|
||||
"noRoom": "",
|
||||
"numbers": "",
|
||||
"password": "",
|
||||
"noRoom": "Няма посочена стая за информация за номера за набиране.",
|
||||
"numbers": "Номера",
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"title": "Споделяне",
|
||||
"tooltip": "",
|
||||
"label": ""
|
||||
"tooltip": "Споделете връзката и информацията за номера свързани със срещата",
|
||||
"label": "Информация за срещата"
|
||||
},
|
||||
"\u0005info": {},
|
||||
"inviteDialog": {
|
||||
"alertText": "",
|
||||
"alertText": "Не успях да поканя участниците.",
|
||||
"header": "Покани",
|
||||
"searchCallOnlyPlaceholder": "Въведете телефонен номер",
|
||||
"searchPeopleOnlyPlaceholder": "",
|
||||
"searchPlaceholder": "",
|
||||
"send": ""
|
||||
"searchPeopleOnlyPlaceholder": "Търсене на участници",
|
||||
"searchPlaceholder": "Участник или телефонен номер",
|
||||
"send": "Изпрати"
|
||||
},
|
||||
"inlineDialogFailure": {
|
||||
"msg": "Имаше грешка.",
|
||||
@@ -329,181 +324,182 @@
|
||||
},
|
||||
"keyboardShortcuts": {
|
||||
"focusLocal": "Фокусиране върху Вашето видео",
|
||||
"focusRemote": "Фокусиране върху видеото на друг участник",
|
||||
"focusRemote": "Фокусирай видеото на друг участник",
|
||||
"fullScreen": "Влизане/излизане от режим на цял екран",
|
||||
"keyboardShortcuts": "Клавишни комбинации",
|
||||
"localRecording": "",
|
||||
"localRecording": "Показване или скриване на контролите за локален запис",
|
||||
"mute": "Спиране/пускане на микрофона",
|
||||
"pushToTalk": "Натиснете, за да говорите",
|
||||
"raiseHand": "Вдигнете или свалете ръка",
|
||||
"showSpeakerStats": "Показване на статистика за говорителя",
|
||||
"toggleChat": "Отваряне/скриване на текстовите съобщения",
|
||||
"toggleFilmstrip": "",
|
||||
"toggleFilmstrip": "Показване или скриване на видео миниатюрите",
|
||||
"toggleScreensharing": "Смяна между камера и споделен екран",
|
||||
"toggleShortcuts": "",
|
||||
"videoMute": "Пускане/спиране на камерата"
|
||||
"toggleShortcuts": "Показване или скриване на клавишните комбинации",
|
||||
"videoMute": "Пускане/спиране на камерата",
|
||||
"videoQuality": "Управление на качество на обаждането"
|
||||
},
|
||||
"\u0005keyboardShortcuts": {},
|
||||
"liveStreaming": {
|
||||
"busy": "Работим върху това да освободим ресурси за излъчване. Моля, опитайте отново след няколко минути.",
|
||||
"busyTitle": "Всички излъчватели в момента са заети.",
|
||||
"changeSignIn": "",
|
||||
"choose": "",
|
||||
"chooseCTA": "",
|
||||
"enterStreamKey": "",
|
||||
"changeSignIn": "Смяна на акаунти.",
|
||||
"choose": "Изберете предаване на живо",
|
||||
"chooseCTA": "Изберете опция за предаване. Влезли сте като {{email}}.",
|
||||
"enterStreamKey": "Въведете ключа от YouTube за предаване на живо.",
|
||||
"error": "Излъчването на живо беше неуспешно. Моля, опитайте отново.",
|
||||
"errorAPI": "",
|
||||
"errorLiveStreamNotEnabled": "",
|
||||
"expandedOff": "",
|
||||
"expandedOn": "",
|
||||
"expandedPending": "",
|
||||
"errorAPI": "Изникна проблем с връзката към YouTube. Моля опитайте отново.",
|
||||
"errorLiveStreamNotEnabled": "Предаването на живо не е пуснато за {{email}}. Моля активирайте го или сменете акаунта.",
|
||||
"expandedOff": "Предаването на живо бе спряно",
|
||||
"expandedOn": "Срещата се излъчва на живо в YouTube.",
|
||||
"expandedPending": "Излъчването на живо се стартира...",
|
||||
"failedToStart": "Излъчването на живо не успя да започне",
|
||||
"getStreamKeyManually": "",
|
||||
"invalidStreamKey": "",
|
||||
"getStreamKeyManually": "Не успяхме да открием никакво предаване на живо. Опитайте да вземете ключа за такова от YouTube.",
|
||||
"invalidStreamKey": "Ключът за предаване на живо е грешен.",
|
||||
"off": "Край на излъчването на живо",
|
||||
"offBy": "{{name}} спря излъчването на живо",
|
||||
"on": "Излъчване на живо",
|
||||
"onBy": "{{name}} пусна излъчване на живо",
|
||||
"pending": "Започване на излъчването на живо…",
|
||||
"serviceName": "",
|
||||
"signedInAs": "",
|
||||
"signIn": "",
|
||||
"signInCTA": "",
|
||||
"serviceName": "Предаване на живо",
|
||||
"signedInAs": "В момента сте влезли като:",
|
||||
"signIn": "Влезте с Гугъл",
|
||||
"signInCTA": "Влезте или въведете ключът за излъчване на живо от YouTube.",
|
||||
"signOut": "",
|
||||
"start": "Започване на излъчване на живо",
|
||||
"streamIdHelp": "",
|
||||
"start": "Започни излъчване на живо",
|
||||
"streamIdHelp": "Какво е това?",
|
||||
"unavailableTitle": "Излъчването на живо е недостъпно"
|
||||
},
|
||||
"\u0005liveStreaming": {},
|
||||
"localRecording": {
|
||||
"clientState": {
|
||||
"off": "",
|
||||
"on": "",
|
||||
"unknown": ""
|
||||
"off": "Изключено",
|
||||
"on": "Включено",
|
||||
"unknown": "Непознат"
|
||||
},
|
||||
"dialogTitle": "",
|
||||
"duration": "",
|
||||
"durationNA": "",
|
||||
"encoding": "",
|
||||
"label": "",
|
||||
"labelToolTip": "",
|
||||
"localRecording": "",
|
||||
"dialogTitle": "Управление на локален запис",
|
||||
"duration": "Продължителност",
|
||||
"durationNA": "Няма",
|
||||
"encoding": "Кодек",
|
||||
"label": "Етикет",
|
||||
"labelToolTip": "Локалния запис е включен",
|
||||
"localRecording": "Локален запис",
|
||||
"me": "Аз",
|
||||
"messages": {
|
||||
"engaged": "",
|
||||
"finished": "",
|
||||
"finishedModerator": "",
|
||||
"notModerator": ""
|
||||
"engaged": "Локалния запис е включен.",
|
||||
"finished": "Записа на сесията {{token}} приключи. Моля изпратете записа на вашият домакин.",
|
||||
"finishedModerator": "Сесията {{token}} за запис приключи. Локалният запис беше запазен. Моля поканете останалите участници да ви изпратят техните записи.",
|
||||
"notModerator": "Нямате права да пускате спирате локален запис."
|
||||
},
|
||||
"moderator": "Модератор",
|
||||
"no": "",
|
||||
"no": "Не",
|
||||
"participant": "Участник",
|
||||
"participantStats": "",
|
||||
"sessionToken": "",
|
||||
"start": "Край на записа",
|
||||
"stop": "Край на записа",
|
||||
"participantStats": "Статистика на участник",
|
||||
"sessionToken": "Тоукън за сесията",
|
||||
"start": "Започни запис",
|
||||
"stop": "Спри записа",
|
||||
"yes": "Да"
|
||||
},
|
||||
"\u0005localRecording": {},
|
||||
"lockRoomPassword": "парола",
|
||||
"lockRoomPasswordUppercase": "Парола",
|
||||
"me": "аз",
|
||||
"notify": {
|
||||
"connectedOneMember": "",
|
||||
"connectedThreePlusMembers": "",
|
||||
"connectedTwoMembers": "",
|
||||
"disconnected": "Връзка:",
|
||||
"connectedOneMember": "{{name}} влезна в срещата",
|
||||
"connectedThreePlusMembers": "{{name}} и още {{count}} влезнаха в срещата",
|
||||
"connectedTwoMembers": "{{first}} и {{second}} влезнаха в срещата",
|
||||
"disconnected": "Напусна срещата",
|
||||
"focus": "Конферентен фокус",
|
||||
"focusFail": "{{component}} не е на раположения - следващ опит след {{ms}} секунди",
|
||||
"focusFail": "{{component}} не е на раположение - следващ опит след {{ms}} секунди",
|
||||
"grantedTo": "Даване на роля модератор на {{to}}!",
|
||||
"invitedOneMember": "",
|
||||
"invitedThreePlusMembers": "",
|
||||
"invitedTwoMembers": "",
|
||||
"kickParticipant": "",
|
||||
"invitedOneMember": "{{name}} бе поканен",
|
||||
"invitedThreePlusMembers": "{{name}} и още {{count}} бяха поканени",
|
||||
"invitedTwoMembers": "{{first}} и {{second}} бяха поканени",
|
||||
"kickParticipant": "{{kicked}} беше изгонен от {{kicker}}",
|
||||
"me": "Аз",
|
||||
"moderator": "Придобихте права на модератор!",
|
||||
"muted": "Започвате разговора без звук.",
|
||||
"mutedTitle": "Звукът ви е спрян!",
|
||||
"mutedRemotelyTitle": "",
|
||||
"mutedRemotelyDescription": "",
|
||||
"passwordRemovedRemotely": "",
|
||||
"passwordSetRemotely": "",
|
||||
"raisedHand": "",
|
||||
"mutedRemotelyTitle": "Микрофонът ви бе спрян от {{participantDisplayName}}!",
|
||||
"mutedRemotelyDescription": "Винаги можете да пуснете микрофона си когато сте готови да говорите. Заглушете го отново за да не изпращате шум в срещата.",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) е премахната от друг потребител",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) създадена от друг потребител",
|
||||
"raisedHand": "{{name}} иска думата.",
|
||||
"somebody": "Някой",
|
||||
"startSilentTitle": "",
|
||||
"startSilentDescription": "",
|
||||
"suboptimalExperienceDescription": "",
|
||||
"suboptimalExperienceTitle": "",
|
||||
"unmute": "",
|
||||
"newDeviceCameraTitle": "",
|
||||
"newDeviceAudioTitle": "",
|
||||
"newDeviceAction": ""
|
||||
"startSilentTitle": "Влязохте с опция да не чувате аудио!",
|
||||
"startSilentDescription": "Влезте повторно за да пуснете звука",
|
||||
"suboptimalBrowserWarning": "Опасяваме се, че няма да можете да се насладите на срещата. Работим по въпроса, междувременно използвайте някой от <a href='static/recommendedBrowsers.html' target='_blank'>напълно поддържаните браузъри</a>.",
|
||||
"suboptimalExperienceTitle": "Внимание",
|
||||
"unmute": "Пускане на микрофона",
|
||||
"newDeviceCameraTitle": "Засечена е нова камера",
|
||||
"newDeviceAudioTitle": "Ново аудио устройство е засечено",
|
||||
"newDeviceAction": "Използвай"
|
||||
},
|
||||
"passwordSetRemotely": "",
|
||||
"passwordDigitsOnly": "",
|
||||
"passwordSetRemotely": "зададена от друг участник",
|
||||
"passwordDigitsOnly": "До {{number}} цифри",
|
||||
"poweredby": "с подкрепата на",
|
||||
"presenceStatus": {
|
||||
"busy": "",
|
||||
"calling": "",
|
||||
"busy": "Зает",
|
||||
"calling": "Обаждане...",
|
||||
"connected": "Свързан",
|
||||
"connecting": "Свързване",
|
||||
"connecting2": "Свързване",
|
||||
"connecting": "Свързване...",
|
||||
"connecting2": "Свързване*...",
|
||||
"disconnected": "Изключен",
|
||||
"expired": "",
|
||||
"ignored": "",
|
||||
"initializingCall": "",
|
||||
"invited": "Покани",
|
||||
"rejected": "",
|
||||
"ringing": ""
|
||||
"expired": "Изтекъл",
|
||||
"ignored": "Пренебрегнат",
|
||||
"initializingCall": "Свързване на обаждането...",
|
||||
"invited": "Поканен",
|
||||
"rejected": "Отхвърлен",
|
||||
"ringing": "Звъни..."
|
||||
},
|
||||
"\u0005presenceStatus": {},
|
||||
"profile": {
|
||||
"setDisplayNameLabel": "Задайте екранното си име",
|
||||
"setEmailInput": "Въведете е-поща",
|
||||
"setEmailLabel": "Задайте е-пощата си в „gravatar“",
|
||||
"title": "Профил"
|
||||
},
|
||||
"raisedHand": "Иска думата",
|
||||
"recording": {
|
||||
"authDropboxText": "",
|
||||
"availableSpace": "",
|
||||
"beta": "",
|
||||
"authDropboxText": "Качете в Dropbox",
|
||||
"availableSpace": "Налично място: {{spaceLeft}} MB (приблизително {{duration}} минути запис)",
|
||||
"beta": "БЕТА",
|
||||
"busy": "Работим върху това да освободим ресурси за запис. Моля, опитайте отново след няколко минути.",
|
||||
"busyTitle": "Всички възможности за запис в момента са заети",
|
||||
"error": "Грешка при опит за запис. Моля опитайте отново.",
|
||||
"expandedOff": "Записът спрян",
|
||||
"expandedOn": "",
|
||||
"expandedPending": "Записът започна",
|
||||
"expandedOff": "Записът спря",
|
||||
"expandedOn": "Срещата се записва в момента",
|
||||
"expandedPending": "Записът започва...",
|
||||
"failedToStart": "Неуспешен опит за записване",
|
||||
"fileSharingdescription": "",
|
||||
"live": "",
|
||||
"loggedIn": "",
|
||||
"fileSharingdescription": "Споделете записа с участниците в срещата",
|
||||
"live": "На Живо",
|
||||
"loggedIn": "Влезли сте като {{userName}}",
|
||||
"off": "Записът спрян",
|
||||
"offBy": "{{name}} спря записът",
|
||||
"on": "Запис",
|
||||
"pending": "",
|
||||
"rec": "",
|
||||
"serviceDescription": "",
|
||||
"serviceName": "",
|
||||
"signIn": "",
|
||||
"signOut": "",
|
||||
"unavailable": "",
|
||||
"onBy": "{{name}} пусна запис",
|
||||
"pending": "Стартира запис на срещата...",
|
||||
"rec": "ЗАПИС",
|
||||
"serviceDescription": "Записът ви ще се запише от специална записваща услуга",
|
||||
"serviceName": "Записваща услуга",
|
||||
"signIn": "Влизане",
|
||||
"signOut": "Излизане",
|
||||
"unavailable": "Упс! В момент {{serviceName}} е недостъпна. В момента се опитваме да решим проблема. Моля опитайте отново малко по-късно.",
|
||||
"unavailableTitle": "Записът е невъзможен"
|
||||
},
|
||||
"\u0005recording": {},
|
||||
"sectionList": {
|
||||
"pullToRefresh": ""
|
||||
"pullToRefresh": "Издърпай за да се обнови"
|
||||
},
|
||||
"settings": {
|
||||
"calendar": {
|
||||
"about": "",
|
||||
"disconnect": "Изключен",
|
||||
"microsoftSignIn": "",
|
||||
"signedIn": "",
|
||||
"about": "Календарната интеграция на {{appName}} сигурно достъпва вашия календар за да покаже настъпващите събития.",
|
||||
"disconnect": "Разкачи",
|
||||
"microsoftSignIn": "Влез с Microsoft акаунт",
|
||||
"signedIn": "В момента достъпва календара с {{email}}. Натиснете бутона Разкачи за да спрете достъпа.",
|
||||
"title": ""
|
||||
},
|
||||
"devices": "",
|
||||
"devices": "Устройства",
|
||||
"followMe": "Всички ме следват",
|
||||
"language": "",
|
||||
"loggedIn": "",
|
||||
"language": "Език",
|
||||
"loggedIn": "Влезли сте като {{name}}",
|
||||
"moderator": "Модератор",
|
||||
"more": "",
|
||||
"more": "Повече",
|
||||
"name": "Име",
|
||||
"noDevice": "Няма",
|
||||
"selectAudioOutput": "Звуков изход",
|
||||
@@ -513,27 +509,24 @@
|
||||
"startVideoMuted": "Всички започват скрити",
|
||||
"title": "Настройки"
|
||||
},
|
||||
"\u0005settings": {
|
||||
"calendar": {}
|
||||
},
|
||||
"settingsView": {
|
||||
"alertOk": "",
|
||||
"alertOk": "Потвърди",
|
||||
"alertTitle": "Внимание",
|
||||
"alertURLText": "",
|
||||
"buildInfoSection": "",
|
||||
"conferenceSection": "",
|
||||
"displayName": "",
|
||||
"email": "",
|
||||
"alertURLText": "Въведената връзка за сървър е невалидна",
|
||||
"buildInfoSection": "Информация за програмата",
|
||||
"conferenceSection": "Конференция",
|
||||
"displayName": "Име",
|
||||
"email": "Поща",
|
||||
"header": "Настройки",
|
||||
"profileSection": "Профил",
|
||||
"serverURL": "",
|
||||
"startWithAudioMuted": "",
|
||||
"startWithVideoMuted": "",
|
||||
"version": ""
|
||||
"serverURL": "Линк на сървъра",
|
||||
"startWithAudioMuted": "Започни със спрян звук",
|
||||
"startWithVideoMuted": "Започни със спряно видео",
|
||||
"version": "Версия"
|
||||
},
|
||||
"share": {
|
||||
"dialInfoText": "",
|
||||
"mainText": ""
|
||||
"dialInfoText": "\n\n=====\n\nИскате да наберете от телефона?\n\n{{defaultDialInNumber}}Използвайте този линк за повече номера\n{{dialInfoPageUrl}}",
|
||||
"mainText": "Използвайте линка за да влезете в срещата:\n{{roomUrl}}"
|
||||
},
|
||||
"speaker": "Говорещ",
|
||||
"speakerStats": {
|
||||
@@ -555,99 +548,95 @@
|
||||
},
|
||||
"toolbar": {
|
||||
"accessibilityLabel": {
|
||||
"audioOnly": "",
|
||||
"audioOnly": "Пускане на режим само с звук",
|
||||
"audioRoute": "",
|
||||
"callQuality": "",
|
||||
"cc": "",
|
||||
"chat": "",
|
||||
"document": "Отваряне/затваряне на споделен документ",
|
||||
"callQuality": "Управление на качестото на обаждането",
|
||||
"cc": "Пускане на субтитри",
|
||||
"chat": "Активиране на прозорец за съобщения",
|
||||
"document": "Показване на споделен документ",
|
||||
"feedback": "",
|
||||
"fullScreen": "",
|
||||
"hangup": "",
|
||||
"fullScreen": "Пускане/Спиране на изглед в цял екран",
|
||||
"hangup": "Напускане на срещата",
|
||||
"invite": "Поканете участници",
|
||||
"kick": "",
|
||||
"localRecording": "",
|
||||
"lockRoom": "",
|
||||
"moreActions": "",
|
||||
"moreActionsMenu": "",
|
||||
"mute": "",
|
||||
"pip": "",
|
||||
"kick": "Изгони участник",
|
||||
"localRecording": "Показване на контроли за локален запис",
|
||||
"lockRoom": "Смяна парола на среща",
|
||||
"moreActions": "Показване на меню с повече опции",
|
||||
"moreActionsMenu": "Меню с повече опции",
|
||||
"mute": "Пускане/спиране на видеото",
|
||||
"pip": "Пускане на Картина-в-Картина",
|
||||
"profile": "Редактиране на профила",
|
||||
"raiseHand": "",
|
||||
"recording": "",
|
||||
"remoteMute": "",
|
||||
"Settings": "",
|
||||
"sharedvideo": "",
|
||||
"raiseHand": "Смяна искане на думата",
|
||||
"recording": "Пускане/спиране на запис",
|
||||
"remoteMute": "Заглуши участник",
|
||||
"Settings": "Промяна на настройки",
|
||||
"sharedvideo": "Споделяне на YouTube видео",
|
||||
"shareRoom": "",
|
||||
"shareYourScreen": "",
|
||||
"shortcuts": "",
|
||||
"shareYourScreen": "Споделяне на екрана",
|
||||
"shortcuts": "Бързи клавиши",
|
||||
"show": "",
|
||||
"speakerStats": "",
|
||||
"speakerStats": "Показване на статистики за участниците",
|
||||
"tileView": "",
|
||||
"toggleCamera": "",
|
||||
"videomute": "",
|
||||
"videoblur": ""
|
||||
"videomute": "Пускане/спиране на видеото",
|
||||
"videoblur": "Пускане/спиране на замъгляване на видеото"
|
||||
},
|
||||
"addPeople": "Добавяне на участници в разговора",
|
||||
"audioOnlyOff": "",
|
||||
"audioOnlyOn": "",
|
||||
"audioRoute": "",
|
||||
"audioOnlyOff": "Спиране режима с нисък трафик",
|
||||
"audioOnlyOn": "Пускане режима с нисък трафик",
|
||||
"audioRoute": "Изберете устройство за звук",
|
||||
"authenticate": "Идентификация",
|
||||
"callQuality": "",
|
||||
"callQuality": "Промяна качеството на видеото",
|
||||
"chat": "Отваряне/затваряне на текстовите съобщения",
|
||||
"closeChat": "",
|
||||
"documentClose": "Отваряне/затваряне на споделен документ",
|
||||
"documentOpen": "Отваряне/затваряне на споделен документ",
|
||||
"enterFullScreen": "",
|
||||
"enterTileView": "",
|
||||
"exitFullScreen": "",
|
||||
"exitTileView": "",
|
||||
"feedback": "",
|
||||
"closeChat": "Затваряне на съобщенията",
|
||||
"documentClose": "Затваряне на споделеният документ",
|
||||
"documentOpen": "Отваряне на споделен документ",
|
||||
"enterFullScreen": "Вижте на цял екран",
|
||||
"enterTileView": "Влизане в изглед галерия",
|
||||
"exitFullScreen": "Изход от цял екран",
|
||||
"exitTileView": "Спиране на изглед галерия",
|
||||
"feedback": "Отзиви",
|
||||
"hangup": "Напускане",
|
||||
"invite": "Поканете участници",
|
||||
"login": "Влез",
|
||||
"logout": "Изход",
|
||||
"lowerYourHand": "",
|
||||
"moreActions": "",
|
||||
"lowerYourHand": "Махни искането на думата",
|
||||
"moreActions": "Още опции",
|
||||
"mute": "Спиране/пускане на микрофона",
|
||||
"openChat": "",
|
||||
"pip": "",
|
||||
"openChat": "Отвори съобщенията",
|
||||
"pip": "Пусни Картина-в-Картина",
|
||||
"profile": "Редактиране на профила",
|
||||
"raiseHand": "Вдигане/сваляне на ръка",
|
||||
"raiseYourHand": "Вдигни ръка.",
|
||||
"raiseYourHand": "Поискай думата",
|
||||
"Settings": "Настройки",
|
||||
"sharedvideo": "Пускане/спиране на споделянето на екрана",
|
||||
"shareRoom": "",
|
||||
"shortcuts": "",
|
||||
"speakerStats": "Статистика на говорителя",
|
||||
"startScreenSharing": "",
|
||||
"startSubtitles": "",
|
||||
"stopScreenSharing": "",
|
||||
"stopSubtitles": "",
|
||||
"stopSharedVideo": "",
|
||||
"shareRoom": "Добавете някого",
|
||||
"shortcuts": "Виж бързите клавиши",
|
||||
"speakerStats": "Статистика за говорителите",
|
||||
"startScreenSharing": "Започни споделяне на екрана",
|
||||
"startSubtitles": "Пускане на субтитри",
|
||||
"stopScreenSharing": "Спиране споделяне на екрана",
|
||||
"stopSubtitles": "Спиране на субтитри",
|
||||
"stopSharedVideo": "Спиране на YouTube видео",
|
||||
"talkWhileMutedPopup": "Опитвате се да говорите? В момента микрофонът Ви е заглушен.",
|
||||
"tileViewToggle": "",
|
||||
"toggleCamera": "",
|
||||
"tileViewToggle": "Превключване на изглед галерия",
|
||||
"toggleCamera": "Пускане/спиране на камера",
|
||||
"videomute": "Пускане/спиране на камерата",
|
||||
"startvideoblur": "",
|
||||
"stopvideoblur": ""
|
||||
},
|
||||
"\u0005toolbar": {
|
||||
"accessibilityLabel": {}
|
||||
"startvideoblur": "Замъгли фона ми",
|
||||
"stopvideoblur": "Спиране замъгляването на фона"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "",
|
||||
"error": "Грешка при опит за запис. Моля опитайте отново.",
|
||||
"expandedLabel": "",
|
||||
"failedToStart": "",
|
||||
"labelToolTip": "",
|
||||
"off": "",
|
||||
"pending": "",
|
||||
"start": "",
|
||||
"stop": "",
|
||||
"tr": ""
|
||||
"ccButtonTooltip": "Пускане / Спиране на субтитри",
|
||||
"error": "Грешка при опит за транскрибиране. Моля опитайте отново.",
|
||||
"expandedLabel": "Транскрибирането е пуснато",
|
||||
"failedToStart": "Транскрибирането не успя при пускане",
|
||||
"labelToolTip": "Тази среща се транскрибира",
|
||||
"off": "Транскрибирането спря",
|
||||
"pending": "Стартира се транскрибиране на срещата...",
|
||||
"start": "Започва показване на субтитри",
|
||||
"stop": "Спира показване на субтитри",
|
||||
"tr": "СУБ"
|
||||
},
|
||||
"\u0005transcribing": {},
|
||||
"userMedia": {
|
||||
"androidGrantPermissions": "Изберете <b><i>Разрешаване</i></b>, когато браузърът Ви помоли за разрешение.",
|
||||
"chromeGrantPermissions": "Изберете <b><i>Разрешаване</i></b>, когато браузърът Ви помоли за разрешение.",
|
||||
@@ -661,31 +650,34 @@
|
||||
"safariGrantPermissions": "Изберете <b><i>Добре</i></b>, когато браузърът Ви помоли за разрешение."
|
||||
},
|
||||
"videoSIPGW": {
|
||||
"busy": "",
|
||||
"busyTitle": "",
|
||||
"errorAlreadyInvited": "",
|
||||
"errorInvite": "",
|
||||
"errorInviteFailed": "",
|
||||
"errorInviteFailedTitle": "",
|
||||
"errorInviteTitle": "",
|
||||
"pending": ""
|
||||
"busy": "Работим по освобождаване на ресурси. Моля, опитайте след няколко минути.",
|
||||
"busyTitle": "Услугата за стаи в момента е заета",
|
||||
"errorAlreadyInvited": "{{displayName}} вече е поканен",
|
||||
"errorInvite": "Конференцията не е стартирана. Моля, опитайте по-късно.",
|
||||
"errorInviteFailed": "Работим по разрешаването на проблем. Моля, опитайте по-късно.",
|
||||
"errorInviteFailedTitle": "Добавянето на {{displayName}} не успя",
|
||||
"errorInviteTitle": "Грешка при добавяне на стая",
|
||||
"pending": "{{displayName}} бе поканен"
|
||||
},
|
||||
"videoStatus": {
|
||||
"audioOnly": "",
|
||||
"audioOnlyExpanded": "",
|
||||
"callQuality": "",
|
||||
"audioOnly": "АУДИО",
|
||||
"audioOnlyExpanded": "Вие сте в режим на нисък трафик. В този режим ще получавате само аудио или споделени екрани.",
|
||||
"callQuality": "Качество на видеото",
|
||||
"hd": "ВК",
|
||||
"hdTooltip": "Гледате високо качество на видеото",
|
||||
"highDefinition": "Високо качество",
|
||||
"labelTooiltipNoVideo": "",
|
||||
"labelTooltipAudioOnly": "Включен е режим само със звук",
|
||||
"labelTooiltipNoVideo": "Няма видео",
|
||||
"labelTooltipAudioOnly": "Пуснат режим на нисък трафик",
|
||||
"ld": "НК",
|
||||
"ldTooltip": "Виждате ниско качество на видеото",
|
||||
"lowDefinition": "Ниско качество",
|
||||
"onlyAudioAvailable": "",
|
||||
"onlyAudioSupported": "",
|
||||
"onlyAudioAvailable": "Само аудио е налично",
|
||||
"onlyAudioSupported": "Този браузър поддържа само аудио.",
|
||||
"p2pEnabled": "Вкл. директно свързване",
|
||||
"p2pVideoQualityDescription": "",
|
||||
"p2pVideoQualityDescription": "В директна връзка, получаваното качество може да се сменя между високо и само аудио. Останалите настройки ще са достъпни когато връзката не е директна.",
|
||||
"recHighDefinitionOnly": "Ще се предпочита високо качество.",
|
||||
"sd": "СК",
|
||||
"sdTooltip": "Гледате стандартно качество на видеото",
|
||||
"standardDefinition": "Стандартно качество"
|
||||
},
|
||||
"videothumbnail": {
|
||||
@@ -693,38 +685,39 @@
|
||||
"flip": "Огледално",
|
||||
"kick": "Изгони",
|
||||
"moderator": "Модератор",
|
||||
"mute": "Учасника е с изключен микрофон",
|
||||
"mute": "Участника е с изключен микрофон",
|
||||
"muted": "Изключен микрофон",
|
||||
"remoteControl": "Отдалечено управление",
|
||||
"show": "",
|
||||
"videomute": ""
|
||||
"show": "Покажи на главния екран",
|
||||
"videomute": "Участник е спрял камерата си"
|
||||
},
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
"join": "",
|
||||
"join": "Натиснете за да влезете",
|
||||
"roomname": "Въведете име на стаята"
|
||||
},
|
||||
"appDescription": "",
|
||||
"appDescription": "Хайде на видео разговорите с целият ви екип. Всъщност, поканете всички познати. {{app}} е напълно защитено, 100% решение за видеоконференции с отворен код което може да ползвате по цял ден, всеки ден, безплатно - без да ви е нужна регистрация.",
|
||||
"audioVideoSwitch": {
|
||||
"audio": "",
|
||||
"video": ""
|
||||
"audio": "Глас",
|
||||
"video": "Видео"
|
||||
},
|
||||
"calendar": "",
|
||||
"connectCalendarButton": "",
|
||||
"connectCalendarText": "",
|
||||
"enterRoomTitle": "",
|
||||
"calendar": "Календар",
|
||||
"connectCalendarButton": "Свържете вашия календар",
|
||||
"connectCalendarText": "Свържете вашия календар за да видите срещите си в {{app}}. Добавяйки {{provider}} срещите в календара си ще можете да ги старирате с едно докосване.",
|
||||
"enterRoomTitle": "Започни нова среща",
|
||||
"onlyAsciiAllowed": "Името на срещата може да съдържа само латински букви и цифри.",
|
||||
"go": "НАПРЕД",
|
||||
"join": "ПРИСЪЕДИНЯВАНЕ",
|
||||
"info": "",
|
||||
"info": "Информация",
|
||||
"privacy": "Поверителност",
|
||||
"recentList": "",
|
||||
"recentListDelete": "",
|
||||
"recentListEmpty": "",
|
||||
"reducedUIText": "",
|
||||
"recentList": "Скорошни срещи",
|
||||
"recentListDelete": "Изтрий",
|
||||
"recentListEmpty": "Списъка с скорошни срещи е празен. След като участвате в някоя среща, ще я намерите тук.",
|
||||
"reducedUIText": "Добре дошли в {{app}}!",
|
||||
"roomname": "Въведете име на стаята",
|
||||
"roomnameHint": "",
|
||||
"roomnameHint": "Въведете името или връзката на стаята в която искате да влезете. Също може да си измислите име. Само го споделете с някой, за да може и той да въведе същото име за да се срещнете.",
|
||||
"sendFeedback": "Изпращане на отзиви",
|
||||
"terms": "Условия",
|
||||
"title": ""
|
||||
"title": "Сигурна, с много възможности, и напълно безплатна платформа за видео конференции"
|
||||
}
|
||||
}
|
||||
1187
lang/main-hu.json
1187
lang/main-hu.json
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
"headphones": "Escotadors",
|
||||
"phone": "Telefòn",
|
||||
"speaker": "Nautparlaire",
|
||||
"none": ""
|
||||
"none": "Cap de periferic àudio pas disponible"
|
||||
},
|
||||
"audioOnly": {
|
||||
"audioOnly": "Benda passanta febla"
|
||||
@@ -182,7 +182,7 @@
|
||||
"liveStreamingDisabledForGuestTooltip": "Los convidats pòdon pas aviar una difusion en dirècte",
|
||||
"liveStreamingDisabledTooltip": "Difusion en dirècte desactivada.",
|
||||
"lockMessage": "Impossible de verrolhar la conferéncia.",
|
||||
"lockRoom": "",
|
||||
"lockRoom": "Ajustar un $t(lockRoomPasswordUppercase) a la conferéncia",
|
||||
"lockTitle": "Fracàs del verrolhatge",
|
||||
"logoutQuestion": "Sètz segur que vos volètz desconnectar e arrestar la conferéncia ?",
|
||||
"logoutTitle": "Desconnexion",
|
||||
@@ -199,10 +199,10 @@
|
||||
"muteParticipantDialog": "",
|
||||
"muteParticipantTitle": "Copar lo micro als participants ?",
|
||||
"Ok": "D'acòrdi",
|
||||
"passwordLabel": "",
|
||||
"passwordNotSupported": "Ajustar un senhal a una conferéncia es pas suportat.",
|
||||
"passwordNotSupportedTitle": "",
|
||||
"passwordRequired": "",
|
||||
"passwordLabel": "SENHAL",
|
||||
"passwordNotSupported": "Ajustar un $t(lockRoomPassword) a una conferéncia es pas suportat.",
|
||||
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) pas suportat",
|
||||
"passwordRequired": "$t(lockRoomPasswordUppercase) requesit",
|
||||
"popupError": "Vòstre navigator bloca las fenèstras que sorgisson a partir d'aqueste site. Mercés d'activar aquelas fenèstras dins los paramètres de vòstre navigator e de tornar ensajar.",
|
||||
"popupErrorTitle": "Fenèstra que sorgís blocada",
|
||||
"recording": "Enregistrament",
|
||||
@@ -217,7 +217,7 @@
|
||||
"remoteControlStopMessage": "La session de contraròtle alonhat es acabada !",
|
||||
"remoteControlTitle": "Contraròtle a distància",
|
||||
"Remove": "Suprimir",
|
||||
"removePassword": "",
|
||||
"removePassword": "Suprimir lo",
|
||||
"removeSharedVideoMsg": "Sètz segur que volètz suprimir vòstra vidèo partejada ?",
|
||||
"removeSharedVideoTitle": "Suprimir la vidèo partejada",
|
||||
"reservationError": "Error del sistèma de reservacion",
|
||||
@@ -250,7 +250,7 @@
|
||||
"tokenAuthFailed": "O planhèm, sètz pas autorizat a rejónher l'apèl.",
|
||||
"tokenAuthFailedTitle": "Fracàs de l'autentificacion",
|
||||
"transcribing": "Transcripcion",
|
||||
"unlockRoom": "",
|
||||
"unlockRoom": "Suprimir lo $t(lockRoomPassword) de la conferéncia",
|
||||
"userPassword": "senhal utilizaire",
|
||||
"WaitForHostMsg": "La conferéncia <b>{{room}}</b> a pas encara començat. Se sètz l’òst volgatz ben vos identificar. Autrament esperatz qu’arribe l’òste.",
|
||||
"WaitForHostMsgWOk": "La conferéncia <b>{{room}}</b> a pas encara començat. Se sètz l’òst volgatz ben clicar Ok per vos identificar. Autrament esperatz qu’arribe l’òste.",
|
||||
@@ -279,8 +279,8 @@
|
||||
},
|
||||
"info": {
|
||||
"accessibilityLabel": "Mostrar las info",
|
||||
"addPassword": "",
|
||||
"cancelPassword": "",
|
||||
"addPassword": "Ajustar un $t(lockRoomPassword)",
|
||||
"cancelPassword": "Anullar lo $t(lockRoomPassword)",
|
||||
"conferenceURL": "Ligam :",
|
||||
"country": "País",
|
||||
"dialANumber": "Per participar a la conferéncia, sonatz un d’aquestes numèros puèi picatz lo senhal.",
|
||||
@@ -355,7 +355,9 @@
|
||||
"getStreamKeyManually": "",
|
||||
"invalidStreamKey": "La clau de difusion en dirècte es benlèu pas corrècta.",
|
||||
"off": "La difusion en dirècte es estada arrestada",
|
||||
"offBy": "",
|
||||
"on": "La difusion en dirècte es estada arrestada",
|
||||
"onBy": "",
|
||||
"pending": "Començar lo dirècte...",
|
||||
"serviceName": "Servici de difusion en dirècte",
|
||||
"signedInAs": "Sètz connectat coma :",
|
||||
@@ -416,8 +418,8 @@
|
||||
"mutedTitle": "Sètz en mut !",
|
||||
"mutedRemotelyTitle": "{{participantDisplayName}} vos a mes en silenci !",
|
||||
"mutedRemotelyDescription": "",
|
||||
"passwordRemovedRemotely": "",
|
||||
"passwordSetRemotely": "",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) tirat per un autre participant",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) definit per un autre participant",
|
||||
"raisedHand": "{{name}} volriá parlar.",
|
||||
"somebody": "Qualqu'un",
|
||||
"startSilentTitle": "Avètz jonch sens cap de sortida àudio !",
|
||||
@@ -468,7 +470,9 @@
|
||||
"live": "DIRÈCTE",
|
||||
"loggedIn": "Session a {{userName}}",
|
||||
"off": "Enregistrament arrestar",
|
||||
"offBy": "",
|
||||
"on": "Enregistrament",
|
||||
"onBy": "",
|
||||
"pending": "Preparacion de l’enregistrament de la conferéncia...",
|
||||
"rec": "ENRG",
|
||||
"serviceDescription": "Vòstre enregistrament serà salvagardat pel servici dedicat.",
|
||||
@@ -508,7 +512,7 @@
|
||||
"alertOk": "D’acòrdi",
|
||||
"alertTitle": "Avertiment",
|
||||
"alertURLText": "L’URL del servidor es pas valida",
|
||||
"buildInfoSection": "",
|
||||
"buildInfoSection": "Informacions de generacion",
|
||||
"conferenceSection": "Conferéncia",
|
||||
"displayName": "Escais-nom",
|
||||
"email": "Corrièl",
|
||||
@@ -553,7 +557,7 @@
|
||||
"fullScreen": "Passar al ecran complèt",
|
||||
"hangup": "Quitar la sonada",
|
||||
"invite": "Convidar de monde",
|
||||
"kick": "",
|
||||
"kick": "Exclure un participan ",
|
||||
"localRecording": "Passar al panèl d’enregistraments locals",
|
||||
"lockRoom": "Tirar lo senhal de la conferéncia",
|
||||
"moreActions": "Passar al menú mai d’accions",
|
||||
@@ -563,7 +567,7 @@
|
||||
"profile": "Modificar vòstre perfil",
|
||||
"raiseHand": "Demandar la paraula",
|
||||
"recording": "Passar al enregistraments",
|
||||
"remoteMute": "",
|
||||
"remoteMute": "Copar lo son del participant",
|
||||
"Settings": "Passar als paramètres",
|
||||
"sharedvideo": "Passar al partatge de vidèo Youtube",
|
||||
"shareRoom": "Convidar qualqu’un",
|
||||
@@ -577,8 +581,8 @@
|
||||
"videoblur": ""
|
||||
},
|
||||
"addPeople": "Ajustar de monde a vòstra sonada",
|
||||
"audioOnlyOff": "",
|
||||
"audioOnlyOn": "",
|
||||
"audioOnlyOff": "Desactivar lo mòde connexion febla",
|
||||
"audioOnlyOn": "Activar lo mòde connexion febla",
|
||||
"audioRoute": "Seleccionar lo periferic àudio",
|
||||
"authenticate": "Autentificatz-vos",
|
||||
"callQuality": "Gerir la qualitat vidèo",
|
||||
@@ -587,9 +591,9 @@
|
||||
"documentClose": "Tampar los documents partejats",
|
||||
"documentOpen": "Dobrir los documents partejats",
|
||||
"enterFullScreen": "Veire l’ecran complèt",
|
||||
"enterTileView": "",
|
||||
"enterTileView": "Dintrar dins la vista mosaïca",
|
||||
"exitFullScreen": "Sortir de l’ecran complèt",
|
||||
"exitTileView": "",
|
||||
"exitTileView": "Quitar la vista mosaïca",
|
||||
"feedback": "Daissar un comentari",
|
||||
"hangup": "Quitar",
|
||||
"invite": "Convidar de monde",
|
||||
@@ -617,8 +621,8 @@
|
||||
"tileViewToggle": "Activar/Desactivar la vista en mosaïc",
|
||||
"toggleCamera": "Passar a la camèra",
|
||||
"videomute": "Aviar / Arrestar la camèra",
|
||||
"startvideoblur": "",
|
||||
"stopvideoblur": ""
|
||||
"startvideoblur": "Trebolar mon rèire-plan",
|
||||
"stopvideoblur": "Desactivar lo borrolatge del rèire-plan"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Aviar / Arrestat los sostítols",
|
||||
@@ -656,13 +660,13 @@
|
||||
},
|
||||
"videoStatus": {
|
||||
"audioOnly": "AUD",
|
||||
"audioOnlyExpanded": "",
|
||||
"audioOnlyExpanded": "Sètz en mòde connexion febla. Amb aqueste mòde recebretz pas que l’àudio e lo partatge d’ecran.",
|
||||
"callQuality": "Qualitat vidèo",
|
||||
"hd": "HD",
|
||||
"hdTooltip": "Difusion vidèo en nauta definicion",
|
||||
"highDefinition": "Nauta definicion",
|
||||
"labelTooiltipNoVideo": "Pas cap de vidèo",
|
||||
"labelTooltipAudioOnly": "",
|
||||
"labelTooltipAudioOnly": "Mòde connexion febla activat",
|
||||
"ld": "Bassa definicion",
|
||||
"ldTooltip": "Difusion vidèo en bassa definicion",
|
||||
"lowDefinition": "Bassa definicion",
|
||||
@@ -684,7 +688,7 @@
|
||||
"muted": "Mut",
|
||||
"remoteControl": "Contraròtle alonhat",
|
||||
"show": "",
|
||||
"videomute": ""
|
||||
"videomute": "Lo participant a arrestat la camèra"
|
||||
},
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
@@ -698,11 +702,12 @@
|
||||
},
|
||||
"calendar": "Calendari",
|
||||
"connectCalendarButton": "Connectar lo calendari",
|
||||
"connectCalendarText": "",
|
||||
"connectCalendarText": "Connectatz vòstre calendièr per veire vòstras reünions dins {{app}}. Ajustatz tanben las reünions de {{provider}} a vòstre calendièr e aviatz-las amb un sol clic.",
|
||||
"enterRoomTitle": "Començar una nòva conferéncia",
|
||||
"onlyAsciiAllowed": "",
|
||||
"go": "Crear",
|
||||
"join": "PARTICIPATZ",
|
||||
"info": "",
|
||||
"info": "Infor",
|
||||
"privacy": "Vida privada",
|
||||
"recentList": "Recents",
|
||||
"recentListDelete": "Suprimits",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,11 @@
|
||||
"bluetooth": "Bluetooth",
|
||||
"headphones": "Fones de ouvido",
|
||||
"phone": "Celular",
|
||||
"speaker": "Apresentador"
|
||||
"speaker": "Alto-falantes",
|
||||
"none": ""
|
||||
},
|
||||
"audioOnly": {
|
||||
"audioOnly": "Somente áudio"
|
||||
"audioOnly": "Largura de banda baixa"
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "Adicionar um link da reunião",
|
||||
@@ -49,9 +50,9 @@
|
||||
"messagebox": "Digite uma mensagem",
|
||||
"nickname": {
|
||||
"popover": "Escolha um apelido",
|
||||
"title": "Digite um apelido para usar o chat"
|
||||
"title": "Digite um apelido para usar o bate-papo"
|
||||
},
|
||||
"title": "Chat"
|
||||
"title": "Bate-papo"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
"joiningRoom": "Conectando você à reunião…"
|
||||
@@ -96,8 +97,7 @@
|
||||
"resolution": "Resolução:",
|
||||
"status": "Conexão:",
|
||||
"transport": "Transporte:",
|
||||
"transport_plural": "Transportes:",
|
||||
"turn": " (virar)"
|
||||
"transport_plural": "Transportes:"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "Mais cedo",
|
||||
@@ -107,7 +107,7 @@
|
||||
"deepLinking": {
|
||||
"appNotInstalled": "Você precisa do aplicativo móvel {{app}} para participar da reunião no seu telefone.",
|
||||
"description": "Nada acontece? Estamos tentando iniciar sua reunião no aplicativo desktop {{app}}. Tente novamente ou inicie ele na aplicação web {{app}}.",
|
||||
"descriptionWithoutWeb": "",
|
||||
"descriptionWithoutWeb": "Nada aconteceu? Tentamos iniciar sua reunião no aplicativo de desktop {{app}}.",
|
||||
"downloadApp": "Baixe o Aplicativo",
|
||||
"launchWebButton": "Iniciar na web",
|
||||
"openApp": "Continue na aplicação",
|
||||
@@ -115,6 +115,7 @@
|
||||
"tryAgainButton": "Tente novamente no desktop"
|
||||
},
|
||||
"defaultLink": "ex.: {{url}}",
|
||||
"defaultNickname": "ex.: João Pedro",
|
||||
"deviceError": {
|
||||
"cameraError": "Falha ao acessar sua câmera",
|
||||
"cameraPermission": "Erro ao obter permissão para a câmera",
|
||||
@@ -132,7 +133,7 @@
|
||||
"liveStreaming": "Transmissão ao vivo"
|
||||
},
|
||||
"allow": "Permitir",
|
||||
"alreadySharedVideoMsg": "",
|
||||
"alreadySharedVideoMsg": "Outro participante já está compartilhando um vídeo. Esta conferência permite apenas um vídeo compartilhado por vez.",
|
||||
"alreadySharedVideoTitle": "Somente um vídeo compartilhado é permitido por vez",
|
||||
"applicationWindow": "Janela de aplicativo",
|
||||
"Back": "Voltar",
|
||||
@@ -158,51 +159,51 @@
|
||||
"contactSupport": "Contate o suporte",
|
||||
"copy": "Copiar",
|
||||
"dismiss": "Dispensar",
|
||||
"displayNameRequired": "",
|
||||
"displayNameRequired": "Oi! Qual o seu nome?",
|
||||
"done": "Feito",
|
||||
"enterDisplayName": "",
|
||||
"enterDisplayName": "Digite seu nome aqui",
|
||||
"error": "Erro",
|
||||
"externalInstallationMsg": "Você precisa instalar nossa extensão de compartilhamento de tela.",
|
||||
"externalInstallationTitle": "Extensão requerida",
|
||||
"goToStore": "Vá para a loja virtual",
|
||||
"gracefulShutdown": "O sistema está em manutenção. Por favor tente novamente mais tarde.",
|
||||
"IamHost": "Eu sou o anfitrião",
|
||||
"incorrectRoomLockPassword": "",
|
||||
"incorrectRoomLockPassword": "Senha incorreta",
|
||||
"incorrectPassword": "Usuário ou senha incorretos",
|
||||
"inlineInstallationMsg": "Você precisa instalar nossa extensão de compartilhamento de tela.",
|
||||
"inlineInstallExtension": "Instalar agora",
|
||||
"internalError": "Oops! Alguma coisa está errada. O seguinte erro ocorreu: {{error}}",
|
||||
"internalErrorTitle": "Erro interno",
|
||||
"kickMessage": "",
|
||||
"kickMessage": "Você pode contatar com {{participantDisplayName}} para obter mais detalhes.",
|
||||
"kickParticipantButton": "Remover",
|
||||
"kickParticipantDialog": "Tem certeza de que deseja remover este participante?",
|
||||
"kickParticipantTitle": "Deixar mudo este participante?",
|
||||
"kickTitle": "",
|
||||
"kickParticipantTitle": "Chutar este participante?",
|
||||
"kickTitle": "Ai! {{participantDisplayName}} expulsou você da reunião",
|
||||
"liveStreaming": "Transmissão ao Vivo",
|
||||
"liveStreamingDisabledForGuestTooltip": "Visitantes não podem iniciar transmissão ao vivo.",
|
||||
"liveStreamingDisabledTooltip": "Iniciar transmissão ao vivo desativada.",
|
||||
"lockMessage": "Falha ao travar a conferência.",
|
||||
"lockRoom": "",
|
||||
"lockRoom": "Adicionar reunião $t(lockRoomPasswordUppercase)",
|
||||
"lockTitle": "Bloqueio falhou",
|
||||
"logoutQuestion": "Deseja encerrar a sessão e finalizar a conferência?",
|
||||
"logoutTitle": "Encerrar sessão",
|
||||
"maxUsersLimitReached": "",
|
||||
"maxUsersLimitReachedTitle": "",
|
||||
"maxUsersLimitReached": "O limite para o número máximo de participantes foi atingido. A conferência está cheia. Entre em contato com o proprietário da reunião ou tente novamente mais tarde!",
|
||||
"maxUsersLimitReachedTitle": "Limite máximo de participantes atingido",
|
||||
"micConstraintFailedError": "Seu microfone não satisfaz algumas condições necessárias.",
|
||||
"micNotFoundError": "O microfone não foi encontrado.",
|
||||
"micNotSendingData": "",
|
||||
"micNotSendingDataTitle": "",
|
||||
"micNotSendingData": "Vá para as configurações do seu computador para ativar o som do microfone e ajustar seu nível",
|
||||
"micNotSendingDataTitle": "Seu microfone está mudo pelas configurações do sistema",
|
||||
"micPermissionDeniedError": "Não foi permitido acessar o seu microfone. Você ainda pode entrar na conferência, mas sem enviar áudio. Clique no botão do microfone para tentar reparar.",
|
||||
"micUnknownError": "Não pode usar o microfone por uma razão desconhecida.",
|
||||
"muteParticipantBody": "Você não está habilitado para tirar o mudo deles, mas eles podem tirar o mudo deles mesmos a qualquer tempo.",
|
||||
"muteParticipantButton": "Mudo",
|
||||
"muteParticipantDialog": "Tem certeza de que deseja silenciar este participante? Você não poderá desativar a opção silenciar dele, mas ele poderá fazer isso quando desejar.",
|
||||
"muteParticipantDialog": "Tem certeza de que deseja silenciar este participante? Você não poderá desfazer isso, mas o participante pode reabilitar o áudio a qualquer momento.",
|
||||
"muteParticipantTitle": "Deixar mudo este participante?",
|
||||
"Ok": "Ok",
|
||||
"passwordLabel": "",
|
||||
"passwordNotSupported": "Configuração de senha para a reunião não é suportada.",
|
||||
"passwordNotSupportedTitle": "",
|
||||
"passwordRequired": "",
|
||||
"passwordLabel": "$t(lockRoomPasswordUppercase)",
|
||||
"passwordNotSupported": "A configuração de uma reunião $t(lockRoomPassword) não é suportada.",
|
||||
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) não suportado",
|
||||
"passwordRequired": "$t(lockRoomPasswordUppercase) requerido",
|
||||
"popupError": "Seu navegador está bloqueando janelas popup deste site. Habilite os popups nas configurações de segurança no seu navegador e tente novamente.",
|
||||
"popupErrorTitle": "Popup bloqueado",
|
||||
"recording": "Gravando",
|
||||
@@ -217,7 +218,7 @@
|
||||
"remoteControlStopMessage": "A sessão de controle remoto terminou!",
|
||||
"remoteControlTitle": "Conexão de área de trabalho remota",
|
||||
"Remove": "Remover",
|
||||
"removePassword": "",
|
||||
"removePassword": "Remove $t(lockRoomPassword)",
|
||||
"removeSharedVideoMsg": "Deseja remover seu vídeo compartilhado?",
|
||||
"removeSharedVideoTitle": "Remover vídeo compartilhado",
|
||||
"reservationError": "Erro de sistema de reserva",
|
||||
@@ -250,7 +251,7 @@
|
||||
"tokenAuthFailed": "Desculpe, você não está autorizado a entrar nesta chamada.",
|
||||
"tokenAuthFailedTitle": "Falha de autenticação",
|
||||
"transcribing": "Transcrevendo",
|
||||
"unlockRoom": "",
|
||||
"unlockRoom": "Remove a reunião $t(lockRoomPassword)",
|
||||
"userPassword": "senha do usuário",
|
||||
"WaitForHostMsg": "A conferência <b>{{room}}</b> ainda não começou. Se você é o anfitrião, faça a autenticação. Do contrário, aguarde a chegada do anfitrião.",
|
||||
"WaitForHostMsgWOk": "A conferência <b>{{room}}</b> ainda não começou. Se você é o anfitrião, pressione Ok para autenticar. Do contrário, aguarde a chegada do anfitrião.",
|
||||
@@ -279,8 +280,8 @@
|
||||
},
|
||||
"info": {
|
||||
"accessibilityLabel": "Mostrar info",
|
||||
"addPassword": "",
|
||||
"cancelPassword": "",
|
||||
"addPassword": "Adicione $t(lockRoomPassword)",
|
||||
"cancelPassword": "Cancela $t(lockRoomPassword)",
|
||||
"conferenceURL": "Link:",
|
||||
"country": "País",
|
||||
"dialANumber": "Para entrar na reunião, disque um desses números e depois insira o PIN.",
|
||||
@@ -291,18 +292,18 @@
|
||||
"dialInTollFree": "Chamada gratuita",
|
||||
"genericError": "Oops, alguma coisa deu errado.",
|
||||
"inviteLiveStream": "Para ver a transmissão ao vivo da reunião, clique no link: {{url}}",
|
||||
"invitePhone": "",
|
||||
"invitePhoneAlternatives": "",
|
||||
"invitePhone": "Para participar por telefone, toque aqui: {{number}} ,, {{conferenceID}} # \\ n",
|
||||
"invitePhoneAlternatives": "Procurando um número de discagem diferente?\nVeja os números de discagem da reunião: {{url}} \n\n\nSe você também estiver discando através de um telefone da sala, participe sem conectar-se ao áudio: {{silentUrl}}",
|
||||
"inviteURLFirstPartGeneral": "Você foi convidado para uma reunião.",
|
||||
"inviteURLFirstPartPersonal": "",
|
||||
"inviteURLSecondPart": "",
|
||||
"inviteURLFirstPartPersonal": "{{name}} está convidando você para uma reunião.\n",
|
||||
"inviteURLSecondPart": "\nEntre na reunião:\n{{url}}\n",
|
||||
"liveStreamURL": "Transmissão ao vivo:",
|
||||
"moreNumbers": "Mais números",
|
||||
"noNumbers": "Sem números de discagem.",
|
||||
"noPassword": "Nenhum",
|
||||
"noRoom": "Nenhuma sala foi especificada para entrar.",
|
||||
"numbers": "Números de discagem",
|
||||
"password": "",
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"title": "Compartilhar",
|
||||
"tooltip": "Compartilhar link e discagem para esta reunião",
|
||||
"label": "Informações da reunião"
|
||||
@@ -335,7 +336,8 @@
|
||||
"toggleFilmstrip": "Mostrar ou ocultar miniaturas de vídeo",
|
||||
"toggleScreensharing": "Trocar entre câmera e compartilhamento de tela",
|
||||
"toggleShortcuts": "Mostrar ou ocultar atalhos de teclado",
|
||||
"videoMute": "Iniciar ou parar sua câmera"
|
||||
"videoMute": "Iniciar ou parar sua câmera",
|
||||
"videoQuality": "Gerenciar qualidade da chamada"
|
||||
},
|
||||
"liveStreaming": {
|
||||
"busy": "Estamos trabalhando para liberar os recursos de transmissão. Tente novamente em alguns minutos.",
|
||||
@@ -349,15 +351,17 @@
|
||||
"errorLiveStreamNotEnabled": "Transmissão ao vivo não está ativada em {{email}}. Ative a transmissão ao vivo ou registre numa conta com transmissão ao vivo ativada.",
|
||||
"expandedOff": "A transmissão ao vivo foi encerrada",
|
||||
"expandedOn": "A reunião está sendo transmitida pelo YouTube.",
|
||||
"expandedPending": "A transmissão ao vivo está sendo iniciada…",
|
||||
"expandedPending": "Iniciando a transmissão ao vivo...",
|
||||
"failedToStart": "Falha ao iniciar a transmissão ao vivo",
|
||||
"getStreamKeyManually": "",
|
||||
"getStreamKeyManually": "Não conseguimos buscar nenhuma transmissão ao vivo. Tente obter sua chave de transmissão ao vivo no YouTube.",
|
||||
"invalidStreamKey": "A senha para transmissão ao vivo pode estar incorreta.",
|
||||
"off": "Transmissão ao vivo encerrada",
|
||||
"offBy": "",
|
||||
"on": "Transmissão ao Vivo",
|
||||
"onBy": "",
|
||||
"pending": "Iniciando Transmissão ao Vivo...",
|
||||
"serviceName": "Serviço de Transmissão ao Vivo",
|
||||
"signedInAs": "Você está conectado atualmente como:",
|
||||
"signedInAs": "Você está conectado como:",
|
||||
"signIn": "Faça login no Google",
|
||||
"signInCTA": "Faça login ou insira sua chave de transmissão ao vivo do YouTube.",
|
||||
"signOut": "Sair",
|
||||
@@ -367,16 +371,16 @@
|
||||
},
|
||||
"localRecording": {
|
||||
"clientState": {
|
||||
"off": "Off",
|
||||
"on": "On",
|
||||
"off": "Desligado",
|
||||
"on": "Ligado",
|
||||
"unknown": "Desconhecido"
|
||||
},
|
||||
"dialogTitle": "Controles da Gravação Local",
|
||||
"duration": "Duração",
|
||||
"durationNA": "N/A",
|
||||
"durationNA": "N/D",
|
||||
"encoding": "Codificando",
|
||||
"label": "LOR",
|
||||
"labelToolTip": "Gravação local está envolvida",
|
||||
"labelToolTip": "Gravação local ativada",
|
||||
"localRecording": "Gravação local",
|
||||
"me": "Eu",
|
||||
"messages": {
|
||||
@@ -406,30 +410,30 @@
|
||||
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
|
||||
"grantedTo": "Direitos de moderador concedido para {{to}}!",
|
||||
"invitedOneMember": "{{displayName}} foi convidado",
|
||||
"invitedThreePlusMembers": "",
|
||||
"invitedTwoMembers": "",
|
||||
"kickParticipant": "",
|
||||
"invitedThreePlusMembers": "{{name}} e {{count}} outros foram convidados",
|
||||
"invitedTwoMembers": "{{first}} e {{second}} foram convidados",
|
||||
"kickParticipant": "{{kicked}} foi chutado por {{kicker}}",
|
||||
"me": "Eu",
|
||||
"moderator": "Direitos de moderador concedidos!",
|
||||
"muted": "Você iniciou uma conversa em mudo.",
|
||||
"mutedTitle": "Você está mudo!",
|
||||
"mutedRemotelyTitle": "",
|
||||
"mutedRemotelyDescription": "",
|
||||
"passwordRemovedRemotely": "",
|
||||
"passwordSetRemotely": "",
|
||||
"mutedRemotelyTitle": "Você foi silenciado por {{participantDisplayName}}!",
|
||||
"mutedRemotelyDescription": "Você sempre pode ativar o som quando estiver pronto para falar. Retire o som quando terminar para manter o ruído longe da reunião.",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removido por outro participante",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) definido por outro participante",
|
||||
"raisedHand": "{{name}} gostaria de falar.",
|
||||
"somebody": "Alguém",
|
||||
"startSilentTitle": "",
|
||||
"startSilentDescription": "",
|
||||
"suboptimalExperienceDescription": "Eer ... temos medo de que sua experiência com o {{appName}} não seja tão boa aqui. Estamos procurando maneiras de melhorar isso, mas até lá tente usar um dos <a href='static/recommendedBrowsers.html' target='_blank'> navegadores totalmente compatíveis</a>.",
|
||||
"startSilentTitle": "Você entrou sem saída de áudio!",
|
||||
"startSilentDescription": "Volte à reunião para habilitar o áudio",
|
||||
"suboptimalBrowserWarning": "",
|
||||
"suboptimalExperienceTitle": "Alerta do navegador",
|
||||
"unmute": "",
|
||||
"unmute": "Ativar som",
|
||||
"newDeviceCameraTitle": "Nova câmera detectada",
|
||||
"newDeviceAudioTitle": "Novo dispositivo de áudio detectado",
|
||||
"newDeviceAction": "Usar"
|
||||
},
|
||||
"passwordSetRemotely": "Definido por outro participante",
|
||||
"passwordDigitsOnly": "",
|
||||
"passwordDigitsOnly": "Até {{number}} dígitos",
|
||||
"poweredby": "distribuído por",
|
||||
"presenceStatus": {
|
||||
"busy": "Ocupado",
|
||||
@@ -443,7 +447,7 @@
|
||||
"initializingCall": "Iniciando Chamada...",
|
||||
"invited": "Convidar",
|
||||
"rejected": "Rejeitado",
|
||||
"ringing": "Chamando..."
|
||||
"ringing": "Tocando..."
|
||||
},
|
||||
"profile": {
|
||||
"setDisplayNameLabel": "Definir seu nome de exibição",
|
||||
@@ -451,6 +455,7 @@
|
||||
"setEmailLabel": "Definir seu email de gravatar",
|
||||
"title": "Perfil"
|
||||
},
|
||||
"raisedHand": "Gostaria de falar",
|
||||
"recording": {
|
||||
"authDropboxText": "Enviar para o Dropbox.",
|
||||
"availableSpace": "Espaço disponível: {{spaceLeft}} MB (aproximadamente {{duration}} minutos de gravação)",
|
||||
@@ -466,12 +471,14 @@
|
||||
"live": "AOVIVO",
|
||||
"loggedIn": "Conectado como {{userName}}",
|
||||
"off": "Gravação parada",
|
||||
"offBy": "",
|
||||
"on": "Gravando",
|
||||
"onBy": "",
|
||||
"pending": "Preparando para gravar a reunião...",
|
||||
"rec": "REC",
|
||||
"serviceDescription": "Sua gravação será salva pelo serviço de gravação",
|
||||
"serviceName": "Serviço de gravação",
|
||||
"signIn": "entrar",
|
||||
"signIn": "Entrar",
|
||||
"signOut": "Sair",
|
||||
"unavailable": "Oops! O {{serviceName}} está indisponível. Estamos trabalhando para resolver o problema. Por favor, tente mais tarde.",
|
||||
"unavailableTitle": "Gravação indisponível"
|
||||
@@ -518,10 +525,10 @@
|
||||
"version": "Versão"
|
||||
},
|
||||
"share": {
|
||||
"dialInfoText": "",
|
||||
"dialInfoText": "\n\n=====\n\nDeseja apenas discar no seu telefone?\n\n{{defaultDialInNumber}}Clique neste link para ver os números de telefone para esta reunião\n{{dialInfoPageUrl}}",
|
||||
"mainText": "Clique no seguinte link para entrar na reunião:{{roomUrl}}\n"
|
||||
},
|
||||
"speaker": "Apresentador",
|
||||
"speaker": "Alto-falantes",
|
||||
"speakerStats": {
|
||||
"hours": "{{count}}h",
|
||||
"minutes": "{{count}}m",
|
||||
@@ -543,7 +550,7 @@
|
||||
"accessibilityLabel": {
|
||||
"audioOnly": "Alternar para apenas áudio",
|
||||
"audioRoute": "Selecionar o dispositivo de som",
|
||||
"callQuality": "Gerenciar qualidade da chamada",
|
||||
"callQuality": "Gerenciar qualidade do vídeo",
|
||||
"cc": "Alternar legendas",
|
||||
"chat": "Alternar para janela de chat",
|
||||
"document": "Alternar para documento compartilhado",
|
||||
@@ -567,19 +574,19 @@
|
||||
"shareRoom": "Convidar alguém",
|
||||
"shareYourScreen": "Alternar compartilhamento de tela",
|
||||
"shortcuts": "Alternar atalhos",
|
||||
"show": "",
|
||||
"show": "Mostrar no palco",
|
||||
"speakerStats": "Alternar estatísticas do apresentador",
|
||||
"tileView": "Alternar visualização em blocos",
|
||||
"toggleCamera": "Alternar câmera",
|
||||
"videomute": "Alternar mudo do vídeo",
|
||||
"videoblur": ""
|
||||
"videoblur": "Alternar desfoque de vídeo"
|
||||
},
|
||||
"addPeople": "Adicionar pessoas à sua chamada",
|
||||
"audioOnlyOff": "Desativar modo somente áudio",
|
||||
"audioOnlyOn": "Desativar modo somente áudio",
|
||||
"audioOnlyOff": "",
|
||||
"audioOnlyOn": "",
|
||||
"audioRoute": "Selecionar o dispositivo de som",
|
||||
"authenticate": "Autenticar",
|
||||
"callQuality": "Gerenciar qualidade da chamada",
|
||||
"callQuality": "Gerenciar qualidade do vídeo",
|
||||
"chat": "Abrir ou fechar o bate-papo",
|
||||
"closeChat": "Fechar chat",
|
||||
"documentClose": "Fechar documento compartilhado",
|
||||
@@ -615,19 +622,19 @@
|
||||
"tileViewToggle": "Alternar visualização em blocos",
|
||||
"toggleCamera": "Alternar câmera",
|
||||
"videomute": "Iniciar ou parar a câmera",
|
||||
"startvideoblur": "",
|
||||
"stopvideoblur": ""
|
||||
"startvideoblur": "Desfocar meu plano de fundo",
|
||||
"stopvideoblur": "Desativar desfoque de fundo"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Iniciar/parar legendas",
|
||||
"error": "Transcrição falhou. Tente novamente.",
|
||||
"expandedLabel": "Transcrição ligada",
|
||||
"expandedLabel": "Transcrição ativada",
|
||||
"failedToStart": "Transcrição falhou ao iniciar",
|
||||
"labelToolTip": "A reunião esta sendo transcrita",
|
||||
"off": "Transcrição parada",
|
||||
"pending": "Preparando a transcrição da reunião...",
|
||||
"start": "Iniciar / Parar de mostrar as legendas",
|
||||
"stop": "Iniciar / Parar de mostrar as legendas",
|
||||
"start": "Exibir legendas",
|
||||
"stop": "Não exibir legendas",
|
||||
"tr": "TR"
|
||||
},
|
||||
"userMedia": {
|
||||
@@ -654,20 +661,23 @@
|
||||
},
|
||||
"videoStatus": {
|
||||
"audioOnly": "AUD",
|
||||
"audioOnlyExpanded": "Você está no modo somente áudio. Esse modo economiza internet mas não permite ver o vídeo dos outros.",
|
||||
"callQuality": "",
|
||||
"audioOnlyExpanded": "",
|
||||
"callQuality": "Qualidade de vídeo",
|
||||
"hd": "HD",
|
||||
"hdTooltip": "Ver vídeo em alta definição",
|
||||
"highDefinition": "Alta definição (HD)",
|
||||
"labelTooiltipNoVideo": "Sem vídeo",
|
||||
"labelTooltipAudioOnly": "Modo somente de áudio habilitado",
|
||||
"labelTooltipAudioOnly": "",
|
||||
"ld": "LD",
|
||||
"ldTooltip": "Ver vídeo em baixa definição",
|
||||
"lowDefinition": "Baixa definição (LD)",
|
||||
"onlyAudioAvailable": "Somente áudio disponível",
|
||||
"onlyAudioSupported": "Suportamos somente áudio neste navegador.",
|
||||
"p2pEnabled": "Ponto-a-ponto habilitada",
|
||||
"p2pVideoQualityDescription": "",
|
||||
"p2pVideoQualityDescription": "No modo ponto a ponto, a qualidade do vídeo recebido só pode ser alternada entre alta e apenas áudio. Outras configurações não serão respeitadas até que o ponto a ponto seja encerrado.",
|
||||
"recHighDefinitionOnly": "Preferência para alta definição",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Ver vídeo em definição padrão",
|
||||
"standardDefinition": "Definição padrão"
|
||||
},
|
||||
"videothumbnail": {
|
||||
@@ -678,8 +688,8 @@
|
||||
"mute": "Participante está mudo",
|
||||
"muted": "Mudo",
|
||||
"remoteControl": "Controle remoto",
|
||||
"show": "",
|
||||
"videomute": ""
|
||||
"show": "Mostrar no palco",
|
||||
"videomute": "O participante parou a câmera"
|
||||
},
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
@@ -695,6 +705,7 @@
|
||||
"connectCalendarButton": "Conectar seu calendário",
|
||||
"connectCalendarText": "Conecte seu calendário para ver todas as reuniões em {{app}}. Além disso, adicione reuniões de {{provider}} ao seu calendário e inicie-as com apenas um clique.",
|
||||
"enterRoomTitle": "Iniciar uma nova reunião",
|
||||
"onlyAsciiAllowed": "",
|
||||
"go": "IR",
|
||||
"join": "Entrar",
|
||||
"info": "Informações",
|
||||
@@ -702,7 +713,7 @@
|
||||
"recentList": "Recente",
|
||||
"recentListDelete": "Remover",
|
||||
"recentListEmpty": "Sua lista recente está vazia. As reuniões que você realizar serão exibidas aqui.",
|
||||
"reducedUIText": "",
|
||||
"reducedUIText": "Bem-vindo ao {{app}}!",
|
||||
"roomname": "Digite o nome da sala",
|
||||
"roomnameHint": "Digite o nome ou a URL da sala que você deseja entrar. Você pode digitar um nome, e apenas deixe para as pessoas que você quer se reunir digitem o mesmo nome.",
|
||||
"sendFeedback": "Enviar comentários",
|
||||
|
||||
@@ -46,13 +46,16 @@
|
||||
"today": "Today"
|
||||
},
|
||||
"chat": {
|
||||
"error": "Error: your message \"{{originalText}}\" was not sent. Reason: {{error}}",
|
||||
"error": "Error: your message was not sent. Reason: {{error}}",
|
||||
"messagebox": "Type a message",
|
||||
"messageTo": "Private message to {{recipient}}",
|
||||
"nickname": {
|
||||
"popover": "Choose a nickname",
|
||||
"title": "Enter a nickname to use chat"
|
||||
},
|
||||
"title": "Chat"
|
||||
"privateNotice": "Private message to {{recipient}}",
|
||||
"title": "Chat",
|
||||
"you": "you"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
"joiningRoom": "Connecting you to your meeting..."
|
||||
@@ -235,6 +238,10 @@
|
||||
"screenSharingFirefoxPermissionDeniedError": "Something went wrong while we were trying to share your screen. Please make sure that you have given us permission to do so. ",
|
||||
"screenSharingFirefoxPermissionDeniedTitle": "Oops! We weren’t able to start screen sharing!",
|
||||
"screenSharingPermissionDeniedError": "Oops! Something went wrong with your screen sharing extension permissions. Please reload and try again.",
|
||||
"sendPrivateMessage": "You recently received a private message. Did you intend to reply to that privately, or you want to send your message to the group?",
|
||||
"sendPrivateMessageCancel": "Send to the group",
|
||||
"sendPrivateMessageOk": "Send privately",
|
||||
"sendPrivateMessageTitle": "Send privately?",
|
||||
"serviceUnavailable": "Service unavailable",
|
||||
"sessTerminated": "Call terminated",
|
||||
"Share": "Share",
|
||||
@@ -268,6 +275,9 @@
|
||||
"dialOut": {
|
||||
"statusMessage": "is now {{status}}"
|
||||
},
|
||||
"documentSharing" : {
|
||||
"title": "Shared Document"
|
||||
},
|
||||
"feedback": {
|
||||
"average": "Average",
|
||||
"bad": "Bad",
|
||||
@@ -362,7 +372,9 @@
|
||||
"getStreamKeyManually": "We weren’t able to fetch any live streams. Try getting your live stream key from YouTube.",
|
||||
"invalidStreamKey": "Live stream key may be incorrect.",
|
||||
"off": "Live Streaming stopped",
|
||||
"offBy": "{{name}} stopped the live streaming",
|
||||
"on": "Live Streaming",
|
||||
"onBy": "{{name}} started the live streaming",
|
||||
"pending": "Starting Live Stream...",
|
||||
"serviceName": "Live Streaming service",
|
||||
"signedInAs": "You are currently signed in as:",
|
||||
@@ -475,7 +487,9 @@
|
||||
"live": "LIVE",
|
||||
"loggedIn": "Logged in as {{userName}}",
|
||||
"off": "Recording stopped",
|
||||
"offBy": "{{name}} stopped the recording",
|
||||
"on": "Recording",
|
||||
"onBy": "{{name}} started the recording",
|
||||
"pending": "Preparing to record the meeting...",
|
||||
"rec": "REC",
|
||||
"serviceDescription": "Your recording will be saved by the recording service",
|
||||
@@ -556,9 +570,11 @@
|
||||
"cc": "Toggle subtitles",
|
||||
"chat": "Toggle chat window",
|
||||
"document": "Toggle shared document",
|
||||
"download": "Download our apps",
|
||||
"feedback": "Leave feedback",
|
||||
"fullScreen": "Toggle full screen",
|
||||
"hangup": "Leave the call",
|
||||
"help": "Help",
|
||||
"invite": "Invite people",
|
||||
"kick": "Kick participant",
|
||||
"localRecording": "Toggle local recording controls",
|
||||
@@ -567,6 +583,7 @@
|
||||
"moreActionsMenu": "More actions menu",
|
||||
"mute": "Toggle mute audio",
|
||||
"pip": "Toggle Picture-in-Picture mode",
|
||||
"privateMessage": "Send private message",
|
||||
"profile": "Edit your profile",
|
||||
"raiseHand": "Toggle raise hand",
|
||||
"recording": "Toggle recording",
|
||||
@@ -593,12 +610,14 @@
|
||||
"closeChat": "Close chat",
|
||||
"documentClose": "Close shared document",
|
||||
"documentOpen": "Open shared document",
|
||||
"download": "Download our apps",
|
||||
"enterFullScreen": "View full screen",
|
||||
"enterTileView": "Enter tile view",
|
||||
"exitFullScreen": "Exit full screen",
|
||||
"exitTileView": "Exit tile view",
|
||||
"feedback": "Leave feedback",
|
||||
"hangup": "Leave",
|
||||
"help": "Help",
|
||||
"invite": "Invite people",
|
||||
"login": "Login",
|
||||
"logout": "Logout",
|
||||
@@ -607,6 +626,7 @@
|
||||
"mute": "Mute / Unmute",
|
||||
"openChat": "Open chat",
|
||||
"pip": "Enter Picture-in-Picture mode",
|
||||
"privateMessage": "Send private message",
|
||||
"profile": "Edit your profile",
|
||||
"raiseHand": "Raise / Lower your hand",
|
||||
"raiseYourHand": "Raise your hand",
|
||||
@@ -707,7 +727,7 @@
|
||||
"connectCalendarButton": "Connect your calendar",
|
||||
"connectCalendarText": "Connect your calendar to view all your meetings in {{app}}. Plus, add {{provider}} meetings to your calendar and start them with one click.",
|
||||
"enterRoomTitle": "Start a new meeting",
|
||||
"onlyAsciiAllowed": "Meeting name should only contain latin characters and numbers.",
|
||||
"roomNameAllowedChars": "Meeting name should not contain any of these characters: ?, &, :, ', \", %, #.",
|
||||
"go": "GO",
|
||||
"join": "JOIN",
|
||||
"info": "Info",
|
||||
|
||||
@@ -15,7 +15,7 @@ import Filmstrip from './videolayout/Filmstrip';
|
||||
|
||||
import { getLocalParticipant } from '../../react/features/base/participants';
|
||||
import { toggleChat } from '../../react/features/chat';
|
||||
import { setEtherpadHasInitialzied } from '../../react/features/etherpad';
|
||||
import { setDocumentUrl } from '../../react/features/etherpad';
|
||||
import { setFilmstripVisible } from '../../react/features/filmstrip';
|
||||
import { setNotificationsEnabled } from '../../react/features/notifications';
|
||||
import {
|
||||
@@ -240,10 +240,12 @@ UI.initEtherpad = name => {
|
||||
return;
|
||||
}
|
||||
logger.log('Etherpad is enabled');
|
||||
etherpadManager
|
||||
= new EtherpadManager(config.etherpad_base, name, eventEmitter);
|
||||
|
||||
APP.store.dispatch(setEtherpadHasInitialzied());
|
||||
etherpadManager = new EtherpadManager(eventEmitter);
|
||||
|
||||
const url = new URL(name, config.etherpad_base);
|
||||
|
||||
APP.store.dispatch(setDocumentUrl(url.toString()));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
/* global $, APP, interfaceConfig */
|
||||
|
||||
import { setDocumentEditingState } from '../../../react/features/etherpad';
|
||||
import { getSharedDocumentUrl, setDocumentEditingState } from '../../../react/features/etherpad';
|
||||
import { getToolboxHeight } from '../../../react/features/toolbox';
|
||||
|
||||
import VideoLayout from '../videolayout/VideoLayout';
|
||||
import LargeContainer from '../videolayout/LargeContainer';
|
||||
import Filmstrip from '../videolayout/Filmstrip';
|
||||
|
||||
/**
|
||||
* Etherpad options.
|
||||
*/
|
||||
const options = $.param({
|
||||
showControls: true,
|
||||
showChat: false,
|
||||
showLineNumbers: true,
|
||||
useMonospaceFont: false
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -70,13 +60,13 @@ class Etherpad extends LargeContainer {
|
||||
/**
|
||||
* Creates new Etherpad object
|
||||
*/
|
||||
constructor(domain, name) {
|
||||
constructor(url) {
|
||||
super();
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
|
||||
iframe.id = 'etherpadIFrame';
|
||||
iframe.src = `${domain + name}?${options}`;
|
||||
iframe.src = url;
|
||||
iframe.frameBorder = 0;
|
||||
iframe.scrolling = 'no';
|
||||
iframe.width = DEFAULT_WIDTH;
|
||||
@@ -199,13 +189,7 @@ export default class EtherpadManager {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(domain, name, eventEmitter) {
|
||||
if (!domain || !name) {
|
||||
throw new Error('missing domain or name');
|
||||
}
|
||||
|
||||
this.domain = domain;
|
||||
this.name = name;
|
||||
constructor(eventEmitter) {
|
||||
this.eventEmitter = eventEmitter;
|
||||
this.etherpad = null;
|
||||
}
|
||||
@@ -228,7 +212,7 @@ export default class EtherpadManager {
|
||||
* Create new Etherpad frame.
|
||||
*/
|
||||
openEtherpad() {
|
||||
this.etherpad = new Etherpad(this.domain, this.name);
|
||||
this.etherpad = new Etherpad(getSharedDocumentUrl(APP.store.getState));
|
||||
VideoLayout.addLargeVideoContainer(
|
||||
ETHERPAD_CONTAINER_TYPE,
|
||||
this.etherpad
|
||||
|
||||
@@ -273,7 +273,7 @@ LocalVideo.prototype._updateVideoElement = function() {
|
||||
// case video does not autoplay.
|
||||
const video = this.container.querySelector('video');
|
||||
|
||||
video && video.play();
|
||||
video && !config.testing?.noAutoPlayVideo && video.play();
|
||||
};
|
||||
|
||||
export default LocalVideo;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Provider } from 'react-redux';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { AtlasKitThemeProvider } from '@atlaskit/theme';
|
||||
|
||||
import { createThumbnailOffsetParentIsNullEvent, sendAnalytics } from '../../../react/features/analytics';
|
||||
import { i18next } from '../../../react/features/base/i18n';
|
||||
import {
|
||||
JitsiParticipantConnectionStatus
|
||||
@@ -486,6 +487,8 @@ RemoteVideo.prototype.hasVideoStarted = function() {
|
||||
|
||||
RemoteVideo.prototype.addRemoteStreamElement = function(stream) {
|
||||
if (!this.container) {
|
||||
logger.debug('Not attaching remote stream due to no container');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -498,6 +501,8 @@ RemoteVideo.prototype.addRemoteStreamElement = function(stream) {
|
||||
}
|
||||
|
||||
if (!stream.getOriginalStream()) {
|
||||
logger.debug('Remote video stream has no original stream');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -508,11 +513,31 @@ RemoteVideo.prototype.addRemoteStreamElement = function(stream) {
|
||||
|
||||
$(streamElement).hide();
|
||||
|
||||
// If the container is currently visible
|
||||
// we attach the stream to the element.
|
||||
if (!isVideo || (this.container.offsetParent !== null && isVideo)) {
|
||||
this.waitForPlayback(streamElement, stream);
|
||||
stream.attach(streamElement);
|
||||
this.waitForPlayback(streamElement, stream);
|
||||
stream.attach(streamElement);
|
||||
|
||||
// TODO: Remove once we verify that this.container.offsetParent === null was the reason for not attached video
|
||||
// streams to the thumbnail.
|
||||
if (isVideo && this.container.offsetParent === null) {
|
||||
sendAnalytics(createThumbnailOffsetParentIsNullEvent(this.id));
|
||||
const parentNodesDisplayProps = [
|
||||
'#filmstripRemoteVideosContainer',
|
||||
'#filmstripRemoteVideos',
|
||||
'#remoteVideos',
|
||||
'.filmstrip',
|
||||
'#videospace',
|
||||
'#videoconference_page',
|
||||
'#react'
|
||||
].map(selector => `${selector} - ${$(selector).css('display')}`);
|
||||
const videoConferencePageParent = $('#videoconference_page').parent();
|
||||
const reactDiv = document.getElementById('react');
|
||||
|
||||
parentNodesDisplayProps.push(
|
||||
`${videoConferencePageParent.attr('class')} - ${videoConferencePageParent.css('display')}`);
|
||||
parentNodesDisplayProps.push(`this.container - ${this.$container.css('display')}`);
|
||||
logger.debug(`this.container.offsetParent is null [user: ${this.id}, ${
|
||||
parentNodesDisplayProps.join(', ')}, #react.offsetParent - ${
|
||||
reactDiv && reactDiv.offsetParent !== null ? 'not null' : 'null'}]`);
|
||||
}
|
||||
|
||||
if (!isVideo) {
|
||||
|
||||
@@ -199,7 +199,7 @@ SmallVideo.createStreamElement = function(stream) {
|
||||
element.muted = true;
|
||||
}
|
||||
|
||||
element.autoplay = true;
|
||||
element.autoplay = !config.testing?.noAutoPlayVideo;
|
||||
element.id = SmallVideo.getStreamElementID(stream);
|
||||
|
||||
return element;
|
||||
@@ -511,7 +511,7 @@ SmallVideo.prototype.isCurrentlyOnLargeVideo = function() {
|
||||
* or <tt>false</tt> otherwise.
|
||||
*/
|
||||
SmallVideo.prototype.isVideoPlayable = function() {
|
||||
return this.videoStream && !this.isVideoMuted && !this.videoStream.isMuted();
|
||||
return this.videoStream && !this.isVideoMuted && !APP.conference.isAudioOnly();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -520,40 +520,33 @@ SmallVideo.prototype.isVideoPlayable = function() {
|
||||
* @return {number} one of <tt>DISPLAY_VIDEO</tt>,<tt>DISPLAY_AVATAR</tt>
|
||||
* or <tt>DISPLAY_BLACKNESS_WITH_NAME</tt>.
|
||||
*/
|
||||
SmallVideo.prototype.selectDisplayMode = function() {
|
||||
const isAudioOnly = APP.conference.isAudioOnly();
|
||||
const tileViewEnabled = shouldDisplayTileView(APP.store.getState());
|
||||
const isVideoPlayable = this.isVideoPlayable();
|
||||
const hasVideo = Boolean(this.selectVideoElement().length);
|
||||
SmallVideo.prototype.selectDisplayMode = function(input) {
|
||||
|
||||
// Display name is always and only displayed when user is on the stage
|
||||
if (this.isCurrentlyOnLargeVideo() && !tileViewEnabled) {
|
||||
return isVideoPlayable && !isAudioOnly ? DISPLAY_BLACKNESS_WITH_NAME : DISPLAY_AVATAR_WITH_NAME;
|
||||
} else if (isVideoPlayable && hasVideo && !isAudioOnly) {
|
||||
if (input.isCurrentlyOnLargeVideo && !input.tileViewEnabled) {
|
||||
return input.isVideoPlayable && !input.isAudioOnly ? DISPLAY_BLACKNESS_WITH_NAME : DISPLAY_AVATAR_WITH_NAME;
|
||||
} else if (input.isVideoPlayable && input.hasVideo && !input.isAudioOnly) {
|
||||
// check hovering and change state to video with name
|
||||
return this._isHovered() ? DISPLAY_VIDEO_WITH_NAME : DISPLAY_VIDEO;
|
||||
return input.isHovered ? DISPLAY_VIDEO_WITH_NAME : DISPLAY_VIDEO;
|
||||
}
|
||||
|
||||
// check hovering and change state to avatar with name
|
||||
return this._isHovered() ? DISPLAY_AVATAR_WITH_NAME : DISPLAY_AVATAR;
|
||||
return input.isHovered ? DISPLAY_AVATAR_WITH_NAME : DISPLAY_AVATAR;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prints information about the current display mode.
|
||||
* Computes information that determine the display mode.
|
||||
*
|
||||
* @param {string} mode - The current mode.
|
||||
* @returns {void}
|
||||
* @returns {Object}
|
||||
*/
|
||||
SmallVideo.prototype._printDisplayModeInfo = function(mode) {
|
||||
const isAudioOnly = APP.conference.isAudioOnly();
|
||||
const tileViewEnabled = shouldDisplayTileView(APP.store.getState());
|
||||
const isVideoPlayable = this.isVideoPlayable();
|
||||
const hasVideo = Boolean(this.selectVideoElement().length);
|
||||
const displayModeInfo = {
|
||||
isAudioOnly,
|
||||
tileViewEnabled,
|
||||
isVideoPlayable,
|
||||
hasVideo,
|
||||
SmallVideo.prototype.computeDisplayModeInput = function() {
|
||||
return {
|
||||
isCurrentlyOnLargeVideo: this.isCurrentlyOnLargeVideo(),
|
||||
isHovered: this._isHovered(),
|
||||
isAudioOnly: APP.conference.isAudioOnly(),
|
||||
tileViewEnabled: shouldDisplayTileView(APP.store.getState()),
|
||||
isVideoPlayable: this.isVideoPlayable(),
|
||||
hasVideo: Boolean(this.selectVideoElement().length),
|
||||
connectionStatus: APP.conference.getParticipantConnectionStatus(this.id),
|
||||
mutedWhileDisconnected: this.mutedWhileDisconnected,
|
||||
wasVideoPlayed: this.wasVideoPlayed,
|
||||
@@ -561,8 +554,6 @@ SmallVideo.prototype._printDisplayModeInfo = function(mode) {
|
||||
isVideoMuted: this.isVideoMuted,
|
||||
videoStreamMuted: this.videoStream ? this.videoStream.isMuted() : 'no stream'
|
||||
};
|
||||
|
||||
logger.debug(`Displaying ${mode} for ${this.id}, reason: [${JSON.stringify(displayModeInfo)}]`);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -596,8 +587,10 @@ SmallVideo.prototype.updateView = function() {
|
||||
const oldDisplayMode = this.displayMode;
|
||||
let displayModeString = '';
|
||||
|
||||
const displayModeInput = this.computeDisplayModeInput();
|
||||
|
||||
// Determine whether video, avatar or blackness should be displayed
|
||||
this.displayMode = this.selectDisplayMode();
|
||||
this.displayMode = this.selectDisplayMode(displayModeInput);
|
||||
|
||||
switch (this.displayMode) {
|
||||
case DISPLAY_AVATAR_WITH_NAME:
|
||||
@@ -624,7 +617,7 @@ SmallVideo.prototype.updateView = function() {
|
||||
}
|
||||
|
||||
if (this.displayMode !== oldDisplayMode) {
|
||||
this._printDisplayModeInfo(displayModeString);
|
||||
logger.debug(`Displaying ${displayModeString} for ${this.id}, data: [${JSON.stringify(displayModeInput)}]`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -200,7 +200,11 @@ const VideoLayout = {
|
||||
const id = stream.getParticipantId();
|
||||
const remoteVideo = remoteVideos[id];
|
||||
|
||||
logger.debug(`Received a new ${stream.getType()} stream for ${id}`);
|
||||
|
||||
if (!remoteVideo) {
|
||||
logger.debug('No remote video element to add stream');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
4179
package-lock.json
generated
4179
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@@ -35,10 +35,11 @@
|
||||
"@atlaskit/tooltip": "12.1.13",
|
||||
"@microsoft/microsoft-graph-client": "1.1.0",
|
||||
"@react-native-community/async-storage": "1.3.4",
|
||||
"@react-native-community/google-signin": "3.0.1",
|
||||
"@react-native-community/netinfo": "4.1.5",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"@tensorflow-models/body-pix": "^1.0.1",
|
||||
"@tensorflow/tfjs": "^1.1.2",
|
||||
"@tensorflow-models/body-pix": "1.1.2",
|
||||
"@tensorflow/tfjs": "1.2.9",
|
||||
"@webcomponents/url": "0.7.1",
|
||||
"amplitude-js": "4.5.2",
|
||||
"bc-css-flags": "3.0.0",
|
||||
@@ -48,7 +49,7 @@
|
||||
"i18next-browser-languagedetector": "3.0.1",
|
||||
"i18next-xhr-backend": "3.0.0",
|
||||
"jQuery-Impromptu": "github:trentrichardson/jQuery-Impromptu#v6.0.0",
|
||||
"jitsi-meet-logger": "github:jitsi/jitsi-meet-logger#a885cc98688ef2c3972284bda901596a26ffee52",
|
||||
"jitsi-meet-logger": "github:jitsi/jitsi-meet-logger#5ec92357570dc8f0b7ffc1528820721c84c6af8b",
|
||||
"jquery": "3.4.0",
|
||||
"jquery-contextmenu": "2.4.5",
|
||||
"jquery-i18next": "1.2.1",
|
||||
@@ -56,22 +57,21 @@
|
||||
"js-utils": "github:jitsi/js-utils#192b1c996e8c05530eb1f19e82a31069c3021e31",
|
||||
"jsrsasign": "8.0.12",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#f43c0c4bbfeb09ed816356eb5088bd61d40b91d5",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#cdd2029b4b6b3626658f9834c324e1ffb7474795",
|
||||
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.13",
|
||||
"moment": "2.19.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
"postis": "2.2.0",
|
||||
"react": "16.8.6",
|
||||
"react-dom": "16.8.6",
|
||||
"react": "16.9",
|
||||
"react-dom": "16.9",
|
||||
"react-emoji-render": "1.0.0",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-native": "0.60.5",
|
||||
"react-native": "0.61.1",
|
||||
"react-native-background-timer": "2.1.1",
|
||||
"react-native-calendar-events": "github:jitsi/react-native-calendar-events#902e6e92d6bae450a6052f76ba4d02f977ffd8f2",
|
||||
"react-native-callstats": "3.61.0",
|
||||
"react-native-google-signin": "2.0.0",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-linear-gradient": "2.5.6",
|
||||
@@ -80,13 +80,14 @@
|
||||
"react-native-svg-transformer": "0.13.0",
|
||||
"react-native-swipeout": "2.3.6",
|
||||
"react-native-watch-connectivity": "0.2.0",
|
||||
"react-native-webrtc": "github:react-native-webrtc/react-native-webrtc#b1275ccf1e0e083d2a5c238e7d21c37657766463",
|
||||
"react-native-webview": "5.8.1",
|
||||
"react-native-webrtc": "github:react-native-webrtc/react-native-webrtc#a12a6cdfdefe53d03b388394e4cf10966bd99fca",
|
||||
"react-native-webview": "7.4.1",
|
||||
"react-redux": "7.1.0",
|
||||
"react-textarea-autosize": "7.1.0",
|
||||
"react-transition-group": "2.4.0",
|
||||
"redux": "4.0.4",
|
||||
"redux-thunk": "2.2.0",
|
||||
"rnnoise-wasm": "github:jitsi/rnnoise-wasm.git#db96d11f175a22ef56c7db1ba9550835b716e615",
|
||||
"styled-components": "3.4.9",
|
||||
"util": "0.12.1",
|
||||
"uuid": "3.1.0",
|
||||
@@ -117,18 +118,18 @@
|
||||
"eslint-plugin-react": "7.11.1",
|
||||
"eslint-plugin-react-native": "3.3.0",
|
||||
"expose-loader": "0.7.5",
|
||||
"flow-bin": "0.98.0",
|
||||
"flow-bin": "0.104.0",
|
||||
"imports-loader": "0.7.1",
|
||||
"jetifier": "1.6.4",
|
||||
"metro-react-native-babel-preset": "0.56.0",
|
||||
"node-sass": "4.10.0",
|
||||
"node-sass": "4.12.0",
|
||||
"precommit-hook": "3.0.0",
|
||||
"string-replace-loader": "2.1.1",
|
||||
"style-loader": "0.19.0",
|
||||
"webpack": "4.26.1",
|
||||
"webpack": "4.27.1",
|
||||
"webpack-bundle-analyzer": "3.4.1",
|
||||
"webpack-cli": "3.1.2",
|
||||
"webpack-dev-server": "3.1.14"
|
||||
"webpack-dev-server": "3.8.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0",
|
||||
|
||||
@@ -692,6 +692,21 @@ export function createSyncTrackStateEvent(mediaType, muted) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event that indicates the thumbnail offset parent is null.
|
||||
*
|
||||
* @param {string} id - The id of the user related to the thumbnail.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createThumbnailOffsetParentIsNullEvent(id) {
|
||||
return {
|
||||
action: 'OffsetParentIsNull',
|
||||
attributes: {
|
||||
id
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event associated with a toolbar button being clicked/pressed. By
|
||||
* convention, where appropriate an attribute named 'enable' should be used to
|
||||
|
||||
@@ -15,6 +15,7 @@ import { connect, disconnect, setLocationURL } from '../base/connection';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet';
|
||||
import { createDesiredLocalTracks } from '../base/tracks';
|
||||
import {
|
||||
getBackendSafeRoomName,
|
||||
getLocationContextRoot,
|
||||
parseURIString,
|
||||
toURLString
|
||||
@@ -85,7 +86,7 @@ export function appNavigate(uri: ?string) {
|
||||
let url = `${baseURL}config.js`;
|
||||
|
||||
// XXX In order to support multiple shards, tell the room to the deployment.
|
||||
room && (url += `?room=${room.toLowerCase()}`);
|
||||
room && (url += `?room=${getBackendSafeRoomName(room)}`);
|
||||
|
||||
let config;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from '../../base/dialog';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { JitsiConnectionErrors } from '../../base/lib-jitsi-meet';
|
||||
import { StyleType } from '../../base/styles';
|
||||
import type { StyleType } from '../../base/styles';
|
||||
|
||||
import { authenticateAndUpgradeRole, cancelLogin } from '../actions';
|
||||
import styles from './styles';
|
||||
|
||||
@@ -42,6 +42,6 @@ export default class AbstractStatelessAvatar<P: Props> extends PureComponent<P>
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_isIcon(iconProp: ?string | ?Object): boolean {
|
||||
return Boolean(iconProp) && typeof iconProp === 'object';
|
||||
return Boolean(iconProp) && (typeof iconProp === 'object' || typeof iconProp === 'function');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +153,8 @@ class ColorSchemeRegistry {
|
||||
const colorScheme = toState(stateful)['features/base/color-scheme'];
|
||||
|
||||
return {
|
||||
...defaultScheme._defaultTheme,
|
||||
...colorScheme._defaultTheme,
|
||||
...defaultScheme[componentName],
|
||||
...colorScheme[componentName]
|
||||
}[colorDefinition];
|
||||
|
||||
@@ -6,18 +6,26 @@ import { ColorPalette, getRGBAFormat } from '../styles';
|
||||
* The default color scheme of the application.
|
||||
*/
|
||||
export default {
|
||||
'BottomSheet': {
|
||||
'_defaultTheme': {
|
||||
// Generic app theme colors that are used accross the entire app.
|
||||
// All scheme definitions below inherit these values.
|
||||
background: 'rgb(255, 255, 255)',
|
||||
icon: '#1c2025',
|
||||
label: '#1c2025'
|
||||
icon: 'rgb(28, 32, 37)',
|
||||
text: 'rgb(28, 32, 37)'
|
||||
},
|
||||
'Chat': {
|
||||
displayName: 'rgb(94, 109, 121)',
|
||||
localMsgBackground: 'rgb(215, 230, 249)',
|
||||
privateMsgBackground: 'rgb(250, 219, 219)',
|
||||
privateMsgNotice: 'rgb(186, 39, 58)',
|
||||
remoteMsgBackground: 'rgb(241, 242, 246)',
|
||||
replyBorder: 'rgb(219, 197, 200)',
|
||||
replyIcon: 'rgb(94, 109, 121)'
|
||||
},
|
||||
'Dialog': {
|
||||
background: 'rgb(255, 255, 255)',
|
||||
border: 'rgba(0, 3, 6, 0.6)',
|
||||
buttonBackground: ColorPalette.blue,
|
||||
buttonLabel: ColorPalette.white,
|
||||
icon: '#1c2025',
|
||||
text: '#1c2025'
|
||||
buttonLabel: ColorPalette.white
|
||||
},
|
||||
'Header': {
|
||||
background: ColorPalette.blue,
|
||||
@@ -30,8 +38,7 @@ export default {
|
||||
background: 'rgb(42, 58, 75)'
|
||||
},
|
||||
'LoadConfigOverlay': {
|
||||
background: 'rgb(249, 249, 249)',
|
||||
text: 'rgb(28, 32, 37)'
|
||||
background: 'rgb(249, 249, 249)'
|
||||
},
|
||||
'Thumbnail': {
|
||||
activeParticipantHighlight: 'rgb(81, 214, 170)',
|
||||
|
||||
@@ -23,7 +23,10 @@ import {
|
||||
participantUpdated
|
||||
} from '../participants';
|
||||
import { getLocalTracks, trackAdded, trackRemoved } from '../tracks';
|
||||
import { getJitsiMeetGlobalNS } from '../util';
|
||||
import {
|
||||
getBackendSafeRoomName,
|
||||
getJitsiMeetGlobalNS
|
||||
} from '../util';
|
||||
|
||||
import {
|
||||
AUTH_STATUS_CHANGED,
|
||||
@@ -74,6 +77,11 @@ declare var APP: Object;
|
||||
* @returns {void}
|
||||
*/
|
||||
function _addConferenceListeners(conference, dispatch) {
|
||||
// A simple logger for conference errors received through
|
||||
// the listener. These errors are not handled now, but logged.
|
||||
conference.on(JitsiConferenceEvents.CONFERENCE_ERROR,
|
||||
error => logger.error('Conference error.', error));
|
||||
|
||||
// Dispatches into features/base/conference follow:
|
||||
|
||||
conference.on(
|
||||
@@ -388,8 +396,7 @@ export function createConference() {
|
||||
const conference
|
||||
= connection.initJitsiConference(
|
||||
|
||||
// XXX Lib-jitsi-meet does not accept uppercase letters.
|
||||
room.toLowerCase(), {
|
||||
getBackendSafeRoomName(room), {
|
||||
...state['features/base/config'],
|
||||
applicationName: getName(),
|
||||
getWiFiStatsMethod: getJitsiMeetGlobalNS().getWiFiStats,
|
||||
|
||||
137
react/features/base/config/configWhitelist.js
Normal file
137
react/features/base/config/configWhitelist.js
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* The config keys to whitelist, the keys that can be overridden.
|
||||
* Currently we can only whitelist the first part of the properties, like
|
||||
* 'p2p.useStunTurn' and 'p2p.enabled' we whitelist all p2p options.
|
||||
* The whitelist is used only for config.js.
|
||||
*
|
||||
* @type Array
|
||||
*/
|
||||
export default [
|
||||
'_desktopSharingSourceDevice',
|
||||
'_peerConnStatusOutOfLastNTimeout',
|
||||
'_peerConnStatusRtcMuteTimeout',
|
||||
'abTesting',
|
||||
'analytics.disabled',
|
||||
'autoRecord',
|
||||
'autoRecordToken',
|
||||
'avgRtpStatsN',
|
||||
'callFlowsEnabled',
|
||||
'callStatsConfIDNamespace',
|
||||
'callStatsID',
|
||||
'callStatsSecret',
|
||||
|
||||
/**
|
||||
* The display name of the CallKit call representing the conference/meeting
|
||||
* associated with this config.js including while the call is ongoing in the
|
||||
* UI presented by CallKit and in the system-wide call history. The property
|
||||
* is meant for use cases in which the room name is not desirable as a
|
||||
* display name for CallKit purposes and the desired display name is not
|
||||
* provided in the form of a JWT callee. As the value is associated with a
|
||||
* conference/meeting, the value makes sense not as a deployment-wide
|
||||
* configuration, only as a runtime configuration override/overwrite
|
||||
* provided by, for example, Jitsi Meet SDK for iOS.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
'callDisplayName',
|
||||
|
||||
/**
|
||||
* The handle
|
||||
* ({@link https://developer.apple.com/documentation/callkit/cxhandle}) of
|
||||
* the CallKit call representing the conference/meeting associated with this
|
||||
* config.js. The property is meant for use cases in which the room URL is
|
||||
* not desirable as the handle for CallKit purposes. As the value is
|
||||
* associated with a conference/meeting, the value makes sense not as a
|
||||
* deployment-wide configuration, only as a runtime configuration
|
||||
* override/overwrite provided by, for example, Jitsi Meet SDK for iOS.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
'callHandle',
|
||||
|
||||
/**
|
||||
* The UUID of the CallKit call representing the conference/meeting
|
||||
* associated with this config.js. The property is meant for use cases in
|
||||
* which Jitsi Meet is to work with a CallKit call created outside of Jitsi
|
||||
* Meet and to be adopted by Jitsi Meet such as, for example, an incoming
|
||||
* and/or outgoing CallKit call created by Jitsi Meet SDK for iOS
|
||||
* clients/consumers prior to giving control to Jitsi Meet. As the value is
|
||||
* associated with a conference/meeting, the value makes sense not as a
|
||||
* deployment-wide configuration, only as a runtime configuration
|
||||
* override/overwrite provided by, for example, Jitsi Meet SDK for iOS.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
'callUUID',
|
||||
|
||||
'channelLastN',
|
||||
'constraints',
|
||||
'debug',
|
||||
'debugAudioLevels',
|
||||
'defaultLanguage',
|
||||
'desktopSharingChromeDisabled',
|
||||
'desktopSharingChromeExtId',
|
||||
'desktopSharingChromeMinExtVersion',
|
||||
'desktopSharingChromeSources',
|
||||
'desktopSharingFrameRate',
|
||||
'desktopSharingFirefoxDisabled',
|
||||
'desktopSharingSources',
|
||||
'disable1On1Mode',
|
||||
'disableAEC',
|
||||
'disableAGC',
|
||||
'disableAP',
|
||||
'disableAudioLevels',
|
||||
'disableDeepLinking',
|
||||
'disableH264',
|
||||
'disableHPF',
|
||||
'disableNS',
|
||||
'disableRemoteControl',
|
||||
'disableRtx',
|
||||
'disableSuspendVideo',
|
||||
'displayJids',
|
||||
'e2eping',
|
||||
'enableDisplayNameInStats',
|
||||
'enableLayerSuspension',
|
||||
'enableLipSync',
|
||||
'disableLocalVideoFlip',
|
||||
'enableRemb',
|
||||
'enableStatsID',
|
||||
'enableTalkWhileMuted',
|
||||
'enableTcc',
|
||||
'etherpad_base',
|
||||
'failICE',
|
||||
'fileRecordingsEnabled',
|
||||
'firefox_fake_device',
|
||||
'forceJVB121Ratio',
|
||||
'gatherStats',
|
||||
'googleApiApplicationClientID',
|
||||
'hiddenDomain',
|
||||
'hosts',
|
||||
'iAmRecorder',
|
||||
'iAmSipGateway',
|
||||
'iceTransportPolicy',
|
||||
'ignoreStartMuted',
|
||||
'liveStreamingEnabled',
|
||||
'localRecording',
|
||||
'minParticipants',
|
||||
'nick',
|
||||
'openBridgeChannel',
|
||||
'p2p',
|
||||
'preferH264',
|
||||
'requireDisplayName',
|
||||
'resolution',
|
||||
'startAudioMuted',
|
||||
'startAudioOnly',
|
||||
'startBitrate',
|
||||
'startSilent',
|
||||
'startScreenSharing',
|
||||
'startVideoMuted',
|
||||
'startWithVideoMuted',
|
||||
'subject',
|
||||
'testing',
|
||||
'useIPv6',
|
||||
'useNicks',
|
||||
'useStunTurn',
|
||||
'webrtcIceTcpDisable',
|
||||
'webrtcIceUdpDisable'
|
||||
];
|
||||
@@ -2,152 +2,12 @@
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
import CONFIG_WHITELIST from './configWhitelist';
|
||||
import { _CONFIG_STORE_PREFIX } from './constants';
|
||||
import INTERFACE_CONFIG_WHITELIST from './interfaceConfigWhitelist';
|
||||
import parseURLParams from './parseURLParams';
|
||||
import logger from './logger';
|
||||
|
||||
declare var $: Object;
|
||||
|
||||
/**
|
||||
* The config keys to whitelist, the keys that can be overridden.
|
||||
* Currently we can only whitelist the first part of the properties, like
|
||||
* 'p2p.useStunTurn' and 'p2p.enabled' we whitelist all p2p options.
|
||||
* The whitelist is used only for config.js.
|
||||
*
|
||||
* @private
|
||||
* @type Array
|
||||
*/
|
||||
const WHITELISTED_KEYS = [
|
||||
'_desktopSharingSourceDevice',
|
||||
'_peerConnStatusOutOfLastNTimeout',
|
||||
'_peerConnStatusRtcMuteTimeout',
|
||||
'abTesting',
|
||||
'analytics.disabled',
|
||||
'autoRecord',
|
||||
'autoRecordToken',
|
||||
'avgRtpStatsN',
|
||||
'callFlowsEnabled',
|
||||
'callStatsConfIDNamespace',
|
||||
'callStatsID',
|
||||
'callStatsSecret',
|
||||
|
||||
/**
|
||||
* The display name of the CallKit call representing the conference/meeting
|
||||
* associated with this config.js including while the call is ongoing in the
|
||||
* UI presented by CallKit and in the system-wide call history. The property
|
||||
* is meant for use cases in which the room name is not desirable as a
|
||||
* display name for CallKit purposes and the desired display name is not
|
||||
* provided in the form of a JWT callee. As the value is associated with a
|
||||
* conference/meeting, the value makes sense not as a deployment-wide
|
||||
* configuration, only as a runtime configuration override/overwrite
|
||||
* provided by, for example, Jitsi Meet SDK for iOS.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
'callDisplayName',
|
||||
|
||||
/**
|
||||
* The handle
|
||||
* ({@link https://developer.apple.com/documentation/callkit/cxhandle}) of
|
||||
* the CallKit call representing the conference/meeting associated with this
|
||||
* config.js. The property is meant for use cases in which the room URL is
|
||||
* not desirable as the handle for CallKit purposes. As the value is
|
||||
* associated with a conference/meeting, the value makes sense not as a
|
||||
* deployment-wide configuration, only as a runtime configuration
|
||||
* override/overwrite provided by, for example, Jitsi Meet SDK for iOS.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
'callHandle',
|
||||
|
||||
/**
|
||||
* The UUID of the CallKit call representing the conference/meeting
|
||||
* associated with this config.js. The property is meant for use cases in
|
||||
* which Jitsi Meet is to work with a CallKit call created outside of Jitsi
|
||||
* Meet and to be adopted by Jitsi Meet such as, for example, an incoming
|
||||
* and/or outgoing CallKit call created by Jitsi Meet SDK for iOS
|
||||
* clients/consumers prior to giving control to Jitsi Meet. As the value is
|
||||
* associated with a conference/meeting, the value makes sense not as a
|
||||
* deployment-wide configuration, only as a runtime configuration
|
||||
* override/overwrite provided by, for example, Jitsi Meet SDK for iOS.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
'callUUID',
|
||||
|
||||
'channelLastN',
|
||||
'constraints',
|
||||
'debug',
|
||||
'debugAudioLevels',
|
||||
'defaultLanguage',
|
||||
'desktopSharingChromeDisabled',
|
||||
'desktopSharingChromeExtId',
|
||||
'desktopSharingChromeMinExtVersion',
|
||||
'desktopSharingChromeSources',
|
||||
'desktopSharingFrameRate',
|
||||
'desktopSharingFirefoxDisabled',
|
||||
'desktopSharingSources',
|
||||
'disable1On1Mode',
|
||||
'disableAEC',
|
||||
'disableAGC',
|
||||
'disableAP',
|
||||
'disableAudioLevels',
|
||||
'disableDeepLinking',
|
||||
'disableH264',
|
||||
'disableHPF',
|
||||
'disableNS',
|
||||
'disableRemoteControl',
|
||||
'disableRtx',
|
||||
'disableSuspendVideo',
|
||||
'displayJids',
|
||||
'e2eping',
|
||||
'enableDisplayNameInStats',
|
||||
'enableLayerSuspension',
|
||||
'enableLipSync',
|
||||
'disableLocalVideoFlip',
|
||||
'enableRemb',
|
||||
'enableStatsID',
|
||||
'enableTalkWhileMuted',
|
||||
'enableTcc',
|
||||
'etherpad_base',
|
||||
'failICE',
|
||||
'fileRecordingsEnabled',
|
||||
'firefox_fake_device',
|
||||
'forceJVB121Ratio',
|
||||
'gatherStats',
|
||||
'googleApiApplicationClientID',
|
||||
'hiddenDomain',
|
||||
'hosts',
|
||||
'iAmRecorder',
|
||||
'iAmSipGateway',
|
||||
'iceTransportPolicy',
|
||||
'ignoreStartMuted',
|
||||
'liveStreamingEnabled',
|
||||
'localRecording',
|
||||
'minParticipants',
|
||||
'nick',
|
||||
'openBridgeChannel',
|
||||
'p2p',
|
||||
'preferH264',
|
||||
'requireDisplayName',
|
||||
'resolution',
|
||||
'startAudioMuted',
|
||||
'startAudioOnly',
|
||||
'startBitrate',
|
||||
'startSilent',
|
||||
'startScreenSharing',
|
||||
'startVideoMuted',
|
||||
'startWithAudioMuted',
|
||||
'startWithVideoMuted',
|
||||
'subject',
|
||||
'testing',
|
||||
'useIPv6',
|
||||
'useNicks',
|
||||
'useStunTurn',
|
||||
'webrtcIceTcpDisable',
|
||||
'webrtcIceUdpDisable'
|
||||
];
|
||||
|
||||
// XXX The functions getRoomName and parseURLParams are split out of
|
||||
// functions.js because they are bundled in both app.bundle and
|
||||
// do_external_connect, webpack 1 does not support tree shaking, and we don't
|
||||
@@ -178,69 +38,6 @@ export function createFakeConfig(baseURL: string) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Promise wrapper on obtain config method. When HttpConfigFetch will be moved
|
||||
* to React app it's better to use load config instead.
|
||||
*
|
||||
* @param {string} location - URL of the domain from which the config is to be
|
||||
* obtained.
|
||||
* @param {string} room - Room name.
|
||||
* @private
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export function obtainConfig(location: string, room: string): Promise<void> {
|
||||
return new Promise((resolve, reject) =>
|
||||
_obtainConfig(location, room, (success, error) => {
|
||||
success ? resolve() : reject(error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends HTTP POST request to specified {@code endpoint}. In request the name
|
||||
* of the room is included in JSON format:
|
||||
* {
|
||||
* "rooomName": "someroom12345"
|
||||
* }.
|
||||
*
|
||||
* @param {string} endpoint - The name of HTTP endpoint to which to send
|
||||
* the HTTP POST request.
|
||||
* @param {string} roomName - The name of the conference room for which config
|
||||
* is requested.
|
||||
* @param {Function} complete - The callback to invoke upon success or failure.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _obtainConfig(endpoint: string, roomName: string, complete: Function) {
|
||||
logger.info(`Send config request to ${endpoint} for room: ${roomName}`);
|
||||
$.ajax(
|
||||
endpoint,
|
||||
{
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ roomName }),
|
||||
dataType: 'json',
|
||||
method: 'POST',
|
||||
|
||||
error(jqXHR, textStatus, errorThrown) {
|
||||
logger.error('Get config error: ', jqXHR, errorThrown);
|
||||
complete(false, `Get config response status: ${textStatus}`);
|
||||
},
|
||||
success(data) {
|
||||
const { config, interfaceConfig, loggingConfig } = window;
|
||||
|
||||
try {
|
||||
overrideConfigJSON(
|
||||
config, interfaceConfig, loggingConfig,
|
||||
data);
|
||||
complete(true);
|
||||
} catch (e) {
|
||||
logger.error('Parse config error: ', e);
|
||||
complete(false, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/* eslint-disable max-params, no-shadow */
|
||||
|
||||
/**
|
||||
@@ -306,8 +103,8 @@ export function overrideConfigJSON(
|
||||
/* eslint-enable max-params, no-shadow */
|
||||
|
||||
/**
|
||||
* Whitelist only config.js, skips this for others configs
|
||||
* (interfaceConfig, loggingConfig).
|
||||
* Apply whitelist filtering for configs with whitelists, skips this for others
|
||||
* configs (loggingConfig).
|
||||
* Only extracts overridden values for keys we allow to be overridden.
|
||||
*
|
||||
* @param {string} configName - The config name, one of config,
|
||||
@@ -318,11 +115,13 @@ export function overrideConfigJSON(
|
||||
* that are whitelisted.
|
||||
*/
|
||||
function _getWhitelistedJSON(configName, configJSON) {
|
||||
if (configName !== 'config') {
|
||||
return configJSON;
|
||||
if (configName === 'interfaceConfig') {
|
||||
return _.pick(configJSON, INTERFACE_CONFIG_WHITELIST);
|
||||
} else if (configName === 'config') {
|
||||
return _.pick(configJSON, CONFIG_WHITELIST);
|
||||
}
|
||||
|
||||
return _.pick(configJSON, WHITELISTED_KEYS);
|
||||
return configJSON;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,8 +11,8 @@ export * from './functions.any';
|
||||
* @returns {void}
|
||||
*/
|
||||
export function _cleanupConfig(config: Object) {
|
||||
config.analytics.scriptURLs = [];
|
||||
if (NativeModules.AppInfo.LIBRE_BUILD) {
|
||||
config.analytics.scriptURLs = [];
|
||||
delete config.analytics.amplitudeAPPKey;
|
||||
delete config.analytics.googleAnalyticsTrackingId;
|
||||
delete config.callStatsID;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* @flow */
|
||||
// @flow
|
||||
|
||||
declare var config: Object;
|
||||
import { getBackendSafeRoomName } from '../util';
|
||||
|
||||
/**
|
||||
* Builds and returns the room name.
|
||||
@@ -8,22 +8,10 @@ declare var config: Object;
|
||||
* @returns {string}
|
||||
*/
|
||||
export default function getRoomName(): ?string {
|
||||
const { getroomnode } = config;
|
||||
const path = window.location.pathname;
|
||||
let roomName;
|
||||
|
||||
// Determine the room node from the URL.
|
||||
if (getroomnode && typeof getroomnode === 'function') {
|
||||
roomName = getroomnode.call(config, path);
|
||||
} else {
|
||||
// Fall back to the default strategy of making assumptions about how the
|
||||
// URL maps to the room (name). It currently assumes a deployment in
|
||||
// which the last non-directory component of the path (name) is the
|
||||
// room.
|
||||
roomName
|
||||
= path.substring(path.lastIndexOf('/') + 1).toLowerCase()
|
||||
|| undefined;
|
||||
}
|
||||
// The last non-directory component of the path (name) is the room.
|
||||
const roomName = path.substring(path.lastIndexOf('/') + 1) || undefined;
|
||||
|
||||
return roomName;
|
||||
return getBackendSafeRoomName(roomName);
|
||||
}
|
||||
|
||||
70
react/features/base/config/interfaceConfigWhitelist.js
Normal file
70
react/features/base/config/interfaceConfigWhitelist.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* The interface config keys to whitelist, the keys that can be overridden.
|
||||
*
|
||||
* @private
|
||||
* @type Array
|
||||
*/
|
||||
export default [
|
||||
'ANDROID_APP_PACKAGE',
|
||||
'APP_NAME',
|
||||
'APP_SCHEME',
|
||||
'AUDIO_LEVEL_PRIMARY_COLOR',
|
||||
'AUDIO_LEVEL_SECONDARY_COLOR',
|
||||
'AUTHENTICATION_ENABLE',
|
||||
'AUTO_PIN_LATEST_SCREEN_SHARE',
|
||||
'BRAND_WATERMARK_LINK',
|
||||
'CLOSE_PAGE_GUEST_HINT',
|
||||
'CONNECTION_INDICATOR_AUTO_HIDE_ENABLED',
|
||||
'CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT',
|
||||
'CONNECTION_INDICATOR_DISABLED',
|
||||
'DEFAULT_BACKGROUND',
|
||||
'DEFAULT_LOCAL_DISPLAY_NAME',
|
||||
'DEFAULT_REMOTE_DISPLAY_NAME',
|
||||
'DISABLE_DOMINANT_SPEAKER_INDICATOR',
|
||||
'DISABLE_FOCUS_INDICATOR',
|
||||
'DISABLE_RINGING',
|
||||
'DISABLE_TRANSCRIPTION_SUBTITLES',
|
||||
'DISABLE_VIDEO_BACKGROUND',
|
||||
'DISPLAY_WELCOME_PAGE_CONTENT',
|
||||
'ENABLE_FEEDBACK_ANIMATION',
|
||||
'ENFORCE_NOTIFICATION_AUTO_DISMISS_TIMEOUT',
|
||||
'FILM_STRIP_MAX_HEIGHT',
|
||||
'GENERATE_ROOMNAMES_ON_WELCOME_PAGE',
|
||||
'INDICATOR_FONT_SIZES',
|
||||
'INITIAL_TOOLBAR_TIMEOUT',
|
||||
'INVITATION_POWERED_BY',
|
||||
'JITSI_WATERMARK_LINK',
|
||||
'LANG_DETECTION',
|
||||
'LIVE_STREAMING_HELP_LINK',
|
||||
'LOCAL_THUMBNAIL_RATIO',
|
||||
'MAXIMUM_ZOOMING_COEFFICIENT',
|
||||
'MOBILE_APP_PROMO',
|
||||
'MOBILE_DOWNLOAD_LINK_ANDROID',
|
||||
'MOBILE_DOWNLOAD_LINK_IOS',
|
||||
'MOBILE_DYNAMIC_LINK',
|
||||
'NATIVE_APP_NAME',
|
||||
'OPTIMAL_BROWSERS',
|
||||
'PHONE_NUMBER_REGEX',
|
||||
'POLICY_LOGO',
|
||||
'PROVIDER_NAME',
|
||||
'RANDOM_AVATAR_URL_PREFIX',
|
||||
'RANDOM_AVATAR_URL_SUFFIX',
|
||||
'RECENT_LIST_ENABLED',
|
||||
'REMOTE_THUMBNAIL_RATIO',
|
||||
'SETTINGS_SECTIONS',
|
||||
'SHOW_BRAND_WATERMARK',
|
||||
'SHOW_DEEP_LINKING_IMAGE',
|
||||
'SHOW_JITSI_WATERMARK',
|
||||
'SHOW_POWERED_BY',
|
||||
'SHOW_WATERMARK_FOR_GUESTS',
|
||||
'SUPPORT_URL',
|
||||
'TILE_VIEW_MAX_COLUMNS',
|
||||
'TOOLBAR_ALWAYS_VISIBLE',
|
||||
'TOOLBAR_BUTTONS',
|
||||
'TOOLBAR_TIMEOUT',
|
||||
'UNSUPPORTED_BROWSERS',
|
||||
'VERTICAL_FILMSTRIP',
|
||||
'VIDEO_LAYOUT_FIT',
|
||||
'VIDEO_QUALITY_LABEL_DISABLED',
|
||||
'filmStripOnly'
|
||||
];
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
import Platform from '../react/Platform';
|
||||
import { equals, ReducerRegistry, set } from '../redux';
|
||||
|
||||
import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes';
|
||||
@@ -20,6 +21,15 @@ import { _cleanupConfig } from './functions';
|
||||
const INITIAL_NON_RN_STATE = {
|
||||
};
|
||||
|
||||
/**
|
||||
* When we should enable H.264 on mobile. iOS 10 crashes so we disable it there.
|
||||
* See: https://bugs.chromium.org/p/webrtc/issues/detail?id=11002
|
||||
* Note that this is only used for P2P calls.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
const RN_ENABLE_H264 = navigator.product === 'ReactNative' && !(Platform.OS === 'ios' && Platform.Version === 10);
|
||||
|
||||
/**
|
||||
* The initial state of the feature base/config when executing in a React Native
|
||||
* environment. The mandatory configuration to be passed to JitsiMeetJS#init().
|
||||
@@ -41,8 +51,8 @@ const INITIAL_RN_STATE = {
|
||||
disableAudioLevels: true,
|
||||
|
||||
p2p: {
|
||||
disableH264: false,
|
||||
preferH264: true
|
||||
disableH264: !RN_ENABLE_H264,
|
||||
preferH264: RN_ENABLE_H264
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,10 @@ import {
|
||||
getCurrentConference
|
||||
} from '../conference';
|
||||
import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
|
||||
import { parseURIString } from '../util';
|
||||
import {
|
||||
getBackendSafeRoomName,
|
||||
parseURIString
|
||||
} from '../util';
|
||||
|
||||
import {
|
||||
CONNECTION_DISCONNECTED,
|
||||
@@ -307,10 +310,7 @@ function _constructOptions(state) {
|
||||
// Append room to the URL's search.
|
||||
const { room } = state['features/base/conference'];
|
||||
|
||||
// XXX The Jitsi Meet deployments require the room argument to be in
|
||||
// lower case at the time of this writing but, unfortunately, they do
|
||||
// not ignore case themselves.
|
||||
room && (bosh += `?room=${room.toLowerCase()}`);
|
||||
room && (bosh += `?room=${getBackendSafeRoomName(room)}`);
|
||||
|
||||
options.bosh = bosh;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ declare var APP: Object;
|
||||
declare var config: Object;
|
||||
|
||||
import { configureInitialDevices } from '../devices';
|
||||
import { getBackendSafeRoomName } from '../util';
|
||||
|
||||
export {
|
||||
connectionEstablished,
|
||||
@@ -21,8 +22,7 @@ import logger from './logger';
|
||||
*/
|
||||
export function connect() {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
// XXX Lib-jitsi-meet does not accept uppercase letters.
|
||||
const room = getState()['features/base/conference'].room.toLowerCase();
|
||||
const room = getBackendSafeRoomName(getState()['features/base/conference'].room);
|
||||
|
||||
// XXX For web based version we use conference initialization logic
|
||||
// from the old app (at the moment of writing).
|
||||
|
||||
@@ -61,11 +61,7 @@ class BottomSheet extends PureComponent<Props> {
|
||||
styles.sheetItemContainer,
|
||||
_styles.sheet
|
||||
] }>
|
||||
<ScrollView
|
||||
bounces = { false }
|
||||
showsVerticalScrollIndicator = { false }>
|
||||
{ this._getWrappedContent() }
|
||||
</ScrollView>
|
||||
{ this._getWrappedContent() }
|
||||
</View>
|
||||
</View>
|
||||
</SlidingView>
|
||||
@@ -73,24 +69,32 @@ class BottomSheet extends PureComponent<Props> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the content when needed (iOS 11 and above), or just returns the original children.
|
||||
* Wraps the content when needed (iOS 11 and above), or just returns the original content.
|
||||
*
|
||||
* @returns {React$Element}
|
||||
*/
|
||||
_getWrappedContent() {
|
||||
const content = (
|
||||
<ScrollView
|
||||
bounces = { false }
|
||||
showsVerticalScrollIndicator = { false } >
|
||||
{ this.props.children }
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
const majorVersionIOS = parseInt(Platform.Version, 10);
|
||||
|
||||
if (majorVersionIOS > 10) {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
{ this.props.children }
|
||||
{ content }
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ ColorSchemeRegistry.register('BottomSheet', {
|
||||
* Style for the label in a generic item rendered in the menu.
|
||||
*/
|
||||
labelStyle: {
|
||||
color: schemeColor('label'),
|
||||
color: schemeColor('text'),
|
||||
flexShrink: 1,
|
||||
fontSize: MD_FONT_SIZE,
|
||||
marginLeft: 32,
|
||||
|
||||
@@ -73,6 +73,12 @@ const _LANGUAGES = {
|
||||
main: require('../../../../lang/main-hr')
|
||||
},
|
||||
|
||||
// Hungarian
|
||||
'hu': {
|
||||
languages: require('../../../../lang/languages-hu'),
|
||||
main: require('../../../../lang/main-hu')
|
||||
},
|
||||
|
||||
// Italian
|
||||
'it': {
|
||||
languages: require('../../../../lang/languages-it'),
|
||||
|
||||
@@ -11,7 +11,7 @@ type Props = {
|
||||
/**
|
||||
* Class name for the web platform, if any.
|
||||
*/
|
||||
className?: string,
|
||||
className: string,
|
||||
|
||||
/**
|
||||
* Color of the icon (if not provided by the style object).
|
||||
@@ -23,6 +23,11 @@ type Props = {
|
||||
*/
|
||||
id?: string,
|
||||
|
||||
/**
|
||||
* Function to invoke on click.
|
||||
*/
|
||||
onClick?: Function,
|
||||
|
||||
/**
|
||||
* The size of the icon (if not provided by the style object).
|
||||
*/
|
||||
@@ -53,6 +58,7 @@ export default function Icon(props: Props) {
|
||||
className,
|
||||
color,
|
||||
id,
|
||||
onClick,
|
||||
size,
|
||||
src: IconComponent,
|
||||
style
|
||||
@@ -68,7 +74,8 @@ export default function Icon(props: Props) {
|
||||
|
||||
return (
|
||||
<Container
|
||||
className = { className }
|
||||
className = { `jitsi-icon ${className}` }
|
||||
onClick = { onClick }
|
||||
style = { restStyle }>
|
||||
<IconComponent
|
||||
fill = { calculatedColor }
|
||||
@@ -79,3 +86,6 @@ export default function Icon(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
Icon.defaultProps = {
|
||||
className: ''
|
||||
};
|
||||
|
||||
3
react/features/base/icons/svg/copy.svg
Normal file
3
react/features/base/icons/svg/copy.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 4C4 2.89543 4.89543 2 6 2H14C15.1046 2 16 2.89543 16 4H6V18C4.89543 18 4 17.1046 4 16V4ZM10 8V20H18V8H10ZM10 6H18C19.1046 6 20 6.89543 20 8V20C20 21.1046 19.1046 22 18 22H10C8.89543 22 8 21.1046 8 20V8C8 6.89543 8.89543 6 10 6Z" fill="#5E6D7A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 401 B |
3
react/features/base/icons/svg/download.svg
Executable file
3
react/features/base/icons/svg/download.svg
Executable file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 13.3705V5C11 4.44772 11.4477 4 12 4C12.5523 4 13 4.44772 13 5V13.4667L15.631 10.5433C16.0005 10.1328 16.6328 10.0995 17.0433 10.469C17.4538 10.8384 17.4871 11.4707 17.1176 11.8812L12.1064 17.4492C12.0727 17.4867 12.0139 17.4867 11.9802 17.4492L6.96897 11.8812C6.59951 11.4707 6.63278 10.8384 7.04329 10.469C7.4538 10.0995 8.08609 10.1328 8.45555 10.5433L11 13.3705ZM20 15C20 14.4477 20.4477 14 21 14C21.5523 14 22 14.4477 22 15V21C22 21.5523 21.5523 22 21 22H3C2.96548 22 2.93137 21.9983 2.89776 21.9948C2.3935 21.9436 2 21.5178 2 21V15C2 14.4477 2.44772 14 3 14C3.55228 14 4 14.4477 4 15V20H20V15Z" fill="#A4B8D1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 773 B |
1
react/features/base/icons/svg/help.svg
Normal file
1
react/features/base/icons/svg/help.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>
|
||||
|
After Width: | Height: | Size: 381 B |
@@ -18,16 +18,19 @@ export { default as IconClose } from './close.svg';
|
||||
export { default as IconClosedCaption } from './closed_caption.svg';
|
||||
export { default as IconConnectionActive } from './gsm-bars.svg';
|
||||
export { default as IconConnectionInactive } from './ninja.svg';
|
||||
export { default as IconCopy } from './copy.svg';
|
||||
export { default as IconDeviceBluetooth } from './bluetooth.svg';
|
||||
export { default as IconDeviceEarpiece } from './phone-talk.svg';
|
||||
export { default as IconDeviceHeadphone } from './headset.svg';
|
||||
export { default as IconDeviceSpeaker } from './volume.svg';
|
||||
export { default as IconDominantSpeaker } from './dominant-speaker.svg';
|
||||
export { default as IconDownload } from './download.svg';
|
||||
export { default as IconEventNote } from './event_note.svg';
|
||||
export { default as IconExitFullScreen } from './exit-full-screen.svg';
|
||||
export { default as IconFeedback } from './feedback.svg';
|
||||
export { default as IconFullScreen } from './full-screen.svg';
|
||||
export { default as IconHangup } from './hangup.svg';
|
||||
export { default as IconHelp } from './help.svg';
|
||||
export { default as IconInfo } from './info.svg';
|
||||
export { default as IconInvite } from './invite.svg';
|
||||
export { default as IconKick } from './kick.svg';
|
||||
@@ -36,6 +39,7 @@ export { default as IconMenu } from './menu.svg';
|
||||
export { default as IconMenuDown } from './menu-down.svg';
|
||||
export { default as IconMenuThumb } from './thumb-menu.svg';
|
||||
export { default as IconMenuUp } from './menu-up.svg';
|
||||
export { default as IconMessage } from './message.svg';
|
||||
export { default as IconMicDisabled } from './mic-disabled.svg';
|
||||
export { default as IconMicrophone } from './microphone.svg';
|
||||
export { default as IconModerator } from './star.svg';
|
||||
@@ -48,6 +52,7 @@ export { default as IconRaisedHand } from './raised-hand.svg';
|
||||
export { default as IconRec } from './rec.svg';
|
||||
export { default as IconRemoteControlStart } from './play.svg';
|
||||
export { default as IconRemoteControlStop } from './stop.svg';
|
||||
export { default as IconReply } from './reply.svg';
|
||||
export { default as IconRestore } from './restore.svg';
|
||||
export { default as IconRoomLock } from './security.svg';
|
||||
export { default as IconRoomUnlock } from './security-locked.svg';
|
||||
|
||||
1
react/features/base/icons/svg/message.svg
Normal file
1
react/features/base/icons/svg/message.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
||||
|
After Width: | Height: | Size: 256 B |
1
react/features/base/icons/svg/reply.svg
Normal file
1
react/features/base/icons/svg/reply.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
||||
|
After Width: | Height: | Size: 194 B |
@@ -1,12 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import { toState } from '../redux';
|
||||
import { loadScript } from '../util';
|
||||
|
||||
import JitsiMeetJS from './_';
|
||||
import logger from './logger';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
const JitsiConferenceErrors = JitsiMeetJS.errors.conference;
|
||||
const JitsiConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
@@ -97,42 +92,3 @@ export function isFatalJitsiConnectionError(error: Object | string) {
|
||||
|| error === JitsiConnectionErrors.OTHER_ERROR
|
||||
|| error === JitsiConnectionErrors.SERVER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads config.js from a specific remote server.
|
||||
*
|
||||
* @param {string} url - The URL to load.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export function loadConfig(url: string): Promise<Object> {
|
||||
let promise;
|
||||
|
||||
if (typeof APP === 'undefined') {
|
||||
promise
|
||||
= loadScript(url, 2.5 * 1000 /* Timeout in ms */)
|
||||
.then(() => {
|
||||
const { config } = window;
|
||||
|
||||
// We don't want to pollute the global scope.
|
||||
window.config = undefined;
|
||||
|
||||
if (typeof config !== 'object') {
|
||||
throw new Error('window.config is not an object');
|
||||
}
|
||||
|
||||
return config;
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error(`Failed to load config from ${url}`, err);
|
||||
|
||||
throw err;
|
||||
});
|
||||
} else {
|
||||
// Return "the config.js file" from the global scope - that is how the
|
||||
// Web app on both the client and the server was implemented before the
|
||||
// React Native app was even conceived.
|
||||
promise = Promise.resolve(window.config);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
36
react/features/base/lib-jitsi-meet/functions.native.js
Normal file
36
react/features/base/lib-jitsi-meet/functions.native.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// @flow
|
||||
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
import { loadScript } from '../util';
|
||||
import logger from './logger';
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
const { JavaScriptSandbox } = NativeModules;
|
||||
|
||||
/**
|
||||
* Loads config.js from a specific remote server.
|
||||
*
|
||||
* @param {string} url - The URL to load.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export async function loadConfig(url: string): Promise<Object> {
|
||||
try {
|
||||
const configTxt = await loadScript(url, 2.5 * 1000 /* Timeout in ms */, true /* skipeval */);
|
||||
const configJson = await JavaScriptSandbox.evaluate(`${configTxt}\nJSON.stringify(config);`);
|
||||
const config = JSON.parse(configJson);
|
||||
|
||||
if (typeof config !== 'object') {
|
||||
throw new Error('config is not an object');
|
||||
}
|
||||
|
||||
logger.info(`Config loaded from ${url}`);
|
||||
|
||||
return config;
|
||||
} catch (err) {
|
||||
logger.error(`Failed to load config from ${url}`, err);
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
16
react/features/base/lib-jitsi-meet/functions.web.js
Normal file
16
react/features/base/lib-jitsi-meet/functions.web.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// @flow
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
/**
|
||||
* Loads config.js from a specific remote server.
|
||||
*
|
||||
* @param {string} url - The URL to load.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export async function loadConfig(url: string): Promise<Object> { // eslint-disable-line no-unused-vars
|
||||
// Return "the config.js file" from the global scope - that is how the
|
||||
// Web app on both the client and the server was implemented before the
|
||||
// React Native app was even conceived.
|
||||
return window.config;
|
||||
}
|
||||
@@ -63,13 +63,13 @@ export default class JitsiMeetLogStorage {
|
||||
for (let i = 0, len = logEntries.length; i < len; i++) {
|
||||
const logEntry = logEntries[i];
|
||||
|
||||
if (typeof logEntry === 'object') {
|
||||
// Aggregated message
|
||||
logMessage += `(${logEntry.count}) ${logEntry.text}\n`;
|
||||
} else {
|
||||
// Regular message
|
||||
logMessage += `${logEntry}\n`;
|
||||
if (logEntry.timestamp) {
|
||||
logMessage += `${logEntry.timestamp} `;
|
||||
}
|
||||
if (logEntry.count > 1) {
|
||||
logMessage += `(${logEntry.count}) `;
|
||||
}
|
||||
logMessage += `${logEntry.text}\n`;
|
||||
}
|
||||
logMessage += '"}';
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ function buildTransport() {
|
||||
'warn',
|
||||
'error'
|
||||
].reduce((logger, logName) => {
|
||||
logger[logName] = (...args: Array<string>) => {
|
||||
logger[logName] = (timestamp: string, ...args: Array<string>) => {
|
||||
// It ignores the timestamp argument, because LogBridge will add it on the native side anyway
|
||||
const nargs = args.map(arg => {
|
||||
if (arg instanceof Error) {
|
||||
const errorBody = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user