Compare commits

..

1 Commits

Author SHA1 Message Date
paweldomas
cf83b4142a ref(config): move loggingConfig to config.js 2016-12-01 16:59:39 -06:00
368 changed files with 7002 additions and 17234 deletions

View File

@@ -3,7 +3,6 @@ build/*
# Third-party source code which we (1) do not want to modify or (2) try to
# modify as little as possible.
flow-typed/*
libs/*
# ESLint will by default ignore its own configuration file. However, there does

View File

@@ -4,10 +4,7 @@ module.exports = {
'commonjs': true,
'es6': true
},
'extends': [
'eslint:recommended',
'plugin:flowtype/recommended'
],
'extends': 'eslint:recommended',
'globals': {
// The globals that (1) are accessed but not defined within many of our
// files, (2) are certainly defined, and (3) we would like to use
@@ -15,16 +12,12 @@ module.exports = {
// files.
'__filename': false
},
'parser': 'babel-eslint',
'parserOptions': {
'ecmaFeatures': {
'experimentalObjectRestSpread': true
},
'sourceType': 'module'
},
'plugins': [
'flowtype'
],
'rules': {
'new-cap': [
'error',

View File

@@ -1,52 +0,0 @@
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*
; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
.*/Libraries/react-native/ReactNative.js
; Ignore packages in node_modules which we (i.e. the jitsi-meet project) have
; seen to cause errors and we have chosen not to fix.
.*/node_modules/babel-core/.*
.*/node_modules/bower/.*
.*/node_modules/jsonlint/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
flow/
[options]
emoji=true
module.system=haste
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-8]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-8]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
unsafe.enable_getters_and_setters=true
[version]
^0.38.0

1
.gitattributes vendored
View File

@@ -1,3 +1,2 @@
*.bundle.js -text -diff
*.pbxproj -text
lib-jitsi-meet.js -text -diff

21
.gitignore vendored
View File

@@ -4,6 +4,7 @@ deploy-local.sh
libs/
all.css
*css.map
unsupported_browser.css
.remote-sync.json
.sync-config.cson
@@ -35,33 +36,21 @@ DerivedData
*.xcuserstate
project.xcworkspace
# Android/IntelliJ
# Android/IJ
#
build/
*.iml
.idea
.gradle
local.properties
*.iml
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# BUCK
#
buck-out/
\.buckd/
*.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use
# fastlane to re-generate the screenshots whenever they are needed. For more
# information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
#
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
android/app/libs
android/keystores/debug.keystore

View File

@@ -1,18 +1,7 @@
# The following do not need to be checked because they do not represent JS
# source code.
build/
debian/
libs/
node_modules/
# The following are checked by ESLint with the maximum configuration which
# supersedes JSHint.
flow-typed/
react/
# The following are checked by ESLint with the minimum configuration which does
# not supersede JSHint but take advantage of advanced language features such as
# Facebook Flow which are not supported by JSHint.
modules/translation/translation.js
analytics.js
webpack.config.babel.js

View File

@@ -1,4 +0,0 @@
/**
* Notifies interested parties that hangup procedure will start.
*/
export const BEFORE_HANGUP = "conference.before_hangup";

View File

@@ -8,6 +8,7 @@ OUTPUT_DIR = .
STYLES_BUNDLE = css/all.bundle.css
STYLES_DESTINATION = css/all.css
STYLES_MAIN = css/main.scss
STYLES_UNSUPPORTED_BROWSER = css/unsupported_browser.scss
WEBPACK = ./node_modules/.bin/webpack
all: update-deps compile deploy clean
@@ -46,6 +47,7 @@ deploy-lib-jitsi-meet:
$(DEPLOY_DIR)
deploy-css:
$(NODE_SASS) css/unsupported_browser.scss css/unsupported_browser.css ; \
$(NODE_SASS) $(STYLES_MAIN) $(STYLES_BUNDLE) && \
$(CLEANCSS) $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
rm $(STYLES_BUNDLE)
@@ -57,5 +59,6 @@ source-package:
mkdir -p source_package/jitsi-meet/css && \
cp -r *.js *.html connection_optimization favicon.ico fonts images libs sounds LICENSE lang source_package/jitsi-meet && \
cp css/all.css source_package/jitsi-meet/css && \
cp css/unsupported_browser.css source_package/jitsi-meet/css && \
(cd source_package ; tar cjf ../jitsi-meet.tar.bz2 jitsi-meet) && \
rm -rf source_package

View File

@@ -1,5 +1,5 @@
# Jitsi Meet - Secure, Simple and Scalable Video Conferences
Jitsi Meet - Secure, Simple and Scalable Video Conferences
====
Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, scalable video conferences. You can see [Jitsi Meet in action](http://youtu.be/7vFUVClsNh0) here at the session #482 of the VoIP Users Conference.
You can also try it out yourself at https://meet.jit.si .
@@ -12,17 +12,6 @@ Installing Jitsi Meet is quite a simple experience. For Debian-based systems, we
For other systems, or if you wish to install all components manually, see the [detailed manual installation instructions](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md).
## Download
You can download Debian/Ubuntu binaries:
* [stable](https://download.jitsi.org/stable/) ([instructions](https://jitsi.org/Main/InstallJitsiMeetDebianStableRepository))
* [testing](https://download.jitsi.org/testing/) ([instructions](https://jitsi.org/Main/InstallJitsiMeetDebianTestingRepository))
* [nightly](https://download.jitsi.org/unstable/) ([instructions](https://jitsi.org/Main/InstallJitsiMeetDebianNightlyRepository))
You can get our mobile versoins 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
Jitsi Meet uses [Browserify](http://browserify.org). If you want to make changes in the code you need to [install Browserify](http://browserify.org/#install). Browserify requires [nodejs](http://nodejs.org).
@@ -39,7 +28,7 @@ To build the Jitsi Meet application, just type
make
```
## Working with the library sources (lib-jitsi-meet)
## Working with the library sources(lib-jitsi-meet).
By default the library is build from its git repository sources. The default dependency path in package.json is :
```json
@@ -86,14 +75,6 @@ npm unlink lib-jitsi-meet
npm install
```
## Embedding in external applications
Jitsi Meet provides a very flexible way of embedding it in external applications by using the [Jitsi Meet API](doc/api.md).
## Mobile app
Jitsi Meet is also available as a React Native application for Android and iOS.
Instructions on how to build it can be found [here](doc/mobile.md).
## Discuss
Please use the [Jitsi dev mailing list](http://lists.jitsi.org/pipermail/dev/) to discuss feature requests before opening an issue on Github.

View File

@@ -46,13 +46,13 @@ android_library(
android_build_config(
name = 'build_config',
package = 'org.jitsi.meet',
package = 'org.jitsi.jitsi_meet_react',
)
android_resource(
name = 'res',
res = 'src/main/res',
package = 'org.jitsi.meet',
package = 'org.jitsi.jitsi_meet_react',
)
android_binary(

View File

@@ -1,4 +1,15 @@
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
import com.android.build.OutputFile
@@ -87,11 +98,11 @@ android {
buildToolsVersion '23.0.1'
defaultConfig {
applicationId 'org.jitsi.meet'
applicationId 'org.jitsi.jitsi_meet_react'
minSdkVersion 16
targetSdkVersion 22
versionCode Integer.parseInt("${version}")
versionName "1.3.${version}"
versionCode 1
versionName '1.0'
ndk {
abiFilters 'armeabi-v7a', 'x86'
}
@@ -138,15 +149,18 @@ if (project.hasProperty('JITSI_SIGNING')
apply from: project.property('JITSI_SIGNING');
}
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
compile project(':react-native-background-timer')
compile project(':react-native-immersive')
compile project(':react-native-keep-awake')
compile project(':react-native-vector-icons')
compile project(':react-native-webrtc')
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.facebook.react:react-native:+' // From node_modules
compile 'com.facebook.react:react-native:+'
compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
transitive = true
}
}
apply from: '../../node_modules/react-native-vector-icons/fonts.gradle'
@@ -154,6 +168,6 @@ apply from: '../../node_modules/react-native-vector-icons/fonts.gradle'
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
from configurations.compile
into 'libs'
}

View File

@@ -1,14 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.jitsi.meet"
package="org.jitsi.jitsi_meet_react"
android:versionCode="1"
android:versionName="1.0">
<!-- XXX: ACCESS_NETWORK_STATE is required by WebRTC. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!-- WebRTC -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
@@ -16,8 +13,8 @@
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="23" />
android:minSdkVersion="16"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
@@ -29,8 +26,7 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -39,21 +35,16 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:host="beta.hipchat.me" android:scheme="https" />
<data android:host="beta.meet.jit.si" android:scheme="https" />
<data android:host="chaos.hipchat.me" android:scheme="https" />
<data android:host="enso.me" android:scheme="https" />
<data android:host="hipchat.me" android:scheme="https" />
<data android:host="meet.jit.si" android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="org.jitsi.meet" />
</intent-filter>
</activity>
<activity
android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<meta-data
android:name="io.fabric.ApiKey"
android:value="a8ae24a58302ba79da1d312138e941f6b86e3242" />
</application>
</manifest>

View File

@@ -1,8 +1,11 @@
package org.jitsi.meet;
package org.jitsi.jitsi_meet_react;
import android.os.Bundle;
import com.crashlytics.android.Crashlytics;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import io.fabric.sdk.android.Fabric;
public class MainActivity extends ReactActivity {
/**
@@ -43,4 +46,11 @@ public class MainActivity extends ReactActivity {
protected String getMainComponentName() {
return "App";
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Crashlytics());
}
}

View File

@@ -0,0 +1,39 @@
package org.jitsi.jitsi_meet_react;
import android.app.Application;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.oney.WebRTCModule.WebRTCModulePackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage(),
new WebRTCModulePackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}

View File

@@ -1,64 +0,0 @@
package org.jitsi.meet;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
/**
* {@inheritDoc}
*/
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
/**
* {@inheritDoc}
*/
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new com.corbt.keepawake.KCKeepAwakePackage(),
new com.facebook.react.shell.MainReactPackage(),
new com.oblador.vectoricons.VectorIconsPackage(),
new com.ocetnik.timer.BackgroundTimerPackage(),
new com.oney.WebRTCModule.WebRTCModulePackage(),
new com.rnimmersive.RNImmersivePackage(),
new org.jitsi.meet.audiomode.AudioModePackage()
);
}
};
/**
* {@inheritDoc}
*/
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
/**
* {@inheritDoc}
*/
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (!getReactNativeHost()
.getReactInstanceManager()
.getDevSupportManager()
.getDevSupportEnabled()) {
// TODO Auto-generated method stub
}
}
}

View File

@@ -1,322 +0,0 @@
package org.jitsi.meet.audiomode;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.util.HashMap;
import java.util.Map;
/**
* Module implementing a simple API to select the appropriate audio device for a
* conference call.
*
* Audio calls should use <tt>AudioModeModule.AUDIO_CALL</tt>, which uses the
* builtin earpiece, wired headset or bluetooth headset. The builtin earpiece is
* the default audio device.
*
* Video calls should should use <tt>AudioModeModule.VIDEO_CALL</tt>, which uses
* the builtin speaker, earpiece, wired headset or bluetooth headset. The
* builtin speaker is the default audio device.
*
* Before a call has started and after it has ended the
* <tt>AudioModeModule.DEFAULT</tt> mode should be used.
*/
public class AudioModeModule extends ReactContextBaseJavaModule {
/**
* Constants representing the audio mode.
* - DEFAULT: Used before and after every call. It represents the default
* audio routing scheme.
* - AUDIO_CALL: Used for audio only calls. It will use the earpiece by
* default, unless a wired or Bluetooth headset is connected.
* - VIDEO_CALL: Used for video calls. It will use the speaker by default,
* unless a wired or Bluetooth headset is connected.
*/
private static final int DEFAULT = 0;
private static final int AUDIO_CALL = 1;
private static final int VIDEO_CALL = 2;
/**
*
*/
private static final String ACTION_HEADSET_PLUG
= (Build.VERSION.SDK_INT >= 21)
? AudioManager.ACTION_HEADSET_PLUG
: Intent.ACTION_HEADSET_PLUG;
/**
* React Native module name.
*/
private static final String MODULE_NAME = "AudioMode";
/**
* Tag used when logging messages.
*/
static final String TAG = MODULE_NAME;
/**
* {@link AudioManager} instance used to interact with the Android audio
* subsystem.
*/
private final AudioManager audioManager;
/**
* {@link BluetoothHeadsetMonitor} for detecting Bluetooth device changes in
* old (< M) Android versions.
*/
private BluetoothHeadsetMonitor bluetoothHeadsetMonitor;
/**
* {@link Handler} for running all operations on the main thread.
*/
private final Handler mainThreadHandler
= new Handler(Looper.getMainLooper());
/**
* {@link Runnable} for running update operation on the main thread.
*/
private final Runnable mainThreadRunner
= new Runnable() {
@Override
public void run() {
if (mode != -1) {
updateAudioRoute(mode);
}
}
};
/**
* Audio mode currently in use.
*/
private int mode = -1;
/**
* Initializes a new module instance. There shall be a single instance of
* this module throughout the lifetime of the application.
*
* @param reactContext the {@link ReactApplicationContext} where this module
* is created.
*/
public AudioModeModule(ReactApplicationContext reactContext) {
super(reactContext);
audioManager
= (AudioManager)
reactContext.getSystemService(Context.AUDIO_SERVICE);
// Setup runtime device change detection.
setupAudioRouteChangeDetection();
}
/**
* Gets a mapping with the constants this module is exporting.
*
* @return a {@link Map} mapping the constants to be exported with their
* values.
*/
@Override
public Map<String, Object> getConstants() {
Map<String, Object> constants = new HashMap<>();
constants.put("AUDIO_CALL", AUDIO_CALL);
constants.put("DEFAULT", DEFAULT);
constants.put("VIDEO_CALL", VIDEO_CALL);
return constants;
}
/**
* Gets the name for this module, to be used in the React Native bridge.
*
* @return a string with the module name.
*/
@Override
public String getName() {
return MODULE_NAME;
}
/**
* Helper method to trigger an audio route update when devices change. It
* makes sure the operation is performed on the main thread.
*/
void onAudioDeviceChange() {
mainThreadHandler.post(mainThreadRunner);
}
/**
* Helper method to set the output route to a Bluetooth device.
*
* @param enabled true if Bluetooth should use used, false otherwise.
*/
private void setBluetoothAudioRoute(boolean enabled) {
if (enabled) {
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
} else {
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
}
}
/**
* Public method to set the current audio mode.
*
* @param mode the desired audio mode.
* @param promise a {@link Promise} which will be resolved if the audio mode
* could be updated successfully, and it will be rejected otherwise.
*/
@ReactMethod
public void setMode(final int mode, final Promise promise) {
if (mode != DEFAULT && mode != AUDIO_CALL && mode != VIDEO_CALL) {
promise.reject("setMode", "Invalid audio mode " + mode);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
if (updateAudioRoute(mode)) {
AudioModeModule.this.mode = mode;
promise.resolve(null);
} else {
promise.reject(
"setMode",
"Failed to set the requested audio mode");
}
}
};
mainThreadHandler.post(r);
}
/**
* Setup the audio route change detection mechanism. We use the
* {@link android.media.AudioDeviceCallback} API on Android >= 23 only.
*/
private void setupAudioRouteChangeDetection() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setupAudioRouteChangeDetectionM();
} else {
setupAudioRouteChangeDetectionPreM();
}
}
/**
* Audio route change detection mechanism for Android API >= 23.
*/
@TargetApi(Build.VERSION_CODES.M)
private void setupAudioRouteChangeDetectionM() {
android.media.AudioDeviceCallback audioDeviceCallback =
new android.media.AudioDeviceCallback() {
@Override
public void onAudioDevicesAdded(
AudioDeviceInfo[] addedDevices) {
Log.d(TAG, "Audio devices added");
onAudioDeviceChange();
}
@Override
public void onAudioDevicesRemoved(
AudioDeviceInfo[] removedDevices) {
Log.d(TAG, "Audio devices removed");
onAudioDeviceChange();
}
};
audioManager.registerAudioDeviceCallback(audioDeviceCallback, null);
}
/**
* Audio route change detection mechanism for Android API < 23.
*/
private void setupAudioRouteChangeDetectionPreM() {
Context context = getReactApplicationContext();
// Detect changes in wired headset connections.
IntentFilter wiredHeadSetFilter = new IntentFilter(ACTION_HEADSET_PLUG);
BroadcastReceiver wiredHeadsetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Wired headset added / removed");
onAudioDeviceChange();
}
};
context.registerReceiver(wiredHeadsetReceiver, wiredHeadSetFilter);
// Detect Bluetooth device changes.
bluetoothHeadsetMonitor = new BluetoothHeadsetMonitor(this, context);
}
/**
* Updates the audio route for the given mode.
*
* @param mode the audio mode to be used when computing the audio route.
* @return true if the audio route was updated successfully, false
* otherwise.
*/
private boolean updateAudioRoute(int mode) {
Log.d(TAG, "Update audio route for mode: " + mode);
if (mode == DEFAULT) {
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.abandonAudioFocus(null);
audioManager.setSpeakerphoneOn(false);
audioManager.setMicrophoneMute(true);
setBluetoothAudioRoute(false);
return true;
}
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setMicrophoneMute(false);
if (audioManager.requestAudioFocus(
null,
AudioManager.STREAM_VOICE_CALL,
AudioManager.AUDIOFOCUS_GAIN)
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
Log.d(TAG, "Audio focus request failed");
return false;
}
boolean useSpeaker = (mode == VIDEO_CALL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// On Android >= M we use the AudioDeviceCallback API, so turn on
// Bluetooth SCO from the start.
if (audioManager.isBluetoothScoAvailableOffCall()) {
audioManager.startBluetoothSco();
}
} else {
// On older Android versions we must set the Bluetooth route
// manually. Also disable the speaker in that case.
setBluetoothAudioRoute(
bluetoothHeadsetMonitor.isHeadsetAvailable());
if (bluetoothHeadsetMonitor.isHeadsetAvailable()) {
useSpeaker = false;
}
}
// XXX: isWiredHeadsetOn is not deprecated when used just for knowing if
// there is a wired headset connected, regardless of audio being routed
// to it.
audioManager.setSpeakerphoneOn(
useSpeaker
&& !(audioManager.isWiredHeadsetOn()
|| audioManager.isBluetoothScoOn()));
return true;
}
}

View File

@@ -1,48 +0,0 @@
package org.jitsi.meet.audiomode;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Implements {@link ReactPackage} for {@link AudioModeModule}.
*/
public class AudioModePackage implements ReactPackage {
/**
* {@inheritDoc}
*/
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
/**
* {@inheritDoc}
*
* @return List of native modules to be exposed by React Native.
*/
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new AudioModeModule(reactContext));
return modules;
}
/**
* {@inheritDoc}
*/
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

View File

@@ -1,189 +0,0 @@
package org.jitsi.meet.audiomode;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
/**
* Helper class to detect and handle Bluetooth device changes. It monitors
* Bluetooth headsets being connected / disconnected and notifies the module
* about device changes when this occurs.
*/
public class BluetoothHeadsetMonitor {
/**
* {@link AudioModeModule} where this monitor reports.
*/
private final AudioModeModule audioModeModule;
/**
* The {@link Context} in which {@link #audioModeModule} executes.
*/
private final Context context;
/**
* Reference to a proxy object which allows us to query connected devices.
*/
private BluetoothHeadset headset;
/**
* Flag indicating if there are any Bluetooth headset devices currently
* available.
*/
private boolean headsetAvailable = false;
/**
* {@link Handler} for running all operations on the main thread.
*/
private final Handler mainThreadHandler
= new Handler(Looper.getMainLooper());
/**
* Helper for running Bluetooth operations on the main thread.
*/
private final Runnable updateDevicesRunnable
= new Runnable() {
@Override
public void run() {
headsetAvailable
= (headset != null)
&& !headset.getConnectedDevices().isEmpty();
audioModeModule.onAudioDeviceChange();
}
};
public BluetoothHeadsetMonitor(
AudioModeModule audioModeModule,
Context context) {
this.audioModeModule = audioModeModule;
this.context = context;
AudioManager audioManager
= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (!audioManager.isBluetoothScoAvailableOffCall()) {
Log.w(AudioModeModule.TAG, "Bluetooth SCO is not available");
return;
}
if (getBluetoothHeadsetProfileProxy()) {
registerBluetoothReceiver();
// Initial detection.
updateDevices();
}
}
private boolean getBluetoothHeadsetProfileProxy() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) {
Log.w(AudioModeModule.TAG, "Device doesn't support Bluetooth");
return false;
}
// XXX: The profile listener listens for system services of the given
// type being available to the application. That is, if our Bluetooth
// adapter has the "headset" profile.
BluetoothProfile.ServiceListener listener
= new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(
int profile,
BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
headset = (BluetoothHeadset) proxy;
updateDevices();
}
}
@Override
public void onServiceDisconnected(int profile) {
// The logic is the same as the logic of onServiceConnected.
onServiceConnected(profile, /* proxy */ null);
}
};
return
adapter.getProfileProxy(
context,
listener,
BluetoothProfile.HEADSET);
}
/**
* Returns the current headset availability.
*
* @return true if there is a Bluetooth headset connected, false otherwise.
*/
public boolean isHeadsetAvailable() {
return headsetAvailable;
}
private void onBluetoothReceiverReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
// XXX: This action will be fired when a Bluetooth headset is
// connected or disconnected to the system. This is not related to
// audio routing.
int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
switch (state) {
case BluetoothHeadset.STATE_CONNECTED:
case BluetoothHeadset.STATE_DISCONNECTED:
Log.d(
AudioModeModule.TAG,
"BT headset connection state changed: " + state);
updateDevices();
break;
}
} else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
// XXX: This action will be fired when the connection established
// with a Bluetooth headset (called a SCO connection) changes state.
// When the SCO connection is active we route audio to it.
int state
= intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -99);
switch (state) {
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
Log.d(
AudioModeModule.TAG,
"BT SCO connection state changed: " + state);
updateDevices();
break;
}
}
}
private void registerBluetoothReceiver() {
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
onBluetoothReceiverReceive(context, intent);
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
context.registerReceiver(receiver, filter);
}
/**
* Detects if there are new devices connected / disconnected and fires the
* {@link AudioModeModule#onAudioDeviceChange()} callback.
*/
private void updateDevices() {
mainThreadHandler.post(updateDevicesRunnable);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -3,7 +3,6 @@
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>

View File

@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.android.tools.build:gradle:1.3.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@@ -18,4 +18,3 @@
# org.gradle.parallel=true
android.useDeprecatedNdk=true
version=1

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip

View File

@@ -1,12 +1,6 @@
rootProject.name = 'jitsi-meet-react'
include ':app'
include ':react-native-background-timer'
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
include ':react-native-immersive'
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
include ':react-native-keep-awake'
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
include ':react-native-webrtc'

257
app.js
View File

@@ -1,4 +1,6 @@
/* global $, config, getRoomName, loggingConfig, JitsiMeetJS */
/* application specific logic */
const logger = require("jitsi-meet-logger").getLogger(__filename);
import "babel-polyfill";
import "jquery";
@@ -6,6 +8,7 @@ import "jquery-contextmenu";
import "jquery-ui";
import "strophe";
import "strophe-disco";
import "strophe-caps";
import "jQuery-Impromptu";
import "autosize";
@@ -16,13 +19,101 @@ import 'aui-experimental-css';
window.toastr = require("toastr");
const Logger = require("jitsi-meet-logger");
const LogCollector = Logger.LogCollector;
import JitsiMeetLogStorage from "./modules/util/JitsiMeetLogStorage";
import URLProcessor from "./modules/config/URLProcessor";
import RoomnameGenerator from './modules/util/RoomnameGenerator';
import UI from "./modules/UI/UI";
import settings from "./modules/settings/Settings";
import conference from './conference';
import ConferenceUrl from './modules/URL/ConferenceUrl';
import API from './modules/API/API';
import UIEvents from './service/UI/UIEvents';
import getTokenData from "./modules/tokendata/TokenData";
import translation from "./modules/translation/translation";
import remoteControl from "./modules/remotecontrol/RemoteControl";
const ConferenceEvents = JitsiMeetJS.events.conference;
/**
* Tries to push history state with the following parameters:
* 'VideoChat', `Room: ${roomName}`, URL. If fail, prints the error and returns
* it.
*/
function pushHistoryState(roomName, URL) {
try {
window.history.pushState(
'VideoChat', `Room: ${roomName}`, URL
);
} catch (e) {
logger.warn("Push history state failed with parameters:",
'VideoChat', `Room: ${roomName}`, URL, e);
return e;
}
return null;
}
/**
* Replaces current history state(replaces the URL displayed by the browser).
* @param {string} newUrl the URL string which is to be displayed by the browser
* to the user.
*/
function replaceHistoryState (newUrl) {
if (window.history
&& typeof window.history.replaceState === 'function') {
window.history.replaceState({}, document.title, newUrl);
}
}
/**
* Builds and returns the room name.
*/
function buildRoomName () {
let roomName = getRoomName();
if(!roomName) {
let word = RoomnameGenerator.generateRoomWithoutSeparator();
roomName = word.toLowerCase();
let historyURL = window.location.href + word;
//Trying to push state with current URL + roomName
pushHistoryState(word, historyURL);
}
return roomName;
}
/**
* Adjusts the logging levels.
* @private
*/
function configureLoggingLevels () {
// NOTE The library Logger is separated from the app loggers, so the levels
// have to be set in two places
// Set default logging level
const defaultLogLevel
= loggingConfig.defaultLogLevel || JitsiMeetJS.logLevels.TRACE;
Logger.setLogLevel(defaultLogLevel);
JitsiMeetJS.setLogLevel(defaultLogLevel);
// NOTE console was used on purpose here to go around the logging
// and always print the default logging level to the console
console.info("Default logging level set to: " + defaultLogLevel);
// Set log level for each logger
if (loggingConfig) {
Object.keys(loggingConfig).forEach(function(loggerName) {
if ('defaultLogLevel' !== loggerName) {
const level = loggingConfig[loggerName];
Logger.setLogLevelById(level, loggerName);
JitsiMeetJS.setLogLevelById(level, loggerName);
}
});
}
}
const APP = {
// Used by do_external_connect.js if we receive the attach data after
@@ -61,15 +152,163 @@ const APP = {
ConferenceUrl : null,
connection: null,
API,
remoteControl
init () {
this.initLogging();
this.keyboardshortcut =
require("./modules/keyboardshortcut/keyboardshortcut");
this.configFetch = require("./modules/config/HttpConfigFetch");
this.tokenData = getTokenData();
},
initLogging () {
// Adjust logging level
configureLoggingLevels();
// Create the LogCollector and register it as the global log transport.
// It is done early to capture as much logs as possible. Captured logs
// will be cached, before the JitsiMeetLogStorage gets ready (statistics
// module is initialized).
if (!this.logCollector && !loggingConfig.disableLogCollector) {
this.logCollector = new LogCollector(new JitsiMeetLogStorage());
Logger.addGlobalTransport(this.logCollector);
JitsiMeetJS.addGlobalLogTransport(this.logCollector);
}
}
};
// TODO The execution of the mobile app starts from react/index.native.js.
// Similarly, the execution of the Web app should start from react/index.web.js
// for the sake of consistency and ease of understanding. Temporarily though
// because we are at the beginning of introducing React into the Web app, allow
// the execution of the Web app to start from app.js in order to reduce the
// complexity of the beginning step.
require('./react');
/**
* If JWT token data it will be used for local user settings
*/
function setTokenData() {
let localUser = APP.tokenData.caller;
if(localUser) {
APP.settings.setEmail((localUser.getEmail() || "").trim(), true);
APP.settings.setAvatarUrl((localUser.getAvatarUrl() || "").trim());
APP.settings.setDisplayName((localUser.getName() || "").trim(), true);
}
}
function init() {
setTokenData();
// Initialize the conference URL handler
APP.ConferenceUrl = new ConferenceUrl(window.location);
// Clean up the URL displayed by the browser
replaceHistoryState(APP.ConferenceUrl.getInviteUrl());
// TODO The execution of the mobile app starts from react/index.native.js.
// Similarly, the execution of the Web app should start from
// react/index.web.js for the sake of consistency and ease of understanding.
// Temporarily though because we are at the beginning of introducing React
// into the Web app, allow the execution of the Web app to start from app.js
// in order to reduce the complexity of the beginning step.
require('./react');
const isUIReady = APP.UI.start();
if (isUIReady) {
APP.conference.init({roomName: buildRoomName()}).then(() => {
if (APP.logCollector) {
// Start the LogCollector's periodic "store logs" task only if
// we're in the conference and not on the welcome page. This is
// determined by the value of "isUIReady" const above.
APP.logCollector.start();
APP.logCollectorStarted = true;
// Make an attempt to flush in case a lot of logs have been
// cached, before the collector was started.
APP.logCollector.flush();
// This event listener will flush the logs, before
// the statistics module (CallStats) is stopped.
//
// NOTE The LogCollector is not stopped, because this event can
// be triggered multiple times during single conference
// (whenever statistics module is stopped). That includes
// the case when Jicofo terminates the single person left in the
// room. It will then restart the media session when someone
// eventually join the room which will start the stats again.
APP.conference.addConferenceListener(
ConferenceEvents.BEFORE_STATISTICS_DISPOSED,
() => {
if (APP.logCollector) {
APP.logCollector.flush();
}
}
);
}
APP.UI.initConference();
APP.UI.addListener(UIEvents.LANG_CHANGED, language => {
APP.translation.setLanguage(language);
APP.settings.setLanguage(language);
});
APP.keyboardshortcut.init();
}).catch(err => {
APP.UI.hideRingOverLay();
APP.API.notifyConferenceLeft(APP.conference.roomName);
logger.error(err);
});
}
}
/**
* If we have an HTTP endpoint for getting config.json configured we're going to
* read it and override properties from config.js and interfaceConfig.js.
* If there is no endpoint we'll just continue with initialization.
* Keep in mind that if the endpoint has been configured and we fail to obtain
* the config for any reason then the conference won't start and error message
* will be displayed to the user.
*/
function obtainConfigAndInit() {
let roomName = APP.conference.roomName;
if (config.configLocation) {
APP.configFetch.obtainConfig(
config.configLocation, roomName,
// Get config result callback
function(success, error) {
if (success) {
var now = APP.connectionTimes["configuration.fetched"] =
window.performance.now();
logger.log("(TIME) configuration fetched:\t", now);
init();
} else {
// Show obtain config error,
// pass the error object for report
APP.UI.messageHandler.openReportDialog(
null, "dialog.connectError", error);
}
});
} else {
require("./modules/config/BoshAddressChoice").chooseAddress(
config, roomName);
init();
}
}
$(document).ready(function () {
var now = APP.connectionTimes["document.ready"] = window.performance.now();
logger.log("(TIME) document ready:\t", now);
URLProcessor.setConfigParametersFromUrl();
APP.init();
APP.translation.init(settings.getLanguage());
APP.API.init(APP.tokenData.externalAPISettings);
obtainConfigAndInit();
});
$(window).bind('beforeunload', function () {
// Stop the LogCollector
if (APP.logCollectorStarted) {
APP.logCollector.stop();
APP.logCollectorStarted = false;
}
APP.API.dispose();
});
module.exports = APP;

View File

@@ -12,7 +12,7 @@
</div>
<div class="hint-msg">
<p>
<span id="hintQuestion">Did you know?</span>
<span>Did you know?</span>
<span class="hint-msg__holder" id="hintMessage"></span>
</p>
<div class="happy-software"></div>

View File

@@ -32,7 +32,7 @@ function insertTextMsg(id, msg){
var el = document.getElementById(id);
if (el)
el.innerHTML = msg;
el.innerText = msg;
}
/**
@@ -42,17 +42,6 @@ function onLoad() {
//Works only for close2.html because close.html doesn't have this element.
insertTextMsg('thanksMessage',
'Thank you for using ' + interfaceConfig.APP_NAME);
// If there is a setting show a special message only for the guests
if (interfaceConfig.CLOSE_PAGE_GUEST_HINT) {
if ( window.sessionStorage.getItem('guest') === 'true' ) {
var element = document.getElementById('hintQuestion');
element.classList.add('hide');
insertTextMsg('hintMessage', interfaceConfig.CLOSE_PAGE_GUEST_HINT);
return;
}
}
insertTextMsg('hintMessage', getHint());
}

View File

@@ -12,7 +12,7 @@
</div>
<div class="hint-msg">
<p>
<span id="hintQuestion">Did you know?</span>
<span>Did you know?</span>
<span class="hint-msg__holder" id="hintMessage"></span>
</p>
<div class="happy-software"></div>

View File

@@ -10,40 +10,13 @@ import Recorder from './modules/recorder/Recorder';
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
import { reload, reportError } from './modules/util/helpers';
import {reportError} from './modules/util/helpers';
import UIEvents from './service/UI/UIEvents';
import UIUtil from './modules/UI/util/UIUtil';
import * as JitsiMeetConferenceEvents from './ConferenceEvents';
import analytics from './modules/analytics/analytics';
import EventEmitter from "events";
import {
AVATAR_ID_COMMAND,
AVATAR_URL_COMMAND,
conferenceFailed,
conferenceJoined,
conferenceLeft,
EMAIL_COMMAND
} from './react/features/base/conference';
import {
isFatalJitsiConnectionError
} from './react/features/base/lib-jitsi-meet';
import {
changeParticipantAvatarID,
changeParticipantAvatarURL,
changeParticipantEmail,
participantJoined,
participantLeft,
participantRoleChanged
} from './react/features/base/participants';
import {
mediaPermissionPromptVisibilityChanged,
suspendDetected
} from './react/features/overlay';
const ConnectionEvents = JitsiMeetJS.events.connection;
const ConnectionErrors = JitsiMeetJS.errors.connection;
@@ -55,8 +28,6 @@ const TrackErrors = JitsiMeetJS.errors.track;
const ConnectionQualityEvents = JitsiMeetJS.events.connectionQuality;
const eventEmitter = new EventEmitter();
let room, connection, localAudio, localVideo;
/**
@@ -70,12 +41,12 @@ import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/VideoContainer";
* Known custom conference commands.
*/
const commands = {
AVATAR_ID: AVATAR_ID_COMMAND,
AVATAR_URL: AVATAR_URL_COMMAND,
CUSTOM_ROLE: "custom-role",
EMAIL: EMAIL_COMMAND,
EMAIL: "email",
AVATAR_URL: "avatar-url",
AVATAR_ID: "avatar-id",
ETHERPAD: "etherpad",
SHARED_VIDEO: "shared-video"
SHARED_VIDEO: "shared-video",
CUSTOM_ROLE: "custom-role"
};
/**
@@ -115,10 +86,7 @@ function createInitialLocalTracksAndConnect(roomName) {
JitsiMeetJS.mediaDevices.addEventListener(
JitsiMeetJS.events.mediaDevices.PERMISSION_PROMPT_IS_SHOWN,
browser =>
APP.store.dispatch(
mediaPermissionPromptVisibilityChanged(true, browser))
);
browser => APP.UI.showUserMediaPermissionsGuidanceOverlay(browser));
// First try to retrieve both audio and video.
let tryCreateLocalTracks = createLocalTracks(
@@ -136,7 +104,8 @@ function createInitialLocalTracksAndConnect(roomName) {
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
.then(([tracks, con]) => {
APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false));
APP.UI.hideUserMediaPermissionsGuidanceOverlay();
if (audioAndVideoError) {
if (audioOnlyError) {
// If both requests for 'audio' + 'video' and 'audio' only
@@ -165,29 +134,6 @@ function sendData (command, value) {
room.sendCommand(command, {value: value});
}
/**
* Sets up initially the properties of the local participant - email, avatarID,
* avatarURL, displayName, etc.
*/
function _setupLocalParticipantProperties() {
const email = APP.settings.getEmail();
email && sendData(commands.EMAIL, email);
const avatarUrl = APP.settings.getAvatarUrl();
avatarUrl && sendData(commands.AVATAR_URL, avatarUrl);
if (!email && !avatarUrl) {
sendData(commands.AVATAR_ID, APP.settings.getAvatarId());
}
let nick = APP.settings.getDisplayName();
if (config.useNicks && !nick) {
nick = APP.UI.askForNickname();
APP.settings.setDisplayName(nick);
}
nick && room.setDisplayName(nick);
}
/**
* Get user nickname by user id.
* @param {string} id user id
@@ -249,11 +195,10 @@ function muteLocalVideo (muted) {
function maybeRedirectToWelcomePage(options) {
// if close page is enabled redirect to it, without further action
if (config.enableClosePage) {
// save whether current user is guest or not, before navigating
// to close page
window.sessionStorage.setItem('guest', APP.tokenData.isGuest);
assignWindowLocationPathname(
options.feedbackSubmitted ? "close.html" : "close2.html");
if (options.feedbackSubmitted)
window.location.pathname = "close.html";
else
window.location.pathname = "close2.html";
return;
}
@@ -266,42 +211,11 @@ function maybeRedirectToWelcomePage(options) {
if (config.enableWelcomePage) {
setTimeout(() => {
APP.settings.setWelcomePageEnabled(true);
assignWindowLocationPathname('./');
window.location.pathname = "/";
}, 3000);
}
}
/**
* Assigns a specific pathname to window.location.pathname taking into account
* the context root of the Web app.
*
* @param {string} pathname - The pathname to assign to
* window.location.pathname. If the specified pathname is relative, the context
* root of the Web app will be prepended to the specified pathname before
* assigning it to window.location.pathname.
* @return {void}
*/
function assignWindowLocationPathname(pathname) {
const windowLocation = window.location;
if (!pathname.startsWith('/')) {
// XXX To support a deployment in a sub-directory, assume that the room
// (name) is the last non-directory component of the path (name).
let contextRoot = windowLocation.pathname;
contextRoot
= contextRoot.substring(0, contextRoot.lastIndexOf('/') + 1);
// A pathname equal to ./ specifies the current directory. It will be
// fine but pointless to include it because contextRoot is the current
// directory.
pathname.startsWith('./') && (pathname = pathname.substring(2));
pathname = contextRoot + pathname;
}
windowLocation.pathname = pathname;
}
/**
* Create local tracks of specified types.
* @param {Object} options
@@ -346,6 +260,22 @@ function createLocalTracks (options, checkForPermissionPrompt) {
'failed to create local tracks', options.devices, err);
return Promise.reject(err);
});
}
/**
* Changes the email for the local user
* @param email {string} the new email
*/
function changeLocalEmail(email = '') {
email = email.trim();
if (email === APP.settings.getEmail()) {
return;
}
APP.settings.setEmail(email);
APP.UI.setUserEmail(room.myUserId(), email);
sendData(commands.EMAIL, email);
}
/**
@@ -383,7 +313,6 @@ class ConferenceConnector {
this._reject(err);
}
_onConferenceFailed(err, ...params) {
APP.store.dispatch(conferenceFailed(room, err, ...params));
logger.error('CONFERENCE FAILED:', err, ...params);
APP.UI.hideRingOverLay();
switch (err) {
@@ -402,7 +331,7 @@ class ConferenceConnector {
case ConferenceErrors.NOT_ALLOWED_ERROR:
{
// let's show some auth not allowed page
assignWindowLocationPathname('authError.html');
window.location.pathname = "authError.html";
}
break;
@@ -458,6 +387,8 @@ class ConferenceConnector {
// the app. Both the errors above are unrecoverable from the library
// perspective.
room.leave().then(() => connection.disconnect());
APP.UI.showPageReloadOverlay(
false /* not a network type of failure */, err);
break;
case ConferenceErrors.CONFERENCE_MAX_USERS:
@@ -465,7 +396,7 @@ class ConferenceConnector {
APP.UI.notifyMaxUsersLimitReached();
break;
case ConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
reload();
window.location.reload();
break;
default:
this._handleConferenceFailed(err, ...params);
@@ -514,23 +445,6 @@ function disconnect() {
return Promise.resolve();
}
/**
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
*
* @param {JitsiMeetJS.connection.error} error - The reported error.
* @returns {void}
* @private
*/
function _connectionFailedHandler(error) {
if (isFatalJitsiConnectionError(error)) {
APP.connection.removeEventListener(
ConnectionEvents.CONNECTION_FAILED,
_connectionFailedHandler);
if (room)
room.leave();
}
}
export default {
isModerator: false,
audioMuted: false,
@@ -583,19 +497,14 @@ export default {
return createInitialLocalTracksAndConnect(options.roomName);
}).then(([tracks, con]) => {
logger.log('initialized with %s local tracks', tracks.length);
con.addEventListener(
ConnectionEvents.CONNECTION_FAILED,
_connectionFailedHandler);
APP.connection = connection = con;
this._bindConnectionFailedHandler(con);
this._createRoom(tracks);
this.isDesktopSharingEnabled =
JitsiMeetJS.isDesktopSharingEnabled();
APP.remoteControl.init();
this._createRoom(tracks);
if (UIUtil.isButtonEnabled('contacts')
&& !interfaceConfig.filmStripOnly) {
if (UIUtil.isButtonEnabled('contacts'))
APP.UI.ContactList = new ContactList(room);
}
// if user didn't give access to mic or camera or doesn't have
// them at all, we disable corresponding toolbar buttons
@@ -628,6 +537,47 @@ export default {
isLocalId (id) {
return this.getMyUserId() === id;
},
/**
* Binds a handler that will handle the case when the connection is dropped
* in the middle of the conference.
* @param {JitsiConnection} connection the connection to which the handler
* will be bound to.
* @private
*/
_bindConnectionFailedHandler (connection) {
const handler = function (error, errMsg) {
/* eslint-disable no-case-declarations */
switch (error) {
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
case ConnectionErrors.OTHER_ERROR:
case ConnectionErrors.SERVER_ERROR:
logger.error("XMPP connection error: " + errMsg);
// From all of the cases above only CONNECTION_DROPPED_ERROR
// is considered a network type of failure
const isNetworkFailure
= error === ConnectionErrors.CONNECTION_DROPPED_ERROR;
APP.UI.showPageReloadOverlay(
isNetworkFailure,
"xmpp-conn-dropped:" + errMsg);
connection.removeEventListener(
ConnectionEvents.CONNECTION_FAILED, handler);
// FIXME it feels like the conference should be stopped
// by lib-jitsi-meet
if (room)
room.leave();
break;
}
/* eslint-enable no-case-declarations */
};
connection.addEventListener(
ConnectionEvents.CONNECTION_FAILED, handler);
},
/**
* Simulates toolbar button click for audio mute. Used by shortcuts and API.
* @param mute true for mute and false for unmute.
@@ -702,7 +652,7 @@ export default {
* false.
*/
isCallstatsEnabled () {
return room && room.isCallstatsEnabled();
return room.isCallstatsEnabled();
},
/**
* Sends the given feedback through CallStats if enabled.
@@ -913,7 +863,21 @@ export default {
this.invite = new Invite(room);
this._room = room; // FIXME do not use this
_setupLocalParticipantProperties();
let email = APP.settings.getEmail();
email && sendData(this.commands.defaults.EMAIL, email);
let avatarUrl = APP.settings.getAvatarUrl();
avatarUrl && sendData(this.commands.defaults.AVATAR_URL,
avatarUrl);
!email && sendData(
this.commands.defaults.AVATAR_ID, APP.settings.getAvatarId());
let nick = APP.settings.getDisplayName();
if (config.useNicks && !nick) {
nick = APP.UI.askForNickname();
APP.settings.setDisplayName(nick);
}
nick && room.setDisplayName(nick);
this._setupListeners();
},
@@ -948,40 +912,43 @@ export default {
return options;
},
/**
* Start using provided video stream.
* Stops previous video stream.
* @param {JitsiLocalTrack} [stream] new stream to use or null
* @returns {Promise}
*/
useVideoStream (stream) {
let promise = Promise.resolve();
if (localVideo) {
// this calls room.removeTrack internally
// so we don't need to remove it manually
promise = localVideo.dispose();
}
localVideo = stream;
/**
* Start using provided video stream.
* Stops previous video stream.
* @param {JitsiLocalTrack} [stream] new stream to use or null
* @returns {Promise}
*/
useVideoStream (newStream) {
return room.replaceTrack(localVideo, newStream)
.then(() => {
// We call dispose after doing the replace because
// dispose will try and do a new o/a after the
// track removes itself. Doing it after means
// the JitsiLocalTrack::conference member is already
// cleared, so it won't try and do the o/a
if (localVideo) {
localVideo.dispose();
}
localVideo = newStream;
if (newStream) {
this.videoMuted = newStream.isMuted();
this.isSharingScreen = newStream.videoType === 'desktop';
return promise.then(function () {
if (stream) {
return room.addTrack(stream);
}
}).then(() => {
if (stream) {
this.videoMuted = stream.isMuted();
this.isSharingScreen = stream.videoType === 'desktop';
APP.UI.addLocalStream(newStream);
APP.UI.addLocalStream(stream);
newStream.videoType === 'camera'
&& APP.UI.setCameraButtonEnabled(true);
} else {
this.videoMuted = false;
this.isSharingScreen = false;
}
APP.UI.setVideoMuted(this.getMyUserId(), this.videoMuted);
APP.UI.updateDesktopSharingButtons();
});
stream.videoType === 'camera'
&& APP.UI.setCameraButtonEnabled(true);
} else {
this.videoMuted = false;
this.isSharingScreen = false;
}
APP.UI.setVideoMuted(this.getMyUserId(), this.videoMuted);
APP.UI.updateDesktopSharingButtons();
});
},
/**
@@ -990,27 +957,31 @@ export default {
* @param {JitsiLocalTrack} [stream] new stream to use or null
* @returns {Promise}
*/
useAudioStream (newStream) {
return room.replaceTrack(localAudio, newStream)
.then(() => {
// We call dispose after doing the replace because
// dispose will try and do a new o/a after the
// track removes itself. Doing it after means
// the JitsiLocalTrack::conference member is already
// cleared, so it won't try and do the o/a
if (localAudio) {
localAudio.dispose();
}
localAudio = newStream;
if (newStream) {
this.audioMuted = newStream.isMuted();
APP.UI.addLocalStream(newStream);
} else {
this.audioMuted = false;
}
APP.UI.setMicrophoneButtonEnabled(true);
APP.UI.setAudioMuted(this.getMyUserId(), this.audioMuted);
});
useAudioStream (stream) {
let promise = Promise.resolve();
if (localAudio) {
// this calls room.removeTrack internally
// so we don't need to remove it manually
promise = localAudio.dispose();
}
localAudio = stream;
return promise.then(function () {
if (stream) {
return room.addTrack(stream);
}
}).then(() => {
if (stream) {
this.audioMuted = stream.isMuted();
APP.UI.addLocalStream(stream);
} else {
this.audioMuted = false;
}
APP.UI.setMicrophoneButtonEnabled(true);
APP.UI.setAudioMuted(this.getMyUserId(), this.audioMuted);
});
},
videoSwitchInProgress: false,
@@ -1028,7 +999,7 @@ export default {
let externalInstallation = false;
if (shareScreen) {
this.screenSharingPromise = createLocalTracks({
createLocalTracks({
devices: ['desktop'],
desktopSharingExtensionExternalInstallation: {
interval: 500,
@@ -1117,10 +1088,7 @@ export default {
dialogTitleKey, dialogTxt, false);
});
} else {
APP.remoteControl.receiver.stop();
this.screenSharingPromise = createLocalTracks(
{ devices: ['video'] })
.then(
createLocalTracks({ devices: ['video'] }).then(
([stream]) => this.useVideoStream(stream)
).then(() => {
this.videoSwitchInProgress = false;
@@ -1140,17 +1108,11 @@ export default {
_setupListeners () {
// add local streams when joined to the conference
room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
APP.store.dispatch(conferenceJoined(room));
APP.UI.mucJoined();
APP.API.notifyConferenceJoined(APP.conference.roomName);
APP.UI.markVideoInterrupted(false);
});
room.on(
ConferenceEvents.CONFERENCE_LEFT,
(...args) => APP.store.dispatch(conferenceLeft(room, ...args)));
room.on(
ConferenceEvents.AUTH_STATUS_CHANGED,
function (authEnabled, authLogin) {
@@ -1158,18 +1120,10 @@ export default {
}
);
room.on(ConferenceEvents.PARTCIPANT_FEATURES_CHANGED,
user => APP.UI.onUserFeaturesChanged(user));
room.on(ConferenceEvents.USER_JOINED, (id, user) => {
if (user.isHidden())
return;
APP.store.dispatch(participantJoined({
id,
name: user.getDisplayName(),
role: user.getRole()
}));
logger.log('USER %s connnected', id, user);
APP.API.notifyUserJoined(id);
APP.UI.addUser(user);
@@ -1178,7 +1132,6 @@ export default {
APP.UI.updateUserRole(user);
});
room.on(ConferenceEvents.USER_LEFT, (id, user) => {
APP.store.dispatch(participantLeft(id, user));
logger.log('USER %s LEFT', id, user);
APP.API.notifyUserLeft(id);
APP.UI.removeUser(id, user.getDisplayName());
@@ -1187,7 +1140,6 @@ export default {
room.on(ConferenceEvents.USER_ROLE_CHANGED, (id, role) => {
APP.store.dispatch(participantRoleChanged(id, role));
if (this.isLocalId(id)) {
logger.info(`My role changed, new role: ${role}`);
if (this.isModerator !== room.isModerator()) {
@@ -1255,8 +1207,7 @@ export default {
room.on(ConferenceEvents.TALK_WHILE_MUTED, () => {
APP.UI.showToolbar(6000);
APP.UI.showCustomToolbarPopup('#talkWhileMutedPopup', true, 5000);
UIUtil.animateShowElement($("#talkWhileMutedPopup"), true, 5000);
});
/*
@@ -1304,57 +1255,6 @@ export default {
APP.API.notifyReceivedChatMessage(id, nick, text, ts);
APP.UI.addMessage(id, nick, text, ts);
});
APP.UI.addListener(UIEvents.MESSAGE_CREATED, (message) => {
APP.API.notifySendingChatMessage(message);
room.sendTextMessage(message);
});
APP.UI.addListener(UIEvents.SELECTED_ENDPOINT, (id) => {
try {
// do not try to select participant if there is none (we
// are alone in the room), otherwise an error will be
// thrown cause reporting mechanism is not available
// (datachannels currently)
if (room.getParticipants().length === 0)
return;
room.selectParticipant(id);
} catch (e) {
JitsiMeetJS.analytics.sendEvent(
'selectParticipant.failed');
reportError(e);
}
});
APP.UI.addListener(UIEvents.PINNED_ENDPOINT,
(smallVideo, isPinned) => {
let smallVideoId = smallVideo.getId();
let isLocal = APP.conference.isLocalId(smallVideoId);
let eventName
= (isPinned ? "pinned" : "unpinned") + "." +
(isLocal ? "local" : "remote");
let participantCount = room.getParticipantCount();
JitsiMeetJS.analytics.sendEvent(
eventName,
{ value: participantCount });
// FIXME why VIDEO_CONTAINER_TYPE instead of checking if
// the participant is on the large video ?
if (smallVideo.getVideoType() === VIDEO_CONTAINER_TYPE
&& !isLocal) {
// When the library starts supporting multiple pins we
// would pass the isPinned parameter together with the
// identifier, but currently we send null to indicate that
// we unpin the last pinned.
try {
room.pinParticipant(isPinned ? smallVideoId : null);
} catch (e) {
reportError(e);
}
}
});
}
room.on(ConferenceEvents.CONNECTION_INTERRUPTED, () => {
@@ -1391,7 +1291,6 @@ export default {
});
room.on(ConferenceEvents.SUSPEND_DETECTED, () => {
APP.store.dispatch(suspendDetected());
// After wake up, we will be in a state where conference is left
// there will be dialog shown to user.
// We do not want video/audio as we show an overlay and after it
@@ -1405,13 +1304,14 @@ export default {
this.deviceChangeListener);
// stop local video
if (localVideo) {
if (localVideo)
localVideo.dispose();
}
// stop local audio
if (localAudio) {
if (localAudio)
localAudio.dispose();
}
// show overlay
APP.UI.showSuspendedOverlay();
});
room.on(ConferenceEvents.DTMF_SUPPORT_CHANGED, (isDTMFSupported) => {
@@ -1432,6 +1332,13 @@ export default {
APP.UI.addListener(UIEvents.AUDIO_MUTED, muteLocalAudio);
APP.UI.addListener(UIEvents.VIDEO_MUTED, muteLocalVideo);
if (!interfaceConfig.filmStripOnly) {
APP.UI.addListener(UIEvents.MESSAGE_CREATED, (message) => {
APP.API.notifySendingChatMessage(message);
room.sendTextMessage(message);
});
}
room.on(ConnectionQualityEvents.LOCAL_STATS_UPDATED,
(stats) => {
APP.UI.updateLocalStats(stats.connectionQuality, stats);
@@ -1447,24 +1354,19 @@ export default {
APP.UI.initEtherpad(value);
});
APP.UI.addListener(UIEvents.EMAIL_CHANGED, this.changeLocalEmail);
APP.UI.addListener(UIEvents.EMAIL_CHANGED, changeLocalEmail);
room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => {
APP.store.dispatch(changeParticipantEmail(from, data.value));
APP.UI.setUserEmail(from, data.value);
});
room.addCommandListener(
this.commands.defaults.AVATAR_URL,
(data, from) => {
APP.store.dispatch(
changeParticipantAvatarURL(from, data.value));
APP.UI.setUserAvatarUrl(from, data.value);
});
room.addCommandListener(this.commands.defaults.AVATAR_ID,
(data, from) => {
APP.store.dispatch(
changeParticipantAvatarID(from, data.value));
APP.UI.setUserAvatarID(from, data.value);
});
@@ -1504,7 +1406,7 @@ export default {
APP.UI.addListener(UIEvents.LOGOUT, () => {
AuthHandler.logout(room).then(url => {
if (url) {
UIUtil.redirect(url);
window.location.href = url;
} else {
this.hangup(true);
}
@@ -1559,6 +1461,50 @@ export default {
AuthHandler.authenticate(room);
});
APP.UI.addListener(UIEvents.SELECTED_ENDPOINT, (id) => {
try {
// do not try to select participant if there is none (we are
// alone in the room), otherwise an error will be thrown cause
// reporting mechanism is not available (datachannels currently)
if (room.getParticipants().length === 0)
return;
room.selectParticipant(id);
} catch (e) {
JitsiMeetJS.analytics.sendEvent('selectParticipant.failed');
reportError(e);
}
});
APP.UI.addListener(UIEvents.PINNED_ENDPOINT, (smallVideo, isPinned) => {
let smallVideoId = smallVideo.getId();
let isLocal = APP.conference.isLocalId(smallVideoId);
let eventName
= (isPinned ? "pinned" : "unpinned") + "." +
(isLocal ? "local" : "remote");
let participantCount = room.getParticipantCount();
JitsiMeetJS.analytics.sendEvent(
eventName,
{ value: participantCount });
// FIXME why VIDEO_CONTAINER_TYPE instead of checking if
// the participant is on the large video ?
if (smallVideo.getVideoType() === VIDEO_CONTAINER_TYPE
&& !isLocal) {
// When the library starts supporting multiple pins we would
// pass the isPinned parameter together with the identifier,
// but currently we send null to indicate that we unpin the
// last pinned.
try {
room.pinParticipant(isPinned ? smallVideoId : null);
} catch (e) {
reportError(e);
}
}
});
APP.UI.addListener(
UIEvents.VIDEO_DEVICE_CHANGED,
(cameraDeviceId) => {
@@ -1670,23 +1616,12 @@ export default {
},
/**
* Adds any room listener.
* @param {string} eventName one of the ConferenceEvents
* @param {Function} listener the function to be called when the event
* occurs
* @param eventName one of the ConferenceEvents
* @param callBack the function to be called when the event occurs
*/
addConferenceListener(eventName, listener) {
room.on(eventName, listener);
addConferenceListener(eventName, callBack) {
room.on(eventName, callBack);
},
/**
* Removes any room listener.
* @param {string} eventName one of the ConferenceEvents
* @param {Function} listener the listener to be removed.
*/
removeConferenceListener(eventName, listener) {
room.off(eventName, listener);
},
/**
* Inits list of current devices and event listener for device change.
* @private
@@ -1844,7 +1779,6 @@ export default {
* requested
*/
hangup (requestFeedback = false) {
eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
APP.UI.hideRingOverLay();
let requestFeedbackPromise = requestFeedback
? APP.UI.requestFeedbackOnHangup()
@@ -1863,70 +1797,5 @@ export default {
APP.API.notifyReadyToClose();
maybeRedirectToWelcomePage(values[0]);
});
},
/**
* Changes the email for the local user
* @param email {string} the new email
*/
changeLocalEmail(email = '') {
email = email.trim();
if (email === APP.settings.getEmail()) {
return;
}
APP.store.dispatch(changeParticipantEmail(room.myUserId(), email));
APP.settings.setEmail(email);
APP.UI.setUserEmail(room.myUserId(), email);
sendData(commands.EMAIL, email);
},
/**
* Changes the avatar url for the local user
* @param url {string} the new url
*/
changeLocalAvatarUrl(url = '') {
url = url.trim();
if (url === APP.settings.getAvatarUrl()) {
return;
}
APP.store.dispatch(changeParticipantAvatarURL(room.myUserId(), url));
APP.settings.setAvatarUrl(url);
APP.UI.setUserAvatarUrl(room.myUserId(), url);
sendData(commands.AVATAR_URL, url);
},
/**
* Sends a message via the data channel.
* @param {string} to the id of the endpoint that should receive the
* message. If "" - the message will be sent to all participants.
* @param {object} payload the payload of the message.
* @throws NetworkError or InvalidStateError or Error if the operation
* fails.
*/
sendEndpointMessage (to, payload) {
room.sendEndpointMessage(to, payload);
},
/**
* Adds new listener.
* @param {String} eventName the name of the event
* @param {Function} listener the listener.
*/
addListener (eventName, listener) {
eventEmitter.addListener(eventName, listener);
},
/**
* Removes listener.
* @param {String} eventName the name of the event that triggers the
* listener
* @param {Function} listener the listener.
*/
removeListener (eventName, listener) {
eventEmitter.removeListener(eventName, listener);
}
};

View File

@@ -20,10 +20,10 @@ var config = { // eslint-disable-line no-unused-vars
//focusUserJid: 'focus@auth.jitsi-meet.example.com', // The real JID of focus participant - can be overridden here
//defaultSipNumber: '', // Default SIP number
// Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
desktopSharingChromeMethod: 'ext',
// The ID of the jidesha extension for Chrome.
desktopSharingChromeExtId: null,
// Whether desktop sharing should be disabled on Chrome.
desktopSharingChromeDisabled: true,
desktopSharingChromeExtId: 'diibjkoicjeejcmhdnailmkgecihlobk',
// The media sources to use when using screen sharing with the Chrome
// extension.
desktopSharingChromeSources: ['screen', 'window', 'tab'],
@@ -40,7 +40,7 @@ var config = { // eslint-disable-line no-unused-vars
// up to and including 41. On Firefox 42 and higher, we will run without the
// extension.
// If set to -1, an extension will be required for all versions of Firefox.
desktopSharingFirefoxMaxVersionExtRequired: 51,
desktopSharingFirefoxMaxVersionExtRequired: -1,
// The URL to the Firefox extension for desktop sharing.
desktopSharingFirefoxExtensionURL: null,
@@ -53,6 +53,8 @@ var config = { // eslint-disable-line no-unused-vars
disableStats: false,
disableAudioLevels: false,
channelLastN: -1, // The default value of the channel attribute last-n.
adaptiveLastN: false,
//disableAdaptiveSimulcast: false,
enableRecording: false,
enableWelcomePage: true,
//enableClosePage: false, // enabling the close page will ignore the welcome
@@ -74,11 +76,15 @@ var config = { // eslint-disable-line no-unused-vars
// If true - all users without token will be considered guests and all users
// with token will be considered non-guests. Only guests will be allowed to
// edit their profile.
enableUserRolesBasedOnToken: false,
// Suspending video might cause problems with audio playback. Disabling until these are fixed.
disableSuspendVideo: true,
// disables or enables RTX (RFC 4588) (defaults to false).
disableRtx: false,
// Sets the preferred resolution (height) for local video. Defaults to 360.
resolution: 720
enableUserRolesBasedOnToken: false
};
// Logging configuration
var loggingConfig = { // eslint-disable-line no-unused-vars
//default log level for the app and lib-jitsi-meet
defaultLogLevel: 'trace',
// Option to disable LogCollector (which stores the logs on CallStats)
//disableLogCollector: true,
// Logging level adjustments for verbose modules:
'modules/xmpp/strophe.util.js': 'log'
};

View File

@@ -4,14 +4,6 @@ const logger = require("jitsi-meet-logger").getLogger(__filename);
import AuthHandler from './modules/UI/authentication/AuthHandler';
import jitsiLocalStorage from './modules/util/JitsiLocalStorage';
import {
connectionEstablished,
connectionFailed
} from './react/features/base/connection';
import {
isFatalJitsiConnectionError
} from './react/features/base/lib-jitsi-meet';
const ConnectionEvents = JitsiMeetJS.events.connection;
const ConnectionErrors = JitsiMeetJS.errors.connection;
@@ -75,18 +67,6 @@ function connect(id, password, roomName) {
connection.addEventListener(
ConnectionEvents.CONNECTION_FAILED, handleConnectionFailed
);
connection.addEventListener(
ConnectionEvents.CONNECTION_FAILED, connectionFailedHandler);
function connectionFailedHandler(error, errMsg) {
APP.store.dispatch(connectionFailed(connection, error, errMsg));
if (isFatalJitsiConnectionError(error)) {
connection.removeEventListener(
ConnectionEvents.CONNECTION_FAILED,
connectionFailedHandler);
}
}
function unsubscribe() {
connection.removeEventListener(
@@ -100,7 +80,6 @@ function connect(id, password, roomName) {
}
function handleConnectionEstablished() {
APP.store.dispatch(connectionEstablished(connection));
unsubscribe();
resolve(connection);
}

View File

@@ -3,25 +3,21 @@
user-select: none;
}
body {
margin: 0px;
width: 100%;
height: 100%;
html, body{
margin:0px;
height:100%;
color: $defaultColor;
font-size: 12px;
font-weight: 400;
background: #000000;
overflow: hidden;
color: $defaultColor;
background: $defaultBackground;
&.filmstrip-only {
background: transparent;
}
}
p {
margin: 0;
}
body, input, textarea, keygen, select, button {
html, body, input, textarea, keygen, select, button {
font-family: $baseFontFamily !important;
}
@@ -88,6 +84,7 @@ form {
}
.leftwatermark {
display: none;
left: $defaultToolbarSize;
margin-left: 10px;
background-image: url($defaultWatermarkLink);
@@ -95,11 +92,13 @@ form {
}
.rightwatermark {
display: none;
right: 15;
background-position: center right;
}
.poweredby {
display: none;
position: absolute;
left: 25;
bottom: 7;
@@ -126,7 +125,6 @@ form {
z-index: $tooltipsZ;
&-inner {
background-color: $tooltipBg;
max-width: 350px;
}
&-arrow {
@@ -144,4 +142,4 @@ form {
#inviteLinkRef {
-webkit-user-select: text;
user-select: text;
}
}

View File

@@ -50,17 +50,14 @@
position:relative;
height:196px;
padding: 0;
/*The filmstrip should not be covered by the left toolbar*/
padding-left: $defaultToolbarSize + 5;
padding-left: 17px;
bottom: 0;
width:auto;
border: $thumbnailsBorder solid transparent;
z-index: 5;
transition: bottom 2s;
overflow: visible !important;
/*!!!Removes the gap between the local video container and the remote
videos.*/
font-size: 0pt;
font-size: 0pt; /*!!!Removes the gap between the local video container and the remote videos.*/
&.hidden {
bottom: -196px;
@@ -71,7 +68,7 @@
position: relative;
background-size: contain;
border: $thumbnailVideoBorder solid transparent;
border-radius: $borderRadius;
border-radius:1px;
margin: 0 $thumbnailVideoMargin;
&.videoContainerFocused, &:hover {
@@ -92,7 +89,7 @@
0 0 3px $videoThumbnailSelected !important;
}
.remotevideomenu > .icon-menu {
.remotevideomenu {
display: none;
}
@@ -105,7 +102,7 @@
box-shadow: inset 0 0 3px $videoThumbnailHovered,
0 0 3px $videoThumbnailHovered;
.remotevideomenu > .icon-menu {
.remotevideomenu {
display: inline-block;
}
}
@@ -115,10 +112,10 @@
& > video,
& > object {
cursor: hand;
border-radius: $borderRadius;
border-radius:1px;
object-fit: cover;
overflow: hidden;
}
}
}
}
}

View File

@@ -25,9 +25,6 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-mic-camera-combined:before {
content: "\e903";
}
.icon-feedback:before {
content: "\e91d";
}
@@ -37,15 +34,15 @@
.icon-avatar:before {
content: "\e901";
}
.icon-autorenew:before {
content: "\e903";
}
.icon-hangup:before {
content: "\e905";
}
.icon-chat:before {
content: "\e906";
}
.icon-download:before {
content: "\e902";
}
.icon-edit:before {
content: "\e907";
}
@@ -58,6 +55,9 @@
.icon-kick:before {
content: "\e904";
}
.icon-menu:before {
content: "\e91f";
}
.icon-menu-up:before {
content: "\e91f";
}
@@ -70,6 +70,9 @@
.icon-exit-full-screen:before {
content: "\e90c";
}
.icon-star:before {
content: "\e916";
}
.icon-star-full:before {
content: "\e90a";
}
@@ -106,12 +109,6 @@
.icon-settings:before {
content: "\e915";
}
.icon-star:before {
content: "\e916";
}
.icon-switch-camera:before {
content: "\e921";
}
.icon-share-desktop:before {
content: "\e917";
}
@@ -136,6 +133,7 @@
.icon-recEnable:before {
content: "\e614";
}
// FIXME not used anymore - consider removing in the next font update
.icon-presentation:before {
content: "\e603";
}
}

View File

@@ -1,6 +1,6 @@
.inlay {
margin-top: 14%;
@include border-radius(4px);
@include border-radius(3px);
padding: 40px 38px 44px;
color: #fff;
background: $inlayColorBg;

View File

@@ -10,7 +10,7 @@
color: $popoverFontColor;
background-color: $popoverBg;
background-clip: padding-box;
border-radius: $borderRadius;
border-radius: 3px;
/*-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);*/
/*box-shadow: 0 5px 10px rgba(0, 0, 0, 0.4);*/
white-space: normal;

View File

@@ -1,18 +1,18 @@
@charset "UTF-8";
/*!
* jQuery contextMenu - Plugin for simple contextMenu handling
*
* Version: v2.1.1
*
* Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF)
* Web: http://swisnl.github.io/jQuery-contextMenu/
*
* Copyright (c) 2011-2016 SWIS BV and contributors
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
*
* Date: 2016-02-28T09:53:18.890Z
/*!
* jQuery contextMenu - Plugin for simple contextMenu handling
*
* Version: v2.1.1
*
* Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF)
* Web: http://swisnl.github.io/jQuery-contextMenu/
*
* Copyright (c) 2011-2016 SWIS BV and contributors
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
*
* Date: 2016-02-28T09:53:18.890Z
*/
@font-face {
font-family: "context-menu-icons";
@@ -88,7 +88,7 @@
list-style-type: none;
background: #fff;
border: 1px solid #bebebe;
border-radius: $borderRadius;
border-radius: 3px;
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
}
@@ -156,8 +156,8 @@
transform: translateY(-50%);
}
/**
* Inputs
/**
* Inputs
*/
.context-menu-item.context-menu-input {
padding: 5px 10px;

View File

@@ -1,10 +1,34 @@
/*Initialize*/
div.loginmenu {
ul.loginmenu {
font-family: $baseFontFamily;
line-height: normal;
display:none;
position: absolute;
margin: 0;
padding: 5px;
top: 40px;
left: 20px;
padding-bottom: 7px;
top: 45px;
left: -5px;
background-color: rgba(0,0,0,0.9);
border: 1px solid rgba(256, 256, 256, 0.2);
border-radius:8px;
}
ul.loginmenu li {
list-style-type: none;
padding: 7px;
color: #fff;
font-size: 11pt;
cursor: default;
white-space: pre;
}
ul.loginmenu:after {
content: url('../images/dropdownPointer.png');
display: block;
position: absolute;
top: -7px;
left: 18px;
}
a.disabled {
@@ -12,7 +36,23 @@ a.disabled {
pointer-events: none;
}
.loginmenuPadding {
width: 50px;
height: 30px;
position: absolute;
top: -30px;
left: 0px;
}
.loginmenu.extendedToolbarPopup {
top: 20px;
left: 40px;
left: 55px;
top: 0px;
}
ul.loginmenu.extendedToolbarPopup:after {
content: url('../images/leftDropdownPointer.png');
display: block;
position: absolute;
top: 18px;
left: -7px;
}

View File

@@ -2,52 +2,52 @@
* Animation mixin.
*/
@mixin animation($animate...) {
$max: length($animate);
$animations: '';
$max: length($animate);
$animations: '';
@for $i from 1 through $max {
$animations: #{$animations + nth($animate, $i)};
@for $i from 1 through $max {
$animations: #{$animations + nth($animate, $i)};
@if $i < $max {
$animations: #{$animations + ", "};
}
@if $i < $max {
$animations: #{$animations + ", "};
}
-webkit-animation: $animations;
-moz-animation: $animations;
-o-animation: $animations;
animation: $animations;
}
-webkit-animation: $animations;
-moz-animation: $animations;
-o-animation: $animations;
animation: $animations;
}
@mixin flex() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
/**
* Keyframes mixin.
*/
@mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} {
@content;
}
@-moz-keyframes #{$animationName} {
@content;
}
@-o-keyframes #{$animationName} {
@content;
}
@keyframes #{$animationName} {
@content;
}
@-webkit-keyframes #{$animationName} {
@content;
}
@-moz-keyframes #{$animationName} {
@content;
}
@-o-keyframes #{$animationName} {
@content;
}
@keyframes #{$animationName} {
@content;
}
}
@mixin circle($diameter) {
width: $diameter;
height: $diameter;
border-radius: 50%;
width: $diameter;
height: $diameter;
border-radius: 50%;
}
/**
@@ -60,10 +60,10 @@
}
@mixin absoluteAligning() {
top: 50%;
left: 50%;
position: absolute;
@include transform(translate(-50%, -50%));
top: 50%;
left: 50%;
position: absolute;
@include transform(translate(-50%, -50%));
}
/**
@@ -75,121 +75,79 @@
}
@mixin transform($func) {
-moz-transform: $func;
-ms-transform: $func;
-webkit-transform: $func;
-o-transform: $func;
transform: $func;
-moz-transform: $func;
-ms-transform: $func;
-webkit-transform: $func;
-o-transform: $func;
transform: $func;
}
@mixin transition($transition...) {
-moz-transition: $transition;
-o-transition: $transition;
-webkit-transition: $transition;
transition: $transition;
-moz-transition: $transition;
-o-transition: $transition;
-webkit-transition: $transition;
transition: $transition;
}
/**
* Mixin styling a placeholder.
**/
* Mixin styling placeholder
**/
@mixin placeholder() {
$selectors: (
"::-webkit-input-placeholder",
"::-moz-placeholder",
":-moz-placeholder",
":-ms-input-placeholder"
);
$selectors: (
"::-webkit-input-placeholder",
"::-moz-placeholder",
":-moz-placeholder",
":-ms-input-placeholder"
);
@each $selector in $selectors {
#{$selector} {
@content;
}
@each $selector in $selectors {
#{$selector} {
@content;
}
}
/**
* Mixin styling a slider track for different browsers.
**/
@mixin slider() {
$selectors: (
"input[type=range]::-webkit-slider-runnable-track",
"input[type=range]::-moz-range-track",
"input[type=range]::-ms-track"
);
@each $selector in $selectors {
#{$selector} {
@content;
}
}
}
/**
* Mixin styling a slider thumb for different browsers.
**/
@mixin slider-thumb() {
$selectors: (
"input[type=range]::-webkit-slider-thumb",
"input[type=range]::-moz-range-thumb",
"input[type=range]::-ms-thumb"
);
@each $selector in $selectors {
#{$selector} {
@content;
}
}
}
@mixin box-shadow($h, $y, $blur, $color, $inset: false) {
@if $inset {
-webkit-box-shadow: inset $h $y $blur $color;
-moz-box-shadow: inset $h $y $blur $color;
box-shadow: inset $h $y $blur $color;
} @else {
-webkit-box-shadow: $h $y $blur $color;
-moz-box-shadow: $h $y $blur $color;
box-shadow: $h $y $blur $color;
}
@if $inset {
-webkit-box-shadow: inset $h $y $blur $color;
-moz-box-shadow: inset $h $y $blur $color;
box-shadow: inset $h $y $blur $color;
} @else {
-webkit-box-shadow: $h $y $blur $color;
-moz-box-shadow: $h $y $blur $color;
box-shadow: $h $y $blur $color;
}
}
@mixin no-box-shadow {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
@mixin box-sizing($box-model) {
-webkit-box-sizing: $box-model; // Safari <= 5
-moz-box-sizing: $box-model; // Firefox <= 19
box-sizing: $box-model;
-webkit-box-sizing: $box-model; // Safari <= 5
-moz-box-sizing: $box-model; // Firefox <= 19
box-sizing: $box-model;
}
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
border-radius: $radius;
/* stops bg color from leaking outside the border: */
background-clip: padding-box;
-webkit-border-radius: $radius;
border-radius: $radius;
/* stops bg color from leaking outside the border: */
background-clip: padding-box;
}
@mixin opacity($opacity) {
opacity: $opacity;
$opacity-ie: $opacity * 100;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=$opacity-ie);
filter: alpha(opacity=$opacity-ie); //IE8
opacity: $opacity;
$opacity-ie: $opacity * 100;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=$opacity-ie);
filter: alpha(opacity=$opacity-ie); //IE8
}
@mixin text-truncate {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/**
* Creates a semi-transparent background with the given color and alpha
* (opacity) value.
*/
@mixin transparentBg($color, $alpha) {
background-color: rgba(red($color), green($color), blue($color), $alpha);
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@@ -6,6 +6,7 @@
padding: 0;
margin: 2px 0;
bottom: 0;
width: 100px;
height: auto;
&:first-child {
@@ -23,8 +24,7 @@
}
// Link Appearance
&__link,
&__contents {
&__link {
display: block;
box-sizing: border-box;
text-decoration: none;
@@ -41,16 +41,11 @@
}
}
&__text,
&__slider {
&__text {
display: inline-block;
vertical-align: middle;
}
&__slider {
width: 50px;
}
&__icon {
vertical-align: middle;
position: relative;
@@ -71,9 +66,4 @@
span.remotevideomenu:hover ul.popupmenu, ul.popupmenu:hover {
display:block !important;
}
.remote-control-spinner {
top: 6px;
left: 2px;
}
}

View File

@@ -1,3 +1,10 @@
html, body {
width: 100%;
height:100%;
color: $defaultColor;
background: $defaultBackground;
}
.redirectPageMessage {
width: 30%;
margin: 20% auto;

View File

@@ -14,8 +14,8 @@ $defaultToolbarSize: 50px;
// Video layout.
$thumbnailToolbarHeight: 22px;
$thumbnailIndicatorBorder: 2px;
$thumbnailIndicatorSize: $thumbnailToolbarHeight;
$thumbnailIndicatorBorder: 0;
$thumbnailIndicatorSize: 3em;
$thumbnailVideoMargin: 2px;
$thumbnailsBorder: 2px;
$thumbnailVideoBorder: 2px;
@@ -43,14 +43,14 @@ $toolbarBadgeColor: #FFFFFF;
$toolbarToggleBackground: #12499C;
$splitterToolbarButtonMargin: 18px;
/**
/*
* Main controls
* TODO: looks like we don't use it
*/
$inputSemiBackground: rgba(132, 132, 132, .8);
$inputLightBackground: #EBEBEB;
/**
/*
* Video layout
*/
$videoThumbnailHovered: rgba(22, 94, 204, .4);
@@ -95,7 +95,7 @@ $notificationWidth: 215px;
/**
* Misc.
*/
$borderRadius: 4px;
$borderRadius: 3px;
$defaultWatermarkLink: '../images/watermark.png';
$sidebarWidth: 220px;
$popoverMenuPadding: 13px;
@@ -126,16 +126,4 @@ $defaultDarkFontColor: #000;
$inputControlEmColor: #f29424;
//buttons
$linkFontColor: #489afe;
$linkHoverFontColor: #287ade;
/**
* Unsupported browser
*/
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
$unsupportedBrowserButtonBgColor: #ff9a00;
$unsupportedBrowserTextColor: #4a4a4a;
$unsupportedBrowserTextSmallFontSize: 17px;
$unsupportedBrowserTitleColor: #fff;
$unsupportedBrowserTitleFontSize: 24px;
$unsupportedDesktopBrowserTextColor: rgba(255, 255, 255, 0.7);
$unsupportedDesktopBrowserTextFontSize: 21px;
$linkHoverFontColor: #287ade;

View File

@@ -18,10 +18,9 @@
&__background {
@include topLeft();
background-color: black;
border-radius: $borderRadius;
width: 100%;
height: 100%;
background-color: black;
}
/**
@@ -107,12 +106,11 @@
}
&__hoverOverlay {
background: rgba(0,0,0,.6);
border-radius: $borderRadius;
position: relative;
width: 100%;
height: 100%;
visibility: hidden;
background: rgba(0,0,0,.6);
z-index: 2;
}
}
@@ -130,8 +128,8 @@
#localVideoWrapper>video,
#localVideoWrapper>object {
border-radius: $borderRadius !important;
cursor: hand;
border-radius:1px !important;
object-fit: cover;
}
@@ -213,7 +211,6 @@
.videocontainer .displayname {
pointer-events: none;
padding: 0 3px 0 3px;
}
.videocontainer .editdisplayname {
@@ -474,7 +471,6 @@
#localConnectionMessage {
display: none;
position: absolute;
left: 0;
width: 100%;
top:50%;
z-index: 2;

View File

@@ -50,7 +50,7 @@
float: left;
}
.domain-name
#domain_name
{
float: left;
height: 55px;
@@ -61,51 +61,37 @@
color: $defaultDarkColor;
}
.enter-room {
&__field {
font-size: 15px;
border: none;
-webkit-appearance: none;
width: 228px;
height: 55px;
line-height: 55px;
font-weight: 500;
box-shadow: none;
float: left;
background-color: #FFFFFF;
position: relative;
z-index: 2;
}
#enter_room_field {
font-size: 15px;
border: none;
-webkit-appearance: none;
width: 228px;
height: 55px;
line-height: 55px;
font-weight: 500;
box-shadow: none;
float: left;
background-color: #FFFFFF;
position: relative;
z-index: 2;
}
&__reload {
display: block;
width: 30px;
color: #acacac;
font-size: 1.9em;
line-height: 55px;
z-index: 3;
float: left;
cursor: pointer;
text-align: center;
}
&__button {
width: 73px;
height: 45px;
background-color: #21B9FC;
moz-border-radius: 1px;
-webkit-border-radius: 1px;
color: #ffffff;
font-weight: 600;
border: none;
margin-top: 5px;
font-size: 19px;
padding-top: 6px;
outline: none;
float:left;
position: relative;
z-index: 2;
}
#enter_room_button {
width: 73px;
height: 45px;
background-color: #21B9FC;
moz-border-radius: 1px;
-webkit-border-radius: 1px;
color: #ffffff;
font-weight: 600;
border: none;
margin-top: 5px;
font-size: 19px;
padding-top: 6px;
outline: none;
float:left;
position: relative;
z-index: 2;
}
#enter_room_container {
@@ -198,3 +184,16 @@
line-height: 22px;
font-weight: 200;
}
#reload_roomname
{
width: 30px;
color: #acacac;
font-size: 1.9em;
line-height: 55px;
z-index: 3;
float: left;
cursor: pointer;
text-align: center;
display: none;
}

View File

@@ -82,8 +82,4 @@
color: $linkHoverFontColor;
}
}
&_center {
float: none !important;
}
}

View File

@@ -1,41 +0,0 @@
/**
* Disable the default webkit styles for range inputs (sliders).
*/
input[type=range]{
-webkit-appearance: none;
background: none;
}
/**
* Disable the default focus styles for webkit range inputs (sliders).
*/
input[type=range]:focus {
outline: none;
}
/**
* Include the mixin for a range input style.
*/
@include slider {
background: $sliderTrackBackground;
border: none;
border-radius: 3px;
cursor: pointer;
height: 6px;
width: 100%;
}
/**
* Include the mixin for a range input thumb style.
*/
@include slider-thumb {
-webkit-appearance: none;
background: white;
border: 1px solid $sliderThumbBackground;
border-radius: 50%;
box-shadow: 0px 0px 1px $sliderThumbBackground;
cursor: pointer;
height: 14px;
margin-top: -4px;
width: 14px;
}

View File

@@ -8,13 +8,4 @@
text-decoration: underline;
@include transition(color .1s ease-in);
}
}
/**
* Helper links are links that are meant to open a documentation page or more
* detailed info.
*/
.helper-link {
@extend .link;
font-size: 12px;
}

View File

@@ -60,14 +60,12 @@
@import 'components/link';
@import 'shortcuts/main';
@import 'components/button-control';
@import 'components/input-control';
@import 'components/input-slider';
@import 'components/_input-control.scss';
@import "modals/invite/invite";
@import "connection-info";
@import 'aui-components/dropdown';
@import '404';
@import 'policy';
@import 'filmstrip';
@import 'unsupported-browser/main';
/* Modules END */

View File

@@ -1,6 +1,5 @@
.overlay {
&__container,
&__container-light {
&__container {
top: 0;
left: 0;
width: 100%;
@@ -10,10 +9,6 @@
background: $defaultBackground;
}
&__container-light {
@include transparentBg($defaultBackground, 0.7);
}
&__content {
position: absolute;
margin: 0 auto;

View File

@@ -4,7 +4,7 @@
line-height: 20px;
}
.reload_overlay_text {
.reload_overlay_msg {
display: block;
font-size: 12px;
line-height: 30px;
@@ -13,4 +13,4 @@
#reloadProgressBar {
width: 180px;
margin: 5px auto;
}
}

View File

@@ -8,8 +8,6 @@ $baseLight: #FFFFFF;
*/
$controlBackground: $baseLight;
$controlColor: #333333;
$sliderTrackBackground: #474747;
$sliderThumbBackground: #3572b0;
/**
* Buttons

View File

@@ -1,3 +0,0 @@
@import 'no-mobile-app';
@import 'unsupported-desktop-browser';
@import 'unsupported-mobile-browser';

View File

@@ -1,21 +0,0 @@
.no-mobile-app {
margin: 30% auto 0;
max-width: 25em;
text-align: center;
width: auto;
&__title {
border-bottom: 1px solid $auiBorderColor;
color: $unsupportedBrowserTitleColor;
font-weight: 400;
letter-spacing: 0.5px;
padding-bottom: em(17, 24);
}
&__description {
font-size: $unsupportedBrowserTextSmallFontSize;
font-weight: 300;
letter-spacing: 1px;
margin-top: 1em;
}
}

View File

@@ -1,39 +0,0 @@
.unsupported-desktop-browser {
@include absoluteAligning();
display: block;
text-align: center;
&__title {
color: $unsupportedBrowserTitleColor;
font-weight: 300;
font-size: $unsupportedBrowserTitleFontSize;
letter-spacing: 1px;
}
&__description {
color: $unsupportedDesktopBrowserTextColor;
font-size: $unsupportedDesktopBrowserTextFontSize;
font-weight: 300;
letter-spacing: 1px;
margin-top: 16px;
&_small {
@extend .unsupported-desktop-browser__description;
font-size: $unsupportedBrowserTextSmallFontSize;
}
}
&__link {
color: $linkFontColor;
@include transition(color .1s ease-out);
&:hover {
color: $linkHoverFontColor;
cursor: pointer;
text-decoration: none;
@include transition(color .1s ease-in);
}
}
}

View File

@@ -1,69 +0,0 @@
.unsupported-mobile-browser {
background-color: #fff;
height: 100vh;
padding: 35px 0;
width: 100vw;
&__body {
color: $unsupportedBrowserTextColor;
margin: auto;
max-width: 40em;
text-align: center;
width: 75%;
a:active {
text-decoration: none;
}
}
&__text {
font-size: 1.8em;
line-height: em(29px, 21px);
margin-bottom: 0.65em;
&_small {
font-size: 1.5em;
margin-bottom: 1em;
margin-top: em(21, 18);
strong {
font-size: em(21, 18);
}
}
}
&__logo {
height: 108px;
width: 77px;
}
&__button {
border: 0;
height: 42px;
margin: 0 auto;
max-width: 300px;
width: 98%;
@include border-radius(8px);
background-color: $unsupportedBrowserButtonBgColor;
font-size: 1.5em;
font-weight: 300;
letter-spacing: 0.5px;
text-shadow: 0px 1px 2px $unsupportedBrowserTextColor;
// Disable standard button effects.
box-shadow: none;
outline: none;
&:active {
background-color: $unsupportedBrowserButtonBgColor;
}
&_primary {
background-color: $primaryUnsupportedBrowserButtonBgColor;
&:active {
background-color: $primaryUnsupportedBrowserButtonBgColor;
}
}
}
}

View File

@@ -0,0 +1,138 @@
@import 'variables';
body {
width:100%;
height:100%;
background-color: white;
color: #424242;
font-family: $baseFontFamily;
font-size: 28px;
margin:0;
padding:0;
}
#wrap{
display: block;
position: absolute;
width:500px;
height: 565px;
overflow:hidden;
text-align: center;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;
}
.firefox{
font-size: 11pt;
color: #c8c8c8;
width: 468px;
text-align: center;
margin: 30px auto 0px auto;
padding-left: 15px;
}
#text{
display:inline-block;
font-size: 28px;
/* width: 568px; */
vertical-align:middle;
padding-top: 25px;
}
a {
color: #087dba;
text-decoration:none;
}
.browser {
width: 138px;
height: 163px;
margin-top: 5px;
background-color: #e8e8e8;
border: 1px solid #cfcfcf;
border-radius: 10px;
}
.browser_wrapper
{
width: 138px;
/* height: 188px; */
vertical-align: middle;
color: #929391;
font-size: 20px;
float: left;
margin-left: 15px;
margin-top: 5px;
}
.browser_text
{
height: 2em;
}
.supported_browsers
{
margin: 0px auto 0px auto;
/* width: 660px; */
}
.clear
{
clear: both;
}
.button
{
background-color: #62c82a;
border: 1px solid #3c8117;
border-radius: 10px;
color: #FFFFFF;
font-size: 12px;
text-align: center;
width: 115px;
height: 26px;
padding-top: 13px;
margin: 15px auto 0px auto;
}
.logo
{
margin: 20px auto 0px auto;
}
#chrome_logo
{
width: 78px;
height: 78px;
background-image: url('../images/chrome.png');
}
#chromium_logo
{
width: 77px;
height: 78px;
background-image: url('../images/chromium.png');
}
#firefox_logo
{
width: 86px;
height: 80px;
background-image: url('../images/firefox.png');
}
#opera_logo
{
width: 73px;
height: 78px;
background-image: url('../images/opera.png');
}
#safari_logo
{
width: 78px;
height: 79px;
background-image: url('../images/safari.png');
}
#ie_logo
{
width: 80px;
height: 78px;
background-image: url('../images/ie.png');
}

5
debian/control vendored
View File

@@ -21,7 +21,8 @@ Description: WebRTC JavaScript video conferences
Package: jitsi-meet-web-config
Architecture: all
Depends: openssl, openjdk-8-jre-headless | nginx | apache2
Depends: openssl, openjdk-8-jre-headless | nginx | apache2,
jitsi-meet-web
Description: Configuration for web serving of Jitsi Meet
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
Videobridge to provide high quality, scalable video conferences.
@@ -36,7 +37,7 @@ Description: Configuration for web serving of Jitsi Meet
Package: jitsi-meet-prosody
Architecture: all
Depends: openssl, prosody | prosody-trunk
Depends: openssl, prosody | prosody-trunk, jitsi-meet-web
Description: Prosody configuration for Jitsi Meet
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
Videobridge to provide high quality, scalable video conferences.

View File

@@ -1 +1 @@
resources/prosody-plugins/ /usr/share/jitsi-meet/
prosody-plugins/ /usr/share/jitsi-meet/

View File

@@ -1,4 +0,0 @@
doc/debian/jitsi-meet/jitsi-meet.example
doc/debian/jitsi-meet/jitsi-meet.example-apache
doc/debian/jitsi-meet/README
config.js

View File

@@ -94,7 +94,7 @@ case "$1" in
# jitsi meet
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
if [ ! -f $JITSI_MEET_CONFIG ] ; then
cp /usr/share/doc/jitsi-meet-web-config/config.js $JITSI_MEET_CONFIG
cp /usr/share/doc/jitsi-meet-web/config.js $JITSI_MEET_CONFIG
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $JITSI_MEET_CONFIG
fi
@@ -127,7 +127,6 @@ case "$1" in
echo "org.jitsi.videobridge.rest.jetty.ResourceHandler.resourceBase=/usr/share/jitsi-meet" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ResourceHandler.alias./config.js=/etc/jitsi/meet/$JVB_HOSTNAME-config.js" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ResourceHandler.alias./interface_config.js=/usr/share/jitsi-meet/interface_config.js" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.ResourceHandler.alias./logging_config.js=/usr/share/jitsi-meet/logging_config.js" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.RewriteHandler.regex=^/([a-zA-Z0-9]+)$" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.RewriteHandler.replacement=/" >> $JVB_CONFIG
echo "org.jitsi.videobridge.rest.jetty.SSIResourceHandler.paths=/" >> $JVB_CONFIG
@@ -172,7 +171,7 @@ case "$1" in
# nginx conf
if [ ! -f /etc/nginx/sites-available/$JVB_HOSTNAME.conf ] ; then
cp /usr/share/doc/jitsi-meet-web-config/jitsi-meet.example /etc/nginx/sites-available/$JVB_HOSTNAME.conf
cp /usr/share/doc/jitsi-meet-web/jitsi-meet.example /etc/nginx/sites-available/$JVB_HOSTNAME.conf
if [ ! -f /etc/nginx/sites-enabled/$JVB_HOSTNAME.conf ] ; then
ln -s /etc/nginx/sites-available/$JVB_HOSTNAME.conf /etc/nginx/sites-enabled/$JVB_HOSTNAME.conf
fi
@@ -203,7 +202,7 @@ case "$1" in
if [ ! -f /etc/apache2/sites-available/$JVB_HOSTNAME.conf ] ; then
# when creating new config, make sure all needed modules are enabled
a2enmod rewrite ssl headers proxy_http include
cp /usr/share/doc/jitsi-meet-web-config/jitsi-meet.example-apache /etc/apache2/sites-available/$JVB_HOSTNAME.conf
cp /usr/share/doc/jitsi-meet-web/jitsi-meet.example-apache /etc/apache2/sites-available/$JVB_HOSTNAME.conf
a2ensite $JVB_HOSTNAME.conf
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" /etc/apache2/sites-available/$JVB_HOSTNAME.conf
fi

View File

@@ -1 +1,5 @@
README.md
doc/debian/jitsi-meet/jitsi-meet.example
doc/debian/jitsi-meet/jitsi-meet.example-apache
doc/debian/jitsi-meet/README
config.js

View File

@@ -4,6 +4,7 @@
*.ico /usr/share/jitsi-meet/
libs /usr/share/jitsi-meet/
css/all.css /usr/share/jitsi-meet/css/
css/unsupported_browser.css /usr/share/jitsi-meet/css/
sounds /usr/share/jitsi-meet/
fonts /usr/share/jitsi-meet/
images /usr/share/jitsi-meet/

View File

@@ -1,17 +1,17 @@
# Jitsi Meet API
Jitsi Meet API
============
You can use the Jitsi Meet API to embed Jitsi Meet in to your application.
You can use Jitsi Meet API to embed Jitsi Meet in to your application.
## Installation
To embed Jitsi Meet in your application you need to add the Jitsi Meet API library:
Installation
==========
To embed Jitsi Meet in your application you need to add Jitsi Meet API library
```javascript
<script src="https://meet.jit.si/external_api.js"></script>
```
The next step for embedding Jitsi Meet is to create the Jitsi Meet API object:
The next step for embedding Jitsi Meet is to create the Jitsi Meet API object
```javascript
<script>
var domain = "meet.jit.si";
@@ -21,174 +21,161 @@ The next step for embedding Jitsi Meet is to create the Jitsi Meet API object:
var api = new JitsiMeetExternalAPI(domain, room, width, height);
</script>
```
You can use the above lines to indicate where exactly you want the Jitsi Meet conference to be placed in your HTML code,
or you can specify the parent HTML element for the Jitsi Meet conference in the `JitsiMeetExternalAPI`
constructor:
You can paste that lines in your html code where you want to be placed the Jitsi Meet conference
or you can specify the parent HTML element for the Jitsi Meet conference in the JitsiMeetExternalAPI
constructor.
```javascript
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
```
If you don't specify room the user will enter in new conference with random room name.
You can overwrite options set in config.js and interface_config.js. For example, to enable the film-strip-only interface mode and disable simulcast, you can use:
```javascript
var configOverwrite = {enableSimulcast: false};
var interfaceConfigOverwrite = {filmStripOnly: true};
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite);
```
If you don't specify the room the user will enter in new conference with a random room name.
Controlling embedded Jitsi Meet Conference
=========
You can overwrite options set in [config.js]() and [interface_config.js](). For example, to enable the film-strip-only interface mode and disable simulcast, you can use:
You can control the embedded Jitsi Meet conference using the JitsiMeetExternalAPI object.
```javascript
var configOverwrite = {disableSimulcast: true};
var interfaceConfigOverwrite = {filmStripOnly: true};
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, configOverwrite, interfaceConfigOverwrite);
You can send command to Jitsi Meet conference using ```executeCommand```.
```
## Controlling the embedded Jitsi Meet Conference
You can control the embedded Jitsi Meet conference using the `JitsiMeetExternalAPI` object by using `executeCommand`:
```javascript
api.executeCommand(command, ...arguments)
api.executeCommand(command, arguments)
```
The ```command``` parameter is String object with the name of the command.
The ```arguments``` parameter is array with the arguments required by the command.
If no arguments are required by the command this parameter can be omitted or you can pass empty array.
Currently we support the following commands:
The `command` parameter is String object with the name of the command. The following commands are currently supported:
* **displayName** - Sets the display name of the local participant. This command requires one argument - the new display name to be set.
```javascript
* **displayName** - sets the display name of the local participant. This command requires one argument -
the new display name to be set
```
api.executeCommand('displayName', 'New Nickname');
```
* **toggleAudio** - Mutes / unmutes the audio for the local participant. No arguments are required.
```javascript
api.executeCommand('toggleAudio')
* **toggleAudio** - mutes / unmutes the audio for the local participant. No arguments are required.
```
api.executeCommand('toggleAudio', [])
```
* **toggleVideo** - mutes / unmutes the video for the local participant. No arguments are required.
```
api.executeCommand('toggleVideo', [])
```
* **toggleFilmStrip** - hides / shows the film strip. No arguments are required.
```
api.executeCommand('filmStrip', [])
```
* **toggleChat** - hides / shows the chat. No arguments are required.
```
api.executeCommand('toggleChat', [])
```
* **toggleContactList** - hides / shows the contact list. No arguments are required.
```
api.executeCommand('toggleContactList', [])
```
* **toggleVideo** - Mutes / unmutes the video for the local participant. No arguments are required.
```javascript
api.executeCommand('toggleVideo')
* **toggleShareScreen** - starts / stops the screen sharing. No arguments are required.
```
* **toggleFilmStrip** - Hides / shows the film strip. No arguments are required.
```javascript
api.executeCommand('toggleFilmStrip')
```
* **toggleChat** - Hides / shows the chat. No arguments are required.
```javascript
api.executeCommand('toggleChat')
```
* **toggleContactList** - Hides / shows the contact list. No arguments are required.
```javascript
api.executeCommand('toggleContactList')
```
* **toggleShareScreen** - Starts / stops screen sharing. No arguments are required.
```javascript
api.executeCommand('toggleShareScreen')
api.executeCommand('toggleShareScreen', [])
```
* **hangup** - Hangups the call. No arguments are required.
```javascript
api.executeCommand('hangup')
```
api.executeCommand('hangup', [])
```
* **email** - Changes the local email address. This command requires one argument - the new email address to be set.
```javascript
api.executeCommand('email', 'example@example.com')
You can also execute multiple commands using the method ```executeCommands```.
```
* **avatarUrl** - Changes the local avatar URL. This command requires one argument - the new avatar URL to be set.
```javascript
api.executeCommand('avatarUrl', 'https://avatars0.githubusercontent.com/u/3671647')
```
You can also execute multiple commands using the `executeCommands` method:
```javascript
api.executeCommands(commands)
```
The `commands` parameter is an object with the names of the commands as keys and the arguments for the commands asvalues:
```javascript
The ```commands``` parameter is object with keys the names of the commands and values the arguments for the
commands.
```
api.executeCommands({displayName: ['nickname'], toggleAudio: []});
```
You can add event listeners to the embedded Jitsi Meet using the `addEventListener` method.
```javascript
You can add event listeners to the embedded Jitsi Meet using ```addEventListener``` method.
```
api.addEventListener(event, listener)
```
The ```event``` parameter is String object with the name of the event.
The ```listener``` paramenter is Function object with one argument that will be notified when the event occurs
with data related to the event.
The `event` parameter is a String object with the name of the event.
The `listener` parameter is a Function object with one argument that will be notified when the event occurs with data related to the event.
Currently we support the following events:
The following events are currently supported:
* **incomingMessage** - Event notifications about incoming
messages. The listener will receive an object with the following structure:
```javascript
* **incomingMessage** - event notifications about incoming
messages. The listener will receive object with the following structure:
```
{
"from": from, // JID of the user that sent the message
"nick": nick, // the nickname of the user that sent the message
"message": txt // the text of the message
"from": from,//JID of the user that sent the message
"nick": nick,//the nickname of the user that sent the message
"message": txt//the text of the message
}
```
* **outgoingMessage** - Event notifications about outgoing
messages. The listener will receive an object with the following structure:
```javascript
* **outgoingMessage** - event notifications about outgoing
messages. The listener will receive object with the following structure:
```
{
"message": txt // the text of the message
"message": txt//the text of the message
}
```
* **displayNameChanged** - event notifications about display name
changes. The listener will receive an object with the following structure:
```javascript
change. The listener will receive object with the following structure:
```
{
"jid": jid, // the JID of the participant that changed his display name
"displayname": displayName // the new display name
jid: jid,//the JID of the participant that changed his display name
displayname: displayName //the new display name
}
```
* **participantJoined** - event notifications about new participants who join the room. The listener will receive an object with the following structure:
```javascript
* **participantJoined** - event notifications about new participant.
The listener will receive object with the following structure:
```
{
"jid": jid // the JID of the participant
jid: jid //the jid of the participant
}
```
* **participantLeft** - event notifications about participants that leave the room. The listener will receive an object with the following structure:
```javascript
* **participantLeft** - event notifications about participant that left room.
The listener will receive object with the following structure:
```
{
"jid": jid // the JID of the participant
jid: jid //the jid of the participant
}
```
* **videoConferenceJoined** - event notifications fired when the local user has joined the video conference. The listener will receive an object with the following structure:
```javascript
* **video-conference-joined** - event notifications fired when the local user has joined the video conference.
The listener will receive object with the following structure:
```
{
"roomName": room // the room name of the conference
roomName: room //the room name of the conference
}
```
* **videoConferenceLeft** - event notifications fired when the local user has left the video conference. The listener will receive an object with the following structure:
```javascript
* **video-conference-left** - event notifications fired when the local user has left the video conference.
The listener will receive object with the following structure:
```
{
"roomName": room // the room name of the conference
roomName: room //the room name of the conference
}
```
* **readyToClose** - event notification fired when Jitsi Meet is ready to be closed (hangup operations are completed).
You can also add multiple event listeners by using `addEventListeners`.
You can also add multiple event listeners by using ```addEventListeners```.
This method requires one argument of type Object. The object argument must
have the names of the events as keys and the listeners of the events as values.
have keys with the names of the events and values the listeners of the events.
```javascript
```
function incomingMessageListener(object)
{
// ...
...
}
function outgoingMessageListener(object)
{
// ...
...
}
api.addEventListeners({
@@ -196,28 +183,20 @@ api.addEventListeners({
outgoingMessage: outgoingMessageListener})
```
If you want to remove a listener you can use `removeEventListener` method with argument the name of the event.
```javascript
If you want to remove a listener you can use ```removeEventListener``` method with argument the name of the event.
```
api.removeEventListener("incomingMessage");
```
If you want to remove more than one event you can use `removeEventListeners` method with an Array with the names of the events as an argument.
```javascript
If you want to remove more than one event you can use ```removeEventListeners``` method with argument
array with the names of the events.
```
api.removeEventListeners(["incomingMessage", "outgoingMessageListener"]);
```
You can get the number of participants in the conference with the following API function:
```javascript
var numberOfParticipants = api.getNumberOfParticipants();
You can remove the embedded Jitsi Meet Conference with the following code:
```
You can remove the embedded Jitsi Meet Conference with the following API function:
```javascript
api.dispose()
```
NOTE: It's a good practice to remove the conference before the page is unloaded.
[config.js]: https://github.com/jitsi/jitsi-meet/blob/master/config.js
[interface_config.js]: https://github.com/jitsi/jitsi-meet/blob/master/interface_config.js
It is a good practice to remove the conference before the page is unloaded.

View File

@@ -1,22 +0,0 @@
<html itemscope itemtype="http://schema.org/Product" prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body>
<script src="https://meet.jit.si/external_api.js"></script>
<script>
var domain = "meet.jit.si";
var room = "JitsiMeetAPIExample";
var width = 700;
var height = 180;
var htmlElement = undefined;
var configOverwrite = {};
var interfaceConfigOverwrite = {
filmStripOnly: true
};
var api = new JitsiMeetExternalAPI(domain, room, width, height,
htmlElement, configOverwrite, interfaceConfigOverwrite);
</script>
</body>
</html>

29
doc/influxdb.md Normal file
View File

@@ -0,0 +1,29 @@
# Overview
Jitsi Meet supports logging to an [InfluxDB](http://influxdb.com/) database.
# Configuration
The following needs to be done to enable this functionality.
## Install InfluxDB
The details are outside the scope of the document, see http://influxdb.com/download/ .
## Create an InfluxDB database
Use the InfluxDB admin interface (running on port 8083) and create a database. In this example we name it <code>jitsi_database</code>
## Enable logging for Jitsi Videobridge
Add the following properties to <code>/usr/share/jitsi-videobridge/.sip-communicator/sip-communicator.properties</code>.
- org.jitsi.videobridge.log.INFLUX_DB_ENABLED=true
- org.jitsi.videobridge.log.INFLUX_URL_BASE=http://influxdb.example.com:8086
- org.jitsi.videobridge.log.INFLUX_DATABASE=jitsi_database
- org.jitsi.videobridge.log.INFLUX_USER=user
- org.jitsi.videobridge.log.INFLUX_PASS=pass
## Enable logging for Jicofo
Add the same properties as above to <code>/usr/share/jicofo/.sip-communicator/sip-communicator.properties</code>.
## Enable logging for Jitsi Meet itself
Change "logStats" to "true" in <code>/etc/jitsi/meet/you-domain.config.js</code> or the <code>config.js</code> file used in your installation.
# User interface
You can explore the database using the [Jiloin](https://github.com/jitsi/jiloin) web interface.

View File

@@ -131,9 +131,9 @@ Or autostart it by adding the line in `/etc/rc.local`:
## Install Jitsi Conference Focus (jicofo)
Install JDK and Maven if missing:
Install JDK and Ant if missing:
```
apt-get install default-jdk maven
apt-get install default-jdk ant
```
_NOTE: When installing on older Debian releases keep in mind that you need JDK >= 1.7._
@@ -145,14 +145,12 @@ git clone https://github.com/jitsi/jicofo.git
Build distribution package. Replace {os-name} with one of: 'lin', 'lin64', 'macosx', 'win', 'win64'.
```sh
cd jicofo
mvn package -DskipTests -Dassembly.skipAssembly=false
ant dist.{os-name}
```
Run jicofo:
```sh
=======
unzip target/jicofo-{os-name}-1.0-SNAPSHOT.zip
cd jicofo-{os-name}-1.0-SNAPSHOT'
./jicofo.sh --host=localhost --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
cd dist/{os-name}'
./jicofo.sh --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
```
## Deploy Jitsi Meet
@@ -161,8 +159,6 @@ Checkout and configure Jitsi Meet:
cd /srv
git clone https://github.com/jitsi/jitsi-meet.git
mv jitsi-meet/ jitsi.example.com
npm install
make
```
Edit host names in `/srv/jitsi.example.com/config.js` (see also the example config file):
@@ -171,11 +167,11 @@ var config = {
hosts: {
domain: 'jitsi.example.com',
muc: 'conference.jitsi.example.com',
bridge: 'jitsi-videobridge.jitsi.example.com',
focus: 'focus.jitsi.example.com'
bridge: 'jitsi-videobridge.jitsi.example.com'
},
useNicks: false,
bosh: '//jitsi.example.com/http-bind', // FIXME: use xep-0156 for that
desktopSharing: 'false' // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
//chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
//minChromeExtVersion: '0.1' // Required version of Chrome extension
};

View File

@@ -1,96 +0,0 @@
# Jitsi Meet mobile apps
Jitsi Meet can also be built as a standalone mobile application for
iOS and Android. It uses the [React Native] framework.
First make sure the [React Native dependencies] are installed.
**NOTE**: This document assumes the app is being built on a macOS system.
**NOTE**: The app must be built for an actual device since the simulators don't
work properly with the native plugins we require.
## iOS
1. Install some extra dependencies
- Install ios-deploy globally (in case you want to use the React Native CLI
to deploy the app to the device)
```bash
npm install -g ios-deploy
```
You may need to add ```--unsafe-perm=true``` if you are running on [Mac OS 10.11 or greater](https://github.com/phonegap/ios-deploy#os-x-1011-el-capitan-or-greater).
2. Build the app
There are 2 ways to build the app: using the CLI or using Xcode.
Using the CLI:
```bash
react-native run-ios --device
```
When the app is launched from the CLI the output can be checked with the
following command:
```bash
react-native log-ios
```
Using Xcode
- Open **ios/jitsi-meet-react.xcworkspace** in Xcode. Make sure it's the
workspace file!
- Select your device from the top bar and hit the "play" button.
When the app is launched from Xcode the Debug console will show the output
logs the application creates.
3. Other remarks
It's likely you'll need to change the bundle ID for deploying to a device
because the default bundle ID points to the application signed by Atlassian.
This can be changed in the "General" tab. Under "Identity" set
"Bundle Identifier" to a different value, and adjust the "Team" in the
"Signing" section to match your own.
## Android
The [React Native dependencies] page has very detailed information on how to
setup [Android Studio] and the required components for getting the necessary
build environment. Make sure you follow it closely.
1. Building the app
The app can be built using the CLI utility as follows:
```bash
react-native run-android
```
It will be launched on the connected Android device.
## Debugging
The official documentation on [debugging] is quite extensive, it is the
preferred method for debugging.
**NOTE**: When using Chrome Developer Tools for debugging the JavaScript code
is being interpreted by Chrome's V8 engine, instead of JSCore which
React Native uses. It's important to keep this in mind due to potential
differences in supported JavaScript features.
[Android Studio]: https://developer.android.com/studio/index.html
[debugging]: https://facebook.github.io/react-native/docs/debugging.html
[React Native]: https://facebook.github.io/react-native/
[React Native dependencies]: https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies

View File

@@ -1,6 +0,0 @@
// flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583
// flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x
declare module "flow-bin" {
declare module.exports: string;
}

View File

@@ -1,36 +0,0 @@
// flow-typed signature: 57cf34196930be78935a42e5c8ac3cb6
// flow-typed version: ae6284e7b7/react-i18next_v2.x.x/flow_>=v0.36.x_<=v0.39.x
declare module 'react-i18next' {
declare type TFunction = (key?: ?string, data?: ?Object) => string;
declare type Locales = string | Array<string>;
declare type StatelessComponent<P> = (props: P) => ?React$Element<any>;
declare type Comp<P> = StatelessComponent<P> | Class<React$Component<*, P, *>>;
declare type Translator<OP, P> = {
(component: StatelessComponent<P>): Class<React$Component<void, OP, void>>;
<Def, St>(component: Class<React$Component<Def, P, St>>): Class<React$Component<Def, OP, St>>;
}
declare function translate<OP, P>(locales: Locales): Translator<OP, P>;
declare type NamespacesProps = {
components: Array<Comp<*>>,
i18n: { loadNamespaces: Function },
};
declare function loadNamespaces(props: NamespacesProps): Promise<void>;
declare type ProviderProps = { i18n: Object, children: React$Element<any> };
declare var I18nextProvider: Class<React$Component<void, ProviderProps, void>>;
declare type InterpolateProps = {
children?: React$Element<any>,
className?: string,
};
declare var Interpolate: Class<React$Component<void, InterpolateProps, void>>;
}

View File

@@ -1,89 +0,0 @@
// flow-typed signature: 0ed284c5a2e97a9e3c0e87af3dedc09d
// flow-typed version: bdf1e66252/react-redux_v5.x.x/flow_>=v0.30.x
import type { Dispatch, Store } from 'redux'
declare module 'react-redux' {
/*
S = State
A = Action
OP = OwnProps
SP = StateProps
DP = DispatchProps
*/
declare type MapStateToProps<S, OP: Object, SP: Object> = (state: S, ownProps: OP) => SP | MapStateToProps<S, OP, SP>;
declare type MapDispatchToProps<A, OP: Object, DP: Object> = ((dispatch: Dispatch<A>, ownProps: OP) => DP) | DP;
declare type MergeProps<SP, DP: Object, OP: Object, P: Object> = (stateProps: SP, dispatchProps: DP, ownProps: OP) => P;
declare type StatelessComponent<P> = (props: P) => ?React$Element<any>;
declare class ConnectedComponent<OP, P, Def, St> extends React$Component<void, OP, void> {
static WrappedComponent: Class<React$Component<Def, P, St>>;
getWrappedInstance(): React$Component<Def, P, St>;
static defaultProps: void;
props: OP;
state: void;
}
declare type ConnectedComponentClass<OP, P, Def, St> = Class<ConnectedComponent<OP, P, Def, St>>;
declare type Connector<OP, P> = {
(component: StatelessComponent<P>): ConnectedComponentClass<OP, P, void, void>;
<Def, St>(component: Class<React$Component<Def, P, St>>): ConnectedComponentClass<OP, P, Def, St>;
};
declare class Provider<S, A> extends React$Component<void, { store: Store<S, A>, children?: any }, void> { }
declare type ConnectOptions = {
pure?: boolean,
withRef?: boolean
};
declare type Null = null | void;
declare function connect<A, OP>(
...rest: Array<void> // <= workaround for https://github.com/facebook/flow/issues/2360
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
declare function connect<A, OP>(
mapStateToProps: Null,
mapDispatchToProps: Null,
mergeProps: Null,
options: ConnectOptions
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
declare function connect<S, A, OP, SP>(
mapStateToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: Null,
mergeProps: Null,
options?: ConnectOptions
): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>;
declare function connect<A, OP, DP>(
mapStateToProps: Null,
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
mergeProps: Null,
options?: ConnectOptions
): Connector<OP, $Supertype<DP & OP>>;
declare function connect<S, A, OP, SP, DP>(
mapStateToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
mergeProps: Null,
options?: ConnectOptions
): Connector<OP, $Supertype<SP & DP & OP>>;
declare function connect<S, A, OP, SP, DP, P>(
mapStateToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
mergeProps: MergeProps<SP, DP, OP, P>,
options?: ConnectOptions
): Connector<OP, P>;
}

View File

@@ -1,56 +0,0 @@
// flow-typed signature: ba132c96664f1a05288f3eb2272a3c35
// flow-typed version: c4bbd91cfc/redux_v3.x.x/flow_>=v0.33.x
declare module 'redux' {
/*
S = State
A = Action
*/
declare type Dispatch<A: { type: $Subtype<string> }> = (action: A) => A;
declare type MiddlewareAPI<S, A> = {
dispatch: Dispatch<A>;
getState(): S;
};
declare type Store<S, A> = {
// rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages)
dispatch: Dispatch<A>;
getState(): S;
subscribe(listener: () => void): () => void;
replaceReducer(nextReducer: Reducer<S, A>): void
};
declare type Reducer<S, A> = (state: S, action: A) => S;
declare type Middleware<S, A> =
(api: MiddlewareAPI<S, A>) =>
(next: Dispatch<A>) => Dispatch<A>;
declare type StoreCreator<S, A> = {
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
};
declare type StoreEnhancer<S, A> = (next: StoreCreator<S, A>) => StoreCreator<S, A>;
declare function createStore<S, A>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
declare function createStore<S, A>(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A>): Store<S, A>;
declare function applyMiddleware<S, A>(...middlewares: Array<Middleware<S, A>>): StoreEnhancer<S, A>;
declare type ActionCreator<A, B> = (...args: Array<B>) => A;
declare type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any> };
declare function bindActionCreators<A, C: ActionCreator<A, any>>(actionCreator: C, dispatch: Dispatch<A>): C;
declare function bindActionCreators<A, K, C: ActionCreators<K, A>>(actionCreators: C, dispatch: Dispatch<A>): C;
declare function combineReducers<O: Object, A>(reducers: O): Reducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
declare function compose<S, A>(...fns: Array<StoreEnhancer<S, A>>): Function;
}

Binary file not shown.

View File

@@ -14,7 +14,7 @@
<glyph unicode="&#xe900;" glyph-name="connection-lost" horiz-adv-x="1414" d="M0 299.153h196.337v-187.951h-196.337v187.951zM271.842 480.372h196.337v-369.169h-196.337v369.169zM543.656 661.562h196.337v-550.36h-196.337v550.36zM815.47 842.766v-731.564h119.56c-14.589 33.025-23.125 71.503-23.232 111.943 0.132 86.42 38.697 163.851 99.656 216.468l0.348 403.153h-196.332zM1087.292 1024v-533.672c28.874 10.572 62.222 16.73 97.009 16.825 35.717-0.129 69.823-6.614 101.322-18.371l-1.999 535.218h-196.332zM1192.868 439.852c-0.009 0-0.020 0-0.031 0-122.247 0-221.351-98.447-221.372-219.896 0-0.007 0-0.014 0-0.021 0-121.467 99.111-219.935 221.372-219.935 0.011 0 0.021 0 0.032 0 122.248 0.014 221.345 98.477 221.345 219.935 0 0.007 0 0.013 0 0.020-0.021 121.441-99.11 219.883-221.345 219.897zM1194.706 372.607c87.601-0.006 158.614-69.787 158.614-155.866 0-0.006 0-0.012 0-0.019-0.022-86.062-71.026-155.822-158.614-155.828-87.588 0.006-158.593 69.766-158.615 155.826 0 0.007 0 0.014 0 0.020 0 86.079 71.013 155.86 158.613 155.866zM1286.795 355.682l48.348-52.528-236.375-217.567-48.348 52.528 236.375 217.567z" />
<glyph unicode="&#xe901;" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
<glyph unicode="&#xe902;" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
<glyph unicode="&#xe903;" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />
<glyph unicode="&#xe903;" glyph-name="autorenew" d="M800 694c34-52 54-116 54-182 0-188-154-342-342-342v-128l-170 172 170 170v-128c142 0 256 114 256 256 0 44-12 84-30 120zM512 768c-142 0-256-114-256-256 0-44 10-84 30-120l-62-62c-34 52-54 116-54 182 0 188 154 342 342 342v128l170-172-170-170v128z" />
<glyph unicode="&#xe904;" glyph-name="kick" d="M512 810l284-426h-568zM214 298h596v-84h-596v84z" />
<glyph unicode="&#xe905;" glyph-name="hangup" d="M512 640c-68 0-134-10-196-30v-132c0-16-10-34-24-40-42-20-80-46-114-78-8-8-18-12-30-12s-22 4-30 12l-106 106c-8 8-12 18-12 30s4 22 12 30c130 124 306 200 500 200s370-76 500-200c8-8 12-18 12-30s-4-22-12-30l-106-106c-8-8-18-12-30-12s-22 4-30 12c-34 32-72 58-114 78-14 6-24 20-24 38v132c-62 20-128 32-196 32z" />
<glyph unicode="&#xe906;" glyph-name="chat" d="M854 342v512h-684v-598l86 86h598zM854 938c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
@@ -44,5 +44,4 @@
<glyph unicode="&#xe91e;" glyph-name="raised-hand" d="M982 790v-620c0-94-78-170-172-170h-310c-46 0-90 18-122 50l-336 342s54 52 56 52c10 8 22 12 34 12 10 0 18-2 26-6 2 0 184-104 184-104v508c0 36 28 64 64 64s64-28 64-64v-300h42v406c0 36 28 64 64 64s64-28 64-64v-406h42v364c0 36 28 64 64 64s64-28 64-64v-364h44v236c0 36 28 64 64 64s64-28 64-64z" />
<glyph unicode="&#xe91f;" glyph-name="menu-up" d="M512 682l256-256-60-60-196 196-196-196-60 60z" />
<glyph unicode="&#xe920;" glyph-name="menu-down" d="M708 658l60-60-256-256-256 256 60 60 196-196z" />
<glyph unicode="&#xe921;" glyph-name="switch-camera" d="M640 362l150 150-150 150v-108h-256v108l-150-150 150-150v108h256v-108zM854 854c46 0 84-40 84-86v-512c0-46-38-86-84-86h-684c-46 0-84 40-84 86v512c0 46 38 86 84 86h136l78 84h256l78-84h136z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -1,35 +1,6 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M756.704 395.862l267.296-202.213v635.075l-267.296-202.213v191.923c0 12.085-11.296 21.863-25.216 21.863h-706.272c-13.92 0-25.216-9.777-25.216-21.863v-612.25c0-12.085 11.296-21.863 25.216-21.863h706.272c13.92 0 25.216 9.777 25.216 21.863v189.679zM371.338 647.772c47.817 0 86.529-40.232 86.529-89.811v-184.835c0-49.651-38.713-89.883-86.529-89.883-47.788 0-86.515 40.232-86.515 89.883v184.835c0 49.579 38.756 89.811 86.515 89.811v0zM356.754 709.93v32.78h33.718v-33.412c73.858-9.606 131.235-73.73 131.235-151.351v-88.232h-30.636v88.232c0 67.57-53.696 122.534-119.734 122.534-66.024 0-119.691-54.964-119.691-122.534v-88.232h-30.636v88.232c0 79.215 59.674 144.502 135.744 151.969v0.014z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"Combined Shape"
]
},
"attrs": [
{}
],
"properties": {
"order": 109,
"id": 0,
"name": "mic-camera-combined",
"prevSize": 32,
"code": 59651
},
"setIdx": 0,
"setId": 2,
"iconIdx": 0
},
{
"icon": {
"paths": [
@@ -55,8 +26,8 @@
"prevSize": 32,
"code": 59677
},
"setIdx": 1,
"setId": 1,
"setIdx": 0,
"setId": 2,
"iconIdx": 0
},
{
@@ -84,8 +55,8 @@
"prevSize": 32,
"code": 59676
},
"setIdx": 1,
"setId": 1,
"setIdx": 0,
"setId": 2,
"iconIdx": 1
},
{
@@ -110,9 +81,35 @@
"code": 59649,
"name": "avatar"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 2
"setIdx": 0,
"setId": 2,
"iconIdx": 12
},
{
"icon": {
"paths": [
"M800 330c34 52 54 116 54 182 0 188-154 342-342 342v128l-170-172 170-170v128c142 0 256-114 256-256 0-44-12-84-30-120zM512 256c-142 0-256 114-256 256 0 44 10 84 30 120l-62 62c-34-52-54-116-54-182 0-188 154-342 342-342v-128l170 172-170 170v-128z"
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"autorenew"
],
"grid": 0,
"attrs": []
},
"attrs": [],
"properties": {
"id": 68,
"order": 84,
"ligatures": "autorenew",
"prevSize": 32,
"code": 59651,
"name": "autorenew"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 69
},
{
"icon": {
@@ -136,9 +133,9 @@
"code": 59653,
"name": "hangup"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 3
"setIdx": 0,
"setId": 2,
"iconIdx": 123
},
{
"icon": {
@@ -162,9 +159,9 @@
"code": 59654,
"name": "chat"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 4
"setIdx": 0,
"setId": 2,
"iconIdx": 149
},
{
"icon": {
@@ -188,9 +185,9 @@
"code": 59650,
"name": "download"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 5
"setIdx": 0,
"setId": 2,
"iconIdx": 165
},
{
"icon": {
@@ -214,9 +211,9 @@
"code": 59655,
"name": "edit"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 6
"setIdx": 0,
"setId": 2,
"iconIdx": 186
},
{
"icon": {
@@ -240,9 +237,9 @@
"code": 59656,
"name": "share-doc"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 7
"setIdx": 0,
"setId": 2,
"iconIdx": 207
},
{
"icon": {
@@ -266,9 +263,9 @@
"code": 59657,
"name": "telephone"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 8
"setIdx": 0,
"setId": 2,
"iconIdx": 216
},
{
"icon": {
@@ -292,9 +289,9 @@
"code": 59652,
"name": "kick"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 9
"setIdx": 0,
"setId": 2,
"iconIdx": 243
},
{
"icon": {
@@ -318,9 +315,9 @@
"code": 59679,
"name": "menu-up"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 10
"setIdx": 0,
"setId": 2,
"iconIdx": 257
},
{
"icon": {
@@ -344,9 +341,9 @@
"code": 59680,
"name": "menu-down"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 11
"setIdx": 0,
"setId": 2,
"iconIdx": 258
},
{
"icon": {
@@ -370,9 +367,9 @@
"code": 59659,
"name": "full-screen"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 12
"setIdx": 0,
"setId": 2,
"iconIdx": 351
},
{
"icon": {
@@ -396,9 +393,9 @@
"code": 59660,
"name": "exit-full-screen"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 13
"setIdx": 0,
"setId": 2,
"iconIdx": 352
},
{
"icon": {
@@ -422,9 +419,9 @@
"code": 59658,
"name": "star-full"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 14
"setIdx": 0,
"setId": 2,
"iconIdx": 364
},
{
"icon": {
@@ -448,9 +445,9 @@
"code": 59661,
"name": "security"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 15
"setIdx": 0,
"setId": 2,
"iconIdx": 474
},
{
"icon": {
@@ -474,9 +471,9 @@
"code": 59662,
"name": "security-locked"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 16
"setIdx": 0,
"setId": 2,
"iconIdx": 475
},
{
"icon": {
@@ -500,9 +497,9 @@
"code": 59663,
"name": "reload"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 17
"setIdx": 0,
"setId": 2,
"iconIdx": 483
},
{
"icon": {
@@ -526,9 +523,9 @@
"code": 59664,
"name": "microphone"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 18
"setIdx": 0,
"setId": 2,
"iconIdx": 493
},
{
"icon": {
@@ -552,9 +549,9 @@
"code": 59665,
"name": "mic-empty"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 19
"setIdx": 0,
"setId": 2,
"iconIdx": 494
},
{
"icon": {
@@ -578,9 +575,9 @@
"code": 59666,
"name": "mic-disabled"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 20
"setIdx": 0,
"setId": 2,
"iconIdx": 495
},
{
"icon": {
@@ -604,9 +601,9 @@
"code": 59678,
"name": "raised-hand"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 21
"setIdx": 0,
"setId": 2,
"iconIdx": 540
},
{
"icon": {
@@ -630,9 +627,9 @@
"code": 59675,
"name": "contactList"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 22
"setIdx": 0,
"setId": 2,
"iconIdx": 550
},
{
"icon": {
@@ -656,9 +653,9 @@
"code": 59667,
"name": "link"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 23
"setIdx": 0,
"setId": 2,
"iconIdx": 560
},
{
"icon": {
@@ -682,9 +679,9 @@
"code": 59668,
"name": "shared-video"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 24
"setIdx": 0,
"setId": 2,
"iconIdx": 591
},
{
"icon": {
@@ -708,9 +705,9 @@
"code": 59669,
"name": "settings"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 25
"setIdx": 0,
"setId": 2,
"iconIdx": 666
},
{
"icon": {
@@ -734,35 +731,9 @@
"code": 59670,
"name": "star"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 26
},
{
"icon": {
"paths": [
"M640 662l150-150-150-150v108h-256v-108l-150 150 150 150v-108h256v108zM854 170c46 0 84 40 84 86v512c0 46-38 86-84 86h-684c-46 0-84-40-84-86v-512c0-46 38-86 84-86h136l78-84h256l78 84h136z"
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"switch_camera"
],
"grid": 0,
"attrs": []
},
"attrs": [],
"properties": {
"id": 741,
"order": 108,
"ligatures": "switch_camera",
"prevSize": 32,
"code": 59681,
"name": "switch-camera"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 27
"setIdx": 0,
"setId": 2,
"iconIdx": 718
},
{
"icon": {
@@ -786,9 +757,9 @@
"code": 59671,
"name": "share-desktop"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 28
"setIdx": 0,
"setId": 2,
"iconIdx": 784
},
{
"icon": {
@@ -812,9 +783,9 @@
"code": 59672,
"name": "camera"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 29
"setIdx": 0,
"setId": 2,
"iconIdx": 799
},
{
"icon": {
@@ -838,9 +809,9 @@
"code": 59673,
"name": "camera-disabled"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 30
"setIdx": 0,
"setId": 2,
"iconIdx": 800
},
{
"icon": {
@@ -864,9 +835,9 @@
"code": 59674,
"name": "volume"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 31
"setIdx": 0,
"setId": 2,
"iconIdx": 822
},
{
"icon": {
@@ -914,7 +885,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 32
"iconIdx": 0
},
{
"icon": {
@@ -985,7 +956,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 33
"iconIdx": 4
},
{
"icon": {
@@ -1012,7 +983,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 34
"iconIdx": 12
},
{
"icon": {
@@ -1040,7 +1011,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 35
"iconIdx": 13
},
{
"icon": {
@@ -1068,7 +1039,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 36
"iconIdx": 22
}
],
"height": 1024,

BIN
images/dropdownPointer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

View File

@@ -1,182 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg3526"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:export-filename="/Users/ystamcheva/Dropbox/Designs/appLogo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
sodipodi:docname="logo-blue.svg">
<defs
id="defs3528" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="817.30793"
inkscape:cy="496.00851"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="851"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata3531">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g4181">
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g33">
<path
d="m 257.311,591.057 c 27.544,0 85.707,-16.445 124.179,-27.332 5.595,-1.575 10.81,-3.049 15.549,-4.371 0.767,-0.211 1.51,-0.403 2.213,-0.579 -2.161,-2.139 -5.755,-5.387 -11.612,-10.295 -25.628,-17.369 -49.827,-25.456 -76.146,-25.456 -5.741,0 -11.707,0.352 -18.208,1.088 -22.283,2.535 -40.848,7.845 -49.767,10.39 -4.521,1.296 -5.883,1.683 -7.292,1.683 -2.688,0 -4.997,-1.599 -5.9,-4.069 -0.904,-2.483 -0.13,-5.223 1.969,-6.981 l 0.127,-0.102 c 15.379,-12.883 44.032,-36.866 98.39,-47.582 9.428,-1.853 19.514,-2.796 29.968,-2.796 24.334,0 49.53,5.026 74.869,14.925 34.511,13.474 58.094,30.771 77.062,44.67 10.211,7.489 19.03,13.959 26.705,17.516 1.961,0.912 2.979,1.169 3.453,1.236 0.349,-0.452 1.106,-1.7 2.219,-4.974 0.298,-0.867 2.453,-10.019 -13.007,-62.071 -8.985,-30.217 -19.822,-61.077 -25.465,-74.778 -10.916,-26.509 -8.237,-45.296 -4.877,-56.284 -9.248,3.399 -18.701,8.688 -28.646,15.993 l -0.62,0.458 c -4.969,3.684 -10.031,7.853 -15.482,12.725 -32.074,28.718 -56.104,43.69 -71.455,44.504 l -0.423,0.021 -0.421,-0.036 c -13.524,-1.148 -34.019,-20.834 -42.403,-30.801 -1.743,-1.169 -3.729,-1.699 -6.35,-1.699 -2.632,0 -5.583,0.553 -8.438,1.095 -2.077,0.394 -4.218,0.795 -6.341,1.01 -6.767,0.679 -16.252,2.867 -25.406,4.974 -4.413,1.014 -8.967,2.063 -13.13,2.922 -0.079,0.013 -1.866,0.382 -5.06,1.224 -22.624,6.693 -39.673,14.372 -48.012,21.628 -0.091,0.079 -0.36,0.288 -0.789,0.603 -5.64,4.009 -19.199,15.447 -23.29,34.907 l -0.043,0.162 c -8.541,35.837 4.408,80.28 21.615,105.666 8.093,11.932 16.814,19.376 23.944,20.42 1.775,0.252 3.905,0.386 6.321,0.386 z"
id="path35"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g37">
<path
d="m 383.729,400.995 c 0.549,0.108 1.191,0.162 1.9,0.162 14.785,0 47.804,-21.408 53.912,-31.205 l 0.486,-0.78 0.694,-0.611 c 2.083,-2.056 8.099,-12.885 11.019,-19.367 -31.312,-9.394 -34.767,-26.347 -37.821,-41.41 -0.355,-1.749 -0.667,-3.324 -0.946,-4.732 -0.357,-1.842 -0.731,-3.713 -1.052,-5.159 -46.646,15.471 -60.905,24.154 -68.687,30.611 -4.027,3.345 -6.398,12.858 5.215,39.189 5.932,13.422 26.386,31.591 35.28,33.302 z"
id="path39"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<path
style="fill:#17a0db;fill-opacity:1"
inkscape:connector-curvature="0"
id="path43"
d="m 183.03568,710.19014 c -5.799,-6.834 -8.258,-15.447 -7.293,-25.624 4.105,-49.397 -1.525,-61.33 -4.132,-64.162 -0.629,-0.685 -0.969,-0.685 -1.238,-0.685 -0.101,0 -0.195,0.006 -0.296,0.016 -4.84,1.157 -37.441,23.198 -44.638,89.005 -3.471,31.758 2.611,72.542 7.794,97.348 4.165,-14.646 10.742,-30.779 23.483,-47.384 11.862,-15.444 24.801,-27.623 40.852,-38.298 -4.99,-2.075 -10.346,-5.274 -14.532,-10.216 z" />
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g45">
<path
d="m 485.028,154.141 c -3.896,25.701 -10.239,50.115 -22.077,75.883 12.904,-14.609 20.445,-30.481 22.971,-48.296 1.051,-7.38 2.045,-14.439 -0.894,-27.587 z"
id="path47"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g49">
<path
d="m 413.102,273.797 c 23.135,-20.915 37.22,-55.455 43.078,-75.971 -20.149,19.407 -44.636,29.82 -60.351,36.512 -5.412,2.308 -10.08,4.295 -12.878,5.926 -1.178,0.685 -2.367,1.374 -3.571,2.069 -9.533,5.515 -23.924,13.85 -26.022,18.987 l -0.06,0.167 -0.078,0.165 c -6.529,13.72 -10.208,34.352 -11.387,46.184 15.135,-9.242 30.738,-15.41 43.699,-20.529 12.03,-4.753 22.432,-8.863 27.57,-13.51 z"
id="path51"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g53">
<path
d="m 436.439,291.877 c -0.141,0.357 -0.292,0.695 -0.455,1.017 -3.833,11.143 1.446,26.3 11.227,32.017 2.602,1.522 5.132,2.452 7.559,2.772 0.334,0.014 0.666,0.027 1.001,0.027 7.601,0 13.801,-5.56 18.4,-16.519 2.896,-8.34 3.308,-18.23 1.125,-27.158 -1.696,-6.936 -6.084,-15.215 -8.88,-19.343 -5.219,3.582 -15.533,11.462 -22.615,17.716 -4.946,4.777 -6.733,7.785 -7.362,9.471 z"
id="path55"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g57">
<path
d="m 501.845,575.103 c 8.403,-2.29 15.076,-4.165 19.998,-5.623 -10.137,-7.061 -21.871,-15.846 -37.823,-28.253 -39.096,-30.404 -81.019,-45.826 -124.587,-45.826 -23.861,0 -44.647,4.592 -61.098,10.151 4.101,-0.255 8.271,-0.377 12.554,-0.377 5.088,0 10.42,0.179 15.842,0.541 16.949,1.136 60.616,8.845 100.106,55.931 7.956,9.469 16.507,17.307 40.828,17.307 8.679,0 18.796,-0.967 30.913,-2.959 0.749,-0.209 1.882,-0.518 3.267,-0.892 z"
id="path59"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g61">
<path
d="m 557.268,369.949 c -7.755,-12.043 -17.498,-19.524 -25.41,-19.524 -1.464,0 -2.862,0.258 -4.154,0.765 -4.239,1.672 -10.952,21.042 -7.979,35.126 2.023,9.582 13.67,41.96 19.262,57.52 2.142,5.958 3.18,8.869 3.527,9.951 0.275,0.853 0.67,2.077 1.17,3.621 4.517,13.765 16.111,49.145 19.562,77.793 7.175,-30.554 11.239,-67.36 9.647,-111.409 -0.723,-20.199 -6.274,-39.323 -15.625,-53.843 z"
id="path63"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g65">
<path
d="m 412.08,575.289 c -0.153,-0.2 -0.3,-0.397 -0.445,-0.585 -0.614,0.1 -1.616,0.319 -3.185,0.776 l -0.657,0.197 c -8.011,2.95 -22.707,7.908 -39.694,13.64 -20.387,6.87 -43.477,14.659 -62.808,21.595 -24.596,9.165 -32.572,12.781 -35.073,14.048 -0.454,1.218 -0.963,2.772 -1.53,4.486 -5.817,17.705 -19.139,58.23 -84.831,86.562 13.568,13.744 43.101,38.415 101.24,38.415 5.035,0 10.258,-0.188 15.494,-0.566 43.896,-3.121 85.158,-22.544 116.206,-54.673 28.233,-29.21 44.259,-65.641 44.507,-100.76 -6.871,-0.571 -18.519,-2.281 -29.301,-7.4 -0.125,-0.061 -12.447,-6.002 -19.923,-15.735 z"
id="path67"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g69">
<path
d="m 162.104,639.109 c -0.122,10.334 -1.489,20.245 -2.82,29.907 -0.716,5.216 -1.464,10.615 -2.014,16.041 -0.746,10.914 1.612,14.717 2.659,15.829 0.571,0.629 1.513,1.346 3.536,1.346 1.558,0 3.418,-0.432 5.383,-1.251 19.507,-8.176 38.032,-22.367 46.937,-30.243 -13.668,-6.095 -34.689,-19.26 -53.681,-31.629 z"
id="path71"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
style="fill:#17a0db;fill-opacity:1"
transform="translate(43.272677,-6.8248629)"
id="g73">
<path
d="m 484.26,598.224 c -0.552,7.258 -1.737,20.949 -3.631,31.378 -2.295,12.629 -6.095,23.31 -8.305,28.889 3.945,3.648 7.878,7.228 10.429,9.488 10.265,-6.718 43.961,-32.297 67.208,-90.368 -7.447,5.03 -17.906,9.456 -31.465,13.332 -13.797,3.929 -27.204,6.229 -34.236,7.281 z"
id="path75"
inkscape:connector-curvature="0"
style="fill:#17a0db;fill-opacity:1" />
</g>
<g
transform="translate(43.272677,-6.8248629)"
id="g85"
style="fill:#17a0db;fill-opacity:1">
<path
style="fill:#17a0db;fill-opacity:1"
inkscape:connector-curvature="0"
id="path87"
d="M 627.562,350.519 C 613.5,321.124 593.893,306.283 580.351,297.677 568.965,290.444 555.872,285.188 541.339,282 c -1.622,-10.158 -4.397,-20.542 -8.198,-30.646 24.507,-36.531 30.407,-77.605 17.008,-119.213 C 539.858,100.151 531.868,79.524 524.996,67.213 510.15,40.585 489.58,34.997 474.936,34.997 c -15.09,0 -29.538,6.412 -39.667,17.61 -10.37,11.462 -15.213,26.462 -13.634,42.228 1.349,13.446 -2.178,37.872 -4.519,46.594 -0.04,0.117 -4.202,11.776 -35.168,26.784 -0.746,0.268 -2.332,0.811 -4.773,1.629 -17.812,5.965 -50.913,17.062 -72.963,46.219 -16.847,20.407 -20.985,40.629 -25.766,64.036 -2.858,13.955 -5.846,32.187 -5.105,53.745 -55.35,12.291 -95.226,37.338 -118.609,74.54 -24.203,38.52 -28.402,86.272 -12.468,141.993 l 0.14,0.414 c 0.292,1.014 0.6,2.024 0.921,3.03 -2.718,-0.466 -5.465,-0.858 -8.285,-1.169 -2.469,-0.284 -5.015,-0.42 -7.54,-0.42 -27.636,0 -57.043,17.371 -78.666,46.474 -16.427,22.098 -36.156,61.131 -36.852,121.593 -0.523,44.905 4.279,86.306 14.283,123.054 7.461,27.381 15.784,44.202 18.979,50.09 l 67.793,127.079 31.06,-140.731 c 10.6,-47.935 21.066,-68.283 34.571,-81.732 31.425,18.938 68.541,28.901 107.941,28.901 43.919,0 89.715,-12.667 128.934,-35.662 25.477,-14.954 47.193,-33.324 64.629,-54.658 0.236,0 0.469,0 0.704,0 l 1.857,-0.038 c 10.782,-0.365 25.522,-5.697 40.434,-14.63 12.421,-7.433 31.147,-21.108 49.946,-44.064 18.945,-23.155 34.402,-51.324 45.926,-83.731 13.5,-37.939 21.717,-82.115 24.404,-131.272 3.253,-45.723 -2.078,-83.533 -15.881,-112.384 z m -31.124,109.427 c -2.415,44.805 -9.745,84.66 -21.764,118.441 -9.713,27.302 -22.502,50.739 -38.005,69.69 -26.696,32.611 -52.783,41.355 -55.551,41.465 l -0.22,0 c -2.528,0 -4.012,-1.032 -11.095,-5.988 -1.979,-1.379 -4.969,-3.467 -7.436,-5.075 -14.813,28.811 -39.145,53.701 -70.659,72.185 -32.098,18.824 -69.432,29.202 -105.1,29.202 -42.352,0 -79.532,-13.979 -107.842,-40.493 -38.621,24.556 -61.833,45.044 -80.652,130.273 l -3.562,16.157 -7.787,-14.59 C 84.8,867.621 78.058,854.32 71.708,830.982 62.852,798.444 58.598,761.384 59.071,720.842 c 0.944,-80.909 44.373,-121.518 68.427,-121.518 0.792,0 1.578,0.039 2.328,0.128 22.8,2.551 37.699,12.402 64.745,30.291 2.796,1.853 5.74,3.8 8.843,5.838 9.69,6.36 23.387,14.125 26.835,14.791 6.562,-0.381 12.986,-15.079 14.853,-28.713 0.114,-0.829 0.226,-1.598 0.334,-2.315 0.147,-1.612 0.227,-3.03 0.27,-4.194 -1.144,-0.399 -2.333,-0.869 -3.547,-1.403 l -0.27,-0.091 c -17.012,-5.857 -41.868,-34.625 -54.378,-76.385 -12.081,-42.21 -9.691,-77.122 7.099,-103.83 27.221,-43.328 86.307,-53.515 105.849,-56.861 6.109,-1.214 12.498,-2.351 18.999,-3.378 3.035,-0.762 5.11,-1.399 6.449,-1.978 0.58,-0.403 0.835,-0.833 0.439,-2.403 l 0.53,-0.148 -0.513,0.115 c -0.237,-1.065 -0.565,-2.311 -0.941,-3.753 -0.521,-1.997 -1.103,-4.256 -1.705,-6.936 -6.05,-27.141 -2.962,-49.884 0.863,-68.559 4.297,-21.019 6.678,-32.656 16.605,-44.279 13.152,-18.103 36.803,-26.025 50.953,-30.77 3.948,-1.322 7.359,-2.462 9.331,-3.412 43.344,-20.789 57.145,-42.646 61.091,-57.318 3.127,-11.642 8.084,-42.253 5.931,-63.63 -0.239,-2.425 0.326,-4.421 1.695,-5.935 1.215,-1.341 2.942,-2.104 4.748,-2.104 4.061,0 9.623,0 30.377,64.478 10.949,33.996 2.785,65.868 -24.244,94.74 -0.347,0.375 -0.7,0.742 -1.04,1.095 -0.738,0.76 -1.848,1.909 -1.999,2.326 0.006,0 -0.048,1.042 1.755,4.031 11.425,18.864 17.633,42.323 15.832,59.763 -0.429,4.062 -1.206,7.971 -1.879,11.411 -0.4,1.968 -0.879,4.377 -1.126,6.241 0.111,0 0.226,0 0.347,0 3.088,-0.327 7.867,-0.7 13.628,-0.7 13.556,0 32.969,2.077 48.503,11.951 9.382,5.952 21.255,15.137 29.981,33.404 10.281,21.472 14.096,51.453 11.369,89.114 z" />
</g>
</g>
<path
style="fill:#ffffff"
d=""
id="path3618"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,8 +1,7 @@
<html itemscope itemtype="http://schema.org/Product" prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<meta charset="utf-8" />
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--#include virtual="base.html" -->
<script>
window.indexLoadedTime = window.performance.now();
@@ -29,95 +28,9 @@
&& criticalFiles.some(
function(file) { return fileRef.indexOf(file) !== -1 })) {
window.onload = function() {
// The whole complex part below implements page reloads with
// "exponential backoff". The retry attempt is passes as
// "rCounter" query parameter
var href = window.location.href;
var retryMatch = href.match(/.+(\?|&)rCounter=(\d+)/);
var retryCountStr = retryMatch ? retryMatch[2] : "0";
var retryCount = Number.parseInt(retryCountStr);
if (retryMatch == null) {
var separator = href.indexOf("?") === -1 ? "?" : "&";
var hashIdx = href.indexOf("#");
if (hashIdx === -1) {
href += separator + "rCounter=1";
} else {
var hashPart = href.substr(hashIdx);
href = href.substr(0, hashIdx)
+ separator + "rCounter=1" + hashPart;
}
} else {
var separator = retryMatch[1];
href = href.replace(
/(\?|&)rCounter=(\d+)/,
separator + "rCounter=" + (retryCount + 1));
}
var delay = Math.pow(2, retryCount) * 2000;
if (isNaN(delay) || delay < 2000 || delay > 60000)
delay = 10000;
var showMoreText = "show more";
var showLessText = "show less";
document.body.innerHTML
= "<div style='"
+ "position: absolute;top: 50%;left: 50%;"
+ "text-align: center;"
+ "font-size: medium;"
+ "font-weight: 400;"
+ "transform: translate(-50%, -50%)'>"
+ "Uh oh! We couldn't fully download everything we needed :(" // jshint ignore:line
+ "<br/> "
+ "We will try again shortly. In the mean time, check for problems with your Internet connection!" // jshint ignore:line
+ "<br/><br/> "
+ "<div id='moreInfo' style='"
+ "display: none;'>" + "Missing " + fileRef
+ "<br/><br/></div>"
+ "<a id='showMore' style='"
+ "text-decoration: underline;"
+ "font-size:small;"
+ "cursor: pointer'>" + showMoreText + "</a>"
+ "&nbsp;&nbsp;&nbsp;"
+ "<a href='" + href + "' style='"
+ "text-decoration: underline;"
+ "font-size:small;"
+ "'>reload now</a>"
+ "</div>";
var showMoreElem = document.getElementById("showMore");
showMoreElem.addEventListener('click', function () {
var moreInfoElem
= document.getElementById("moreInfo");
if (showMoreElem.innerHTML === showMoreText) {
moreInfoElem.setAttribute(
"style",
"display: block;"
+ "color:#FF991F;"
+ "font-size:small;"
+ "user-select:text;");
showMoreElem.innerHTML = showLessText;
}
else {
moreInfoElem.setAttribute(
"style", "display: none;");
showMoreElem.innerHTML = showMoreText;
}
});
window.setTimeout(
function () { window.location.replace(href); }, delay);
// Call extra handler if defined.
if (typeof postLoadErrorHandler === "function") {
postLoadErrorHandler();
}
= "The application failed to load, missing file: "
+ fileRef;
};
window.removeEventListener(
'error', loadErrHandler, true /* capture phase */);
@@ -131,11 +44,10 @@
<!--#include virtual="connection_optimization/connection_optimization.html" -->
<script src="connection_optimization/do_external_connect.js?v=1"></script>
<script><!--#include virtual="/interface_config.js" --></script>
<script><!--#include virtual="/logging_config.js" --></script>
<script src="libs/lib-jitsi-meet.min.js?v=139"></script>
<script src="libs/app.bundle.min.js?v=139"></script>
<!--#include virtual="title.html" -->
<link rel="stylesheet" href="css/all.css">
<link rel="stylesheet" href="css/all.css"/>
<!--#include virtual="plugin.head.html" -->
</head>
<body>

View File

@@ -11,8 +11,6 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
DEFAULT_LOCAL_DISPLAY_NAME: "me",
SHOW_JITSI_WATERMARK: true,
JITSI_WATERMARK_LINK: "https://jitsi.org",
// if watermark is disabled by default, it can be shown only for guests
SHOW_WATERMARK_FOR_GUESTS: true,
SHOW_BRAND_WATERMARK: false,
BRAND_WATERMARK_LINK: "",
SHOW_POWERED_BY: false,
@@ -55,8 +53,6 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
* Whether to only show the filmstrip (and hide the toolbar).
*/
filmStripOnly: false,
//A html text to be shown to guests on the close page, false disables it
CLOSE_PAGE_GUEST_HINT: false,
RANDOM_AVATAR_URL_PREFIX: false,
RANDOM_AVATAR_URL_SUFFIX: false,
FILM_STRIP_MAX_HEIGHT: 120,
@@ -70,16 +66,5 @@ var interfaceConfig = { // eslint-disable-line no-unused-vars
AUDIO_LEVEL_SECONDARY_COLOR: "rgba(255,255,255,0.2)",
POLICY_LOGO: null,
LOCAL_THUMBNAIL_RATIO: 16/9, //16:9
REMOTE_THUMBNAIL_RATIO: 1, //1:1
// Documentation reference for the live streaming feature.
LIVE_STREAMING_HELP_LINK: "https://jitsi.org/live",
/**
* Whether the mobile app Jitsi Meet is to be promoted to participants
* attempting to join a conference in a mobile Web browser. If undefined,
* default to true.
*
* @type {boolean}
*/
MOBILE_APP_PROMO: true
REMOTE_THUMBNAIL_RATIO: 1 //1:1
};

12
ios/Podfile Normal file
View File

@@ -0,0 +1,12 @@
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'jitsi-meet-react' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for jitsi-meet-react
pod 'Crashlytics'
pod 'Fabric'
end

16
ios/Podfile.lock Normal file
View File

@@ -0,0 +1,16 @@
PODS:
- Crashlytics (3.8.3):
- Fabric (~> 1.6.3)
- Fabric (1.6.11)
DEPENDENCIES:
- Crashlytics
- Fabric
SPEC CHECKSUMS:
Crashlytics: 2b6dbe138a42395577cfa73dfa1aa7248cadf39e
Fabric: 5911403591946b8228ab1c51d98f1d7137e863c6
PODFILE CHECKSUM: 672d557f679f28c07b3364884b4580e605000f01
COCOAPODS: 1.1.1

View File

@@ -8,35 +8,11 @@
*/
#import "AppDelegate.h"
#import <React/RCTAssert.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h>
#import <React/RCTRootView.h>
/**
* A <tt>RCTFatalHandler</tt> implementation which swallows JavaScript errors.
* In the Release configuration, React Native will (intentionally) raise an
* unhandled NSException for an unhandled JavaScript error. This will
* effectively kill the application. <tt>_RCTFatal</tt> is suitable to be in
* accord with the Web i.e. not kill the application.
*/
RCTFatalHandler _RCTFatal = ^(NSError *error) {
id jsStackTrace = error.userInfo[RCTJSStackTraceKey];
@try {
NSString *name
= [NSString stringWithFormat:@"%@: %@",
RCTFatalExceptionName,
error.localizedDescription];
NSString *message
= RCTFormatError(error.localizedDescription, jsStackTrace, 75);
[NSException raise:name format:@"%@", message];
} @catch (NSException *e) {
if (!jsStackTrace) {
@throw;
}
}
};
#import <Crashlytics/Crashlytics.h>
#import <Fabric/Fabric.h>
#import "RCTBundleURLProvider.h"
#import "RCTLinkingManager.h"
#import "RCTRootView.h"
@implementation AppDelegate
@@ -53,15 +29,7 @@ continueUserActivity:(NSUserActivity *)userActivity
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if !DEBUG
// In the Release configuration, React Native will (intentionally) raise an
// unhandled NSException for an unhandled JavaScript error. This will
// effectively kill the application. In accord with the Web, do not kill the
// application.
if (!RCTGetFatalHandler()) {
RCTSetFatalHandler(_RCTFatal);
}
#endif
[Fabric with:@[[Crashlytics class]]];
NSURL *jsCodeLocation
= [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios"

View File

@@ -1,134 +0,0 @@
#import "RCTBridgeModule.h"
#import "RCTLog.h"
#import <AVFoundation/AVFoundation.h>
@interface AudioMode : NSObject<RCTBridgeModule>
@end
@implementation AudioMode {
NSString *_category;
NSString *_mode;
}
RCT_EXPORT_MODULE();
typedef enum {
kAudioModeDefault,
kAudioModeAudioCall,
kAudioModeVideoCall
} JitsiMeetAudioMode;
- (NSDictionary *)constantsToExport {
return @{
@"AUDIO_CALL" : [NSNumber numberWithInt: kAudioModeAudioCall],
@"DEFAULT" : [NSNumber numberWithInt: kAudioModeDefault],
@"VIDEO_CALL" : [NSNumber numberWithInt: kAudioModeVideoCall]
};
};
- (instancetype)init {
self = [super init];
if (self) {
_category = nil;
_mode = nil;
}
return self;
}
- (dispatch_queue_t)methodQueue {
// Make sure all our methods run in the main thread. The route change
// notification runs there so this will make sure it will only be fired
// after our changes have been applied (when we cause them, that is).
return dispatch_get_main_queue();
}
- (void)routeChanged:(NSNotification*)notification {
NSInteger reason
= [[notification.userInfo
valueForKey:AVAudioSessionRouteChangeReasonKey]
integerValue];
switch (reason) {
case AVAudioSessionRouteChangeReasonCategoryChange:
// The category has changed. Check if it's the one we want and adjust as
// needed.
[self setCategory:_category mode:_mode error:nil];
break;
default:
// Do nothing.
break;
}
}
- (BOOL)setCategory:(NSString *)category
mode:(NSString *)mode
error:(NSError * _Nullable *)outError {
AVAudioSession *session = [AVAudioSession sharedInstance];
if (session.category != category
&& ![session setCategory:category error:outError]) {
RCTLogError(@"Failed to (re)apply specified AVAudioSession category!");
return NO;
}
if (session.mode != mode && ![session setMode:mode error:outError]) {
RCTLogError(@"Failed to (re)apply specified AVAudioSession mode!");
return NO;
}
return YES;
}
RCT_EXPORT_METHOD(setMode:(int)mode
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
NSString *avCategory;
NSString *avMode;
NSError *error;
switch (mode) {
case kAudioModeAudioCall:
avCategory = AVAudioSessionCategoryPlayAndRecord;
avMode = AVAudioSessionModeVoiceChat;
break;
case kAudioModeDefault:
avCategory = AVAudioSessionCategorySoloAmbient;
avMode = AVAudioSessionModeDefault;
break;
case kAudioModeVideoCall:
avCategory = AVAudioSessionCategoryPlayAndRecord;
avMode = AVAudioSessionModeVideoChat;
break;
default:
reject(@"setMode", @"Invalid mode", nil);
return;
}
if (![self setCategory:avCategory mode:avMode error:&error] || error) {
reject(@"setMode", error.localizedDescription, error);
return;
}
// Even though the specified category and mode were successfully set, the
// AVAudioSession is a singleton and other parts of the application such as
// WebRTC may undo the settings. Make sure that the settings are reapplied
// upon undoes.
if (!_category || !_mode) {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(routeChanged:)
name:AVAudioSessionRouteChangeNotification
object:nil];
}
// Save the desired/specified category and mode so that they may be
// reapplied (upon undoes as described above).
_category = avCategory;
_mode = avMode;
resolve(nil);
}
@end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -2,103 +2,53 @@
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
"size" : "20x20",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-60@2x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "AppIcon-29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "AppIcon-40@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "AppIcon-76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "AppIcon-76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "AppIcon-83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
"version" : 1,
"author" : "xcode"
}
}
}

View File

@@ -1,23 +1,22 @@
{
"images" : [
{
"filename" : "LaunchScreen-480@1x.png",
"idiom" : "universal",
"filename" : "LaunchScreen-480@1x.png",
"scale" : "1x"
},
{
"filename" : "LaunchScreen-480@2x.png",
"idiom" : "universal",
"filename" : "LaunchScreen-480@2x.png",
"scale" : "2x"
},
{
"filename" : "LaunchScreen-480@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
"version" : 1,
"author" : "xcode"
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 KiB

View File

@@ -17,24 +17,25 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.3</string>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>org.jitsi.meet</string>
<key>CFBundleURLSchemes</key>
<array>
<string>org.jitsi.meet</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>Fabric</key>
<dict>
<key>APIKey</key>
<string>a8ae24a58302ba79da1d312138e941f6b86e3242</string>
<key>Kits</key>
<array>
<dict>
<key>KitInfo</key>
<dict/>
<key>KitName</key>
<string>Crashlytics</string>
</dict>
</array>
</dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
@@ -56,11 +57,11 @@
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>Participate in conferences with video.</string>
<string></string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSMicrophoneUsageDescription</key>
<string>Participate in conferences with audio.</string>
<string></string>
<key>UIAppFonts</key>
<array>
<string>jitsi.ttf</string>
@@ -80,10 +81,9 @@
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

View File

@@ -1,66 +0,0 @@
#import "RCTBridgeModule.h"
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
@interface POSIX : NSObject<RCTBridgeModule>
@end
@implementation POSIX
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(getaddrinfo:(NSString *)hostname
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
int err;
struct addrinfo *res;
NSString *rejectCode;
if (0 == (err = getaddrinfo(hostname.UTF8String, NULL, NULL, &res))) {
int af = res->ai_family;
struct sockaddr *sa = res->ai_addr;
void *addr;
switch (af) {
case AF_INET:
addr = &(((struct sockaddr_in *) sa)->sin_addr);
break;
case AF_INET6:
addr = &(((struct sockaddr_in6 *) sa)->sin6_addr);
break;
default:
addr = NULL;
break;
}
if (addr) {
char v[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
if (inet_ntop(af, addr, v, sizeof(v))) {
resolve([NSString stringWithUTF8String:v]);
} else {
err = errno;
rejectCode = @"inet_ntop";
}
} else {
err = EAFNOSUPPORT;
rejectCode = @"EAFNOSUPPORT";
}
freeaddrinfo(res);
} else {
rejectCode = @"getaddrinfo";
}
if (0 != err) {
NSError *error
= [NSError errorWithDomain:NSPOSIXErrorDomain
code:err
userInfo:nil];
reject(rejectCode, error.localizedDescription, error);
}
}
@end

View File

@@ -5,10 +5,8 @@
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:beta.meet.jit.si</string>
<string>applinks:beta.hipchat.me</string>
<string>applinks:chaos.hipchat.me</string>
<string>applinks:enso.me</string>
<string>applinks:hipchat.me</string>
<string>applinks:meet.jit.si</string>
</array>
</dict>

View File

@@ -13,7 +13,6 @@
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
0B42DFAE1E2FD90700111B12 /* AudioMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B42DFAD1E2FD90700111B12 /* AudioMode.m */; };
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
@@ -24,13 +23,9 @@
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
2602576C1D0A7703001E3363 /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2602576B1D0A7703001E3363 /* jitsi.ttf */; };
3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 821D8ABD506944B4BDBB069B /* libRNVectorIcons.a */; };
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
7FAD39BE09A84D6AB0ABACA8 /* libRNBackgroundTimer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27A0018BBB2C4FD5A4F9CE71 /* libRNBackgroundTimer.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA8C046B2BF46279796F07D /* libKCKeepAwake.a */; };
B30EF2311DC0ED7C00690F45 /* WebRTC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B30EF2301DC0ED7C00690F45 /* WebRTC.framework */; };
B30EF2331DC0EEA500690F45 /* WebRTC.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B30EF2301DC0ED7C00690F45 /* WebRTC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B3A9D0251E0481E10009343D /* POSIX.m in Sources */ = {isa = PBXBuildFile; fileRef = B3A9D0241E0481E10009343D /* POSIX.m */; };
BF9643821C34FBB300B0BBDF /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9643811C34FBB300B0BBDF /* AVFoundation.framework */; };
BF9643841C34FBBB00B0BBDF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9643831C34FBBB00B0BBDF /* AudioToolbox.framework */; };
BF9643861C34FBC100B0BBDF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9643851C34FBC100B0BBDF /* CoreGraphics.framework */; };
@@ -80,13 +75,6 @@
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
remoteInfo = RCTVibration;
};
0B8752851E26E54A004C5CAB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = KCKeepAwake;
};
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
@@ -115,62 +103,6 @@
remoteGlobalIDString = 5DBEB1501B18CEA900B34395;
remoteInfo = RNVectorIcons;
};
3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3C059A1DE3340900C268FA;
remoteInfo = yoga;
};
3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3C06751DE3340C00C268FA;
remoteInfo = "yoga-tvOS";
};
3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;
remoteInfo = cxxreact;
};
3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;
remoteInfo = "cxxreact-tvOS";
};
3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4;
remoteInfo = jschelpers;
};
3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4;
remoteInfo = "jschelpers-tvOS";
};
5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTAnimation;
};
5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
remoteInfo = "RCTAnimation-tvOS";
};
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
@@ -185,13 +117,6 @@
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText;
};
B332D04E1E54E3170086EA16 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RNBackgroundTimer;
};
B3BA19D41DC6B37B00BCD481 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
@@ -271,9 +196,6 @@
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNBackgroundTimer.xcodeproj; path = "../node_modules/react-native-background-timer/ios/RNBackgroundTimer.xcodeproj"; sourceTree = "<group>"; };
0B42DFAD1E2FD90700111B12 /* AudioMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AudioMode.m; path = app/AudioMode.m; sourceTree = "<group>"; };
0EA8C046B2BF46279796F07D /* libKCKeepAwake.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libKCKeepAwake.a; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* jitsi-meet-react.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet-react.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -286,14 +208,10 @@
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
2602576B1D0A7703001E3363 /* jitsi.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = jitsi.ttf; path = ../android/app/src/main/assets/fonts/jitsi.ttf; sourceTree = "<group>"; };
27A0018BBB2C4FD5A4F9CE71 /* libRNBackgroundTimer.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNBackgroundTimer.a; sourceTree = "<group>"; };
5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = KCKeepAwake.xcodeproj; path = "../node_modules/react-native-keep-awake/ios/KCKeepAwake.xcodeproj"; sourceTree = "<group>"; };
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
821D8ABD506944B4BDBB069B /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
B30EF2301DC0ED7C00690F45 /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
B3A9D0241E0481E10009343D /* POSIX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = POSIX.m; path = app/POSIX.m; sourceTree = "<group>"; };
B3B083EB1D4955FF0069CEE7 /* jitsi-meet-react.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "jitsi-meet-react.entitlements"; sourceTree = "<group>"; };
B96AF9B6FBC0453798399985 /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = "<group>"; };
BF9643811C34FBB300B0BBDF /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
@@ -325,9 +243,8 @@
BF9643881C34FBC800B0BBDF /* GLKit.framework in Frameworks */,
B30EF2311DC0ED7C00690F45 /* WebRTC.framework in Frameworks */,
BF96438E1C34FBE100B0BBDF /* VideoToolbox.framework in Frameworks */,
901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */,
146834051AC3E58100842450 /* libReact.a in Frameworks */,
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
@@ -337,8 +254,6 @@
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
BFC745141CB829B300673F38 /* libRCTWebRTC.a in Frameworks */,
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
146834051AC3E58100842450 /* libReact.a in Frameworks */,
7FAD39BE09A84D6AB0ABACA8 /* libRNBackgroundTimer.a in Frameworks */,
3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -388,14 +303,6 @@
name = Products;
sourceTree = "<group>";
};
0B8752821E26E54A004C5CAB /* Products */ = {
isa = PBXGroup;
children = (
0B8752861E26E54A004C5CAB /* libKCKeepAwake.a */,
);
name = Products;
sourceTree = "<group>";
};
139105B71AF99BAD00B5F7CC /* Products */ = {
isa = PBXGroup;
children = (
@@ -419,13 +326,11 @@
children = (
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
0B42DFAD1E2FD90700111B12 /* AudioMode.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FB71A68108700A75B9A /* main.m */,
B3A9D0241E0481E10009343D /* POSIX.m */,
);
name = app;
sourceTree = "<group>";
@@ -434,13 +339,7 @@
isa = PBXGroup;
children = (
146834041AC3E56700842450 /* libReact.a */,
B3BA19EF1DC6B37B00BCD481 /* libReact.a */,
3DAD3EA51DF850E9000B6D8A /* libyoga.a */,
3DAD3EA71DF850E9000B6D8A /* libyoga.a */,
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
B3BA19EF1DC6B37B00BCD481 /* libReact-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
@@ -453,15 +352,6 @@
name = Products;
sourceTree = "<group>";
};
5E91572E1DD0AC6500FF2AA8 /* Products */ = {
isa = PBXGroup;
children = (
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
};
6956B374CC3C453DB7B8E82D /* Resources */ = {
isa = PBXGroup;
children = (
@@ -483,12 +373,10 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */,
BF96438F1C34FBEB00B0BBDF /* libc.tbd */,
BF9643911C34FBF100B0BBDF /* libsqlite3.tbd */,
BF9643931C34FBF900B0BBDF /* libstdc++.tbd */,
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
@@ -499,7 +387,6 @@
BFC7450D1CB829A700673F38 /* RCTWebRTC.xcodeproj */,
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */,
0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */,
22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */,
);
name = Libraries;
@@ -536,14 +423,6 @@
name = Products;
sourceTree = "<group>";
};
B332D0301E54E3170086EA16 /* Products */ = {
isa = PBXGroup;
children = (
B332D04F1E54E3170086EA16 /* libRNBackgroundTimer.a */,
);
name = Products;
sourceTree = "<group>";
};
B3BA19B71DC6B02F00BCD481 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -579,6 +458,7 @@
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
B30EF2341DC0EEA500690F45 /* Embed Frameworks */,
B3DBBAC41DC6A3BE001DA4DD /* ShellScript */,
B35383AD1DDA0083008F406A /* ShellScript */,
);
buildRules = (
@@ -596,7 +476,7 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0820;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
@@ -621,18 +501,10 @@
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 0B8752821E26E54A004C5CAB /* Products */;
ProjectRef = 5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */;
},
{
ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
},
{
ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */;
ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
},
{
ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
@@ -673,10 +545,6 @@
ProductGroup = 146834001AC3E56700842450 /* Products */;
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
},
{
ProductGroup = B332D0301E54E3170086EA16 /* Products */;
ProjectRef = 0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */;
},
{
ProductGroup = 26D589F81D0B42EE00FC396B /* Products */;
ProjectRef = 22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */;
@@ -725,13 +593,6 @@
remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
0B8752861E26E54A004C5CAB /* libKCKeepAwake.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libKCKeepAwake.a;
remoteRef = 0B8752851E26E54A004C5CAB /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -760,62 +621,6 @@
remoteRef = 26D58A061D0B42EE00FC396B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libyoga.a;
remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libyoga.a;
remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libcxxreact.a;
remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libcxxreact.a;
remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjschelpers.a;
remoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjschelpers.a;
remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAnimation.a;
remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTAnimation-tvOS.a";
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -830,13 +635,6 @@
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
B332D04F1E54E3170086EA16 /* libRNBackgroundTimer.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNBackgroundTimer.a;
remoteRef = B332D04E1E54E3170086EA16 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
B3BA19D51DC6B37B00BCD481 /* libRCTImage-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -879,10 +677,10 @@
remoteRef = B3BA19EA1DC6B37B00BCD481 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
B3BA19EF1DC6B37B00BCD481 /* libReact.a */ = {
B3BA19EF1DC6B37B00BCD481 /* libReact-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libReact.a;
path = "libReact-tvOS.a";
remoteRef = B3BA19EE1DC6B37B00BCD481 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
@@ -937,6 +735,19 @@
shellPath = /bin/sh;
shellScript = "APP_PATH=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}\"\n\n# This script loops through the frameworks embedded in the application and\n# removes unused architectures.\nfind \"$APP_PATH\" -name '*.framework' -type d | while read -r FRAMEWORK\ndo\nFRAMEWORK_EXECUTABLE_NAME=$(defaults read \"$FRAMEWORK/Info.plist\" CFBundleExecutable)\nFRAMEWORK_EXECUTABLE_PATH=\"$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME\"\necho \"Executable is $FRAMEWORK_EXECUTABLE_PATH\"\n\nEXTRACTED_ARCHS=()\n\nfor ARCH in $ARCHS\ndo\necho \"Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME\"\nlipo -extract \"$ARCH\" \"$FRAMEWORK_EXECUTABLE_PATH\" -o \"$FRAMEWORK_EXECUTABLE_PATH-$ARCH\"\nEXTRACTED_ARCHS+=(\"$FRAMEWORK_EXECUTABLE_PATH-$ARCH\")\ndone\n\necho \"Merging extracted architectures: ${ARCHS}\"\nlipo -o \"$FRAMEWORK_EXECUTABLE_PATH-merged\" -create \"${EXTRACTED_ARCHS[@]}\"\nrm \"${EXTRACTED_ARCHS[@]}\"\n\necho \"Replacing original executable with thinned version\"\nrm \"$FRAMEWORK_EXECUTABLE_PATH\"\nmv \"$FRAMEWORK_EXECUTABLE_PATH-merged\" \"$FRAMEWORK_EXECUTABLE_PATH\"\n\ndone";
};
B3DBBAC41DC6A3BE001DA4DD /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Fabric/run\" a8ae24a58302ba79da1d312138e941f6b86e3242 256ed316263eb534e26a1ad5dcc42ca9c179af5937dd864c3e44cfefa2e8b54c";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -944,8 +755,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B3A9D0251E0481E10009343D /* POSIX.m in Sources */,
0B42DFAE1E2FD90700111B12 /* AudioMode.m in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
@@ -983,12 +792,10 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**",
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
);
INFOPLIST_FILE = app/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@@ -1001,7 +808,6 @@
);
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeet.ios;
PRODUCT_NAME = "jitsi-meet-react";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@@ -1021,12 +827,10 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**",
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
);
INFOPLIST_FILE = app/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@@ -1039,7 +843,6 @@
);
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeet.ios;
PRODUCT_NAME = "jitsi-meet-react";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
@@ -1056,19 +859,15 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -1085,8 +884,6 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
);
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -1109,10 +906,8 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -1120,7 +915,6 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -1131,8 +925,6 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
);
IPHONEOS_DEPLOYMENT_TARGET = 8.0;

Some files were not shown because too many files have changed in this diff Show More