Compare commits
5 Commits
3685
...
android-sd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c506ae5fd | ||
|
|
54e8d2c1a8 | ||
|
|
d27a94b3b5 | ||
|
|
e1710eaa38 | ||
|
|
f4467206d7 |
79
.flowconfig
@@ -2,30 +2,22 @@
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
.*/node_modules/.*/node_modules/fbjs/.*
|
||||
node_modules/react-native/Libraries/react-native/React.js
|
||||
|
||||
; 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
|
||||
node_modules/react-native/Libraries/react-native/React.js
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
.*/Libraries/react-native/React.js
|
||||
|
||||
; Ignore polyfills
|
||||
node_modules/react-native/Libraries/polyfills/.*
|
||||
.*/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
node_modules/warning/.*
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/HMRLoadingView.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
; Ignore metro
|
||||
.*/node_modules/metro/.*
|
||||
|
||||
; 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.
|
||||
@@ -48,18 +40,6 @@ emoji=true
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
; We (i.e. the jitsi-meet project) are using the haste module system on Web as
|
||||
; well, not only on React Native. Unfortunately, Flow does not support .web.js
|
||||
; by default. Override Flow's defaults to include .web.js as well. Technically,
|
||||
; we have .native.js as well so the choice of .web.js may lead to errors.
|
||||
; Practically though, it is a potential future problem that we do not have at
|
||||
; the time of this writing.
|
||||
module.file_ext=.web.js
|
||||
; Flow's defaults:
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.ios.js
|
||||
|
||||
module.system=haste
|
||||
module.system.haste.use_name_reducers=true
|
||||
# get basename
|
||||
@@ -72,11 +52,8 @@ module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
|
||||
module.system.haste.paths.blacklist=.*/__tests__/.*
|
||||
module.system.haste.paths.blacklist=.*/__mocks__/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/RNTester/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/IntegrationTests/.*
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation.js
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
@@ -87,32 +64,22 @@ suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=warn
|
||||
unsafe-getters-setters=warn
|
||||
inexact-spread=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
deprecated-utility=error
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
nonstrict-import
|
||||
sketchy-null
|
||||
unclear-type
|
||||
unsafe-getters-setters
|
||||
untyped-import
|
||||
untyped-type-import
|
||||
; We (i.e. the jitsi-meet project) are using the haste module system on Web as
|
||||
; well, not only on React Native. Unfortunately, Flow does not support .web.js
|
||||
; by default. Override Flow's defaults to include .web.js as well. Technically,
|
||||
; we have .native.js as well so the choice of .web.js may lead to errors.
|
||||
; Practically though, it is a potential future problem that we do not have at
|
||||
; the time of this writing.
|
||||
module.file_ext=.web.js
|
||||
; Flow's defaults:
|
||||
module.file_ext=.js
|
||||
module.file_ext=.jsx
|
||||
module.file_ext=.json
|
||||
|
||||
[version]
|
||||
^0.104.0
|
||||
^0.92.0
|
||||
|
||||
11
.github/ISSUE_TEMPLATE/4-security-issues.md
vendored
@@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Security issues
|
||||
about: Please email security@jitsi.org
|
||||
|
||||
---
|
||||
|
||||
We take security very seriously and develop all Jitsi projects to be secure and safe.
|
||||
|
||||
If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
|
||||
|
||||
We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.
|
||||
@@ -1,6 +1,4 @@
|
||||
osx_image: xcode11.1
|
||||
osx_image: xcode10.2
|
||||
language: objective-c
|
||||
script:
|
||||
- "./ios/travis-ci/build-ipa.sh"
|
||||
after_script:
|
||||
- sleep 10
|
||||
|
||||
14
Makefile
@@ -3,7 +3,6 @@ CLEANCSS = ./node_modules/.bin/cleancss
|
||||
DEPLOY_DIR = libs
|
||||
LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet/
|
||||
LIBFLAC_DIR = node_modules/libflacjs/dist/min/
|
||||
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist/
|
||||
NODE_SASS = ./node_modules/.bin/node-sass
|
||||
NPM = npm
|
||||
OUTPUT_DIR = .
|
||||
@@ -21,7 +20,7 @@ compile:
|
||||
clean:
|
||||
rm -fr $(BUILD_DIR)
|
||||
|
||||
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
|
||||
deploy: deploy-init deploy-appbundle deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
|
||||
|
||||
deploy-init:
|
||||
rm -fr $(DEPLOY_DIR)
|
||||
@@ -46,10 +45,6 @@ deploy-appbundle:
|
||||
$(OUTPUT_DIR)/analytics-ga.js \
|
||||
$(BUILD_DIR)/analytics-ga.min.js \
|
||||
$(BUILD_DIR)/analytics-ga.min.map \
|
||||
$(BUILD_DIR)/video-blur-effect.min.js \
|
||||
$(BUILD_DIR)/video-blur-effect.min.map \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.js \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.map \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-lib-jitsi-meet:
|
||||
@@ -66,11 +61,6 @@ deploy-libflac:
|
||||
$(LIBFLAC_DIR)/libflac4-1.3.2.min.js.mem \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-rnnoise-binary:
|
||||
cp \
|
||||
$(RNNOISE_WASM_DIR)/rnnoise.wasm \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-css:
|
||||
$(NODE_SASS) $(STYLES_MAIN) $(STYLES_BUNDLE) && \
|
||||
$(CLEANCSS) $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
|
||||
@@ -79,7 +69,7 @@ deploy-css:
|
||||
deploy-local:
|
||||
([ ! -x deploy-local.sh ] || ./deploy-local.sh)
|
||||
|
||||
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac
|
||||
dev: deploy-init deploy-css deploy-lib-jitsi-meet deploy-libflac
|
||||
$(WEBPACK_DEV_SERVER)
|
||||
|
||||
source-package:
|
||||
|
||||
90
README.md
@@ -31,9 +31,82 @@ You can get our mobile versions from here:
|
||||
* [Android](https://play.google.com/store/apps/details?id=org.jitsi.meet)
|
||||
* [iOS](https://itunes.apple.com/us/app/jitsi-meet/id1165103905)
|
||||
|
||||
## Development
|
||||
## Building the sources
|
||||
|
||||
For web development see [here](doc/development.md), and for mobile see [here](doc/mobile.md).
|
||||
Node.js >= 10 and npm >= 6 are required.
|
||||
|
||||
On Debian/Ubuntu systems, the required packages can be installed with:
|
||||
```
|
||||
sudo apt-get install npm nodejs
|
||||
cd jitsi-meet
|
||||
npm install
|
||||
```
|
||||
|
||||
To build the Jitsi Meet application, just type
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
### Working with the library sources (lib-jitsi-meet)
|
||||
|
||||
By default the library is build from its git repository sources. The default dependency path in package.json is :
|
||||
```json
|
||||
"lib-jitsi-meet": "jitsi/lib-jitsi-meet",
|
||||
```
|
||||
|
||||
To work with local copy you must change the path to:
|
||||
```json
|
||||
"lib-jitsi-meet": "file:///Users/name/local-lib-jitsi-meet-copy",
|
||||
```
|
||||
|
||||
To make the project you must force it to take the sources as 'npm update':
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make
|
||||
```
|
||||
|
||||
Or if you are making only changes to the library:
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make deploy-lib-jitsi-meet
|
||||
```
|
||||
|
||||
Alternative way is to use [npm link](https://docs.npmjs.com/cli/link).
|
||||
It allows to link `lib-jitsi-meet` dependency to local source in few steps:
|
||||
|
||||
```bash
|
||||
cd lib-jitsi-meet
|
||||
|
||||
#### create global symlink for lib-jitsi-meet package
|
||||
npm link
|
||||
|
||||
cd ../jitsi-meet
|
||||
|
||||
#### create symlink from the local node_modules folder to the global lib-jitsi-meet symlink
|
||||
npm link lib-jitsi-meet
|
||||
```
|
||||
|
||||
After changes in local `lib-jitsi-meet` repository, you can rebuild it with `npm run install` and your `jitsi-meet` repository will use that modified library.
|
||||
Note: when using node version 4.x, the make file of jitsi-meet do npm update which will delete the link. It is no longer the case with version 6.x.
|
||||
|
||||
If you do not want to use local repository anymore you should run
|
||||
```bash
|
||||
cd jitsi-meet
|
||||
npm unlink lib-jitsi-meet
|
||||
npm install
|
||||
```
|
||||
### Running with webpack-dev-server for development
|
||||
|
||||
Use it at the CLI, type
|
||||
```
|
||||
make dev
|
||||
```
|
||||
|
||||
By default the backend deployment used is `beta.meet.jit.si`. You can point the Jitsi-Meet app at a different backend by using a proxy server. To do this, set the WEBPACK_DEV_SERVER_PROXY_TARGET variable:
|
||||
```
|
||||
export WEBPACK_DEV_SERVER_PROXY_TARGET=https://your-example-server.com
|
||||
make dev
|
||||
```
|
||||
|
||||
The app should be running at https://localhost:8080/
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -45,8 +118,7 @@ see our [guidelines for contributing](CONTRIBUTING.md).
|
||||
Jitsi Meet provides a very flexible way of embedding in external applications by using the [Jitsi Meet API](doc/api.md).
|
||||
|
||||
## Security
|
||||
|
||||
WebRTC does not (yet) provide a way of conducting multi-party conversations with end-to-end encryption.
|
||||
WebRTC does not provide a way of conducting multi-party conversations with end-to-end encryption.
|
||||
Unless you consistently compare DTLS fingerprints with your peers vocally, the same goes for one-to-one calls.
|
||||
As a result, your stream is encrypted on the network but decrypted on the machine that hosts the bridge when using Jitsi Meet.
|
||||
|
||||
@@ -58,13 +130,9 @@ Jitsi Meet in terms of security.
|
||||
The [meet.jit.si](https://meet.jit.si) service is maintained by the Jitsi team
|
||||
at [8x8](https://8x8.com).
|
||||
|
||||
## Security issues
|
||||
|
||||
We take security very seriously and develop all Jitsi projects to be secure and safe.
|
||||
|
||||
If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
|
||||
|
||||
**We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.**
|
||||
## Mobile app
|
||||
Jitsi Meet is also available as a React Native app for Android and iOS.
|
||||
Instructions on how to build it can be found [here](doc/mobile.md).
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
@@ -207,6 +207,24 @@ public class MainActivity extends FragmentActivity implements JitsiMeetActivityI
|
||||
|
||||
</details>
|
||||
|
||||
Starting with SDK version 1.22, a Glide module must be provided by the host app.
|
||||
This makes it possible to use the Glide image processing library from both the
|
||||
SDK and the host app itself.
|
||||
|
||||
You can use the code in `JitsiGlideModule.java` and adjust the package name.
|
||||
When building, add the following code in your `app/build.gradle` file, adjusting
|
||||
the Glide version to match the one in https://github.com/jitsi/jitsi-meet/blob/master/android/build.gradle
|
||||
|
||||
```
|
||||
// Glide
|
||||
implementation("com.github.bumptech.glide:glide:${glideVersion}") {
|
||||
exclude group: "com.android.support", module: "glide"
|
||||
}
|
||||
implementation("com.github.bumptech.glide:annotations:${glideVersion}") {
|
||||
exclude group: "com.android.support", module: "annotations"
|
||||
}
|
||||
```
|
||||
|
||||
### JitsiMeetActivity
|
||||
|
||||
This class encapsulates a high level API in the form of an Android `FragmentActivity`
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>app</name>
|
||||
<comment>Project app created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,2 +0,0 @@
|
||||
connection.project.dir=..
|
||||
eclipse.preferences.version=1
|
||||
@@ -34,6 +34,8 @@ android {
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro'
|
||||
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}"
|
||||
buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}"
|
||||
}
|
||||
@@ -68,8 +70,8 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||
implementation "com.android.support:support-v4:${rootProject.ext.supportLibVersion}"
|
||||
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
|
||||
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
implementation 'com.google.android.gms:play-services-auth:16.0.1'
|
||||
@@ -86,6 +88,15 @@ dependencies {
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
|
||||
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
|
||||
|
||||
// Glide
|
||||
implementation("com.github.bumptech.glide:glide:${rootProject.ext.glideVersion}") {
|
||||
exclude group: "com.android.support", module: "glide"
|
||||
}
|
||||
implementation("com.github.bumptech.glide:annotations:${rootProject.ext.glideVersion}") {
|
||||
exclude group: "com.android.support", module: "annotations"
|
||||
}
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:${rootProject.ext.glideVersion}"
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
|
||||
5
android/app/proguard-rules-debug.pro
Normal file
@@ -0,0 +1,5 @@
|
||||
-include proguard-rules.pro
|
||||
|
||||
# Disabling obfuscation is useful if you collect stack traces from production crashes
|
||||
# (unless you are using a system that supports de-obfuscate the stack traces).
|
||||
-dontobfuscate
|
||||
22
android/app/proguard-rules.pro
vendored
@@ -9,6 +9,13 @@
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# React Native
|
||||
|
||||
# Keep our interfaces so they can be used by other ProGuard rules.
|
||||
@@ -53,9 +60,19 @@
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-keep class okio.** { *; }
|
||||
-dontwarn okio.**
|
||||
|
||||
# FastImage + Glide
|
||||
|
||||
-keep public class com.dylanvann.fastimage.* {*;}
|
||||
-keep public class com.dylanvann.fastimage.** {*;}
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
||||
# WebRTC
|
||||
|
||||
-keep class org.webrtc.** { *; }
|
||||
@@ -83,6 +100,3 @@
|
||||
-dontwarn javax.servlet.**
|
||||
|
||||
# ^^^ We added the above when we switched minifyEnabled on.
|
||||
|
||||
# Rule to avoid build errors related to SVGs.
|
||||
-keep public class com.horcrux.svg.** {*;}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.jitsi.meet;
|
||||
|
||||
import com.bumptech.glide.annotation.GlideModule;
|
||||
import com.bumptech.glide.module.AppGlideModule;
|
||||
|
||||
/**
|
||||
* An AppGlideModule needs to be present for image loading events to work in
|
||||
* react-native-fast-image. However, if this is defined by the SDK it will cause trouble with
|
||||
* apps which are using Glide themselves.
|
||||
*
|
||||
* In order to avoid the problem, define a Jitsi Glide module here, so applications already using
|
||||
* it are not in trouble.
|
||||
*/
|
||||
@GlideModule
|
||||
public final class JitsiGlideModule extends AppGlideModule {
|
||||
}
|
||||
@@ -21,13 +21,14 @@ import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeet;
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
import org.jitsi.meet.sdk.JitsiMeetConferenceOptions;
|
||||
import org.jitsi.meet.sdk.JitsiMeetUserInfo;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#66A8DD</color>
|
||||
</resources>
|
||||
@@ -25,10 +25,9 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
// React Native (JS, Obj-C sources, Android binaries) is installed from npm.
|
||||
// React Native (JS, Obj-C sources, Android binaries) is installed from
|
||||
// npm.
|
||||
maven { url "$rootDir/../node_modules/react-native/android" }
|
||||
// Android JSC is installed from npm.
|
||||
maven { url("$rootDir/../node_modules/jsc-android/dist") }
|
||||
}
|
||||
|
||||
// Make sure we use the react-native version in node_modules and not the one
|
||||
@@ -75,13 +74,6 @@ allprojects {
|
||||
def versionQualifierNumber = (int)(((new Date().getTime()/1000) - 1546297200) / 10)
|
||||
|
||||
afterEvaluate { project ->
|
||||
if (project.plugins.hasPlugin('android') || project.plugins.hasPlugin('android-library')) {
|
||||
project.android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
}
|
||||
}
|
||||
|
||||
if (project.name.startsWith('react-native-')) {
|
||||
def npmManifest = project.file('../package.json')
|
||||
def json = new JsonSlurper().parseText(npmManifest.text)
|
||||
@@ -91,6 +83,17 @@ allprojects {
|
||||
|
||||
project.version = "${json.version}-jitsi-${versionQualifierNumber}"
|
||||
|
||||
project.android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
if (rootProject.ext.has('buildToolsVersion')) {
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
}
|
||||
}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.source
|
||||
@@ -161,6 +164,10 @@ ext {
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Glide
|
||||
excludeAppGlideModule = true
|
||||
glideVersion = "4.7.1" // keep in sync with react-native-fast-image
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
}
|
||||
|
||||
@@ -17,8 +17,5 @@
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
appVersion=19.4.0
|
||||
sdkVersion=2.4.0
|
||||
appVersion=19.2.0
|
||||
sdkVersion=2.2.2
|
||||
|
||||
@@ -10,7 +10,6 @@ MVN_HTTP=0
|
||||
DEFAULT_SDK_VERSION=$(grep sdkVersion ${THIS_DIR}/../gradle.properties | cut -d"=" -f2)
|
||||
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
|
||||
RN_VERSION=$(jq -r '.dependencies."react-native"' ${THIS_DIR}/../../package.json)
|
||||
JSC_VERSION="r"$(jq -r '.dependencies."jsc-android"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -d . -f 1 | cut -c 2-)
|
||||
DO_GIT_TAG=${GIT_TAG:-0}
|
||||
|
||||
if [[ $THE_MVN_REPO == http* ]]; then
|
||||
@@ -38,20 +37,14 @@ if [[ $MVN_HTTP == 1 ]]; then
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom || true
|
||||
popd
|
||||
# Push JSC
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-DrepositoryId=${MVN_REPO_ID} \
|
||||
-Dfile=android-jsc-${JSC_VERSION}.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=android-jsc-${JSC_VERSION}.pom || true
|
||||
popd
|
||||
else
|
||||
# Push React Native, if necessary
|
||||
# Check if an SDK with that same version has already been released
|
||||
if [[ -d ${MVN_REPO}/org/jitsi/react/jitsi-meet-sdk/${SDK_VERSION} ]]; then
|
||||
echo "There is already a release with that version in the Maven repo!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# First push React Native, if necessary
|
||||
if [[ ! -d ${MVN_REPO}/com/facebook/react/react-native/${RN_VERSION} ]]; then
|
||||
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
|
||||
@@ -64,26 +57,6 @@ else
|
||||
-DpomFile=react-native-${RN_VERSION}.pom
|
||||
popd
|
||||
fi
|
||||
|
||||
# Push JSC, if necessary
|
||||
if [[ ! -d ${MVN_REPO}/org/webkit/android-jsc/${JSC_VERSION} ]]; then
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-Dfile=android-jsc-${JSC_VERSION}.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=android-jsc-${JSC_VERSION}.pom
|
||||
popd
|
||||
fi
|
||||
|
||||
# Check if an SDK with that same version has already been released
|
||||
if [[ -d ${MVN_REPO}/org/jitsi/react/jitsi-meet-sdk/${SDK_VERSION} ]]; then
|
||||
echo "There is already a release with that version in the Maven repo!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Now build and publish the Jitsi Meet SDK and its dependencies
|
||||
|
||||
@@ -8,14 +8,13 @@ THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOUR
|
||||
export RCT_METRO_PORT="${RCT_METRO_PORT:=8081}"
|
||||
echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${THIS_DIR}/../../node_modules/react-native/scripts/.packager.env"
|
||||
|
||||
adb reverse tcp:8081 tcp:8081
|
||||
|
||||
if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then
|
||||
if ! curl -s "http://localhost:${RCT_METRO_PORT}/status" | grep -q "packager-status:running" ; then
|
||||
echo "Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
adb reverse tcp:8081 tcp:8081
|
||||
CMD="${THIS_DIR}/../../node_modules/react-native/scripts/launchPackager.command"
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
open -g "${CMD}" || echo "Can't start packager automatically"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sdk</name>
|
||||
<comment>Project sdk created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,2 +0,0 @@
|
||||
connection.project.dir=..
|
||||
eclipse.preferences.version=1
|
||||
@@ -36,34 +36,32 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||
implementation 'androidx.fragment:fragment:1.0.0'
|
||||
implementation "com.android.support:support-v4:${rootProject.ext.supportLibVersion}"
|
||||
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
|
||||
|
||||
api 'com.facebook.react:react-native:+'
|
||||
implementation 'org.webkit:android-jsc:+'
|
||||
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
implementation 'com.squareup.duktape:duktape-android:1.3.0'
|
||||
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
implementation 'com.amplitude:android-sdk:2.14.1'
|
||||
implementation(project(":react-native-google-signin")) {
|
||||
exclude group: 'com.google.android.gms'
|
||||
exclude group: 'androidx'
|
||||
exclude group: 'com.android.support'
|
||||
}
|
||||
}
|
||||
|
||||
implementation project(':react-native-background-timer')
|
||||
implementation project(':react-native-calendar-events')
|
||||
implementation project(':react-native-community-async-storage')
|
||||
implementation project(':react-native-community_netinfo')
|
||||
implementation(project(':react-native-fast-image')) {
|
||||
exclude group: 'com.android.support'
|
||||
}
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-linear-gradient')
|
||||
implementation project(':react-native-sound')
|
||||
implementation project(':react-native-svg')
|
||||
implementation project(':react-native-vector-icons')
|
||||
implementation project(':react-native-webrtc')
|
||||
implementation project(':react-native-webview')
|
||||
|
||||
@@ -141,14 +139,19 @@ android.libraryVariants.all { def variant ->
|
||||
mergeAssetsTask.doLast {
|
||||
def assetsDir = mergeAssetsTask.outputDir
|
||||
|
||||
// Bundle fonts
|
||||
//
|
||||
copy {
|
||||
from("${projectDir}/../../fonts/jitsi.ttf")
|
||||
into("${assetsDir}/fonts")
|
||||
}
|
||||
|
||||
// Bundle sounds
|
||||
//
|
||||
copy {
|
||||
from("${projectDir}/../../sounds/incomingMessage.wav")
|
||||
from("${projectDir}/../../sounds/joined.wav")
|
||||
from("${projectDir}/../../sounds/left.wav")
|
||||
from("${projectDir}/../../sounds/liveStreamingOn.mp3")
|
||||
from("${projectDir}/../../sounds/liveStreamingOff.mp3")
|
||||
from("${projectDir}/../../sounds/outgoingRinging.wav")
|
||||
from("${projectDir}/../../sounds/outgoingStart.wav")
|
||||
from("${projectDir}/../../sounds/recordingOn.mp3")
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.facebook.react.bridge.ReadableMap;
|
||||
import com.amplitude.api.Amplitude;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -91,7 +90,7 @@ class AmplitudeModule
|
||||
JSONObject eventProps = new JSONObject(eventPropsString);
|
||||
Amplitude.getInstance(instanceName).logEvent(eventType, eventProps);
|
||||
} catch (JSONException e) {
|
||||
JitsiMeetLogger.e(e, "Error logging event");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ import android.content.pm.PackageManager;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
@@ -36,8 +37,6 @@ import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -122,7 +121,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
case DEVICE_SPEAKER:
|
||||
return android.telecom.CallAudioState.ROUTE_SPEAKER;
|
||||
default:
|
||||
JitsiMeetLogger.e(TAG + " Unsupported device name: " + audioDevice);
|
||||
Log.e(TAG, "Unsupported device name: " + audioDevice);
|
||||
return android.telecom.CallAudioState.ROUTE_EARPIECE;
|
||||
}
|
||||
}
|
||||
@@ -219,7 +218,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
|
||||
availableDevices = devices;
|
||||
JitsiMeetLogger.i(TAG + " Available audio devices: " +
|
||||
Log.d(TAG, "Available audio devices: " +
|
||||
availableDevices.toString());
|
||||
|
||||
// Reset user selection
|
||||
@@ -231,6 +230,19 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* {@link Runnable} for running update operation on the main thread.
|
||||
*/
|
||||
private final Runnable updateAudioRouteRunner
|
||||
= new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mode != -1) {
|
||||
updateAudioRoute(mode);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Audio mode currently in use.
|
||||
*/
|
||||
@@ -244,11 +256,6 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
private static final String DEVICE_HEADPHONES = "HEADPHONES";
|
||||
private static final String DEVICE_SPEAKER = "SPEAKER";
|
||||
|
||||
/**
|
||||
* Device change event.
|
||||
*/
|
||||
private static final String DEVICE_CHANGE_EVENT = "org.jitsi.meet:features/audio-mode#devices-update";
|
||||
|
||||
/**
|
||||
* List of currently available audio devices.
|
||||
*/
|
||||
@@ -296,7 +303,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// Do an initial detection on Android >= M.
|
||||
onAudioDeviceChange();
|
||||
runInAudioThread(onAudioDeviceChangeRunner);
|
||||
} else {
|
||||
// On Android < M, detect if we have an earpiece.
|
||||
PackageManager pm = reactContext.getPackageManager();
|
||||
@@ -320,7 +327,6 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
public Map<String, Object> getConstants() {
|
||||
Map<String, Object> constants = new HashMap<>();
|
||||
|
||||
constants.put("DEVICE_CHANGE_EVENT", DEVICE_CHANGE_EVENT);
|
||||
constants.put("AUDIO_CALL", AUDIO_CALL);
|
||||
constants.put("DEFAULT", DEFAULT);
|
||||
constants.put("VIDEO_CALL", VIDEO_CALL);
|
||||
@@ -329,26 +335,31 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies JS land that the devices list has changed.
|
||||
* Gets the list of available audio device categories, i.e. 'bluetooth',
|
||||
* 'earpiece ', 'speaker', 'headphones'.
|
||||
*
|
||||
* @param promise a {@link Promise} which will be resolved with an object
|
||||
* containing a 'devices' key with a list of devices, plus a
|
||||
* 'selected' key with the selected one.
|
||||
*/
|
||||
private void notifyDevicesChanged() {
|
||||
@ReactMethod
|
||||
public void getAudioDevices(final Promise promise) {
|
||||
runInAudioThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
WritableArray data = Arguments.createArray();
|
||||
final boolean hasHeadphones = availableDevices.contains(DEVICE_HEADPHONES);
|
||||
WritableMap map = Arguments.createMap();
|
||||
map.putString("selected", selectedDevice);
|
||||
WritableArray devices = Arguments.createArray();
|
||||
for (String device : availableDevices) {
|
||||
if (hasHeadphones && device.equals(DEVICE_EARPIECE)) {
|
||||
// Skip earpiece when headphones are plugged in.
|
||||
if (mode == VIDEO_CALL && device.equals(DEVICE_EARPIECE)) {
|
||||
// Skip earpiece when in video call mode.
|
||||
continue;
|
||||
}
|
||||
WritableMap deviceInfo = Arguments.createMap();
|
||||
deviceInfo.putString("type", device);
|
||||
deviceInfo.putBoolean("selected", device.equals(selectedDevice));
|
||||
data.pushMap(deviceInfo);
|
||||
devices.pushString(device);
|
||||
}
|
||||
ReactInstanceManagerHolder.emitEvent(DEVICE_CHANGE_EVENT, data);
|
||||
JitsiMeetLogger.i(TAG + " Updating audio device list");
|
||||
map.putArray("devices", devices);
|
||||
|
||||
promise.resolve(map);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -431,7 +442,8 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
if (audioDevicesChanged) {
|
||||
supportedRouteMask = newSupportedRoutes;
|
||||
availableDevices = routesToDeviceNames(supportedRouteMask);
|
||||
JitsiMeetLogger.i(TAG + " Available audio devices: "
|
||||
Log.d(TAG,
|
||||
"Available audio devices: "
|
||||
+ availableDevices.toString());
|
||||
}
|
||||
|
||||
@@ -465,7 +477,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
switch (focusChange) {
|
||||
case AudioManager.AUDIOFOCUS_GAIN: {
|
||||
JitsiMeetLogger.d(TAG + " Audio focus gained");
|
||||
Log.d(TAG, "Audio focus gained");
|
||||
// Some other application potentially stole our audio focus
|
||||
// temporarily. Restore our mode.
|
||||
if (audioFocusLost) {
|
||||
@@ -477,7 +489,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
|
||||
JitsiMeetLogger.d(TAG + " Audio focus lost");
|
||||
Log.d(TAG, "Audio focus lost");
|
||||
audioFocusLost = true;
|
||||
break;
|
||||
}
|
||||
@@ -504,13 +516,13 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
@Override
|
||||
public void run() {
|
||||
if (!availableDevices.contains(device)) {
|
||||
JitsiMeetLogger.w(TAG + " Audio device not available: " + device);
|
||||
Log.d(TAG, "Audio device not available: " + device);
|
||||
userSelectedDevice = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode != -1) {
|
||||
JitsiMeetLogger.i(TAG + " User selected device set to: " + device);
|
||||
Log.d(TAG, "User selected device set to: " + device);
|
||||
userSelectedDevice = device;
|
||||
updateAudioRoute(mode);
|
||||
}
|
||||
@@ -572,7 +584,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
return;
|
||||
}
|
||||
|
||||
runInAudioThread(new Runnable() {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean success;
|
||||
@@ -581,7 +593,10 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
success = updateAudioRoute(mode);
|
||||
} catch (Throwable e) {
|
||||
success = false;
|
||||
JitsiMeetLogger.e(e, TAG + " Failed to update audio route for mode: " + mode);
|
||||
Log.e(
|
||||
TAG,
|
||||
"Failed to update audio route for mode: " + mode,
|
||||
e);
|
||||
}
|
||||
if (success) {
|
||||
AudioModeModule.this.mode = mode;
|
||||
@@ -592,7 +607,8 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
"Failed to set audio mode to " + mode);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
runInAudioThread(r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -617,14 +633,14 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
@Override
|
||||
public void onAudioDevicesAdded(
|
||||
AudioDeviceInfo[] addedDevices) {
|
||||
JitsiMeetLogger.d(TAG + " Audio devices added");
|
||||
Log.d(TAG, "Audio devices added");
|
||||
onAudioDeviceChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioDevicesRemoved(
|
||||
AudioDeviceInfo[] removedDevices) {
|
||||
JitsiMeetLogger.d(TAG + " Audio devices removed");
|
||||
Log.d(TAG, "Audio devices removed");
|
||||
onAudioDeviceChange();
|
||||
}
|
||||
};
|
||||
@@ -643,7 +659,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
BroadcastReceiver wiredHeadsetReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
JitsiMeetLogger.d(TAG + " Wired headset added / removed");
|
||||
Log.d(TAG, "Wired headset added / removed");
|
||||
onHeadsetDeviceChange();
|
||||
}
|
||||
};
|
||||
@@ -661,7 +677,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
* {@code false}, otherwise.
|
||||
*/
|
||||
private boolean updateAudioRoute(int mode) {
|
||||
JitsiMeetLogger.i(TAG + " Update audio route for mode: " + mode);
|
||||
Log.d(TAG, "Update audio route for mode: " + mode);
|
||||
|
||||
if (mode == DEFAULT) {
|
||||
if (!useConnectionService()) {
|
||||
@@ -674,7 +690,6 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
selectedDevice = null;
|
||||
userSelectedDevice = null;
|
||||
|
||||
notifyDevicesChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -687,12 +702,13 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
AudioManager.STREAM_VOICE_CALL,
|
||||
AudioManager.AUDIOFOCUS_GAIN)
|
||||
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
|
||||
JitsiMeetLogger.w(TAG + " Audio focus request failed");
|
||||
Log.d(TAG, "Audio focus request failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean bluetoothAvailable = availableDevices.contains(DEVICE_BLUETOOTH);
|
||||
boolean earpieceAvailable = availableDevices.contains(DEVICE_EARPIECE);
|
||||
boolean headsetAvailable = availableDevices.contains(DEVICE_HEADPHONES);
|
||||
|
||||
// Pick the desired device based on what's available and the mode.
|
||||
@@ -701,6 +717,8 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
audioDevice = DEVICE_BLUETOOTH;
|
||||
} else if (headsetAvailable) {
|
||||
audioDevice = DEVICE_HEADPHONES;
|
||||
} else if (mode == AUDIO_CALL && earpieceAvailable) {
|
||||
audioDevice = DEVICE_EARPIECE;
|
||||
} else {
|
||||
audioDevice = DEVICE_SPEAKER;
|
||||
}
|
||||
@@ -718,7 +736,7 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
|
||||
selectedDevice = audioDevice;
|
||||
JitsiMeetLogger.i(TAG + " Selected audio device: " + audioDevice);
|
||||
Log.d(TAG, "Selected audio device: " + audioDevice);
|
||||
|
||||
if (useConnectionService()) {
|
||||
setAudioRoute(audioDevice);
|
||||
@@ -726,7 +744,6 @@ class AudioModeModule extends ReactContextBaseJavaModule
|
||||
setAudioRoutePreO(audioDevice);
|
||||
}
|
||||
|
||||
notifyDevicesChanged();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ package org.jitsi.meet.sdk;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.widget.FrameLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
@@ -111,7 +111,8 @@ public abstract class BaseReactView<ListenerT>
|
||||
|
||||
setBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
ReactInstanceManagerHolder.initReactInstanceManager((Activity)context);
|
||||
ReactInstanceManagerHolder.initReactInstanceManager(
|
||||
((Activity) context).getApplication());
|
||||
|
||||
// Hook this BaseReactView into ExternalAPI.
|
||||
externalAPIScope = UUID.randomUUID().toString();
|
||||
|
||||
@@ -24,8 +24,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Helper class to detect and handle Bluetooth device changes. It monitors
|
||||
@@ -78,7 +77,7 @@ class BluetoothHeadsetMonitor {
|
||||
= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
if (!audioManager.isBluetoothScoAvailableOffCall()) {
|
||||
JitsiMeetLogger.w(AudioModeModule.TAG + " Bluetooth SCO is not available");
|
||||
Log.w(AudioModeModule.TAG, "Bluetooth SCO is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -94,7 +93,7 @@ class BluetoothHeadsetMonitor {
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (adapter == null) {
|
||||
JitsiMeetLogger.w(AudioModeModule.TAG + " Device doesn't support Bluetooth");
|
||||
Log.w(AudioModeModule.TAG, "Device doesn't support Bluetooth");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -149,7 +148,9 @@ class BluetoothHeadsetMonitor {
|
||||
switch (state) {
|
||||
case BluetoothHeadset.STATE_CONNECTED:
|
||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||
JitsiMeetLogger.d(AudioModeModule.TAG + " BT headset connection state changed: " + state);
|
||||
Log.d(
|
||||
AudioModeModule.TAG,
|
||||
"BT headset connection state changed: " + state);
|
||||
updateDevices();
|
||||
break;
|
||||
}
|
||||
@@ -163,7 +164,9 @@ class BluetoothHeadsetMonitor {
|
||||
switch (state) {
|
||||
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
|
||||
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
|
||||
JitsiMeetLogger.d(AudioModeModule.TAG + " BT SCO connection state changed: " + state);
|
||||
Log.d(
|
||||
AudioModeModule.TAG,
|
||||
"BT SCO connection state changed: " + state);
|
||||
updateDevices();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.telecom.CallAudioState;
|
||||
import android.telecom.Connection;
|
||||
import android.telecom.ConnectionRequest;
|
||||
@@ -13,14 +14,12 @@ import android.telecom.PhoneAccount;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telecom.VideoProfile;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -130,7 +129,9 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
if (connection != null) {
|
||||
connection.setActive();
|
||||
} else {
|
||||
JitsiMeetLogger.e("%s setConnectionActive - no connection for UUID: %s", TAG, callUUID);
|
||||
Log.e(TAG, String.format(
|
||||
"setConnectionActive - no connection for UUID: %s",
|
||||
callUUID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +162,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
connection.setDisconnected(cause);
|
||||
connection.destroy();
|
||||
} else {
|
||||
JitsiMeetLogger.e(TAG + " endCall no connection for UUID: " + callUUID);
|
||||
Log.e(TAG, "endCall no connection for UUID: " + callUUID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,14 +194,15 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
boolean hasVideo
|
||||
= callState.getBoolean(ConnectionImpl.KEY_HAS_VIDEO);
|
||||
|
||||
JitsiMeetLogger.i(" %s updateCall: %s hasVideo: %s", TAG, callUUID, hasVideo);
|
||||
Log.d(TAG, String.format(
|
||||
"updateCall: %s hasVideo: %s", callUUID, hasVideo));
|
||||
connection.setVideoState(
|
||||
hasVideo
|
||||
? VideoProfile.STATE_BIDIRECTIONAL
|
||||
: VideoProfile.STATE_AUDIO_ONLY);
|
||||
}
|
||||
} else {
|
||||
JitsiMeetLogger.e(TAG + " updateCall no connection for UUID: " + callUUID);
|
||||
Log.e(TAG, "updateCall no connection for UUID: " + callUUID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,11 +238,13 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
= unregisterStartCallPromise(connection.getCallUUID());
|
||||
|
||||
if (startCallPromise != null) {
|
||||
JitsiMeetLogger.d(TAG + " onCreateOutgoingConnection " + connection.getCallUUID());
|
||||
Log.d(TAG,
|
||||
"onCreateOutgoingConnection " + connection.getCallUUID());
|
||||
startCallPromise.resolve(null);
|
||||
} else {
|
||||
JitsiMeetLogger.e(
|
||||
TAG + " onCreateOutgoingConnection: no start call Promise for " + connection.getCallUUID());
|
||||
Log.e(TAG, String.format(
|
||||
"onCreateOutgoingConnection: no start call Promise for %s",
|
||||
connection.getCallUUID()));
|
||||
}
|
||||
|
||||
return connection;
|
||||
@@ -264,7 +268,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
PhoneAccountHandle theAccountHandle = request.getAccountHandle();
|
||||
String callUUID = theAccountHandle.getId();
|
||||
|
||||
JitsiMeetLogger.e(TAG + " onCreateOutgoingConnectionFailed " + callUUID);
|
||||
Log.e(TAG, "onCreateOutgoingConnectionFailed " + callUUID);
|
||||
|
||||
if (callUUID != null) {
|
||||
Promise startCallPromise = unregisterStartCallPromise(callUUID);
|
||||
@@ -274,10 +278,12 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
"CREATE_OUTGOING_CALL_FAILED",
|
||||
"The request has been denied by the system");
|
||||
} else {
|
||||
JitsiMeetLogger.e(TAG + " startCallFailed - no start call Promise for UUID: " + callUUID);
|
||||
Log.e(TAG, String.format(
|
||||
"startCallFailed - no start call Promise for UUID: %s",
|
||||
callUUID));
|
||||
}
|
||||
} else {
|
||||
JitsiMeetLogger.e(TAG + " onCreateOutgoingConnectionFailed - no call UUID");
|
||||
Log.e(TAG, "onCreateOutgoingConnectionFailed - no call UUID");
|
||||
}
|
||||
|
||||
unregisterPhoneAccount(theAccountHandle);
|
||||
@@ -289,10 +295,10 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
if (phoneAccountHandle != null) {
|
||||
telecom.unregisterPhoneAccount(phoneAccountHandle);
|
||||
} else {
|
||||
JitsiMeetLogger.e(TAG + " unregisterPhoneAccount - account handle is null");
|
||||
Log.e(TAG, "unregisterPhoneAccount - account handle is null");
|
||||
}
|
||||
} else {
|
||||
JitsiMeetLogger.e(TAG + " unregisterPhoneAccount - telecom is null");
|
||||
Log.e(TAG, "unregisterPhoneAccount - telecom is null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +357,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
*/
|
||||
@Override
|
||||
public void onDisconnect() {
|
||||
JitsiMeetLogger.i(TAG + " onDisconnect " + getCallUUID());
|
||||
Log.d(TAG, "onDisconnect " + getCallUUID());
|
||||
WritableNativeMap data = new WritableNativeMap();
|
||||
data.putString("callUUID", getCallUUID());
|
||||
ReactInstanceManagerHolder.emitEvent(
|
||||
@@ -371,7 +377,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
*/
|
||||
@Override
|
||||
public void onAbort() {
|
||||
JitsiMeetLogger.i(TAG + " onAbort " + getCallUUID());
|
||||
Log.d(TAG, "onAbort " + getCallUUID());
|
||||
WritableNativeMap data = new WritableNativeMap();
|
||||
data.putString("callUUID", getCallUUID());
|
||||
ReactInstanceManagerHolder.emitEvent(
|
||||
@@ -389,7 +395,9 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
// What ?! Android will still call this method even if we do not add
|
||||
// the HOLD capability, so do the same thing as on abort.
|
||||
// TODO implement HOLD
|
||||
JitsiMeetLogger.w(TAG + " onHold %s - HOLD is not supported, aborting the call...", getCallUUID());
|
||||
Log.d(TAG, String.format(
|
||||
"onHold %s - HOLD is not supported, aborting the call...",
|
||||
getCallUUID()));
|
||||
this.onAbort();
|
||||
}
|
||||
|
||||
@@ -402,7 +410,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
*/
|
||||
@Override
|
||||
public void onCallAudioStateChanged(CallAudioState state) {
|
||||
JitsiMeetLogger.d(TAG + " onCallAudioStateChanged: " + state);
|
||||
Log.d(TAG, "onCallAudioStateChanged: " + state);
|
||||
AudioModeModule audioModeModule
|
||||
= ReactInstanceManagerHolder
|
||||
.getNativeModule(AudioModeModule.class);
|
||||
@@ -418,8 +426,10 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
*/
|
||||
@Override
|
||||
public void onStateChanged(int state) {
|
||||
JitsiMeetLogger.d(
|
||||
"%s onStateChanged: %s %s", TAG, Connection.stateToString(state), getCallUUID());
|
||||
Log.d(TAG,
|
||||
String.format("onStateChanged: %s %s",
|
||||
Connection.stateToString(state),
|
||||
getCallUUID()));
|
||||
|
||||
if (state == STATE_DISCONNECTED) {
|
||||
removeConnection(this);
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
/**
|
||||
* Module implementing an API for sending events from JavaScript to native code.
|
||||
*/
|
||||
@@ -76,11 +76,11 @@ class ExternalAPIModule
|
||||
BaseReactView view = BaseReactView.findViewByExternalAPIScope(scope);
|
||||
|
||||
if (view != null) {
|
||||
JitsiMeetLogger.d(TAG + " Sending event: " + name + " with data: " + data);
|
||||
Log.d(TAG, "Sending event: " + name + " with data: " + data);
|
||||
try {
|
||||
view.onExternalAPIEvent(name, data);
|
||||
} catch(Exception e) {
|
||||
JitsiMeetLogger.e(e, TAG + " onExternalAPIEvent: error sending event");
|
||||
Log.e(TAG, "onExternalAPIEvent: error sending event", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.squareup.duktape.Duktape;
|
||||
|
||||
@ReactModule(name = JavaScriptSandboxModule.NAME)
|
||||
class JavaScriptSandboxModule extends ReactContextBaseJavaModule {
|
||||
public static final String NAME = "JavaScriptSandbox";
|
||||
|
||||
public JavaScriptSandboxModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given code in a Duktape VM.
|
||||
* @param code - The code that needs to evaluated.
|
||||
* @param promise - Resolved with the output in case of success or rejected with an exception
|
||||
* in case of failure.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void evaluate(String code, Promise promise) {
|
||||
Duktape vm = Duktape.create();
|
||||
try {
|
||||
Object res = vm.evaluate(code);
|
||||
promise.resolve(res.toString());
|
||||
} catch (Throwable tr) {
|
||||
promise.reject(tr);
|
||||
} finally {
|
||||
vm.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
@@ -33,9 +33,6 @@ public class JitsiMeet {
|
||||
}
|
||||
|
||||
public static void setDefaultConferenceOptions(JitsiMeetConferenceOptions options) {
|
||||
if (options != null && options.getRoom() != null) {
|
||||
throw new RuntimeException("'room' must be null in the default conference options");
|
||||
}
|
||||
defaultConferenceOptions = options;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,12 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -209,19 +208,19 @@ public class JitsiMeetActivity extends FragmentActivity
|
||||
|
||||
@Override
|
||||
public void onConferenceJoined(Map<String, Object> data) {
|
||||
JitsiMeetLogger.i("Conference joined: " + data);
|
||||
Log.d(TAG, "Conference joined: " + data);
|
||||
// Launch the service for the ongoing notification.
|
||||
JitsiMeetOngoingConferenceService.launch(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConferenceTerminated(Map<String, Object> data) {
|
||||
JitsiMeetLogger.i("Conference terminated: " + data);
|
||||
Log.d(TAG, "Conference terminated: " + data);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConferenceWillJoin(Map<String, Object> data) {
|
||||
JitsiMeetLogger.i("Conference will join: " + data);
|
||||
Log.d(TAG, "Conference will join: " + data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.os.Build;
|
||||
import com.calendarevents.CalendarEventsPackage;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
|
||||
/**
|
||||
@@ -118,13 +117,7 @@ public class JitsiMeetActivityDelegate {
|
||||
= ReactInstanceManagerHolder.getReactInstanceManager();
|
||||
|
||||
if (reactInstanceManager != null) {
|
||||
// Try to avoid a crash because some devices trip on this assert:
|
||||
// https://github.com/facebook/react-native/blob/df4e67fe75d781d1eb264128cadf079989542755/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java#L512
|
||||
// Why this happens is a mystery wrapped in an enigma.
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext != null && activity == reactContext.getCurrentActivity()) {
|
||||
reactInstanceManager.onHostPause(activity);
|
||||
}
|
||||
reactInstanceManager.onHostPause(activity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionAwareActivity;
|
||||
|
||||
|
||||
@@ -72,46 +72,6 @@ public class JitsiMeetConferenceOptions implements Parcelable {
|
||||
*/
|
||||
private JitsiMeetUserInfo userInfo;
|
||||
|
||||
public URL getServerURL() {
|
||||
return serverURL;
|
||||
}
|
||||
|
||||
public String getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public Bundle getColorScheme() {
|
||||
return colorScheme;
|
||||
}
|
||||
|
||||
public Bundle getFeatureFlags() {
|
||||
return featureFlags;
|
||||
}
|
||||
|
||||
public boolean getAudioMuted() {
|
||||
return audioMuted;
|
||||
}
|
||||
|
||||
public boolean getAudioOnly() {
|
||||
return audioOnly;
|
||||
}
|
||||
|
||||
public boolean getVideoMuted() {
|
||||
return videoMuted;
|
||||
}
|
||||
|
||||
public JitsiMeetUserInfo getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used to build the immutable {@link JitsiMeetConferenceOptions} object.
|
||||
*/
|
||||
|
||||
@@ -19,10 +19,9 @@ package org.jitsi.meet.sdk;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@@ -21,10 +21,8 @@ import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
@@ -49,14 +47,9 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
|
||||
intent.setAction(Actions.START);
|
||||
|
||||
ComponentName componentName;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
componentName = context.startForegroundService(intent);
|
||||
} else {
|
||||
componentName = context.startService(intent);
|
||||
}
|
||||
ComponentName componentName = context.startService(intent);
|
||||
if (componentName == null) {
|
||||
JitsiMeetLogger.w(TAG + " Ongoing conference service not started");
|
||||
Log.w(TAG, "Ongoing conference service not started");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,24 +80,19 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
final String action = intent.getAction();
|
||||
if (Actions.START.equals(action)) {
|
||||
if (action.equals(Actions.START)) {
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification();
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
JitsiMeetLogger.i(TAG + " Service started");
|
||||
}
|
||||
} else if (Actions.HANGUP.equals(action)) {
|
||||
JitsiMeetLogger.i(TAG + " Hangup requested");
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
Log.i(TAG, "Service started");
|
||||
} else if (action.equals(Actions.HANGUP)) {
|
||||
Log.i(TAG, "Hangup requested");
|
||||
// Abort all ongoing calls
|
||||
if (AudioModeModule.useConnectionService()) {
|
||||
ConnectionService.abortConnections();
|
||||
}
|
||||
stopSelf();
|
||||
} else {
|
||||
JitsiMeetLogger.w(TAG + " Unknown action received: " + action);
|
||||
Log.w(TAG, "Unknown action received: " + action);
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
@@ -115,7 +103,7 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
public void onCurrentConferenceChanged(String conferenceUrl) {
|
||||
if (conferenceUrl == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.i(TAG + "Service stopped");
|
||||
Log.i(TAG, "Service stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import android.util.Log;
|
||||
|
||||
class JitsiMeetUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
private final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler;
|
||||
@@ -37,7 +37,7 @@ class JitsiMeetUncaughtExceptionHandler implements Thread.UncaughtExceptionHandl
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
JitsiMeetLogger.e(e, this.getClass().getSimpleName() + " FATAL ERROR");
|
||||
Log.e(this.getClass().getSimpleName(), "FATAL ERROR", e);
|
||||
|
||||
// Abort all ConnectionService ongoing calls
|
||||
if (AudioModeModule.useConnectionService()) {
|
||||
|
||||
@@ -19,13 +19,12 @@ package org.jitsi.meet.sdk;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -40,6 +39,12 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
private static final Map<String, Method> LISTENER_METHODS
|
||||
= ListenerUtils.mapListenerMethods(JitsiMeetViewListener.class);
|
||||
|
||||
/**
|
||||
* The {@link Log} tag which identifies the source of the log messages of
|
||||
* {@code JitsiMeetView}.
|
||||
*/
|
||||
private static final String TAG = JitsiMeetView.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* The URL of the current conference.
|
||||
*/
|
||||
@@ -132,7 +137,7 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
try {
|
||||
pipModule.enterPictureInPicture();
|
||||
} catch (RuntimeException re) {
|
||||
JitsiMeetLogger.e(re, "Failed to enter PiP mode");
|
||||
Log.e(TAG, "failed to enter PiP mode", re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Module implementing a "bridge" between the JS loggers and the native one.
|
||||
*/
|
||||
@ReactModule(name = LogBridgeModule.NAME)
|
||||
class LogBridgeModule extends ReactContextBaseJavaModule {
|
||||
public static final String NAME = "LogBridge";
|
||||
|
||||
public LogBridgeModule(@Nonnull ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void trace(final String message) {
|
||||
JitsiMeetLogger.v(message);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void debug(final String message) {
|
||||
JitsiMeetLogger.d(message);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void info(final String message) {
|
||||
JitsiMeetLogger.i(message);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void log(final String message) {
|
||||
JitsiMeetLogger.i(message);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void warn(final String message) {
|
||||
JitsiMeetLogger.w(message);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void error(final String message) {
|
||||
JitsiMeetLogger.e(message);
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,8 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -51,7 +50,7 @@ class OngoingNotification {
|
||||
|
||||
Context context = ReactInstanceManagerHolder.getCurrentActivity();
|
||||
if (context == null) {
|
||||
JitsiMeetLogger.w(TAG + " Cannot create notification channel: no current context");
|
||||
Log.w(TAG, "Cannot create notification channel: no current context");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -76,7 +75,7 @@ class OngoingNotification {
|
||||
static Notification buildOngoingConferenceNotification() {
|
||||
Context context = ReactInstanceManagerHolder.getCurrentActivity();
|
||||
if (context == null) {
|
||||
JitsiMeetLogger.w(TAG + " Cannot create notification: no current context");
|
||||
Log.w(TAG, "Cannot create notification: no current context");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.util.Rational;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
@@ -28,8 +29,6 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@ReactModule(name = PictureInPictureModule.NAME)
|
||||
class PictureInPictureModule
|
||||
extends ReactContextBaseJavaModule {
|
||||
@@ -71,7 +70,7 @@ class PictureInPictureModule
|
||||
throw new IllegalStateException("No current Activity!");
|
||||
}
|
||||
|
||||
JitsiMeetLogger.i(TAG + " Entering Picture-in-Picture");
|
||||
Log.d(TAG, "Entering Picture-in-Picture");
|
||||
|
||||
PictureInPictureParams.Builder builder
|
||||
= new PictureInPictureParams.Builder()
|
||||
|
||||
@@ -5,12 +5,13 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.telecom.DisconnectCause;
|
||||
import android.telecom.PhoneAccount;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telecom.VideoProfile;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
@@ -19,8 +20,6 @@ import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
/**
|
||||
* The react-native side of Jitsi Meet's {@link ConnectionService}. Exposes
|
||||
* the Java Script API.
|
||||
@@ -75,11 +74,11 @@ class RNConnectionService
|
||||
String handle,
|
||||
boolean hasVideo,
|
||||
Promise promise) {
|
||||
JitsiMeetLogger.d("%s startCall UUID=%s, h=%s, v=%s",
|
||||
TAG,
|
||||
Log.d(TAG,
|
||||
String.format("startCall UUID=%s, h=%s, v=%s",
|
||||
callUUID,
|
||||
handle,
|
||||
hasVideo);
|
||||
hasVideo));
|
||||
|
||||
ReactApplicationContext ctx = getReactApplicationContext();
|
||||
|
||||
@@ -119,7 +118,7 @@ class RNConnectionService
|
||||
*/
|
||||
@ReactMethod
|
||||
public void reportCallFailed(String callUUID) {
|
||||
JitsiMeetLogger.d(TAG + " reportCallFailed " + callUUID);
|
||||
Log.d(TAG, "reportCallFailed " + callUUID);
|
||||
ConnectionService.setConnectionDisconnected(
|
||||
callUUID,
|
||||
new DisconnectCause(DisconnectCause.ERROR));
|
||||
@@ -132,7 +131,7 @@ class RNConnectionService
|
||||
*/
|
||||
@ReactMethod
|
||||
public void endCall(String callUUID) {
|
||||
JitsiMeetLogger.d(TAG + " endCall " + callUUID);
|
||||
Log.d(TAG, "endCall " + callUUID);
|
||||
ConnectionService.setConnectionDisconnected(
|
||||
callUUID,
|
||||
new DisconnectCause(DisconnectCause.LOCAL));
|
||||
@@ -144,10 +143,9 @@ class RNConnectionService
|
||||
* @param callUUID - the call's UUID.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void reportConnectedOutgoingCall(String callUUID, Promise promise) {
|
||||
JitsiMeetLogger.d(TAG + " reportConnectedOutgoingCall " + callUUID);
|
||||
public void reportConnectedOutgoingCall(String callUUID) {
|
||||
Log.d(TAG, "reportConnectedOutgoingCall " + callUUID);
|
||||
ConnectionService.setConnectionActive(callUUID);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.app.Application;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactPackage;
|
||||
@@ -27,20 +28,7 @@ import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.devsupport.DevInternalSettings;
|
||||
import com.facebook.react.jscexecutor.JSCExecutorFactory;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.oney.WebRTCModule.RTCVideoViewManager;
|
||||
import com.oney.WebRTCModule.WebRTCModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import org.webrtc.SoftwareVideoDecoderFactory;
|
||||
import org.webrtc.SoftwareVideoEncoderFactory;
|
||||
import org.webrtc.VideoDecoderFactory;
|
||||
import org.webrtc.VideoEncoderFactory;
|
||||
import org.webrtc.audio.AudioDeviceModule;
|
||||
import org.webrtc.audio.JavaAudioDeviceModule;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
@@ -59,7 +47,8 @@ class ReactInstanceManagerHolder {
|
||||
*/
|
||||
private static ReactInstanceManager reactInstanceManager;
|
||||
|
||||
private static List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
private static List<NativeModule> createNativeModules(
|
||||
ReactApplicationContext reactContext) {
|
||||
List<NativeModule> nativeModules
|
||||
= new ArrayList<>(Arrays.<NativeModule>asList(
|
||||
new AndroidSettingsModule(reactContext),
|
||||
@@ -67,9 +56,7 @@ class ReactInstanceManagerHolder {
|
||||
new AudioModeModule(reactContext),
|
||||
new DropboxModule(reactContext),
|
||||
new ExternalAPIModule(reactContext),
|
||||
new JavaScriptSandboxModule(reactContext),
|
||||
new LocaleDetector(reactContext),
|
||||
new LogBridgeModule(reactContext),
|
||||
new PictureInPictureModule(reactContext),
|
||||
new ProximityModule(reactContext),
|
||||
new WiFiStatsModule(reactContext),
|
||||
@@ -79,21 +66,6 @@ class ReactInstanceManagerHolder {
|
||||
nativeModules.add(new RNConnectionService(reactContext));
|
||||
}
|
||||
|
||||
// Initialize the WebRTC module by hand, since we want to override some
|
||||
// initialization options.
|
||||
WebRTCModule.Options options = new WebRTCModule.Options();
|
||||
|
||||
AudioDeviceModule adm = JavaAudioDeviceModule.builder(reactContext)
|
||||
.createAudioDeviceModule();
|
||||
VideoDecoderFactory videoDecoderFactory = new SoftwareVideoDecoderFactory();
|
||||
VideoEncoderFactory videoEncoderFactory = new SoftwareVideoEncoderFactory();
|
||||
|
||||
options.setAudioDeviceModule(adm);
|
||||
options.setVideoDecoderFactory(videoDecoderFactory);
|
||||
options.setVideoEncoderFactory(videoEncoderFactory);
|
||||
|
||||
nativeModules.add(new WebRTCModule(reactContext, options));
|
||||
|
||||
try {
|
||||
Class<?> amplitudeModuleClass = Class.forName("org.jitsi.meet.sdk.AmplitudeModule");
|
||||
Constructor constructor = amplitudeModuleClass.getConstructor(ReactApplicationContext.class);
|
||||
@@ -105,13 +77,6 @@ class ReactInstanceManagerHolder {
|
||||
return nativeModules;
|
||||
}
|
||||
|
||||
private static List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Arrays.<ViewManager>asList(
|
||||
// WebRTC, see createNativeModules for details.
|
||||
new RTCVideoViewManager()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to send an event to JavaScript.
|
||||
*
|
||||
@@ -178,25 +143,24 @@ class ReactInstanceManagerHolder {
|
||||
* time. All {@code ReactRootView} instances will be tied to the one and
|
||||
* only {@code ReactInstanceManager}.
|
||||
*
|
||||
* @param activity {@code Activity} current running Activity.
|
||||
* @param application {@code Application} instance which is running.
|
||||
*/
|
||||
static void initReactInstanceManager(Activity activity) {
|
||||
static void initReactInstanceManager(Application application) {
|
||||
if (reactInstanceManager != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
SoLoader.init(activity, /* native exopackage */ false);
|
||||
|
||||
List<ReactPackage> packages
|
||||
= new ArrayList<>(Arrays.asList(
|
||||
new com.BV.LinearGradient.LinearGradientPackage(),
|
||||
new com.calendarevents.CalendarEventsPackage(),
|
||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.dylanvann.fastimage.FastImageViewPackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new com.oblador.vectoricons.VectorIconsPackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
new com.reactnativecommunity.webview.RNCWebViewPackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
@@ -205,10 +169,6 @@ class ReactInstanceManagerHolder {
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
return ReactInstanceManagerHolder.createNativeModules(reactContext);
|
||||
}
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return ReactInstanceManagerHolder.createViewManagers(reactContext);
|
||||
}
|
||||
}));
|
||||
|
||||
try {
|
||||
@@ -219,17 +179,11 @@ class ReactInstanceManagerHolder {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
}
|
||||
|
||||
// Keep on using JSC, the jury is out on Hermes.
|
||||
JSCExecutorFactory jsFactory
|
||||
= new JSCExecutorFactory("", "");
|
||||
|
||||
reactInstanceManager
|
||||
= ReactInstanceManager.builder()
|
||||
.setApplication(activity.getApplication())
|
||||
.setCurrentActivity(activity)
|
||||
.setApplication(application)
|
||||
.setBundleAssetName("index.android.bundle")
|
||||
.setJSMainModulePath("index.android")
|
||||
.setJavaScriptExecutorFactory(jsFactory)
|
||||
.addPackages(packages)
|
||||
.setUseDeveloperSupport(BuildConfig.DEBUG)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jitsi.meet.sdk;
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
@@ -26,7 +27,6 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -144,7 +144,8 @@ class WiFiStatsModule
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("rssi", rssi)
|
||||
.put("signal", signalLevel)
|
||||
.put("timestamp", System.currentTimeMillis());
|
||||
.put("timestamp",
|
||||
String.valueOf(System.currentTimeMillis()));
|
||||
|
||||
JSONArray addresses = new JSONArray();
|
||||
|
||||
@@ -184,15 +185,17 @@ class WiFiStatsModule
|
||||
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
JitsiMeetLogger.e(e, TAG + " Unable to NetworkInterface.getNetworkInterfaces()");
|
||||
Log.wtf(TAG,
|
||||
"Unable to NetworkInterface.getNetworkInterfaces()"
|
||||
);
|
||||
}
|
||||
|
||||
result.put("addresses", addresses);
|
||||
promise.resolve(result.toString());
|
||||
|
||||
JitsiMeetLogger.d(TAG + " WiFi stats: " + result.toString());
|
||||
Log.d(TAG, "WiFi stats: " + result.toString());
|
||||
} catch (Throwable e) {
|
||||
JitsiMeetLogger.e(e, TAG + " Failed to obtain wifi stats");
|
||||
Log.e(TAG, "Failed to obtain wifi stats", e);
|
||||
promise.reject(
|
||||
new Exception("Failed to obtain wifi stats"));
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jitsi.meet.sdk.incoming_call;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
public class IncomingCallInfo {
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jitsi.meet.sdk.incoming_call;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk.log;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Base class for all custom log handlers. Implementations must inherit from this class and
|
||||
* implement a `doLog` method which does the actual logging, in addition with a `getTag` method
|
||||
* with which to tag all logs coming into this logger.
|
||||
*
|
||||
* See {@link JitsiMeetDefaultLogHandler} for an example.
|
||||
*/
|
||||
public abstract class JitsiMeetBaseLogHandler extends Timber.Tree {
|
||||
@Override
|
||||
protected void log(int priority, @Nullable String tag, @NotNull String msg, @Nullable Throwable t) {
|
||||
String errmsg = Log.getStackTraceString(t);
|
||||
if (errmsg.isEmpty()) {
|
||||
doLog(priority, getDefaultTag(), msg);
|
||||
} else {
|
||||
doLog(priority, getDefaultTag(), MessageFormat.format("{0}\n{1}", msg, errmsg));
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doLog(int priority, @NotNull String tag, @NotNull String msg);
|
||||
|
||||
protected abstract String getDefaultTag();
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk.log;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link JitsiMeetBaseLogHandler}. This is the main SDK logger, which
|
||||
* logs using the Android util.Log module.
|
||||
*/
|
||||
public class JitsiMeetDefaultLogHandler extends JitsiMeetBaseLogHandler {
|
||||
private static final String TAG = "JitsiMeetSDK";
|
||||
|
||||
@Override
|
||||
protected void doLog(int priority, @NotNull String tag, @NotNull String msg) {
|
||||
Log.println(priority, tag, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultTag() {
|
||||
return TAG;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk.log;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class JitsiMeetLogger {
|
||||
static {
|
||||
addHandler(new JitsiMeetDefaultLogHandler());
|
||||
}
|
||||
|
||||
public static void addHandler(JitsiMeetBaseLogHandler handler) {
|
||||
Timber.plant(handler);
|
||||
}
|
||||
|
||||
public static void removeHandler(JitsiMeetBaseLogHandler handler) {
|
||||
Timber.uproot(handler);
|
||||
}
|
||||
|
||||
public static void v(String message, Object... args) {
|
||||
Timber.v(message, args);
|
||||
}
|
||||
|
||||
public static void v(Throwable t, String message, Object... args) {
|
||||
Timber.v(t, message, args);
|
||||
}
|
||||
|
||||
public static void v(Throwable t) {
|
||||
Timber.v(t);
|
||||
}
|
||||
|
||||
public static void d(String message, Object... args) {
|
||||
Timber.d(message, args);
|
||||
}
|
||||
|
||||
public static void d(Throwable t, String message, Object... args) {
|
||||
Timber.d(t, message, args);
|
||||
}
|
||||
|
||||
public static void d(Throwable t) {
|
||||
Timber.d(t);
|
||||
}
|
||||
|
||||
public static void i(String message, Object... args) {
|
||||
Timber.i(message, args);
|
||||
}
|
||||
|
||||
public static void i(Throwable t, String message, Object... args) {
|
||||
Timber.i(t, message, args);
|
||||
}
|
||||
|
||||
public static void i(Throwable t) {
|
||||
Timber.i(t);
|
||||
}
|
||||
|
||||
public static void w(String message, Object... args) {
|
||||
Timber.w(message, args);
|
||||
}
|
||||
|
||||
public static void w(Throwable t, String message, Object... args) {
|
||||
Timber.w(t, message, args);
|
||||
}
|
||||
|
||||
public static void w(Throwable t) {
|
||||
Timber.w(t);
|
||||
}
|
||||
|
||||
public static void e(String message, Object... args) {
|
||||
Timber.e(message, args);
|
||||
}
|
||||
|
||||
public static void e(Throwable t, String message, Object... args) {
|
||||
Timber.e(t, message, args);
|
||||
}
|
||||
|
||||
public static void e(Throwable t) {
|
||||
Timber.e(t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package org.jitsi.meet.sdk.net;
|
||||
|
||||
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 com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ public class NAT64AddrInfoModule
|
||||
* The host for which the module wil try to resolve both IPv4 and IPv6
|
||||
* addresses in order to figure out the NAT64 prefix.
|
||||
*/
|
||||
private final static String HOST = "ipv4only.arpa";
|
||||
private final static String HOST = "nat64.jitsi.net";
|
||||
|
||||
/**
|
||||
* How long is the {@link NAT64AddrInfo} instance valid.
|
||||
@@ -97,7 +97,7 @@ public class NAT64AddrInfoModule
|
||||
try {
|
||||
info = NAT64AddrInfo.discover(host);
|
||||
} catch (UnknownHostException e) {
|
||||
JitsiMeetLogger.e(e, TAG + " NAT64AddrInfo.discover: " + host);
|
||||
Log.e(TAG, "NAT64AddrInfo.discover: " + host, e);
|
||||
}
|
||||
infoTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
@@ -107,7 +107,7 @@ public class NAT64AddrInfoModule
|
||||
try {
|
||||
result = info == null ? null : info.getIPv6Address(ipv4Address);
|
||||
} catch (IllegalArgumentException exc) {
|
||||
JitsiMeetLogger.e(exc, TAG + " Failed to get IPv6 address for: " + ipv4Address);
|
||||
Log.e(TAG, "Failed to get IPv6 address for: " + ipv4Address, exc);
|
||||
|
||||
// We don't want to reject. It's not a big deal if there's no IPv6
|
||||
// address resolved.
|
||||
|
||||
@@ -7,10 +7,10 @@ include ':react-native-calendar-events'
|
||||
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
|
||||
include ':react-native-community-async-storage'
|
||||
project(':react-native-community-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
|
||||
include ':react-native-community_netinfo'
|
||||
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
|
||||
include ':react-native-fast-image'
|
||||
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-keep-awake'
|
||||
@@ -19,8 +19,8 @@ include ':react-native-linear-gradient'
|
||||
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
|
||||
include ':react-native-sound'
|
||||
project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
|
||||
include ':react-native-svg'
|
||||
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/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'
|
||||
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
|
||||
include ':react-native-webview'
|
||||
|
||||
288
conference.js
@@ -23,8 +23,7 @@ import {
|
||||
sendAnalytics
|
||||
} from './react/features/analytics';
|
||||
import {
|
||||
maybeRedirectToWelcomePage,
|
||||
redirectToStaticPage,
|
||||
redirectWithStoredParams,
|
||||
reloadWithStoredParams
|
||||
} from './react/features/app';
|
||||
|
||||
@@ -44,7 +43,6 @@ import {
|
||||
conferenceWillJoin,
|
||||
conferenceWillLeave,
|
||||
dataChannelOpened,
|
||||
kickedOut,
|
||||
lockStateChanged,
|
||||
onStartMutedPolicyChanged,
|
||||
p2pStatusChanged,
|
||||
@@ -98,21 +96,28 @@ import {
|
||||
createLocalTracksF,
|
||||
destroyLocalTracks,
|
||||
isLocalTrackMuted,
|
||||
isUserInteractionRequiredForUnmute,
|
||||
replaceLocalTrack,
|
||||
trackAdded,
|
||||
trackRemoved
|
||||
} from './react/features/base/tracks';
|
||||
import { getJitsiMeetGlobalNS } from './react/features/base/util';
|
||||
import {
|
||||
getLocationContextRoot,
|
||||
getJitsiMeetGlobalNS
|
||||
} from './react/features/base/util';
|
||||
import { notifyKickedOut } from './react/features/conference';
|
||||
import { addMessage } from './react/features/chat';
|
||||
import { showDesktopPicker } from './react/features/desktop-picker';
|
||||
import { appendSuffix } from './react/features/display-name';
|
||||
import {
|
||||
maybeOpenFeedbackDialog,
|
||||
submitFeedback
|
||||
} from './react/features/feedback';
|
||||
import { mediaPermissionPromptVisibilityChanged } from './react/features/overlay';
|
||||
import { suspendDetected } from './react/features/power-monitor';
|
||||
import {
|
||||
mediaPermissionPromptVisibilityChanged,
|
||||
suspendDetected
|
||||
} from './react/features/overlay';
|
||||
import { setSharedVideoStatus } from './react/features/shared-video';
|
||||
import { isButtonEnabled } from './react/features/toolbox';
|
||||
import { endpointMessageReceived } from './react/features/subtitles';
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
@@ -206,6 +211,77 @@ function muteLocalVideo(muted) {
|
||||
APP.store.dispatch(setVideoMuted(muted));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the welcome page is enabled and redirects to it.
|
||||
* If requested show a thank you dialog before that.
|
||||
* If we have a close page enabled, redirect to it without
|
||||
* showing any other dialog.
|
||||
*
|
||||
* @param {object} options used to decide which particular close page to show
|
||||
* or if close page is disabled, whether we should show the thankyou dialog
|
||||
* @param {boolean} options.showThankYou - whether we should
|
||||
* show thank you dialog
|
||||
* @param {boolean} options.feedbackSubmitted - whether feedback was submitted
|
||||
*/
|
||||
function maybeRedirectToWelcomePage(options) {
|
||||
// if close page is enabled redirect to it, without further action
|
||||
if (config.enableClosePage) {
|
||||
const { isGuest } = APP.store.getState()['features/base/jwt'];
|
||||
|
||||
// save whether current user is guest or not, before navigating
|
||||
// to close page
|
||||
window.sessionStorage.setItem('guest', isGuest);
|
||||
redirectToStaticPage(`static/${
|
||||
options.feedbackSubmitted ? 'close.html' : 'close2.html'}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// else: show thankYou dialog only if there is no feedback
|
||||
if (options.showThankYou) {
|
||||
APP.store.dispatch(showNotification({
|
||||
titleArguments: { appName: interfaceConfig.APP_NAME },
|
||||
titleKey: 'dialog.thankYou'
|
||||
}));
|
||||
}
|
||||
|
||||
// if Welcome page is enabled redirect to welcome page after 3 sec, if
|
||||
// there is a thank you message to be shown, 0.5s otherwise.
|
||||
if (config.enableWelcomePage) {
|
||||
setTimeout(
|
||||
() => {
|
||||
APP.store.dispatch(redirectWithStoredParams('/'));
|
||||
},
|
||||
options.showThankYou ? 3000 : 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 redirectToStaticPage(pathname) {
|
||||
const windowLocation = window.location;
|
||||
let newPathname = pathname;
|
||||
|
||||
if (!newPathname.startsWith('/')) {
|
||||
// A pathname equal to ./ specifies the current directory. It will be
|
||||
// fine but pointless to include it because contextRoot is the current
|
||||
// directory.
|
||||
newPathname.startsWith('./')
|
||||
&& (newPathname = newPathname.substring(2));
|
||||
newPathname = getLocationContextRoot(windowLocation) + newPathname;
|
||||
}
|
||||
|
||||
windowLocation.pathname = newPathname;
|
||||
}
|
||||
|
||||
/**
|
||||
* A queue for the async replaceLocalTrack action so that multiple audio
|
||||
* replacements cannot happen simultaneously. This solves the issue where
|
||||
@@ -242,6 +318,8 @@ class ConferenceConnector {
|
||||
this._handleConferenceJoined.bind(this));
|
||||
room.on(JitsiConferenceEvents.CONFERENCE_FAILED,
|
||||
this._onConferenceFailed.bind(this));
|
||||
room.on(JitsiConferenceEvents.CONFERENCE_ERROR,
|
||||
this._onConferenceError.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,7 +347,7 @@ class ConferenceConnector {
|
||||
|
||||
case JitsiConferenceErrors.NOT_ALLOWED_ERROR: {
|
||||
// let's show some auth not allowed page
|
||||
APP.store.dispatch(redirectToStaticPage('static/authError.html'));
|
||||
redirectToStaticPage('static/authError.html');
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -344,6 +422,31 @@ class ConferenceConnector {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_onConferenceError(err, ...params) {
|
||||
logger.error('CONFERENCE Error:', err, params);
|
||||
switch (err) {
|
||||
case JitsiConferenceErrors.CHAT_ERROR:
|
||||
logger.error('Chat error.', err);
|
||||
if (isButtonEnabled('chat') && !interfaceConfig.filmStripOnly) {
|
||||
const [ code, msg ] = params;
|
||||
|
||||
APP.store.dispatch(addMessage({
|
||||
hasRead: true,
|
||||
error: code,
|
||||
message: msg,
|
||||
messageType: 'error',
|
||||
timestamp: Date.now()
|
||||
}));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.error('Unknown error.', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -526,7 +629,8 @@ export default {
|
||||
// Resolve with no tracks
|
||||
tryCreateLocalTracks = Promise.resolve([]);
|
||||
} else {
|
||||
tryCreateLocalTracks = createLocalTracksF({ devices: initialDevices }, true)
|
||||
tryCreateLocalTracks = createLocalTracksF(
|
||||
{ devices: initialDevices }, true)
|
||||
.catch(err => {
|
||||
if (requestedAudio && requestedVideo) {
|
||||
|
||||
@@ -630,11 +734,8 @@ export default {
|
||||
options.roomName, {
|
||||
startAudioOnly: config.startAudioOnly,
|
||||
startScreenSharing: config.startScreenSharing,
|
||||
startWithAudioMuted: config.startWithAudioMuted
|
||||
|| config.startSilent
|
||||
|| isUserInteractionRequiredForUnmute(APP.store.getState()),
|
||||
startWithAudioMuted: config.startWithAudioMuted || config.startSilent,
|
||||
startWithVideoMuted: config.startWithVideoMuted
|
||||
|| isUserInteractionRequiredForUnmute(APP.store.getState())
|
||||
}))
|
||||
.then(([ tracks, con ]) => {
|
||||
tracks.forEach(track => {
|
||||
@@ -735,13 +836,6 @@ export default {
|
||||
* dialogs in case of media permissions error.
|
||||
*/
|
||||
muteAudio(mute, showUI = true) {
|
||||
if (!mute
|
||||
&& isUserInteractionRequiredForUnmute(APP.store.getState())) {
|
||||
logger.error('Unmuting audio requires user interaction');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Not ready to modify track's state yet
|
||||
if (!this._localTracksInitialized) {
|
||||
// This will only modify base/media.audio.muted which is then synced
|
||||
@@ -805,13 +899,6 @@ export default {
|
||||
* dialogs in case of media permissions error.
|
||||
*/
|
||||
muteVideo(mute, showUI = true) {
|
||||
if (!mute
|
||||
&& isUserInteractionRequiredForUnmute(APP.store.getState())) {
|
||||
logger.error('Unmuting video requires user interaction');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If not ready to modify track's state yet adjust the base/media
|
||||
if (!this._localTracksInitialized) {
|
||||
// This will only modify base/media.video.muted which is then synced
|
||||
@@ -931,15 +1018,17 @@ export default {
|
||||
* Returns the connection times stored in the library.
|
||||
*/
|
||||
getConnectionTimes() {
|
||||
return room.getConnectionTimes();
|
||||
return this._room.getConnectionTimes();
|
||||
},
|
||||
|
||||
// used by torture currently
|
||||
isJoined() {
|
||||
return room && room.isJoined();
|
||||
return this._room
|
||||
&& this._room.isJoined();
|
||||
},
|
||||
getConnectionState() {
|
||||
return room && room.getConnectionState();
|
||||
return this._room
|
||||
&& this._room.getConnectionState();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -948,7 +1037,8 @@ export default {
|
||||
* P2P connection
|
||||
*/
|
||||
getP2PConnectionState() {
|
||||
return room && room.getP2PConnectionState();
|
||||
return this._room
|
||||
&& this._room.getP2PConnectionState();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -957,7 +1047,7 @@ export default {
|
||||
*/
|
||||
_startP2P() {
|
||||
try {
|
||||
room && room.startP2PSession();
|
||||
this._room && this._room.startP2PSession();
|
||||
} catch (error) {
|
||||
logger.error('Start P2P failed', error);
|
||||
throw error;
|
||||
@@ -970,7 +1060,7 @@ export default {
|
||||
*/
|
||||
_stopP2P() {
|
||||
try {
|
||||
room && room.stopP2PSession();
|
||||
this._room && this._room.stopP2PSession();
|
||||
} catch (error) {
|
||||
logger.error('Stop P2P failed', error);
|
||||
throw error;
|
||||
@@ -985,7 +1075,7 @@ export default {
|
||||
* false otherwise.
|
||||
*/
|
||||
isConnectionInterrupted() {
|
||||
return room.isConnectionInterrupted();
|
||||
return this._room.isConnectionInterrupted();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1046,7 +1136,7 @@ export default {
|
||||
},
|
||||
|
||||
getMyUserId() {
|
||||
return room && room.myUserId();
|
||||
return this._room && this._room.myUserId();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1069,7 +1159,7 @@ export default {
|
||||
* least one track.
|
||||
*/
|
||||
getNumberOfParticipantsWithTracks() {
|
||||
return room.getParticipants()
|
||||
return this._room.getParticipants()
|
||||
.filter(p => p.getTracks().length > 0)
|
||||
.length;
|
||||
},
|
||||
@@ -1207,34 +1297,17 @@ export default {
|
||||
const options = config;
|
||||
|
||||
const nick = APP.store.getState()['features/base/settings'].displayName;
|
||||
const { locationURL } = APP.store.getState()['features/base/connection'];
|
||||
|
||||
if (nick) {
|
||||
options.displayName = nick;
|
||||
}
|
||||
|
||||
options.applicationName = interfaceConfig.APP_NAME;
|
||||
options.getWiFiStatsMethod = this._getWiFiStatsMethod;
|
||||
options.confID = `${locationURL.host}${locationURL.pathname}`;
|
||||
options.getWiFiStatsMethod = getJitsiMeetGlobalNS().getWiFiStats;
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the result of getWiFiStats from the global NS or does nothing
|
||||
* (returns empty result).
|
||||
* Fixes a concurrency problem where we need to pass a function when creating
|
||||
* JitsiConference, but that method is added to the context later.
|
||||
*
|
||||
* @returns {Promise}
|
||||
* @private
|
||||
*/
|
||||
_getWiFiStatsMethod() {
|
||||
const gloabalNS = getJitsiMeetGlobalNS();
|
||||
|
||||
return gloabalNS.getWiFiStats ? gloabalNS.getWiFiStats() : Promise.resolve('{}');
|
||||
},
|
||||
|
||||
/**
|
||||
* Start using provided video stream.
|
||||
* Stops previous video stream.
|
||||
@@ -1250,7 +1323,7 @@ export default {
|
||||
this.localVideo = newStream;
|
||||
this._setSharingScreen(newStream);
|
||||
if (newStream) {
|
||||
APP.UI.addLocalVideoStream(newStream);
|
||||
APP.UI.addLocalStream(newStream);
|
||||
}
|
||||
this.setVideoMuteStatus(this.isLocalVideoMuted());
|
||||
})
|
||||
@@ -1301,6 +1374,9 @@ export default {
|
||||
replaceLocalTrack(this.localAudio, newStream, room))
|
||||
.then(() => {
|
||||
this.localAudio = newStream;
|
||||
if (newStream) {
|
||||
APP.UI.addLocalStream(newStream);
|
||||
}
|
||||
this.setAudioMuteStatus(this.isLocalAudioMuted());
|
||||
})
|
||||
.then(resolve)
|
||||
@@ -1316,7 +1392,8 @@ export default {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAudioOnly() {
|
||||
return Boolean(APP.store.getState()['features/base/audio-only'].enabled);
|
||||
return Boolean(
|
||||
APP.store.getState()['features/base/conference'].audioOnly);
|
||||
},
|
||||
|
||||
videoSwitchInProgress: false,
|
||||
@@ -1428,9 +1505,7 @@ export default {
|
||||
return this._switchToScreenSharing(options);
|
||||
}
|
||||
|
||||
return this._untoggleScreenSharing
|
||||
? this._untoggleScreenSharing()
|
||||
: Promise.resolve();
|
||||
return this._untoggleScreenSharing();
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1682,7 +1757,14 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const displayName = user.getDisplayName();
|
||||
|
||||
logger.log(`USER ${id} connnected:`, user);
|
||||
APP.API.notifyUserJoined(id, {
|
||||
displayName,
|
||||
formattedDisplayName: appendSuffix(
|
||||
displayName || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME)
|
||||
});
|
||||
APP.UI.addUser(user);
|
||||
|
||||
// check the roles for the new user and reflect them
|
||||
@@ -1698,7 +1780,12 @@ export default {
|
||||
}
|
||||
|
||||
logger.log(`USER ${id} LEFT:`, user);
|
||||
|
||||
APP.API.notifyUserLeft(id);
|
||||
APP.UI.messageHandler.participantNotification(
|
||||
user.getDisplayName(),
|
||||
'notify.somebody',
|
||||
'disconnected',
|
||||
'notify.disconnected');
|
||||
APP.UI.onSharedVideoStop(id);
|
||||
});
|
||||
|
||||
@@ -1767,12 +1854,15 @@ export default {
|
||||
APP.UI.setAudioLevel(id, newLvl);
|
||||
});
|
||||
|
||||
room.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, (track, participantThatMutedUs) => {
|
||||
room.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, (_, participantThatMutedUs) => {
|
||||
if (participantThatMutedUs) {
|
||||
APP.store.dispatch(participantMutedUs(participantThatMutedUs));
|
||||
}
|
||||
});
|
||||
|
||||
room.on(JitsiConferenceEvents.TALK_WHILE_MUTED, () => {
|
||||
APP.UI.showToolbar(6000);
|
||||
});
|
||||
room.on(JitsiConferenceEvents.SUBJECT_CHANGED,
|
||||
subject => APP.store.dispatch(conferenceSubjectChanged(subject)));
|
||||
|
||||
@@ -1872,7 +1962,7 @@ export default {
|
||||
|
||||
room.on(JitsiConferenceEvents.KICKED, participant => {
|
||||
APP.UI.hideStats();
|
||||
APP.store.dispatch(kickedOut(room, participant));
|
||||
APP.store.dispatch(notifyKickedOut(participant));
|
||||
|
||||
// FIXME close
|
||||
});
|
||||
@@ -1883,6 +1973,33 @@ export default {
|
||||
|
||||
room.on(JitsiConferenceEvents.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
|
||||
// user need to rejoin or close, while waking up we can detect
|
||||
// camera wakeup as a problem with device.
|
||||
// We also do not care about device change, which happens
|
||||
// on resume after suspending PC.
|
||||
if (this.deviceChangeListener) {
|
||||
JitsiMeetJS.mediaDevices.removeEventListener(
|
||||
JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED,
|
||||
this.deviceChangeListener);
|
||||
}
|
||||
|
||||
// stop local video
|
||||
if (this.localVideo) {
|
||||
this.localVideo.dispose();
|
||||
this.localVideo = null;
|
||||
}
|
||||
|
||||
// stop local audio
|
||||
if (this.localAudio) {
|
||||
this.localAudio.dispose();
|
||||
this.localAudio = null;
|
||||
}
|
||||
|
||||
APP.API.notifySuspendDetected();
|
||||
});
|
||||
|
||||
APP.UI.addListener(UIEvents.AUDIO_MUTED, muted => {
|
||||
@@ -2138,27 +2255,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Cleanups local conference on suspend.
|
||||
*/
|
||||
onSuspendDetected() {
|
||||
// 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
|
||||
// user need to rejoin or close, while waking up we can detect
|
||||
// camera wakeup as a problem with device.
|
||||
// We also do not care about device change, which happens
|
||||
// on resume after suspending PC.
|
||||
if (this.deviceChangeListener) {
|
||||
JitsiMeetJS.mediaDevices.removeEventListener(
|
||||
JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED,
|
||||
this.deviceChangeListener);
|
||||
}
|
||||
|
||||
this.localVideo = null;
|
||||
this.localAudio = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback invoked when the conference has been successfully joined.
|
||||
* Initializes the UI and various other features.
|
||||
@@ -2171,6 +2267,12 @@ export default {
|
||||
|
||||
APP.keyboardshortcut.init();
|
||||
|
||||
if (config.requireDisplayName
|
||||
&& !APP.conference.getLocalDisplayName()
|
||||
&& !this._room.isHidden()) {
|
||||
APP.UI.promptDisplayName();
|
||||
}
|
||||
|
||||
APP.store.dispatch(conferenceJoined(room));
|
||||
|
||||
const displayName
|
||||
@@ -2499,7 +2601,7 @@ export default {
|
||||
room = undefined;
|
||||
|
||||
APP.API.notifyReadyToClose();
|
||||
APP.store.dispatch(maybeRedirectToWelcomePage(values[0]));
|
||||
maybeRedirectToWelcomePage(values[0]);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -2511,11 +2613,7 @@ export default {
|
||||
leaveRoomAndDisconnect() {
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
|
||||
if (room.isJoined()) {
|
||||
return room.leave().then(disconnect, disconnect);
|
||||
}
|
||||
|
||||
return disconnect();
|
||||
return room.leave().then(disconnect, disconnect);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -2697,18 +2795,6 @@ export default {
|
||||
*/
|
||||
convertVideoToDesktop: true,
|
||||
|
||||
/**
|
||||
* Callback invoked when the connection has been closed
|
||||
* automatically. Triggers cleanup of screensharing if active.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onConnectionClosed: () => {
|
||||
if (this._untoggleScreenSharing) {
|
||||
this._untoggleScreenSharing();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback invoked to pass messages from the local client back
|
||||
* out to the external client.
|
||||
|
||||
35
config.js
@@ -1,6 +1,16 @@
|
||||
/* eslint-disable no-unused-vars, no-var */
|
||||
|
||||
var config = {
|
||||
// Configuration
|
||||
//
|
||||
|
||||
// Alternative location for the configuration.
|
||||
// configLocation: './config.json',
|
||||
|
||||
// Custom function which given the URL path should return a room name.
|
||||
// getroomnode: function (path) { return 'someprefixpossiblybasedonpath'; },
|
||||
|
||||
|
||||
// Connection
|
||||
//
|
||||
|
||||
@@ -50,10 +60,6 @@ var config = {
|
||||
|
||||
// Enables the test specific features consumed by jitsi-meet-torture
|
||||
// testMode: false
|
||||
|
||||
// Disables the auto-play behavior of *all* newly created video element.
|
||||
// This is useful when the client runs on a host with limited resources.
|
||||
// noAutoPlayVideo: false
|
||||
},
|
||||
|
||||
// Disables ICE/UDP by filtering out local and remote UDP candidates in
|
||||
@@ -117,6 +123,10 @@ var config = {
|
||||
// are requested again.
|
||||
// enableLayerSuspension: false,
|
||||
|
||||
// Suspend sending video if bandwidth estimation is too low. This may cause
|
||||
// problems with audio playback. Disabled until these are fixed.
|
||||
disableSuspendVideo: true,
|
||||
|
||||
// Every participant after the Nth will start video muted.
|
||||
// startVideoMuted: 10,
|
||||
|
||||
@@ -191,9 +201,6 @@ var config = {
|
||||
// subtitles and buttons can be configured)
|
||||
// transcribingEnabled: false,
|
||||
|
||||
// Enables automatic turning on captions when recording is started
|
||||
// autoCaptionOnRecord: false,
|
||||
|
||||
// Misc
|
||||
|
||||
// Default value for the channel "last N" attribute. -1 for unlimited.
|
||||
@@ -411,24 +418,10 @@ var config = {
|
||||
// use only.
|
||||
// _desktopSharingSourceDevice: 'sample-id-or-label'
|
||||
|
||||
// If true, any checks to handoff to another application will be prevented
|
||||
// and instead the app will continue to display in the current browser.
|
||||
// disableDeepLinking: false
|
||||
|
||||
// A property to disable the right click context menu for localVideo
|
||||
// the menu has option to flip the locally seen video for local presentations
|
||||
// disableLocalVideoFlip: false
|
||||
|
||||
// Deployment specific URLs.
|
||||
// deploymentUrls: {
|
||||
// // If specified a 'Help' button will be displayed in the overflow menu with a link to the specified URL for
|
||||
// // user documentation.
|
||||
// userDocumentationURL: 'https://docs.example.com/video-meetings.html',
|
||||
// // If specified a 'Download our apps' button will be displayed in the overflow menu with a link
|
||||
// // to the specified URL for an app download page.
|
||||
// downloadAppsUrl: 'https://docs.example.com/our-apps.html'
|
||||
// }
|
||||
|
||||
// List of undocumented settings used in jitsi-meet
|
||||
/**
|
||||
_immediateReloadThreshold
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
.avatar {
|
||||
align-items: center;
|
||||
background-color: #AAA;
|
||||
display: flex;
|
||||
border-radius: 50%;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-weight: 100;
|
||||
justify-content: center;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.avatar-foreign {
|
||||
align-items: center;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
font-size: 40pt;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.avatar-svg {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.defaultAvatar {
|
||||
opacity: 0.6
|
||||
}
|
||||
@@ -33,10 +33,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.jitsi-icon svg {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
/**
|
||||
* AtlasKitThemeProvider sets a background color on an app-wrapping div, thereby
|
||||
* preventing transparency in filmstrip-only mode. The selector chosen to
|
||||
|
||||
@@ -80,28 +80,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
#chat-recipient {
|
||||
align-items: center;
|
||||
background-color: $chatPrivateMessageBackgroundColor;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-weight: 100;
|
||||
padding: 10px;
|
||||
|
||||
span {
|
||||
color: white;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
div {
|
||||
svg {
|
||||
cursor: pointer;
|
||||
fill: white
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
background-color: $chatHeaderBackgroundColor;
|
||||
height: 70px;
|
||||
@@ -133,7 +111,6 @@
|
||||
#chat-input {
|
||||
border-top: 1px solid $chatInputSeparatorColor;
|
||||
display: flex;
|
||||
padding: 5px 10px;
|
||||
|
||||
* {
|
||||
background-color: transparent;
|
||||
@@ -154,7 +131,8 @@
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
padding: 10px;
|
||||
line-height: 30px;
|
||||
padding: 5px;
|
||||
overflow-y: auto;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
@@ -184,7 +162,6 @@
|
||||
.display-name {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
@@ -198,6 +175,7 @@
|
||||
color: white;
|
||||
margin-top: 3px;
|
||||
max-width: 100%;
|
||||
padding-bottom: 3px;
|
||||
position: relative;
|
||||
|
||||
&.localuser {
|
||||
@@ -218,15 +196,6 @@
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.privatemessagenotice {
|
||||
font-size: 11px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.messagecontent {
|
||||
margin: 5px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.smiley {
|
||||
@@ -259,7 +228,6 @@
|
||||
.smileys-panel {
|
||||
bottom: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(0, 0, 0, .6) !important;
|
||||
height: auto;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
@@ -302,6 +270,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#usermsg::-webkit-input-placeholder {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
#usermsg::-webkit-scrollbar-track-piece {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
@@ -316,10 +288,6 @@
|
||||
.chatmessage {
|
||||
background-color: $chatLocalMessageBackgroundColor;
|
||||
border-radius: 6px 0px 6px 6px;
|
||||
|
||||
&.privatemessage {
|
||||
background-color: $chatPrivateMessageBackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
.display-name {
|
||||
@@ -333,9 +301,8 @@
|
||||
|
||||
&.error {
|
||||
.chatmessage {
|
||||
background-color: $defaultWarningColor;
|
||||
border-radius: 0px;
|
||||
font-weight: 100;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.display-name {
|
||||
@@ -345,25 +312,6 @@
|
||||
|
||||
.chatmessage-wrapper {
|
||||
max-width: 100%;
|
||||
|
||||
.replywrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.messageactions {
|
||||
align-self: stretch;
|
||||
border-left: 1px solid $chatActionsSeparatorColor;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 5px;
|
||||
|
||||
.toolbox-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chatmessage {
|
||||
@@ -372,9 +320,6 @@
|
||||
display: inline-block;
|
||||
margin-top: 3px;
|
||||
color: white;
|
||||
|
||||
&.privatemessage {
|
||||
background-color: $chatPrivateMessageBackgroundColor;
|
||||
}
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
222
css/_font.scss
Normal file
@@ -0,0 +1,222 @@
|
||||
@font-face {
|
||||
font-family: 'jitsi';
|
||||
src: url('../fonts/jitsi.eot?3vw865');
|
||||
src: url('../fonts/jitsi.eot?3vw865#iefix') format('embedded-opentype'),
|
||||
url('../fonts/jitsi.ttf?3vw865') format('truetype'),
|
||||
url('../fonts/jitsi.woff?3vw865') format('woff'),
|
||||
url('../fonts/jitsi.svg?3vw865#jitsi') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
font-family: 'jitsi';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1.22em;
|
||||
font-size: 1.22em;
|
||||
cursor: default;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-enlarge:before {
|
||||
content: "\e90a";
|
||||
}
|
||||
.icon-signal_cellular_0:before {
|
||||
content: "\e901";
|
||||
}
|
||||
.icon-signal_cellular_1:before {
|
||||
content: "\e902";
|
||||
}
|
||||
.icon-signal_cellular_2:before {
|
||||
content: "\e907";
|
||||
}
|
||||
.icon-phone:before {
|
||||
content: "\e0cd";
|
||||
}
|
||||
.icon-radio_button_unchecked:before {
|
||||
content: "\e836";
|
||||
}
|
||||
.icon-radio_button_checked:before {
|
||||
content: "\e837";
|
||||
}
|
||||
.icon-search:before {
|
||||
content: "\e8b6";
|
||||
}
|
||||
.icon-chat-unread:before {
|
||||
content: "\e0b7";
|
||||
}
|
||||
.icon-closed_caption:before {
|
||||
content: "\e930";
|
||||
}
|
||||
.icon-tiles-many:before {
|
||||
content: "\e92e";
|
||||
}
|
||||
.icon-close:before {
|
||||
content: "\e5cd";
|
||||
}
|
||||
.icon-open_in_new:before {
|
||||
content: "\e89e";
|
||||
}
|
||||
.icon-restore:before {
|
||||
content: "\e8b3";
|
||||
}
|
||||
.icon-navigate_next:before {
|
||||
content: "\e409";
|
||||
}
|
||||
.icon-menu:before {
|
||||
content: "\e5d2";
|
||||
}
|
||||
.icon-arrow_back:before {
|
||||
content: "\e5c4";
|
||||
}
|
||||
.icon-public:before {
|
||||
content: "\e80b";
|
||||
}
|
||||
.icon-event_note:before {
|
||||
content: "\e616";
|
||||
}
|
||||
.icon-bluetooth:before {
|
||||
content: "\e1aa";
|
||||
}
|
||||
.icon-headset:before {
|
||||
content: "\e310";
|
||||
}
|
||||
.icon-phone-talk:before {
|
||||
content: "\e61d";
|
||||
}
|
||||
.icon-thumb-menu:before {
|
||||
content: "\e5d4";
|
||||
}
|
||||
.icon-ninja:before {
|
||||
content: "\e909";
|
||||
}
|
||||
.icon-invite:before {
|
||||
content: "\e145";
|
||||
}
|
||||
.icon-add:before {
|
||||
content: "\e146";
|
||||
}
|
||||
.icon-play:before {
|
||||
content: "\f04b";
|
||||
}
|
||||
.icon-stop:before {
|
||||
content: "\f04d";
|
||||
}
|
||||
.icon-dominant-speaker:before {
|
||||
content: "\f0a1";
|
||||
}
|
||||
.icon-speaker:before {
|
||||
content: "\e92d";
|
||||
}
|
||||
.icon-rec:before {
|
||||
content: "\e92b";
|
||||
}
|
||||
.icon-camera-take-picture:before {
|
||||
content: "\e92a";
|
||||
}
|
||||
.icon-AUD:before {
|
||||
content: "\e900";
|
||||
}
|
||||
.icon-HD:before {
|
||||
content: "\e927";
|
||||
}
|
||||
.icon-LD:before {
|
||||
content: "\e928";
|
||||
}
|
||||
.icon-SD:before {
|
||||
content: "\e929";
|
||||
}
|
||||
.icon-gsm-bars:before {
|
||||
content: "\e926";
|
||||
}
|
||||
.icon-info:before {
|
||||
content: "\e922";
|
||||
}
|
||||
.icon-mic-camera-combined:before {
|
||||
content: "\e903";
|
||||
}
|
||||
.icon-feedback:before {
|
||||
content: "\e91d";
|
||||
}
|
||||
.icon-hangup:before {
|
||||
content: "\e905";
|
||||
}
|
||||
.icon-chat:before {
|
||||
content: "\e906";
|
||||
}
|
||||
.icon-share-doc:before {
|
||||
content: "\e908";
|
||||
}
|
||||
.icon-kick:before {
|
||||
content: "\e904";
|
||||
}
|
||||
.icon-menu-up:before {
|
||||
content: "\e91f";
|
||||
}
|
||||
.icon-menu-down:before {
|
||||
content: "\e920";
|
||||
}
|
||||
.icon-full-screen:before {
|
||||
content: "\e90b";
|
||||
}
|
||||
.icon-exit-full-screen:before {
|
||||
content: "\e90c";
|
||||
}
|
||||
.icon-security:before {
|
||||
content: "\e90d";
|
||||
}
|
||||
.icon-security-locked:before {
|
||||
content: "\e90e";
|
||||
}
|
||||
.icon-microphone:before {
|
||||
content: "\e910";
|
||||
}
|
||||
.icon-mic-disabled:before {
|
||||
content: "\e912";
|
||||
}
|
||||
.icon-raised-hand:before {
|
||||
content: "\e91e";
|
||||
}
|
||||
.icon-link:before {
|
||||
content: "\e913";
|
||||
}
|
||||
.icon-shared-video:before {
|
||||
content: "\e914";
|
||||
}
|
||||
.icon-settings:before {
|
||||
content: "\e915";
|
||||
}
|
||||
.icon-star:before {
|
||||
content: "\e916";
|
||||
}
|
||||
.icon-switch-camera:before {
|
||||
content: "\e921";
|
||||
}
|
||||
.icon-share-desktop:before {
|
||||
content: "\e917";
|
||||
}
|
||||
.icon-camera:before {
|
||||
content: "\e918";
|
||||
}
|
||||
.icon-camera-disabled:before {
|
||||
content: "\e919";
|
||||
}
|
||||
.icon-volume:before {
|
||||
content: "\e91a";
|
||||
}
|
||||
.icon-presentation:before {
|
||||
content: "\e603";
|
||||
}
|
||||
.icon-visibility:before {
|
||||
content: "\e923";
|
||||
}
|
||||
.icon-visibility-off:before {
|
||||
content: "\e924";
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
.filmstrip-toolbox,
|
||||
.always-on-top-toolbox {
|
||||
background-color: $newToolbarBackgroundColor;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
z-index: $toolbarZ;
|
||||
|
||||
.toolbox-icon {
|
||||
cursor: pointer;
|
||||
padding: 7px;
|
||||
|
||||
&.toggled {
|
||||
background: $AOTToolbarButtonToggleColor;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.always-on-top-toolbox {
|
||||
flex-direction: row;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.toolbox-button {
|
||||
&:first-child {
|
||||
.toolbox-icon {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
svg {
|
||||
fill: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.toolbox-icon {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filmstrip-toolbox {
|
||||
flex-direction: column;
|
||||
|
||||
.toolbox-button {
|
||||
&:nth-child(1) {
|
||||
svg {
|
||||
fill: $hangupColor;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
min-width: 75px;
|
||||
text-align: left;
|
||||
padding: 0px;
|
||||
width: 180px;
|
||||
width: 150px;
|
||||
white-space: nowrap;
|
||||
|
||||
&__item {
|
||||
@@ -87,7 +87,6 @@
|
||||
display: inline-block;
|
||||
min-width: 20px;
|
||||
height: 100%;
|
||||
padding-right: 10px;
|
||||
|
||||
> * {
|
||||
@include absoluteAligning();
|
||||
|
||||
@@ -73,62 +73,8 @@
|
||||
|
||||
.button-group-center {
|
||||
justify-content: center;
|
||||
|
||||
.toolbox-button {
|
||||
|
||||
.toolbox-icon {
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #d1dbe8;
|
||||
margin: 0px 4px;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
|
||||
&:hover {
|
||||
background-color: #daebfa;
|
||||
border: 1px solid #daebfa;
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: #2a3a4b;
|
||||
border: 1px solid #5e6d7a;
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #5e6d7a;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled, .disabled & {
|
||||
cursor: initial;
|
||||
color: #fff;
|
||||
background-color: #a4b8d1;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #5e6d7a;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
.toolbox-icon {
|
||||
background-color: $hangupColor;
|
||||
border: 1px solid $hangupColor;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
&:hover {
|
||||
background-color: $hangupColor;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.toolbox-icon {
|
||||
margin: 0px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +82,75 @@
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
i {
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: inherit;
|
||||
height: 100%;
|
||||
line-height: inherit;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
i:hover {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
i.toggled {
|
||||
background: $newToolbarButtonToggleColor;
|
||||
}
|
||||
|
||||
i.toggled:hover {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
.icon-hangup {
|
||||
background-color: #e12d2d;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
&:hover {
|
||||
background-color: #e54b4b;
|
||||
}
|
||||
}
|
||||
i.disabled, .disabled i {
|
||||
cursor: initial !important;
|
||||
color: #fff !important;
|
||||
background-color: #a4b8d1 !important;
|
||||
}
|
||||
|
||||
.icon-mic-disabled, .icon-microphone, .icon-camera-disabled, .icon-camera {
|
||||
background-color: #fff;
|
||||
color: #5e6d7a;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #d1dbe8;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
|
||||
&:hover {
|
||||
background-color: #daebfa;
|
||||
border: 1px solid #daebfa;
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
background: #2a3a4b;
|
||||
color: #fff;
|
||||
border: 1px solid #5e6d7a;
|
||||
|
||||
&:hover {
|
||||
background-color: #5e6d7a;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled, .disabled & {
|
||||
cursor: initial;
|
||||
color: #fff;
|
||||
background-color: #a4b8d1;
|
||||
}
|
||||
}
|
||||
|
||||
.overflow-menu {
|
||||
font-size: 1.2em;
|
||||
list-style-type: none;
|
||||
@@ -176,6 +191,14 @@
|
||||
cursor: initial;
|
||||
color: #3b475c;
|
||||
}
|
||||
|
||||
i.toggled {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
i.toggled:hover {
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.beta-tag {
|
||||
@@ -204,10 +227,6 @@
|
||||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #B8C7E0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-text {
|
||||
@@ -246,30 +265,104 @@
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
display: flex;
|
||||
border-radius: 5px;
|
||||
flex-direction: column;
|
||||
font-size: 24px;
|
||||
height: $newToolbarSize;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
width: $newToolbarSize;
|
||||
|
||||
&:hover, &.toggled {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: initial !important;
|
||||
background-color: #a4b8d1 !important;
|
||||
|
||||
svg {
|
||||
fill: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.always-on-top-toolbox,
|
||||
.filmstrip-toolbox {
|
||||
background-color: $newToolbarBackgroundColor;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: $toolbarZ;
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
|
||||
i:hover {
|
||||
background-color: $AOTToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
i.toggled {
|
||||
background: $AOTToolbarButtonToggleColor;
|
||||
}
|
||||
|
||||
i.toggled:hover:not(.disabled) {
|
||||
background-color: $AOTToolbarButtonHoverColor;
|
||||
}
|
||||
|
||||
.icon-hangup {
|
||||
color: $hangupColor;
|
||||
}
|
||||
|
||||
.toolbox-button {
|
||||
color: $toolbarButtonColor;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.always-on-top-toolbox {
|
||||
flex-direction: row;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
transform: translateX(-50%);
|
||||
z-index: $toolbarZ;
|
||||
|
||||
i {
|
||||
font-size: $newToolbarFontSize;
|
||||
height: $newToolbarSize;
|
||||
line-height: $newToolbarSize;
|
||||
width: $newToolbarSize;
|
||||
}
|
||||
|
||||
.icon-hangup {
|
||||
font-size: $newToolbarHangupFontSize;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
.toolbox-button:first-child i {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
.toolbox-button:last-child i {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.filmstrip-toolbox {
|
||||
i {
|
||||
font-size: 1.9em;
|
||||
height: 37px;
|
||||
line-height: 37px;
|
||||
width: 37px;
|
||||
}
|
||||
|
||||
.toolbox-button:first-child i {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
.toolbox-button:last-child i {
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* START of fade in animation for main toolbar
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,6 @@ $defaultColor: #F1F1F1;
|
||||
$defaultSideBarFontColor: #44A5FF;
|
||||
$defaultSemiDarkColor: #ACACAC;
|
||||
$defaultDarkColor: #2b3d5c;
|
||||
$defaultWarningColor: rgb(215, 121, 118);
|
||||
|
||||
/**
|
||||
* Toolbar
|
||||
@@ -86,12 +85,10 @@ $modalTextColor: #333;
|
||||
/**
|
||||
* Chat
|
||||
*/
|
||||
$chatActionsSeparatorColor: rgb(173, 105, 112);
|
||||
$chatHeaderBackgroundColor: rgba(42, 58, 75, 0.9);
|
||||
$chatInputSeparatorColor: #A4B8D1;
|
||||
$chatLocalMessageBackgroundColor: rgb(4, 98, 178);
|
||||
$chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
|
||||
$chatRemoteMessageBackgroundColor: rgb(86, 101, 114);
|
||||
$chatLocalMessageBackgroundColor: rgba(26, 108, 180, 1);
|
||||
$chatRemoteMessageBackgroundColor: rgba(240, 243, 247, 0.15);
|
||||
$sidebarWidth: 375px;
|
||||
|
||||
/**
|
||||
@@ -166,45 +163,9 @@ $watermarkHeight: 74px;
|
||||
*/
|
||||
$welcomePageDescriptionColor: #fff;
|
||||
$welcomePageFontFamily: inherit;
|
||||
$welcomePageBackground: linear-gradient(-90deg, #1251AE 0%, #0074FF 50%, #1251AE 100%);
|
||||
$welcomePageHeaderBackground: linear-gradient(-90deg, #1251AE 0%, #0074FF 50%, #1251AE 100%);
|
||||
$welcomePageTitleColor: #fff;
|
||||
|
||||
$welcomePageHeaderBackground: none;
|
||||
$welcomePageHeaderBackgroundSmall: none;
|
||||
$welcomePageHeaderBackgroundPosition: none;
|
||||
$welcomePageHeaderBackgroundRepeat: none;
|
||||
$welcomePageHeaderBackgroundSize: none;
|
||||
$welcomePageHeaderPaddingBottom: 0px;
|
||||
|
||||
$welcomePageHeaderTextMarginTop: 35px;
|
||||
$welcomePageHeaderTextMarginBottom: 35px;
|
||||
|
||||
$welcomePageHeaderTextTitleMarginBottom: 16px;
|
||||
|
||||
$welcomePageHeaderTextDescriptionDisplay: inherit;
|
||||
|
||||
$welcomePageEnterRoomWidth: 680px;
|
||||
$welcomePageEnterRoomPadding: 25px 30px;
|
||||
$welcomePageEnterRoomBorderRadius: 0px;
|
||||
|
||||
$welcomePageEnterRoomInputContainerPadding: 0 8px 5px 0px;
|
||||
$welcomePageEnterRoomInputContainerBorderWidth: 0px 0px 2px 0px;
|
||||
$welcomePageEnterRoomInputContainerBorderStyle: solid;
|
||||
$welcomePageEnterRoomInputContainerBorderImage: linear-gradient(to right, #dee1e6, #fff) 1;
|
||||
|
||||
$welcomePageEnterRoomTitleDisplay: inherit;
|
||||
|
||||
$welcomePageTabContainerDisplay: flex;
|
||||
$welcomePageTabContentDisplay: inherit;
|
||||
$welcomePageTabButtonsDisplay: flex;
|
||||
$welcomePageTabDisplay: block;
|
||||
|
||||
$welcomePageButtonWidth: 51px;
|
||||
$welcomePageButtonHeight: 35px;
|
||||
$welcomePageButtonFontWeight: inherit;
|
||||
$welcomePageButtonBorderRadius: 4px;
|
||||
$welcomePageButtonLineHeight: 35px;
|
||||
|
||||
/**
|
||||
* Deep-linking page variables.
|
||||
*/
|
||||
|
||||
@@ -344,11 +344,8 @@
|
||||
/**
|
||||
* Toolbar icon internal i elements (font icons).
|
||||
*/
|
||||
.toolbar-icon>div {
|
||||
height: $thumbnailToolbarHeight;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.toolbar-icon>i {
|
||||
line-height: $thumbnailToolbarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -496,6 +493,7 @@
|
||||
}
|
||||
|
||||
#dominantSpeakerAvatarContainer,
|
||||
#dominantSpeakerAvatar,
|
||||
.dynamic-shadow {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
@@ -505,9 +503,14 @@
|
||||
top: 50px;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
border-radius: 100px;
|
||||
overflow: hidden;
|
||||
visibility: inherit;
|
||||
}
|
||||
#dominantSpeakerAvatar {
|
||||
background-color: #000000;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.dynamic-shadow {
|
||||
border-radius: 50%;
|
||||
@@ -521,6 +524,7 @@
|
||||
.avatar-container {
|
||||
@include maxSize(60px);
|
||||
@include absoluteAligning();
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 50%;
|
||||
|
||||
@@ -4,7 +4,7 @@ body.welcome-page {
|
||||
}
|
||||
|
||||
.welcome {
|
||||
background-image: $welcomePageBackground;
|
||||
background-image: $welcomePageHeaderBackground;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family: $welcomePageFontFamily;
|
||||
@@ -13,11 +13,6 @@ body.welcome-page {
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
background-image: $welcomePageHeaderBackground;
|
||||
background-position: $welcomePageHeaderBackgroundPosition;
|
||||
background-repeat: $welcomePageHeaderBackgroundRepeat;
|
||||
background-size: $welcomePageHeaderBackgroundSize;
|
||||
padding-bottom: $welcomePageHeaderPaddingBottom;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -29,8 +24,8 @@ body.welcome-page {
|
||||
.header-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: $watermarkHeight + $welcomePageHeaderTextMarginTop;
|
||||
margin-bottom: $welcomePageHeaderTextMarginBottom;
|
||||
margin-top: $watermarkHeight + 35;
|
||||
margin-bottom: 35px;
|
||||
max-width: calc(100% - 40px);
|
||||
width: 650px;
|
||||
z-index: $zindex2;
|
||||
@@ -41,11 +36,10 @@ body.welcome-page {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.18;
|
||||
margin-bottom: $welcomePageHeaderTextTitleMarginBottom;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.header-text-description {
|
||||
display: $welcomePageHeaderTextDescriptionDisplay;
|
||||
color: $welcomePageDescriptionColor;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
@@ -57,24 +51,23 @@ body.welcome-page {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: calc(100% - 40px);
|
||||
width: $welcomePageEnterRoomWidth;
|
||||
width: 680px;
|
||||
z-index: $zindex2;
|
||||
background-color: #fff;
|
||||
padding: $welcomePageEnterRoomPadding;
|
||||
border-radius: $welcomePageEnterRoomBorderRadius;
|
||||
padding: 25px 30px;
|
||||
|
||||
.enter-room-input-container {
|
||||
width: 100%;
|
||||
padding: $welcomePageEnterRoomInputContainerPadding;
|
||||
padding-right: 8px;
|
||||
padding-bottom: 5px;
|
||||
text-align: left;
|
||||
color: #253858;
|
||||
height: fit-content;
|
||||
border-width: $welcomePageEnterRoomInputContainerBorderWidth;
|
||||
border-style: $welcomePageEnterRoomInputContainerBorderStyle;
|
||||
border-image: $welcomePageEnterRoomInputContainerBorderImage;
|
||||
border-width: 0px 0px 2px 0px;
|
||||
border-style: solid;
|
||||
border-image: linear-gradient(to right, #dee1e6, #fff) 1;
|
||||
|
||||
.enter-room-title {
|
||||
display: $welcomePageEnterRoomTitleDisplay;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
padding-bottom: 5px;
|
||||
@@ -101,11 +94,10 @@ body.welcome-page {
|
||||
min-height: 354px;
|
||||
width: 710px;
|
||||
background: #75A7E7;
|
||||
display: $welcomePageTabContainerDisplay;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.tab-content{
|
||||
display: $welcomePageTabContentDisplay;
|
||||
margin: 5px 0px;
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
@@ -119,14 +111,13 @@ body.welcome-page {
|
||||
.tab-buttons {
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
display: $welcomePageTabButtonsDisplay;
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
flex-direction: row;
|
||||
min-height: 54px;
|
||||
width: 100%;
|
||||
|
||||
.tab {
|
||||
display: $welcomePageTabDisplay;
|
||||
text-align: center;
|
||||
background: rgba(9,30,66,0.37);
|
||||
height: 55px;
|
||||
@@ -147,16 +138,15 @@ body.welcome-page {
|
||||
}
|
||||
|
||||
.welcome-page-button {
|
||||
width: $welcomePageButtonWidth;
|
||||
height: $welcomePageButtonHeight;
|
||||
width: 51px;
|
||||
height: 35px;
|
||||
font-size: 14px;
|
||||
font-weight: $welcomePageButtonFontWeight;
|
||||
background: #0074E0;
|
||||
border-radius: $welcomePageButtonBorderRadius;
|
||||
border-radius: 4px;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: $welcomePageButtonLineHeight;
|
||||
line-height: 35px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/** Insert custom CSS for any additional content in the welcome page settings toolbar **/
|
||||
@@ -23,6 +23,12 @@ $flagsImagePath: "../images/";
|
||||
@import "../node_modules/bc-css-flags/dist/css/bc-css-flags.scss";
|
||||
/* Flags END */
|
||||
|
||||
/* Fonts BEGIN */
|
||||
|
||||
@import 'font';
|
||||
|
||||
/* Fonts END */
|
||||
|
||||
/* Modules BEGIN */
|
||||
|
||||
@import 'aui_reset';
|
||||
@@ -32,7 +38,6 @@ $flagsImagePath: "../images/";
|
||||
@import 'overlay/overlay';
|
||||
@import 'inlay';
|
||||
@import 'reload_overlay/reload_overlay';
|
||||
@import 'mini_toolbox';
|
||||
@import 'modals/desktop-picker/desktop-picker';
|
||||
@import 'modals/device-selection/device-selection';
|
||||
@import 'modals/dialog';
|
||||
@@ -52,7 +57,6 @@ $flagsImagePath: "../images/";
|
||||
@import 'ringing/ringing';
|
||||
@import 'welcome_page';
|
||||
@import 'welcome_page_content';
|
||||
@import 'welcome_page_settings_toolbar';
|
||||
@import 'toolbars';
|
||||
@import 'jquery.contextMenu';
|
||||
@import 'keyboard-shortcuts';
|
||||
@@ -82,6 +86,5 @@ $flagsImagePath: "../images/";
|
||||
@import 'navigate_section_list';
|
||||
@import 'third-party-branding/google';
|
||||
@import 'third-party-branding/microsoft';
|
||||
@import 'avatar';
|
||||
|
||||
/* Modules END */
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
width: -webkit-max-content;
|
||||
word-break: break-all;
|
||||
max-width: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-dialog-dial-in {
|
||||
@@ -88,15 +86,6 @@
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.info-dialog-url-icon {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
|
||||
svg {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.info-dialog-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
@@ -225,10 +214,4 @@
|
||||
-moz-user-select: text;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
|
||||
.info-dialog-url-text-unselectable {
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
7
debian/rules
vendored
@@ -17,15 +17,8 @@ override_dh_install: $(LANGUAGES)
|
||||
dh_install -X/config.js -X/package.json
|
||||
|
||||
$(LANGUAGES):
|
||||
LOCALE=$$(echo $@ | cut -c1-2) ; \
|
||||
if [ -f $(COUNTRIES_DIR)/$@.json ] ; \
|
||||
then \
|
||||
dh_install -pjitsi-meet-web $(COUNTRIES_DIR)/$@.json usr/share/jitsi-meet/lang/; \
|
||||
mv debian/jitsi-meet-web/usr/share/jitsi-meet/lang/$@.json debian/jitsi-meet-web/usr/share/jitsi-meet/lang/countries-$@.json; \
|
||||
else \
|
||||
if [ -f $(COUNTRIES_DIR)/$$LOCALE.json ] ; \
|
||||
then \
|
||||
dh_install -pjitsi-meet-web $(COUNTRIES_DIR)/$$LOCALE.json usr/share/jitsi-meet/lang/; \
|
||||
mv debian/jitsi-meet-web/usr/share/jitsi-meet/lang/$$LOCALE.json debian/jitsi-meet-web/usr/share/jitsi-meet/lang/countries-$@.json; \
|
||||
fi; \
|
||||
fi;
|
||||
|
||||
12
doc/adding-an-icon.md
Normal file
@@ -0,0 +1,12 @@
|
||||
### Adding an icon to the font file (e.g. for the floating menu)
|
||||
1. Go to https://icomoon.io/app/
|
||||
2. Go to "Manage Projects" from the menu on the top left.
|
||||
3. Use "Import project" and select <code>fonts/selection.json</code> from Jitsi Meet.
|
||||
4. Click "load".
|
||||
5. Add the new icons using the "Add icons from library" button...
|
||||
6. Go to "generate font" and make sure the identifiers for the new icons are correct.
|
||||
7. Download the result in a zip file using the "download" button.
|
||||
8. Copy <code>selection.json</code> and <code>fonts/jitsi.*</code> from the zip file to <code>fonts/</code> in Jitsi Meet
|
||||
9. Copy the class for the new icon from <code>style.css</code> in the zip file to <code>css/_font.scss</code> in Jitsi Meet (do *not* copy the whole file)
|
||||
|
||||
Sample commit: https://github.com/jitsi/jitsi-meet/commit/68bc819b89aec12364fcf07b81efa83a1900eed6
|
||||
36
doc/api.md
@@ -197,15 +197,6 @@ api.executeCommand('displayName', 'New Nickname');
|
||||
api.executeCommand('password', 'The Password');
|
||||
```
|
||||
|
||||
* **sendTones** - Play touch tones.
|
||||
```javascript
|
||||
api.executeCommand('sendTones', {
|
||||
tones: string, // The dial pad touch tones to play. For example, '12345#'.
|
||||
duration: number, // Optional. The number of milliseconds each tone should play. The default is 200.
|
||||
pause: number // Optional. The number of milliseconds between each tone. The default is 200.
|
||||
});
|
||||
```
|
||||
|
||||
* **subject** - Sets the subject of the conference. This command requires one argument - the new subject to be set.
|
||||
```javascript
|
||||
api.executeCommand('subject', 'New Conference Subject');
|
||||
@@ -331,13 +322,6 @@ changes. The listener will receive an object with the following structure:
|
||||
}
|
||||
```
|
||||
|
||||
* **dominantSpeakerChanged** - receives event notifications about change in the dominant speaker. The listener will receive object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
id: string //participantId of the new dominant speaker
|
||||
}
|
||||
```
|
||||
|
||||
* **tileViewChanged** - event notifications about tile view layout mode being entered or exited. The listener will receive object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
@@ -388,13 +372,6 @@ changes. The listener will receive an object with the following structure:
|
||||
email: string // the new email
|
||||
}
|
||||
```
|
||||
* **feedbackSubmitted** - event notifications about conference feedback submission
|
||||
```javascript
|
||||
{
|
||||
error: string // The error which occurred during submission, if any.
|
||||
}
|
||||
```
|
||||
|
||||
* **filmstripDisplayChanged** - event notifications about the visibility of the filmstrip being updated.
|
||||
```javascript
|
||||
{
|
||||
@@ -410,19 +387,6 @@ changes. The listener will receive an object with the following structure:
|
||||
}
|
||||
```
|
||||
|
||||
* **participantKickedOut** - event notifications about a participants being removed from the room. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
kicked: {
|
||||
id: string, // the id of the participant removed from the room
|
||||
local: boolean // whether or not the participant is the local particiapnt
|
||||
},
|
||||
kicker: {
|
||||
id: string // the id of the participant who kicked out the other participant
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* **participantLeft** - event notifications about participants that leave the room. The listener will receive an object with the following structure:
|
||||
```javascript
|
||||
{
|
||||
|
||||
@@ -19,37 +19,29 @@ server {
|
||||
ssl_certificate_key /etc/jitsi/meet/jitsi-meet.example.com.key;
|
||||
|
||||
root /usr/share/jitsi-meet;
|
||||
ssi on;
|
||||
index index.html index.htm;
|
||||
error_page 404 /static/404.html;
|
||||
|
||||
location = /config.js {
|
||||
location /config.js {
|
||||
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
}
|
||||
|
||||
location = /external_api.js {
|
||||
location /external_api.js {
|
||||
alias /usr/share/jitsi-meet/libs/external_api.min.js;
|
||||
}
|
||||
|
||||
#ensure all static content can always be found first
|
||||
location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
|
||||
{
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
alias /usr/share/jitsi-meet/$1/$2;
|
||||
location ~ ^/([a-zA-Z0-9=\?]+)$ {
|
||||
rewrite ^/(.*)$ / break;
|
||||
}
|
||||
|
||||
location / {
|
||||
ssi on;
|
||||
}
|
||||
|
||||
# BOSH
|
||||
location = /http-bind {
|
||||
location /http-bind {
|
||||
proxy_pass http://localhost:5280/http-bind;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
|
||||
location ~ ^/([^?&:’“]+)$ {
|
||||
try_files $uri @root_path;
|
||||
}
|
||||
|
||||
location @root_path {
|
||||
rewrite ^/(.*)$ / break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
# Developing Jitsi Meet
|
||||
|
||||
## Building the sources
|
||||
|
||||
Node.js >= 10 and npm >= 6 are required.
|
||||
|
||||
On Debian/Ubuntu systems, the required packages can be installed with:
|
||||
```
|
||||
sudo apt-get install npm nodejs
|
||||
cd jitsi-meet
|
||||
npm install
|
||||
```
|
||||
|
||||
To build the Jitsi Meet application, just type
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
### Working with the library sources (lib-jitsi-meet)
|
||||
|
||||
By default the library is build from its git repository sources. The default dependency path in package.json is :
|
||||
```json
|
||||
"lib-jitsi-meet": "jitsi/lib-jitsi-meet",
|
||||
```
|
||||
|
||||
To work with local copy you must change the path to:
|
||||
```json
|
||||
"lib-jitsi-meet": "file:///Users/name/local-lib-jitsi-meet-copy",
|
||||
```
|
||||
|
||||
To make the project you must force it to take the sources as 'npm update':
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make
|
||||
```
|
||||
|
||||
Or if you are making only changes to the library:
|
||||
```
|
||||
npm install lib-jitsi-meet --force && make deploy-lib-jitsi-meet
|
||||
```
|
||||
|
||||
Alternative way is to use [npm link](https://docs.npmjs.com/cli/link).
|
||||
It allows to link `lib-jitsi-meet` dependency to local source in few steps:
|
||||
|
||||
```bash
|
||||
cd lib-jitsi-meet
|
||||
|
||||
#### create global symlink for lib-jitsi-meet package
|
||||
npm link
|
||||
|
||||
cd ../jitsi-meet
|
||||
|
||||
#### create symlink from the local node_modules folder to the global lib-jitsi-meet symlink
|
||||
npm link lib-jitsi-meet
|
||||
```
|
||||
|
||||
After changes in local `lib-jitsi-meet` repository, you can rebuild it with `npm run install` and your `jitsi-meet` repository will use that modified library.
|
||||
Note: when using node version 4.x, the make file of jitsi-meet do npm update which will delete the link. It is no longer the case with version 6.x.
|
||||
|
||||
If you do not want to use local repository anymore you should run
|
||||
```bash
|
||||
cd jitsi-meet
|
||||
npm unlink lib-jitsi-meet
|
||||
npm install
|
||||
```
|
||||
### Running with webpack-dev-server for development
|
||||
|
||||
Use it at the CLI, type
|
||||
```
|
||||
make dev
|
||||
```
|
||||
|
||||
By default the backend deployment used is `beta.meet.jit.si`. You can point the Jitsi-Meet app at a different backend by using a proxy server. To do this, set the WEBPACK_DEV_SERVER_PROXY_TARGET variable:
|
||||
```
|
||||
export WEBPACK_DEV_SERVER_PROXY_TARGET=https://your-example-server.com
|
||||
make dev
|
||||
```
|
||||
|
||||
The app should be running at https://localhost:8080/
|
||||
4
flow-typed/npm/flow-bin_v0.x.x.js
vendored
@@ -1,5 +1,5 @@
|
||||
// flow-typed signature: 4e6a5da3290fe9ea49e6bcdced64f358
|
||||
// flow-typed version: c6154227d1/flow-bin_v0.x.x/flow_>=v0.25.x <=v0.103.x
|
||||
// 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;
|
||||
|
||||
4
flow-typed/npm/jquery_v3.x.x.js
vendored
@@ -1,5 +1,5 @@
|
||||
// flow-typed signature: 538d762382091f2239d2d55cab1b574d
|
||||
// flow-typed version: c6154227d1/jquery_v3.x.x/flow_>=v0.28.x <=v0.103.x
|
||||
// flow-typed signature: f26fda66e3a551aef37d3b0f53058e6a
|
||||
// flow-typed version: 44ad941b7a/jquery_v3.x.x/flow_>=v0.28.x
|
||||
|
||||
/* eslint-disable max-len, no-unused-vars, flowtype/no-weak-types */
|
||||
|
||||
|
||||
413
flow-typed/npm/lodash_v4.x.x.js
vendored
@@ -1,5 +1,5 @@
|
||||
// flow-typed signature: 96e97db746b98786dbff6de500b4b862
|
||||
// flow-typed version: 5fe02f287a/lodash_v4.x.x/flow_>=v0.63.x <=v0.103.x
|
||||
// flow-typed signature: a9b75804169260d49cda34b56dcfabe1
|
||||
// flow-typed version: e9dac1347c/lodash_v4.x.x/flow_>=v0.63.x
|
||||
|
||||
declare module "lodash" {
|
||||
declare type Path = $ReadOnlyArray<string | number> | string | number;
|
||||
@@ -149,11 +149,6 @@ declare module "lodash" {
|
||||
separator?: RegExp | string
|
||||
};
|
||||
|
||||
declare type Cancelable = {
|
||||
cancel: () => void,
|
||||
flush: () => mixed
|
||||
};
|
||||
|
||||
declare type DebounceOptions = {
|
||||
leading?: boolean,
|
||||
maxWait?: number,
|
||||
@@ -270,14 +265,14 @@ declare module "lodash" {
|
||||
): -1;
|
||||
// alias of _.head
|
||||
first<T>(array: ?$ReadOnlyArray<T>): T;
|
||||
flatten<T, X>(array?: ?$ReadOnlyArray<$ReadOnlyArray<T> | X>): Array<T | X>;
|
||||
flatten<T, X>(array?: ?Array<Array<T> | X>): Array<T | X>;
|
||||
flattenDeep<T>(array?: ?(any[])): Array<T>;
|
||||
flattenDepth(array?: ?(any[]), depth?: ?number): any[];
|
||||
fromPairs<A, B>(pairs?: ?Array<[A, B]>): { [key: A]: B };
|
||||
head<T>(array: ?$ReadOnlyArray<T>): T;
|
||||
indexOf<T>(array: $ReadOnlyArray<T>, value: T, fromIndex?: number): number;
|
||||
indexOf<T>(array: Array<T>, value: T, fromIndex?: number): number;
|
||||
indexOf<T>(array: void | null, value?: ?T, fromIndex?: ?number): -1;
|
||||
initial<T>(array: ?$ReadOnlyArray<T>): Array<T>;
|
||||
initial<T>(array: ?Array<T>): Array<T>;
|
||||
intersection<T>(...arrays?: Array<$ReadOnlyArray<T>>): Array<T>;
|
||||
//Workaround until (...parameter: T, parameter2: U) works
|
||||
intersectionBy<T>(
|
||||
@@ -325,10 +320,10 @@ declare module "lodash" {
|
||||
a4?: ?$ReadOnlyArray<T>,
|
||||
comparator?: ?Comparator<T>
|
||||
): Array<T>;
|
||||
join<T>(array: $ReadOnlyArray<T>, separator?: ?string): string;
|
||||
join<T>(array: Array<T>, separator?: ?string): string;
|
||||
join<T>(array: void | null, separator?: ?string): "";
|
||||
last<T>(array: ?$ReadOnlyArray<T>): T;
|
||||
lastIndexOf<T>(array: $ReadOnlyArray<T>, value?: ?T, fromIndex?: ?number): number;
|
||||
lastIndexOf<T>(array: Array<T>, value?: ?T, fromIndex?: ?number): number;
|
||||
lastIndexOf<T>(array: void | null, value?: ?T, fromIndex?: ?number): -1;
|
||||
nth<T>(array: T[], n?: ?number): T;
|
||||
nth(array: void | null, n?: ?number): void;
|
||||
@@ -362,10 +357,10 @@ declare module "lodash" {
|
||||
start?: ?number,
|
||||
end?: ?number
|
||||
): Array<T>;
|
||||
sortedIndex<T>(array: $ReadOnlyArray<T>, value: T): number;
|
||||
sortedIndex<T>(array: Array<T>, value: T): number;
|
||||
sortedIndex<T>(array: void | null, value: ?T): 0;
|
||||
sortedIndexBy<T>(
|
||||
array: $ReadOnlyArray<T>,
|
||||
array: Array<T>,
|
||||
value?: ?T,
|
||||
iteratee?: ?ValueOnlyIteratee<T>
|
||||
): number;
|
||||
@@ -374,12 +369,12 @@ declare module "lodash" {
|
||||
value?: ?T,
|
||||
iteratee?: ?ValueOnlyIteratee<T>
|
||||
): 0;
|
||||
sortedIndexOf<T>(array: $ReadOnlyArray<T>, value: T): number;
|
||||
sortedIndexOf<T>(array: Array<T>, value: T): number;
|
||||
sortedIndexOf<T>(array: void | null, value?: ?T): -1;
|
||||
sortedLastIndex<T>(array: $ReadOnlyArray<T>, value: T): number;
|
||||
sortedLastIndex<T>(array: Array<T>, value: T): number;
|
||||
sortedLastIndex<T>(array: void | null, value?: ?T): 0;
|
||||
sortedLastIndexBy<T>(
|
||||
array: $ReadOnlyArray<T>,
|
||||
array: Array<T>,
|
||||
value: T,
|
||||
iteratee?: ValueOnlyIteratee<T>
|
||||
): number;
|
||||
@@ -388,16 +383,16 @@ declare module "lodash" {
|
||||
value?: ?T,
|
||||
iteratee?: ?ValueOnlyIteratee<T>
|
||||
): 0;
|
||||
sortedLastIndexOf<T>(array: $ReadOnlyArray<T>, value: T): number;
|
||||
sortedLastIndexOf<T>(array: Array<T>, value: T): number;
|
||||
sortedLastIndexOf<T>(array: void | null, value?: ?T): -1;
|
||||
sortedUniq<T>(array?: ?$ReadOnlyArray<T>): Array<T>;
|
||||
sortedUniq<T>(array?: ?Array<T>): Array<T>;
|
||||
sortedUniqBy<T>(
|
||||
array?: ?$ReadOnlyArray<T>,
|
||||
array?: ?Array<T>,
|
||||
iteratee?: ?ValueOnlyIteratee<T>
|
||||
): Array<T>;
|
||||
tail<T>(array?: ?$ReadOnlyArray<T>): Array<T>;
|
||||
take<T>(array?: ?$ReadOnlyArray<T>, n?: ?number): Array<T>;
|
||||
takeRight<T>(array?: ?$ReadOnlyArray<T>, n?: ?number): Array<T>;
|
||||
tail<T>(array?: ?Array<T>): Array<T>;
|
||||
take<T>(array?: ?Array<T>, n?: ?number): Array<T>;
|
||||
takeRight<T>(array?: ?Array<T>, n?: ?number): Array<T>;
|
||||
takeRightWhile<T>(array?: ?Array<T>, predicate?: ?Predicate<T>): Array<T>;
|
||||
takeWhile<T>(array?: ?Array<T>, predicate?: ?Predicate<T>): Array<T>;
|
||||
union<T>(...arrays?: Array<$ReadOnlyArray<T>>): Array<T>;
|
||||
@@ -447,59 +442,59 @@ declare module "lodash" {
|
||||
uniq<T>(array?: ?$ReadOnlyArray<T>): Array<T>;
|
||||
uniqBy<T>(array?: ?$ReadOnlyArray<T>, iteratee?: ?ValueOnlyIteratee<T>): Array<T>;
|
||||
uniqWith<T>(array?: ?$ReadOnlyArray<T>, comparator?: ?Comparator<T>): Array<T>;
|
||||
unzip<T>(array?: ?$ReadOnlyArray<T>): Array<T>;
|
||||
unzip<T>(array?: ?Array<T>): Array<T>;
|
||||
unzipWith<T>(array: ?Array<T>, iteratee?: ?Iteratee<T>): Array<T>;
|
||||
without<T>(array?: ?$ReadOnlyArray<T>, ...values?: Array<?T>): Array<T>;
|
||||
xor<T>(...array: Array<Array<T>>): Array<T>;
|
||||
//Workaround until (...parameter: T, parameter2: U) works
|
||||
xorBy<T>(a1?: ?$ReadOnlyArray<T>, iteratee?: ?ValueOnlyIteratee<T>): Array<T>;
|
||||
xorBy<T>(a1?: ?Array<T>, iteratee?: ?ValueOnlyIteratee<T>): Array<T>;
|
||||
xorBy<T>(
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>,
|
||||
a1: Array<T>,
|
||||
a2: Array<T>,
|
||||
iteratee?: ValueOnlyIteratee<T>
|
||||
): Array<T>;
|
||||
xorBy<T>(
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>,
|
||||
a3: $ReadOnlyArray<T>,
|
||||
a1: Array<T>,
|
||||
a2: Array<T>,
|
||||
a3: Array<T>,
|
||||
iteratee?: ValueOnlyIteratee<T>
|
||||
): Array<T>;
|
||||
xorBy<T>(
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>,
|
||||
a3: $ReadOnlyArray<T>,
|
||||
a4: $ReadOnlyArray<T>,
|
||||
a1: Array<T>,
|
||||
a2: Array<T>,
|
||||
a3: Array<T>,
|
||||
a4: Array<T>,
|
||||
iteratee?: ValueOnlyIteratee<T>
|
||||
): Array<T>;
|
||||
//Workaround until (...parameter: T, parameter2: U) works
|
||||
xorWith<T>(a1?: ?$ReadOnlyArray<T>, comparator?: ?Comparator<T>): Array<T>;
|
||||
xorWith<T>(a1?: ?Array<T>, comparator?: ?Comparator<T>): Array<T>;
|
||||
xorWith<T>(
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>,
|
||||
a1: Array<T>,
|
||||
a2: Array<T>,
|
||||
comparator?: Comparator<T>
|
||||
): Array<T>;
|
||||
xorWith<T>(
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>,
|
||||
a3: $ReadOnlyArray<T>,
|
||||
a1: Array<T>,
|
||||
a2: Array<T>,
|
||||
a3: Array<T>,
|
||||
comparator?: Comparator<T>
|
||||
): Array<T>;
|
||||
xorWith<T>(
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>,
|
||||
a3: $ReadOnlyArray<T>,
|
||||
a4: $ReadOnlyArray<T>,
|
||||
a1: Array<T>,
|
||||
a2: Array<T>,
|
||||
a3: Array<T>,
|
||||
a4: Array<T>,
|
||||
comparator?: Comparator<T>
|
||||
): Array<T>;
|
||||
zip<A, B>(a1?: ?($ReadOnlyArray<A>), a2?: ?($ReadOnlyArray<B>)): Array<[A, B]>;
|
||||
zip<A, B, C>(a1: $ReadOnlyArray<A>, a2: $ReadOnlyArray<B>, a3: $ReadOnlyArray<C>): Array<[A, B, C]>;
|
||||
zip<A, B, C, D>(a1: $ReadOnlyArray<A>, a2: $ReadOnlyArray<B>, a3: $ReadOnlyArray<C>, a4: $ReadOnlyArray<D>): Array<[A, B, C, D]>;
|
||||
zip<A, B>(a1?: ?(A[]), a2?: ?(B[])): Array<[A, B]>;
|
||||
zip<A, B, C>(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>;
|
||||
zip<A, B, C, D>(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>;
|
||||
zip<A, B, C, D, E>(
|
||||
a1: $ReadOnlyArray<A>,
|
||||
a2: $ReadOnlyArray<B>,
|
||||
a3: $ReadOnlyArray<C>,
|
||||
a4: $ReadOnlyArray<D>,
|
||||
a5: $ReadOnlyArray<E>
|
||||
a1: A[],
|
||||
a2: B[],
|
||||
a3: C[],
|
||||
a4: D[],
|
||||
a5: E[]
|
||||
): Array<[A, B, C, D, E]>;
|
||||
|
||||
zipObject<K, V>(props: Array<K>, values?: ?Array<V>): { [key: K]: V };
|
||||
@@ -507,44 +502,44 @@ declare module "lodash" {
|
||||
zipObjectDeep(props: any[], values?: ?any): Object;
|
||||
zipObjectDeep(props: void | null, values?: ?any): {};
|
||||
|
||||
zipWith<A>(a1?: ?$ReadOnlyArray<A>): Array<[A]>;
|
||||
zipWith<T, A>(a1: $ReadOnlyArray<A>, iteratee: (A) => T): Array<T>;
|
||||
zipWith<A>(a1?: ?Array<A>): Array<[A]>;
|
||||
zipWith<T, A>(a1: Array<A>, iteratee: (A) => T): Array<T>;
|
||||
|
||||
zipWith<A, B>(a1: $ReadOnlyArray<A>, a2: $ReadOnlyArray<B>): Array<[A, B]>;
|
||||
zipWith<A, B>(a1: Array<A>, a2: Array<B>): Array<[A, B]>;
|
||||
zipWith<T, A, B>(
|
||||
a1: $ReadOnlyArray<A>,
|
||||
a2: $ReadOnlyArray<B>,
|
||||
a1: Array<A>,
|
||||
a2: Array<B>,
|
||||
iteratee: (A, B) => T
|
||||
): $ReadOnlyArray<T>;
|
||||
): Array<T>;
|
||||
|
||||
zipWith<A, B, C>(
|
||||
a1: $ReadOnlyArray<A>,
|
||||
a2: $ReadOnlyArray<B>,
|
||||
a3: $ReadOnlyArray<C>
|
||||
a1: Array<A>,
|
||||
a2: Array<B>,
|
||||
a3: Array<C>
|
||||
): Array<[A, B, C]>;
|
||||
zipWith<T, A, B, C>(
|
||||
a1: $ReadOnlyArray<A>,
|
||||
a2: $ReadOnlyArray<B>,
|
||||
a3: $ReadOnlyArray<C>,
|
||||
a1: Array<A>,
|
||||
a2: Array<B>,
|
||||
a3: Array<C>,
|
||||
iteratee: (A, B, C) => T
|
||||
): Array<T>;
|
||||
|
||||
zipWith<A, B, C, D>(
|
||||
a1: $ReadOnlyArray<A>,
|
||||
a2: $ReadOnlyArray<B>,
|
||||
a3: $ReadOnlyArray<C>,
|
||||
a4: $ReadOnlyArray<D>
|
||||
a1: Array<A>,
|
||||
a2: Array<B>,
|
||||
a3: Array<C>,
|
||||
a4: Array<D>
|
||||
): Array<[A, B, C, D]>;
|
||||
zipWith<T, A, B, C, D>(
|
||||
a1: $ReadOnlyArray<A>,
|
||||
a2: $ReadOnlyArray<B>,
|
||||
a3: $ReadOnlyArray<C>,
|
||||
a4: $ReadOnlyArray<D>,
|
||||
a1: Array<A>,
|
||||
a2: Array<B>,
|
||||
a3: Array<C>,
|
||||
a4: Array<D>,
|
||||
iteratee: (A, B, C, D) => T
|
||||
): Array<T>;
|
||||
|
||||
// Collection
|
||||
countBy<T>(array: $ReadOnlyArray<T>, iteratee?: ?ValueOnlyIteratee<T>): Object;
|
||||
countBy<T>(array: Array<T>, iteratee?: ?ValueOnlyIteratee<T>): Object;
|
||||
countBy<T>(array: void | null, iteratee?: ?ValueOnlyIteratee<T>): {};
|
||||
countBy<T: Object>(object: T, iteratee?: ?ValueOnlyIteratee<T>): Object;
|
||||
// alias of _.forEach
|
||||
@@ -680,7 +675,7 @@ declare module "lodash" {
|
||||
iteratees?: ?$ReadOnlyArray<Iteratee<T>> | ?string,
|
||||
orders?: ?$ReadOnlyArray<"asc" | "desc"> | ?string
|
||||
): Array<T>;
|
||||
orderBy<V, T: {}>(
|
||||
orderBy<V, T: Object>(
|
||||
object: T,
|
||||
iteratees?: $ReadOnlyArray<OIteratee<*>> | string,
|
||||
orders?: $ReadOnlyArray<"asc" | "desc"> | string
|
||||
@@ -748,11 +743,11 @@ declare module "lodash" {
|
||||
object?: ?T,
|
||||
predicate?: ?OPredicate<A, T>
|
||||
): Array<V>;
|
||||
sample<T>(array: ?$ReadOnlyArray<T>): T;
|
||||
sample<T>(array: ?Array<T>): T;
|
||||
sample<V, T: Object>(object: T): V;
|
||||
sampleSize<T>(array?: ?$ReadOnlyArray<T>, n?: ?number): Array<T>;
|
||||
sampleSize<T>(array?: ?Array<T>, n?: ?number): Array<T>;
|
||||
sampleSize<V, T: Object>(object: T, n?: number): Array<V>;
|
||||
shuffle<T>(array: ?$ReadOnlyArray<T>): Array<T>;
|
||||
shuffle<T>(array: ?Array<T>): Array<T>;
|
||||
shuffle<V, T: Object>(object: T): Array<V>;
|
||||
size(collection: $ReadOnlyArray<any> | Object | string): number;
|
||||
some<T>(array: void | null, predicate?: ?Predicate<T>): false;
|
||||
@@ -790,11 +785,7 @@ declare module "lodash" {
|
||||
curry: Curry;
|
||||
curry(func: Function, arity?: number): Function;
|
||||
curryRight(func: Function, arity?: number): Function;
|
||||
debounce<F: (...any[]) => any>(
|
||||
func: F,
|
||||
wait?: number,
|
||||
options?: DebounceOptions
|
||||
): F & Cancelable;
|
||||
debounce<F: (...any[]) => any>(func: F, wait?: number, options?: DebounceOptions): F;
|
||||
defer(func: (...any[]) => any, ...args?: Array<any>): TimeoutID;
|
||||
delay(func: Function, wait: number, ...args?: Array<any>): TimeoutID;
|
||||
flip<R>(func: (...any[]) => R): (...any[]) => R;
|
||||
@@ -814,7 +805,7 @@ declare module "lodash" {
|
||||
func: F,
|
||||
wait?: number,
|
||||
options?: ThrottleOptions
|
||||
): F & Cancelable;
|
||||
): F;
|
||||
unary<F: (...any[]) => any>(func: F): F;
|
||||
wrap(value?: any, wrapper?: ?Function): Function;
|
||||
|
||||
@@ -839,13 +830,13 @@ declare module "lodash" {
|
||||
gte(value: any, other: any): boolean;
|
||||
isArguments(value: void | null): false;
|
||||
isArguments(value: any): boolean;
|
||||
isArray(value: $ReadOnlyArray<any>): true;
|
||||
isArray(value: Array<any>): true;
|
||||
isArray(value: any): false;
|
||||
isArrayBuffer(value: ArrayBuffer): true;
|
||||
isArrayBuffer(value: any): false;
|
||||
isArrayLike(value: $ReadOnlyArray<any> | string | { length: number }): true;
|
||||
isArrayLike(value: Array<any> | string | { length: number }): true;
|
||||
isArrayLike(value: any): false;
|
||||
isArrayLikeObject(value: { length: number } | $ReadOnlyArray<any>): true;
|
||||
isArrayLikeObject(value: { length: number } | Array<any>): true;
|
||||
isArrayLikeObject(value: any): false;
|
||||
isBoolean(value: boolean): true;
|
||||
isBoolean(value: any): false;
|
||||
@@ -948,16 +939,16 @@ declare module "lodash" {
|
||||
ceil(number: number, precision?: number): number;
|
||||
divide(dividend: number, divisor: number): number;
|
||||
floor(number: number, precision?: number): number;
|
||||
max<T>(array: ?$ReadOnlyArray<T>): T;
|
||||
max<T>(array: ?Array<T>): T;
|
||||
maxBy<T>(array: ?$ReadOnlyArray<T>, iteratee?: Iteratee<T>): T;
|
||||
mean(array: $ReadOnlyArray<*>): number;
|
||||
mean(array: Array<*>): number;
|
||||
meanBy<T>(array: Array<T>, iteratee?: Iteratee<T>): number;
|
||||
min<T>(array: ?$ReadOnlyArray<T>): T;
|
||||
min<T>(array: ?Array<T>): T;
|
||||
minBy<T>(array: ?$ReadOnlyArray<T>, iteratee?: Iteratee<T>): T;
|
||||
multiply(multiplier: number, multiplicand: number): number;
|
||||
round(number: number, precision?: number): number;
|
||||
subtract(minuend: number, subtrahend: number): number;
|
||||
sum(array: $ReadOnlyArray<*>): number;
|
||||
sum(array: Array<*>): number;
|
||||
sumBy<T>(array: $ReadOnlyArray<T>, iteratee?: Iteratee<T>): number;
|
||||
|
||||
// number
|
||||
@@ -1075,8 +1066,8 @@ declare module "lodash" {
|
||||
source: A | B | C | D
|
||||
) => any | void
|
||||
): Object;
|
||||
at(object?: ?Object, ...paths: $ReadOnlyArray<string>): Array<any>;
|
||||
at(object?: ?Object, paths: $ReadOnlyArray<string>): Array<any>;
|
||||
at(object?: ?Object, ...paths: Array<string>): Array<any>;
|
||||
at(object?: ?Object, paths: Array<string>): Array<any>;
|
||||
create(prototype: void | null, properties: void | null): {};
|
||||
create<T>(prototype: T, properties: Object): T;
|
||||
create(prototype: any, properties: void | null): {};
|
||||
@@ -1246,15 +1237,15 @@ declare module "lodash" {
|
||||
source: A | B | C | D
|
||||
) => any | void
|
||||
): Object;
|
||||
omit(object?: ?Object, ...props: $ReadOnlyArray<string>): Object;
|
||||
omit(object?: ?Object, props: $ReadOnlyArray<string>): Object;
|
||||
omit(object?: ?Object, ...props: Array<string>): Object;
|
||||
omit(object?: ?Object, props: Array<string>): Object;
|
||||
omitBy<A, T: { [id: any]: A } | { [id: number]: A }>(
|
||||
object: T,
|
||||
predicate?: ?OPredicate<A, T>
|
||||
): Object;
|
||||
omitBy<A, T>(object: void | null, predicate?: ?OPredicate<A, T>): {};
|
||||
pick(object?: ?Object, ...props: $ReadOnlyArray<string>): Object;
|
||||
pick(object?: ?Object, props: $ReadOnlyArray<string>): Object;
|
||||
pick(object?: ?Object, ...props: Array<string>): Object;
|
||||
pick(object?: ?Object, props: Array<string>): Object;
|
||||
pickBy<A, T: { [id: any]: A } | { [id: number]: A }>(
|
||||
object: T,
|
||||
predicate?: ?OPredicate<A, T>
|
||||
@@ -1767,65 +1758,65 @@ declare module "lodash/fp" {
|
||||
): number;
|
||||
// alias of _.head
|
||||
first<T>(array: $ReadOnlyArray<T>): T;
|
||||
flatten<T, X>(array: $ReadOnlyArray<$ReadOnlyArray<T> | X>): Array<T | X>;
|
||||
flatten<T, X>(array: Array<Array<T> | X>): Array<T | X>;
|
||||
unnest<T, X>(array: Array<Array<T> | X>): Array<T | X>;
|
||||
flattenDeep<T>(array: any[]): Array<T>;
|
||||
flattenDepth(depth: number): (array: any[]) => any[];
|
||||
flattenDepth(depth: number, array: any[]): any[];
|
||||
fromPairs<A, B>(pairs: Array<[A, B]>): { [key: A]: B };
|
||||
head<T>(array: $ReadOnlyArray<T>): T;
|
||||
indexOf<T>(value: T): (array: $ReadOnlyArray<T>) => number;
|
||||
indexOf<T>(value: T, array: $ReadOnlyArray<T>): number;
|
||||
indexOf<T>(value: T): (array: Array<T>) => number;
|
||||
indexOf<T>(value: T, array: Array<T>): number;
|
||||
indexOfFrom<T>(
|
||||
value: T
|
||||
): ((fromIndex: number) => (array: $ReadOnlyArray<T>) => number) &
|
||||
((fromIndex: number, array: $ReadOnlyArray<T>) => number);
|
||||
indexOfFrom<T>(value: T, fromIndex: number): (array: $ReadOnlyArray<T>) => number;
|
||||
indexOfFrom<T>(value: T, fromIndex: number, array: $ReadOnlyArray<T>): number;
|
||||
initial<T>(array: $ReadOnlyArray<T>): Array<T>;
|
||||
): ((fromIndex: number) => (array: Array<T>) => number) &
|
||||
((fromIndex: number, array: Array<T>) => number);
|
||||
indexOfFrom<T>(value: T, fromIndex: number): (array: Array<T>) => number;
|
||||
indexOfFrom<T>(value: T, fromIndex: number, array: Array<T>): number;
|
||||
initial<T>(array: Array<T>): Array<T>;
|
||||
init<T>(array: Array<T>): Array<T>;
|
||||
intersection<T>(a1: $ReadOnlyArray<T>): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
intersection<T>(a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>): Array<T>;
|
||||
intersection<T>(a1: Array<T>): (a2: Array<T>) => Array<T>;
|
||||
intersection<T>(a1: Array<T>, a2: Array<T>): Array<T>;
|
||||
intersectionBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
intersectionBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
intersectionBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
intersectionWith<T>(
|
||||
comparator: Comparator<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
intersectionWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
intersectionWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
join<T>(separator: string): (array: $ReadOnlyArray<T>) => string;
|
||||
join<T>(separator: string, array: $ReadOnlyArray<T>): string;
|
||||
last<T>(array: $ReadOnlyArray<T>): T;
|
||||
lastIndexOf<T>(value: T): (array: $ReadOnlyArray<T>) => number;
|
||||
lastIndexOf<T>(value: T, array: $ReadOnlyArray<T>): number;
|
||||
join<T>(separator: string): (array: Array<T>) => string;
|
||||
join<T>(separator: string, array: Array<T>): string;
|
||||
last<T>(array: Array<T>): T;
|
||||
lastIndexOf<T>(value: T): (array: Array<T>) => number;
|
||||
lastIndexOf<T>(value: T, array: Array<T>): number;
|
||||
lastIndexOfFrom<T>(
|
||||
value: T
|
||||
): ((fromIndex: number) => (array: $ReadOnlyArray<T>) => number) &
|
||||
((fromIndex: number, array: $ReadOnlyArray<T>) => number);
|
||||
): ((fromIndex: number) => (array: Array<T>) => number) &
|
||||
((fromIndex: number, array: Array<T>) => number);
|
||||
lastIndexOfFrom<T>(
|
||||
value: T,
|
||||
fromIndex: number
|
||||
): (array: $ReadOnlyArray<T>) => number;
|
||||
lastIndexOfFrom<T>(value: T, fromIndex: number, array: $ReadOnlyArray<T>): number;
|
||||
): (array: Array<T>) => number;
|
||||
lastIndexOfFrom<T>(value: T, fromIndex: number, array: Array<T>): number;
|
||||
nth<T>(n: number): (array: T[]) => T;
|
||||
nth<T>(n: number, array: T[]): T;
|
||||
pull<T>(value: T): (array: Array<T>) => Array<T>;
|
||||
@@ -1858,154 +1849,154 @@ declare module "lodash/fp" {
|
||||
reverse<T>(array: Array<T>): Array<T>;
|
||||
slice<T>(
|
||||
start: number
|
||||
): ((end: number) => (array: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((end: number, array: $ReadOnlyArray<T>) => Array<T>);
|
||||
slice<T>(start: number, end: number): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
slice<T>(start: number, end: number, array: $ReadOnlyArray<T>): Array<T>;
|
||||
sortedIndex<T>(value: T): (array: $ReadOnlyArray<T>) => number;
|
||||
sortedIndex<T>(value: T, array: $ReadOnlyArray<T>): number;
|
||||
): ((end: number) => (array: Array<T>) => Array<T>) &
|
||||
((end: number, array: Array<T>) => Array<T>);
|
||||
slice<T>(start: number, end: number): (array: Array<T>) => Array<T>;
|
||||
slice<T>(start: number, end: number, array: Array<T>): Array<T>;
|
||||
sortedIndex<T>(value: T): (array: Array<T>) => number;
|
||||
sortedIndex<T>(value: T, array: Array<T>): number;
|
||||
sortedIndexBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): ((value: T) => (array: $ReadOnlyArray<T>) => number) &
|
||||
): ((value: T) => (array: Array<T>) => number) &
|
||||
((value: T, array: Array<T>) => number);
|
||||
sortedIndexBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
value: T
|
||||
): (array: $ReadOnlyArray<T>) => number;
|
||||
): (array: Array<T>) => number;
|
||||
sortedIndexBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
value: T,
|
||||
array: $ReadOnlyArray<T>
|
||||
array: Array<T>
|
||||
): number;
|
||||
sortedIndexOf<T>(value: T): (array: $ReadOnlyArray<T>) => number;
|
||||
sortedIndexOf<T>(value: T, array: $ReadOnlyArray<T>): number;
|
||||
sortedLastIndex<T>(value: T): (array: $ReadOnlyArray<T>) => number;
|
||||
sortedLastIndex<T>(value: T, array: $ReadOnlyArray<T>): number;
|
||||
sortedIndexOf<T>(value: T): (array: Array<T>) => number;
|
||||
sortedIndexOf<T>(value: T, array: Array<T>): number;
|
||||
sortedLastIndex<T>(value: T): (array: Array<T>) => number;
|
||||
sortedLastIndex<T>(value: T, array: Array<T>): number;
|
||||
sortedLastIndexBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): ((value: T) => (array: $ReadOnlyArray<T>) => number) &
|
||||
): ((value: T) => (array: Array<T>) => number) &
|
||||
((value: T, array: Array<T>) => number);
|
||||
sortedLastIndexBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
value: T
|
||||
): (array: $ReadOnlyArray<T>) => number;
|
||||
): (array: Array<T>) => number;
|
||||
sortedLastIndexBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
value: T,
|
||||
array: $ReadOnlyArray<T>
|
||||
array: Array<T>
|
||||
): number;
|
||||
sortedLastIndexOf<T>(value: T): (array: $ReadOnlyArray<T>) => number;
|
||||
sortedLastIndexOf<T>(value: T, array: $ReadOnlyArray<T>): number;
|
||||
sortedUniq<T>(array: $ReadOnlyArray<T>): Array<T>;
|
||||
sortedUniqBy<T>(iteratee: ValueOnlyIteratee<T>, array: $ReadOnlyArray<T>): Array<T>;
|
||||
tail<T>(array: $ReadOnlyArray<T>): Array<T>;
|
||||
take<T>(n: number): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
take<T>(n: number, array: $ReadOnlyArray<T>): Array<T>;
|
||||
takeRight<T>(n: number): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
takeRight<T>(n: number, array: $ReadOnlyArray<T>): Array<T>;
|
||||
takeLast<T>(n: number): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
takeLast<T>(n: number, array: $ReadOnlyArray<T>): Array<T>;
|
||||
sortedLastIndexOf<T>(value: T): (array: Array<T>) => number;
|
||||
sortedLastIndexOf<T>(value: T, array: Array<T>): number;
|
||||
sortedUniq<T>(array: Array<T>): Array<T>;
|
||||
sortedUniqBy<T>(iteratee: ValueOnlyIteratee<T>, array: Array<T>): Array<T>;
|
||||
tail<T>(array: Array<T>): Array<T>;
|
||||
take<T>(n: number): (array: Array<T>) => Array<T>;
|
||||
take<T>(n: number, array: Array<T>): Array<T>;
|
||||
takeRight<T>(n: number): (array: Array<T>) => Array<T>;
|
||||
takeRight<T>(n: number, array: Array<T>): Array<T>;
|
||||
takeLast<T>(n: number): (array: Array<T>) => Array<T>;
|
||||
takeLast<T>(n: number, array: Array<T>): Array<T>;
|
||||
takeRightWhile<T>(predicate: Predicate<T>): (array: Array<T>) => Array<T>;
|
||||
takeRightWhile<T>(predicate: Predicate<T>, array: Array<T>): Array<T>;
|
||||
takeLastWhile<T>(predicate: Predicate<T>): (array: Array<T>) => Array<T>;
|
||||
takeLastWhile<T>(predicate: Predicate<T>, array: Array<T>): Array<T>;
|
||||
takeWhile<T>(predicate: Predicate<T>): (array: Array<T>) => Array<T>;
|
||||
takeWhile<T>(predicate: Predicate<T>, array: Array<T>): Array<T>;
|
||||
union<T>(a1: $ReadOnlyArray<T>): (a2: Array<T>) => Array<T>;
|
||||
union<T>(a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>): Array<T>;
|
||||
union<T>(a1: Array<T>): (a2: Array<T>) => Array<T>;
|
||||
union<T>(a1: Array<T>, a2: Array<T>): Array<T>;
|
||||
unionBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
unionBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
unionBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
unionWith<T>(
|
||||
comparator: Comparator<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
unionWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
unionWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
uniq<T>(array: $ReadOnlyArray<T>): Array<T>;
|
||||
uniqBy<T>(iteratee: ValueOnlyIteratee<T>): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
uniqBy<T>(iteratee: ValueOnlyIteratee<T>, array: $ReadOnlyArray<T>): Array<T>;
|
||||
uniqWith<T>(comparator: Comparator<T>): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
uniqWith<T>(comparator: Comparator<T>, array: $ReadOnlyArray<T>): Array<T>;
|
||||
unzip<T>(array: $ReadOnlyArray<T>): Array<T>;
|
||||
uniq<T>(array: Array<T>): Array<T>;
|
||||
uniqBy<T>(iteratee: ValueOnlyIteratee<T>): (array: Array<T>) => Array<T>;
|
||||
uniqBy<T>(iteratee: ValueOnlyIteratee<T>, array: Array<T>): Array<T>;
|
||||
uniqWith<T>(comparator: Comparator<T>): (array: Array<T>) => Array<T>;
|
||||
uniqWith<T>(comparator: Comparator<T>, array: Array<T>): Array<T>;
|
||||
unzip<T>(array: Array<T>): Array<T>;
|
||||
unzipWith<T>(iteratee: Iteratee<T>): (array: Array<T>) => Array<T>;
|
||||
unzipWith<T>(iteratee: Iteratee<T>, array: Array<T>): Array<T>;
|
||||
without<T>(values: $ReadOnlyArray<T>): (array: $ReadOnlyArray<T>) => Array<T>;
|
||||
without<T>(values: $ReadOnlyArray<T>, array: $ReadOnlyArray<T>): Array<T>;
|
||||
xor<T>(a1: $ReadOnlyArray<T>): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
xor<T>(a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>): Array<T>;
|
||||
symmetricDifference<T>(a1: $ReadOnlyArray<T>): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
symmetricDifference<T>(a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>): Array<T>;
|
||||
without<T>(values: Array<T>): (array: Array<T>) => Array<T>;
|
||||
without<T>(values: Array<T>, array: Array<T>): Array<T>;
|
||||
xor<T>(a1: Array<T>): (a2: Array<T>) => Array<T>;
|
||||
xor<T>(a1: Array<T>, a2: Array<T>): Array<T>;
|
||||
symmetricDifference<T>(a1: Array<T>): (a2: Array<T>) => Array<T>;
|
||||
symmetricDifference<T>(a1: Array<T>, a2: Array<T>): Array<T>;
|
||||
xorBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
xorBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
xorBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
symmetricDifferenceBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
symmetricDifferenceBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
symmetricDifferenceBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
xorWith<T>(
|
||||
comparator: Comparator<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
xorWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
xorWith<T>(comparator: Comparator<T>, a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>): Array<T>;
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
xorWith<T>(comparator: Comparator<T>, a1: Array<T>, a2: Array<T>): Array<T>;
|
||||
symmetricDifferenceWith<T>(
|
||||
comparator: Comparator<T>
|
||||
): ((a1: $ReadOnlyArray<T>) => (a2: $ReadOnlyArray<T>) => Array<T>) &
|
||||
((a1: $ReadOnlyArray<T>, a2: $ReadOnlyArray<T>) => Array<T>);
|
||||
): ((a1: Array<T>) => (a2: Array<T>) => Array<T>) &
|
||||
((a1: Array<T>, a2: Array<T>) => Array<T>);
|
||||
symmetricDifferenceWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>
|
||||
): (a2: $ReadOnlyArray<T>) => Array<T>;
|
||||
a1: Array<T>
|
||||
): (a2: Array<T>) => Array<T>;
|
||||
symmetricDifferenceWith<T>(
|
||||
comparator: Comparator<T>,
|
||||
a1: $ReadOnlyArray<T>,
|
||||
a2: $ReadOnlyArray<T>
|
||||
a1: Array<T>,
|
||||
a2: Array<T>
|
||||
): Array<T>;
|
||||
zip<A, B>(a1: $ReadOnlyArray<A>): (a2: $ReadOnlyArray<B>) => Array<[A, B]>;
|
||||
zip<A, B>(a1: $ReadOnlyArray<A>, a2: $ReadOnlyArray<B>): Array<[A, B]>;
|
||||
zipAll(arrays: $ReadOnlyArray<$ReadOnlyArray<any>>): Array<any>;
|
||||
zipObject<K, V>(props?: $ReadOnlyArray<K>): (values?: $ReadOnlyArray<V>) => { [key: K]: V };
|
||||
zipObject<K, V>(props?: $ReadOnlyArray<K>, values?: $ReadOnlyArray<V>): { [key: K]: V };
|
||||
zip<A, B>(a1: A[]): (a2: B[]) => Array<[A, B]>;
|
||||
zip<A, B>(a1: A[], a2: B[]): Array<[A, B]>;
|
||||
zipAll(arrays: Array<Array<any>>): Array<any>;
|
||||
zipObject<K, V>(props?: Array<K>): (values?: Array<V>) => { [key: K]: V };
|
||||
zipObject<K, V>(props?: Array<K>, values?: Array<V>): { [key: K]: V };
|
||||
zipObj(props: Array<any>): (values: Array<any>) => Object;
|
||||
zipObj(props: Array<any>, values: Array<any>): Object;
|
||||
zipObjectDeep(props: any[]): (values: any) => Object;
|
||||
@@ -2026,10 +2017,10 @@ declare module "lodash/fp" {
|
||||
// Collection
|
||||
countBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>
|
||||
): (collection: $ReadOnlyArray<T> | { [id: any]: T }) => { [string]: number };
|
||||
): (collection: Array<T> | { [id: any]: T }) => { [string]: number };
|
||||
countBy<T>(
|
||||
iteratee: ValueOnlyIteratee<T>,
|
||||
collection: $ReadOnlyArray<T> | { [id: any]: T }
|
||||
collection: Array<T> | { [id: any]: T }
|
||||
): { [string]: number };
|
||||
// alias of _.forEach
|
||||
each<T>(
|
||||
@@ -2955,10 +2946,8 @@ declare module "lodash/fp" {
|
||||
predicate: OPredicate<A>
|
||||
): (object: T) => Object;
|
||||
omitBy<A, T: { [id: any]: A }>(predicate: OPredicate<A>, object: T): Object;
|
||||
pick(...props: Array<string | {}>): Object;
|
||||
pick(props: $ReadOnlyArray<string>, object: Object): Object;
|
||||
pick(...props: Array<string>): (object: Object) => Object;
|
||||
pick(props: $ReadOnlyArray<string>): (object: Object) => Object;
|
||||
pick(props: Array<string>): (object: Object) => Object;
|
||||
pick(props: Array<string>, object: Object): Object;
|
||||
pickAll(props: Array<string>): (object: Object) => Object;
|
||||
pickAll(props: Array<string>, object: Object): Object;
|
||||
pickBy<A, T: { [id: any]: A }>(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// flow-typed signature: d2ddacbbca9700881249a9435381e689
|
||||
// flow-typed version: c6154227d1/react-redux_v7.x.x/flow_>=v0.89.x <=v0.103.x
|
||||
// flow-typed signature: f06f00c3ad0cfedb90c0c6de04b219f3
|
||||
// flow-typed version: 3a6d556e4b/react-redux_v5.x.x/flow_>=v0.89.x
|
||||
|
||||
/**
|
||||
The order of type arguments for connect() is as follows:
|
||||
@@ -27,7 +27,6 @@ Decrypting the abbreviations:
|
||||
RMP = Returned merge props
|
||||
CP = Props for returned component
|
||||
Com = React Component
|
||||
SS = Selected state
|
||||
ST = Static properties of Com
|
||||
EFO = Extra factory options (used only in connectAdvanced)
|
||||
*/
|
||||
@@ -39,7 +38,7 @@ declare module "react-redux" {
|
||||
|
||||
declare export type Options<S, OP, SP, MP> = {|
|
||||
pure?: boolean,
|
||||
forwardRef?: boolean,
|
||||
withRef?: boolean,
|
||||
areStatesEqual?: (next: S, prev: S) => boolean,
|
||||
areOwnPropsEqual?: (next: OP, prev: OP) => boolean,
|
||||
areStatePropsEqual?: (next: SP, prev: SP) => boolean,
|
||||
@@ -199,19 +198,6 @@ declare module "react-redux" {
|
||||
options?: ?Options<S, OP, SP, P>,
|
||||
): Connector<P, OP, P>;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Typings for Hooks
|
||||
// ------------------------------------------------------------
|
||||
|
||||
declare export function useDispatch<D>(): D;
|
||||
|
||||
declare export function useSelector<S, SS>(
|
||||
selector: (state: S) => SS,
|
||||
equalityFn?: (a: SS, b: SS) => boolean,
|
||||
): SS;
|
||||
|
||||
declare export function useStore<Store>(): Store;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Typings for Provider
|
||||
// ------------------------------------------------------------
|
||||
@@ -236,7 +222,7 @@ declare module "react-redux" {
|
||||
renderCountProp?: string,
|
||||
shouldHandleStateChanges?: boolean,
|
||||
storeKey?: string,
|
||||
forwardRef?: boolean,
|
||||
withRef?: boolean,
|
||||
};
|
||||
|
||||
declare type SelectorFactoryOptions<Com> = {
|
||||
@@ -245,7 +231,7 @@ declare module "react-redux" {
|
||||
renderCountProp: ?string,
|
||||
shouldHandleStateChanges: boolean,
|
||||
storeKey: string,
|
||||
forwardRef: boolean,
|
||||
withRef: boolean,
|
||||
displayName: string,
|
||||
wrappedComponentName: string,
|
||||
WrappedComponent: Com,
|
||||
@@ -286,8 +272,5 @@ declare module "react-redux" {
|
||||
createProvider: typeof createProvider,
|
||||
connect: typeof connect,
|
||||
connectAdvanced: typeof connectAdvanced,
|
||||
useDispatch: typeof useDispatch,
|
||||
useSelector: typeof useSelector,
|
||||
useStore: typeof useStore,
|
||||
};
|
||||
}
|
||||
89
flow-typed/npm/redux_v4.x.x.js
vendored
@@ -1,7 +1,8 @@
|
||||
// flow-typed signature: 99b2d8ebd0ab4be20976dc62a3bbf54c
|
||||
// flow-typed version: c6154227d1/redux_v4.x.x/flow_>=v0.89.x <=v0.103.x
|
||||
// flow-typed signature: df80bdd535bfed9cf3223e077f3b4543
|
||||
// flow-typed version: c4c8963c9c/redux_v4.x.x/flow_>=v0.55.x
|
||||
|
||||
declare module 'redux' {
|
||||
|
||||
/*
|
||||
|
||||
S = State
|
||||
@@ -10,91 +11,49 @@ declare module 'redux' {
|
||||
|
||||
*/
|
||||
|
||||
declare export type Action<T> = {
|
||||
type: T
|
||||
}
|
||||
|
||||
declare export type DispatchAPI<A> = (action: A) => A;
|
||||
|
||||
declare export type Dispatch<A: { type: * }> = DispatchAPI<A>;
|
||||
declare export type Dispatch<A: { type: $Subtype<string> }> = DispatchAPI<A>;
|
||||
|
||||
declare export type MiddlewareAPI<S, A, D = Dispatch<A>> = {
|
||||
dispatch: D,
|
||||
getState(): S,
|
||||
dispatch: D;
|
||||
getState(): S;
|
||||
};
|
||||
|
||||
declare export type Store<S, A, D = Dispatch<A>> = {
|
||||
// rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages)
|
||||
dispatch: D,
|
||||
getState(): S,
|
||||
subscribe(listener: () => void): () => void,
|
||||
replaceReducer(nextReducer: Reducer<S, A>): void,
|
||||
dispatch: D;
|
||||
getState(): S;
|
||||
subscribe(listener: () => void): () => void;
|
||||
replaceReducer(nextReducer: Reducer<S, A>): void
|
||||
};
|
||||
|
||||
declare export type Reducer<S, A> = (state: S | void, action: A) => S;
|
||||
|
||||
declare export type CombinedReducer<S, A> = (
|
||||
state: ($Shape<S> & {}) | void,
|
||||
action: A
|
||||
) => S;
|
||||
declare export type CombinedReducer<S, A> = (state: $Shape<S> & {} | void, action: A) => S;
|
||||
|
||||
declare export type Middleware<S, A, D = Dispatch<A>> = (
|
||||
api: MiddlewareAPI<S, A, D>
|
||||
) => (next: D) => D;
|
||||
declare export type Middleware<S, A, D = Dispatch<A>> =
|
||||
(api: MiddlewareAPI<S, A, D>) =>
|
||||
(next: D) => D;
|
||||
|
||||
declare export type StoreCreator<S, A, D = Dispatch<A>> = {
|
||||
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>,
|
||||
(
|
||||
reducer: Reducer<S, A>,
|
||||
preloadedState: S,
|
||||
enhancer?: StoreEnhancer<S, A, D>
|
||||
): Store<S, A, D>,
|
||||
(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
};
|
||||
|
||||
declare export type StoreEnhancer<S, A, D = Dispatch<A>> = (
|
||||
next: StoreCreator<S, A, D>
|
||||
) => StoreCreator<S, A, D>;
|
||||
declare export type StoreEnhancer<S, A, D = Dispatch<A>> = (next: StoreCreator<S, A, D>) => StoreCreator<S, A, D>;
|
||||
|
||||
declare export function createStore<S, A, D>(
|
||||
reducer: Reducer<S, A>,
|
||||
enhancer?: StoreEnhancer<S, A, D>
|
||||
): Store<S, A, D>;
|
||||
declare export function createStore<S, A, D>(
|
||||
reducer: Reducer<S, A>,
|
||||
preloadedState?: S,
|
||||
enhancer?: StoreEnhancer<S, A, D>
|
||||
): Store<S, A, D>;
|
||||
declare export function createStore<S, A, D>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
declare export function createStore<S, A, D>(reducer: Reducer<S, A>, preloadedState?: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
|
||||
|
||||
declare export function applyMiddleware<S, A, D>(
|
||||
...middlewares: Array<Middleware<S, A, D>>
|
||||
): StoreEnhancer<S, A, D>;
|
||||
declare export function applyMiddleware<S, A, D>(...middlewares: Array<Middleware<S, A, D>>): StoreEnhancer<S, A, D>;
|
||||
|
||||
declare export type ActionCreator<A, B> = (...args: Array<B>) => A;
|
||||
declare export type ActionCreators<K, A> = {
|
||||
[key: K]: ActionCreator<A, any>,
|
||||
};
|
||||
declare export type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any> };
|
||||
|
||||
declare export function bindActionCreators<
|
||||
A,
|
||||
C: ActionCreator<A, any>,
|
||||
D: DispatchAPI<A>
|
||||
>(
|
||||
actionCreator: C,
|
||||
dispatch: D
|
||||
): C;
|
||||
declare export function bindActionCreators<
|
||||
A,
|
||||
K,
|
||||
C: ActionCreators<K, A>,
|
||||
D: DispatchAPI<A>
|
||||
>(
|
||||
actionCreators: C,
|
||||
dispatch: D
|
||||
): C;
|
||||
declare export function bindActionCreators<A, C: ActionCreator<A, any>, D: DispatchAPI<A>>(actionCreator: C, dispatch: D): C;
|
||||
declare export function bindActionCreators<A, K, C: ActionCreators<K, A>, D: DispatchAPI<A>>(actionCreators: C, dispatch: D): C;
|
||||
|
||||
declare export function combineReducers<O: {}, A>(
|
||||
reducers: O
|
||||
): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||
declare export function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||
|
||||
declare export var compose: $Compose;
|
||||
}
|
||||
|
||||
4
flow-typed/npm/uuid_v3.x.x.js
vendored
@@ -1,5 +1,5 @@
|
||||
// flow-typed signature: 609c1622fc97de96d59519934aa5ce87
|
||||
// flow-typed version: c6154227d1/uuid_v3.x.x/flow_>=v0.32.x <=v0.103.x
|
||||
// flow-typed signature: 3cf668e64747095cab0bb360cf2fb34f
|
||||
// flow-typed version: d659bd0cb8/uuid_v3.x.x/flow_>=v0.32.x
|
||||
|
||||
declare module "uuid" {
|
||||
declare class uuid {
|
||||
|
||||
BIN
fonts/jitsi.eot
Executable file
75
fonts/jitsi.svg
Executable file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="jitsi" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="1024" descent="0" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " d="" />
|
||||
<glyph unicode="" glyph-name="chat-unread" d="M768 682v86h-512v-86h512zM598 426v86h-342v-86h342zM256 640v-86h512v86h-512zM854 938c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
|
||||
<glyph unicode="" glyph-name="phone" d="M282 564c62-120 162-220 282-282l94 94c12 12 30 16 44 10 48-16 100-24 152-24 24 0 42-18 42-42v-150c0-24-18-42-42-42-400 0-726 326-726 726 0 24 18 42 42 42h150c24 0 42-18 42-42 0-54 8-104 24-152 4-14 2-32-10-44z" />
|
||||
<glyph unicode="" glyph-name="invite" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
|
||||
<glyph unicode="" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
|
||||
<glyph unicode="" glyph-name="bluetooth" d="M550 328l-80 82v-162zM470 776v-162l80 82zM670 696l-184-184 184-184-244-242h-42v324l-196-196-60 60 238 238-238 238 60 60 196-196v324h42zM834 738c40-64 62-142 62-222 0-84-24-160-66-226l-50 50c26 52 42 110 42 172s-16 120-42 172zM608 512l98 98c12-30 20-64 20-98s-8-70-20-100z" />
|
||||
<glyph unicode="" glyph-name="headset" d="M512 982c212 0 384-172 384-384v-300c0-70-58-128-128-128h-128v342h170v86c0 166-132 298-298 298s-298-132-298-298v-86h170v-342h-128c-70 0-128 58-128 128v300c0 212 172 384 384 384z" />
|
||||
<glyph unicode="" glyph-name="navigate_next" d="M426 768l256-256-256-256-60 60 196 196-196 196z" />
|
||||
<glyph unicode="" glyph-name="arrow_back" d="M854 554v-84h-520l238-240-60-60-342 342 342 342 60-60-238-240h520z" />
|
||||
<glyph unicode="" glyph-name="close" d="M810 750l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z" />
|
||||
<glyph unicode="" glyph-name="menu" d="M128 768h768v-86h-768v86zM128 470v84h768v-84h-768zM128 256v86h768v-86h-768z" />
|
||||
<glyph unicode="" glyph-name="thumb-menu" d="M512 342c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 598c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 682c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
|
||||
<glyph unicode="" glyph-name="presentation" horiz-adv-x="1088" d="M952.495 1019.065h-818.689c-72.81 0-132.183-60.63-132.183-135.162v-750.719c0-74.473 59.372-135.101 132.183-135.101h818.686c72.936 0 132.314 60.625 132.314 135.101v750.722c0.003 74.532-59.378 135.159-132.311 135.159zM946.346 139.651h-806.14v737.822h806.015l0.126-737.822zM685.753 738.544h216.911v-566.758h-216.911v566.758zM428.672 610.002h216.911v-438.216h-216.911v438.216zM172.339 481.46h216.161v-309.677h-216.161v309.677z" />
|
||||
<glyph unicode="" glyph-name="event_note" d="M598 426v-84h-300v84h300zM810 214v468h-596v-468h596zM810 896c46 0 86-40 86-86v-596c0-46-40-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h42v86h86v-86h340v86h86v-86h42zM726 598v-86h-428v86h428z" />
|
||||
<glyph unicode="" glyph-name="phone-talk" d="M640 512c0 70-58 128-128 128v86c118 0 214-96 214-214h-86zM810 512c0 166-132 298-298 298v86c212 0 384-172 384-384h-86zM854 362c24 0 42-18 42-42v-150c0-24-18-42-42-42-400 0-726 326-726 726 0 24 18 42 42 42h150c24 0 42-18 42-42 0-54 8-104 24-152 4-14 2-32-10-44l-94-94c62-122 162-220 282-282l94 94c12 12 30 14 44 10 48-16 98-24 152-24z" />
|
||||
<glyph unicode="" glyph-name="public" d="M764 282c56 60 90 142 90 230 0 142-88 266-214 316v-18c0-46-40-84-86-84h-84v-86c0-24-20-42-44-42h-84v-86h256c24 0 42-18 42-42v-128h42c38 0 70-26 82-60zM470 174v82c-46 0-86 40-86 86v42l-204 204c-6-24-10-50-10-76 0-174 132-318 300-338zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="radio_button_unchecked" d="M512 170c188 0 342 154 342 342s-154 342-342 342-342-154-342-342 154-342 342-342zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="radio_button_checked" d="M512 170c188 0 342 154 342 342s-154 342-342 342-342-154-342-342 154-342 342-342zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426zM512 726c118 0 214-96 214-214s-96-214-214-214-214 96-214 214 96 214 214 214z" />
|
||||
<glyph unicode="" glyph-name="open_in_new" d="M598 896h298v-298h-86v152l-418-418-60 60 418 418h-152v86zM810 214v298h86v-298c0-46-40-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h298v-86h-298v-596h596z" />
|
||||
<glyph unicode="" glyph-name="restore" d="M512 682h64v-180l150-90-32-52-182 110v212zM554 896c212 0 384-172 384-384s-172-384-384-384c-106 0-200 42-270 112l60 62c54-54 128-88 210-88 166 0 300 132 300 298s-134 298-300 298-298-132-298-298h128l-172-172-4 6-166 166h128c0 212 172 384 384 384z" />
|
||||
<glyph unicode="" glyph-name="search" d="M406 426c106 0 192 86 192 192s-86 192-192 192-192-86-192-192 86-192 192-192zM662 426l212-212-64-64-212 212v34l-12 12c-48-42-112-66-180-66-154 0-278 122-278 276s124 278 278 278 276-124 276-278c0-68-24-132-66-180l12-12h34z" />
|
||||
<glyph unicode="" glyph-name="AUD" d="M512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512c282.77 0 512-229.23 512-512s-229.23-512-512-512zM308.25 387.3h57.225l-87.675 252.525h-62.125l-87.675-252.525h53.025l19.425 60.2h88.725l19.075-60.2zM461.9 639.825h-52.85v-165.375c0-56 41.125-93.625 105.7-93.625 64.75 0 105.875 37.625 105.875 93.625v165.375h-52.85v-159.95c0-31.85-19.075-52.15-53.025-52.15-33.775 0-52.85 20.3-52.85 52.15v159.95zM682.225 640v-252.7h99.4c75.6 0 118.475 46.025 118.475 128.1 0 79.1-43.4 124.6-118.475 124.6h-99.4zM735.075 594.85v-162.4h38.15c46.725 0 72.975 28.7 72.975 82.075 0 51.1-27.125 80.325-72.975 80.325h-38.15zM243.5 587.325l-31.675-99.050h66.15l-31.325 99.050h-3.15z" />
|
||||
<glyph unicode="" glyph-name="signal_cellular_0" d="M938 938v-852h-852zM854 732l-562-562h562v562z" />
|
||||
<glyph unicode="" glyph-name="signal_cellular_1" d="M86 86l852 852v-256h-170v-596h-682zM854 86v84h84v-84h-84zM854 256v342h84v-342h-84z" />
|
||||
<glyph unicode="" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />
|
||||
<glyph unicode="" glyph-name="kick" d="M512 810l284-426h-568zM214 298h596v-84h-596v84z" />
|
||||
<glyph unicode="" glyph-name="hangup" d="M512 640c-68 0-134-10-196-30v-132c0-16-10-34-24-40-42-20-80-46-114-78-8-8-18-12-30-12s-22 4-30 12l-106 106c-8 8-12 18-12 30s4 22 12 30c130 124 306 200 500 200s370-76 500-200c8-8 12-18 12-30s-4-22-12-30l-106-106c-8-8-18-12-30-12s-22 4-30 12c-34 32-72 58-114 78-14 6-24 20-24 38v132c-62 20-128 32-196 32z" />
|
||||
<glyph unicode="" glyph-name="chat" d="M854 342v512h-684v-598l86 86h598zM854 938c46 0 84-38 84-84v-512c0-46-38-86-84-86h-598l-170-170v768c0 46 38 84 84 84h684z" />
|
||||
<glyph unicode="" glyph-name="signal_cellular_2" d="M86 86l852 852v-852h-852z" />
|
||||
<glyph unicode="" glyph-name="share-doc" d="M554 640h236l-236 234v-234zM682 426v86h-340v-86h340zM682 256v86h-340v-86h340zM598 938l256-256v-512c0-46-40-84-86-84h-512c-46 0-86 38-86 84l2 684c0 46 38 84 84 84h342z" />
|
||||
<glyph unicode="" glyph-name="ninja" d="M330.667 469.333c-0.427 14.933 6.4 29.44 17.92 39.253 32-6.827 61.867-20.053 88.747-39.253 0-29.013-23.893-52.907-53.333-52.907s-52.907 23.467-53.333 52.907zM586.667 469.333c26.88 18.773 56.747 32 88.747 38.827 11.52-9.813 18.347-24.32 17.92-38.827 0-29.867-23.893-53.76-53.333-53.76s-53.333 23.893-53.333 53.76v0zM512 640c-118.187 1.707-234.667-27.733-338.347-85.333l-2.987-42.667c0-52.48 12.373-104.107 35.84-151.040 101.12 15.36 203.093 23.040 305.493 23.040s204.373-7.68 305.493-23.040c23.467 46.933 35.84 98.56 35.84 151.040l-2.987 42.667c-103.68 57.6-220.16 87.040-338.347 85.333zM512 938.667c235.641 0 426.667-191.025 426.667-426.667s-191.025-426.667-426.667-426.667c-235.641 0-426.667 191.025-426.667 426.667s191.025 426.667 426.667 426.667z" />
|
||||
<glyph unicode="" glyph-name="enlarge" d="M896 212v600h-768v-600h768zM896 896q34 0 60-26t26-60v-596q0-34-26-60t-60-26h-768q-34 0-60 26t-26 60v596q0 34 26 60t60 26h768zM598 342l-86-108-86 108h172zM256 598v-172l-106 86zM768 598l106-86-106-86v172zM512 790l86-108h-172z" />
|
||||
<glyph unicode="" glyph-name="full-screen" d="M598 810h212v-212h-84v128h-128v84zM726 298v128h84v-212h-212v84h128zM214 598v212h212v-84h-128v-128h-84zM298 426v-128h128v-84h-212v212h84z" />
|
||||
<glyph unicode="" glyph-name="exit-full-screen" d="M682 682h128v-84h-212v212h84v-128zM598 214v212h212v-84h-128v-128h-84zM342 682v128h84v-212h-212v84h128zM214 342v84h212v-212h-84v128h-128z" />
|
||||
<glyph unicode="" glyph-name="security" d="M768 170v428h-512v-428h512zM768 682c46 0 86-38 86-84v-428c0-46-40-84-86-84h-512c-46 0-86 38-86 84v428c0 46 40 84 86 84h388v86c0 72-60 132-132 132s-132-60-132-132h-82c0 118 96 214 214 214s214-96 214-214v-86h42zM512 298c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
|
||||
<glyph unicode="" glyph-name="security-locked" d="M768 170v428h-512v-428h512zM380 768v-86h264v86c0 72-60 132-132 132s-132-60-132-132zM768 682c46 0 86-38 86-84v-428c0-46-40-84-86-84h-512c-46 0-86 38-86 84v428c0 46 40 84 86 84h42v86c0 118 96 214 214 214s214-96 214-214v-86h42zM512 298c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
|
||||
<glyph unicode="" glyph-name="microphone" d="M738 554h72c0-146-116-266-256-286v-140h-84v140c-140 20-256 140-256 286h72c0-128 108-216 226-216s226 88 226 216zM512 426c-70 0-128 58-128 128v256c0 70 58 128 128 128s128-58 128-128v-256c0-70-58-128-128-128z" />
|
||||
<glyph unicode="" glyph-name="mic-disabled" d="M182 896l714-714-54-54-178 178c-32-20-72-32-110-38v-140h-84v140c-140 20-256 140-256 286h72c0-128 108-216 226-216 34 0 68 8 98 22l-70 70c-8-2-18-4-28-4-70 0-128 58-128 128v32l-256 256zM640 548l-256 254v8c0 70 58 128 128 128s128-58 128-128v-262zM810 554c0-50-14-98-38-140l-52 54c12 26 18 54 18 86h72z" />
|
||||
<glyph unicode="" glyph-name="link" d="M640 426c114 0 342-56 342-170v-86h-684v86c0 114 228 170 342 170zM256 598h128v-86h-128v-128h-86v128h-128v86h128v128h86v-128zM640 512c-94 0-170 76-170 170s76 172 170 172 170-78 170-172-76-170-170-170z" />
|
||||
<glyph unicode="" glyph-name="shared-video" d="M512 170c188 0 342 154 342 342s-154 342-342 342-342-154-342-342 154-342 342-342zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426zM426 320v384l256-192z" />
|
||||
<glyph unicode="" glyph-name="settings" d="M512 362c82 0 150 68 150 150s-68 150-150 150-150-68-150-150 68-150 150-150zM830 470l90-70c8-6 10-18 4-28l-86-148c-6-10-16-12-26-8l-106 42c-22-16-46-32-72-42l-16-112c-2-10-10-18-20-18h-172c-10 0-18 8-20 18l-16 112c-26 10-50 24-72 42l-106-42c-10-4-20-2-26 8l-86 148c-6 10-4 22 4 28l90 70c-2 14-2 28-2 42s0 28 2 42l-90 70c-8 6-10 18-4 28l86 148c6 10 16 12 26 8l106-42c22 16 46 32 72 42l16 112c2 10 10 18 20 18h172c10 0 18-8 20-18l16-112c26-10 50-24 72-42l106 42c10 4 20 2 26-8l86-148c6-10 4-22-4-28l-90-70c2-14 2-28 2-42s0-28-2-42z" />
|
||||
<glyph unicode="" glyph-name="star" d="M512 366l160-96-42 182 142 124-188 16-72 172-72-172-188-16 142-124-42-182zM938 630l-232-202 70-300-264 160-264-160 70 300-232 202 306 26 120 282 120-282z" />
|
||||
<glyph unicode="" glyph-name="share-desktop" d="M896 298v512h-768v-512h768zM896 896c46 0 86-40 86-86l-2-512c0-46-38-84-84-84h-214v-86h-340v86h-214c-46 0-86 38-86 84v512c0 46 40 86 86 86h768z" />
|
||||
<glyph unicode="" glyph-name="camera" d="M726 576l170 170v-468l-170 170v-150c0-24-20-42-44-42h-512c-24 0-42 18-42 42v428c0 24 18 42 42 42h512c24 0 44-18 44-42v-150z" />
|
||||
<glyph unicode="" glyph-name="camera-disabled" d="M140 938l756-756-54-54-136 136c-6-4-16-8-24-8h-512c-24 0-42 18-42 42v428c0 24 18 42 42 42h32l-116 116zM896 746v-456l-478 478h264c24 0 44-18 44-42v-150z" />
|
||||
<glyph unicode="" glyph-name="volume" d="M598 886c172-38 298-192 298-374s-126-336-298-374v88c124 36 212 150 212 286s-88 250-212 286v88zM704 512c0-76-42-140-106-172v344c64-32 106-96 106-172zM128 640h170l214 214v-684l-214 214h-170v256z" />
|
||||
<glyph unicode="" glyph-name="feedback" d="M42.667 128h170.667v512h-170.667v-512zM981.333 597.333c0 46.933-38.4 85.333-85.333 85.333h-269.227l40.533 194.987 1.28 13.653c0 17.493-7.253 33.707-18.773 45.227l-45.227 44.8-280.747-281.173c-15.787-15.36-25.173-36.693-25.173-60.16v-426.667c0-46.933 38.4-85.333 85.333-85.333h384c35.413 0 65.707 21.333 78.507 52.053l128.853 300.8c3.84 9.813 5.973 20.053 5.973 31.147v81.493l-0.427 0.427 0.427 3.413z" />
|
||||
<glyph unicode="" 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="" glyph-name="menu-up" d="M512 682l256-256-60-60-196 196-196-196-60 60z" />
|
||||
<glyph unicode="" glyph-name="menu-down" d="M708 658l60-60-256-256-256 256 60 60 196-196z" />
|
||||
<glyph unicode="" 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" />
|
||||
<glyph unicode="" glyph-name="info" d="M512 938.667c-235.52 0-426.667-191.147-426.667-426.667s191.147-426.667 426.667-426.667 426.667 191.147 426.667 426.667-191.147 426.667-426.667 426.667zM554.667 298.667h-85.333v256h85.333v-256zM554.667 640h-85.333v85.333h85.333v-85.333z" />
|
||||
<glyph unicode="" glyph-name="visibility" d="M512 640c70 0 128-58 128-128s-58-128-128-128-128 58-128 128 58 128 128 128zM512 298c118 0 214 96 214 214s-96 214-214 214-214-96-214-214 96-214 214-214zM512 832c214 0 396-132 470-320-74-188-256-320-470-320s-396 132-470 320c74 188 256 320 470 320z" />
|
||||
<glyph unicode="" glyph-name="visibility-off" d="M506 640h6c70 0 128-58 128-128v-8zM322 606c-14-28-24-60-24-94 0-118 96-214 214-214 34 0 66 10 94 24l-66 66c-8-2-18-4-28-4-70 0-128 58-128 128 0 10 2 20 4 28zM86 842l54 54 756-756-54-54c-47.968 47.365-96.266 94.401-144 142-58-24-120-36-186-36-214 0-396 132-470 320 34 84 90 156 160 212-39.017 38.983-77.307 78.693-116 118zM512 726c-28 0-54-6-78-16l-92 92c52 20 110 30 170 30 214 0 394-132 468-320-32-80-82-148-146-202l-124 124c10 24 16 50 16 78 0 118-96 214-214 214z" />
|
||||
<glyph unicode="" glyph-name="gsm-bars" d="M896 1024c70.692 0 128-57.308 128-128v-768c0-70.692-57.308-128-128-128s-128 57.308-128 128v768c0 70.692 57.308 128 128 128zM512 768c70.692 0 128-57.308 128-128v-512c0-70.692-57.308-128-128-128s-128 57.308-128 128v512c0 70.692 57.308 128 128 128zM128 384v0c70.692 0 128-57.308 128-128v-128c0-70.692-57.308-128-128-128s-128 57.308-128 128v128c0 70.692 57.308 128 128 128v0z" />
|
||||
<glyph unicode="" glyph-name="HD" d="M512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512c282.77 0 512-229.23 512-512s-229.23-512-512-512zM481.359 384v255.823h-54.273v-103.18h-116.813v103.18h-54.273v-255.823h54.273v106.903h116.813v-106.903h54.273zM544.258 640v-256h102.077c77.636 0 121.665 46.626 121.665 129.773 0 80.133-44.569 126.227-121.665 126.227h-102.077zM598.531 594.26v-164.521h39.177c47.983 0 74.94 29.075 74.94 83.147 0 51.767-27.855 81.374-74.94 81.374h-39.177z" />
|
||||
<glyph unicode="" glyph-name="LD" d="M512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512c282.77 0 512-229.23 512-512s-229.23-512-512-512zM472.4 433.325h-112.35v206.5h-52.85v-252.525h165.2v46.025zM520.35 640v-252.7h99.4c75.6 0 118.475 46.025 118.475 128.1 0 79.1-43.4 124.6-118.475 124.6h-99.4zM573.2 594.85v-162.4h38.15c46.725 0 72.975 28.7 72.975 82.075 0 51.1-27.125 80.325-72.975 80.325h-38.15z" />
|
||||
<glyph unicode="" glyph-name="SD" d="M512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512c282.77 0 512-229.23 512-512s-229.23-512-512-512zM281.6 451.175c1.925-47.075 40.95-76.65 101.15-76.65 63.35 0 102.375 31.15 102.375 82.075 0 39.2-21.875 61.075-72.625 71.75l-30.45 6.475c-29.575 6.3-41.65 15.225-41.65 30.8 0 19.25 17.5 31.5 43.925 31.5 25.55 0 44.1-13.3 46.55-33.25h49.7c-1.575 44.975-40.95 76.125-96.6 76.125-58.275 0-96.6-31.325-96.6-78.925 0-38.5 22.575-62.475 68.6-72.1l32.9-7c30.975-6.65 43.575-15.925 43.575-32.025 0-19.075-19.425-32.375-46.9-32.375-29.75 0-50.4 13.125-52.85 33.6h-51.1zM535 633.7v-252.7h99.4c75.6 0 118.475 46.025 118.475 128.1 0 79.1-43.4 124.6-118.475 124.6h-99.4zM587.85 588.55v-162.4h38.15c46.725 0 72.975 28.7 72.975 82.075 0 51.1-27.125 80.325-72.975 80.325h-38.15z" />
|
||||
<glyph unicode="" glyph-name="camera-take-picture" d="M725.333 512c0-117.821-95.513-213.333-213.333-213.333s-213.333 95.513-213.333 213.333c0 117.821 95.513 213.333 213.333 213.333s213.333-95.513 213.333-213.333zM512 256c141.385 0 256 114.615 256 256s-114.615 256-256 256v0c-141.385 0-256-114.615-256-256s114.615-256 256-256v0zM512 213.333c-164.949 0-298.667 133.718-298.667 298.667s133.718 298.667 298.667 298.667v0c164.949 0 298.667-133.718 298.667-298.667s-133.718-298.667-298.667-298.667v0z" />
|
||||
<glyph unicode="" glyph-name="rec" d="M512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512c282.77 0 512-229.23 512-512s-229.23-512-512-512zM581.333 433.782h-110.595v59.233h104.338v40.332h-104.338v56.87h110.595v43.539h-161.665v-243.512h161.665v43.539zM738.771 384c58.849 0 101.802 36.282 106.029 88.933h-49.717c-4.904-26.832-26.888-44.045-56.143-44.045-38.556 0-62.4 31.895-62.4 83.196s23.844 83.027 62.231 83.027c29.086 0 51.239-18.394 56.143-46.407h49.717c-3.72 52.989-48.026 91.296-105.86 91.296-70.855 0-114.485-48.77-114.485-127.916 0-79.314 43.798-128.084 114.485-128.084zM230.27 478.502h41.769l45.489-88.258h57.834l-51.408 96.19c28.072 11.138 44.306 38.138 44.306 69.189 0 48.432-32.976 78.133-86.582 78.133h-102.478v-243.512h51.070v88.258zM230.27 592.58v-74.927h44.813c25.704 0 40.754 13.838 40.754 37.295 0 23.119-15.896 37.632-41.262 37.632h-44.306z" />
|
||||
<glyph unicode="" glyph-name="speaker" d="M0 512c0-282.795 229.205-512 512-512s512 229.205 512 512c0 282.795-229.205 512-512 512s-512-229.205-512-512zM525.005 759.362c-20.475 24.944-16.326 61.342 9.268 81.297s62.94 15.911 83.416-9.033c16.036-19.536 38.593-52.97 60.894-97.797 81.621-164.065 89.461-340.992-26.857-506.352-8.384-11.919-17.386-23.69-27.012-35.307-20.593-24.851-57.959-28.727-83.458-8.657s-29.476 56.487-8.882 81.338c7.686 9.275 14.833 18.621 21.455 28.035 88.66 126.041 82.71 260.306 17.953 390.475-10.599 21.305-21.94 40.51-33.198 57.196-6.515 9.657-11.322 16.057-13.578 18.805zM353.479 647.46c-19.353 24.679-15.129 60.448 9.434 79.893s60.164 15.2 79.517-9.479c9.635-12.287 22.577-32.644 35.209-60.034 50.35-109.176 50.35-231.689-33.639-349.612-18.198-25.551-53.566-31.441-78.997-13.157s-31.294 53.819-13.096 79.37c57.564 80.822 57.564 160.581 22.983 235.565-8.601 18.65-16.892 31.691-21.412 37.455z" />
|
||||
<glyph unicode="" glyph-name="tiles-many" d="M113.778 1024h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM170.667 910.222c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778zM113.778 455.111h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM170.667 341.333c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778zM682.667 1024h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM739.556 910.222c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778zM682.667 455.111h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM739.556 341.333c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778z" />
|
||||
<glyph unicode="" glyph-name="closed_caption" d="M768 554v44c0 24-18 42-42 42h-128c-24 0-44-18-44-42v-172c0-24 20-42 44-42h128c24 0 42 18 42 42v44h-64v-22h-86v128h86v-22h64zM470 554v44c0 24-20 42-44 42h-128c-24 0-42-18-42-42v-172c0-24 18-42 42-42h128c24 0 44 18 44 42v44h-64v-22h-86v128h86v-22h64zM810 854c46 0 86-40 86-86v-512c0-46-40-86-86-86h-596c-48 0-86 40-86 86v512c0 46 38 86 86 86h596z" />
|
||||
<glyph unicode="" glyph-name="play" horiz-adv-x="809" d="M790.857 494.286l-758.857-421.714c-17.714-9.714-32-1.143-32 18.857v841.143c0 20 14.286 28.571 32 18.857l758.857-421.714c17.714-9.714 17.714-25.714 0-35.429z" />
|
||||
<glyph unicode="" glyph-name="stop" horiz-adv-x="878" d="M877.714 914.286v-804.571c0-20-16.571-36.571-36.571-36.571h-804.571c-20 0-36.571 16.571-36.571 36.571v804.571c0 20 16.571 36.571 36.571 36.571h804.571c20 0 36.571-16.571 36.571-36.571z" />
|
||||
<glyph unicode="" glyph-name="dominant-speaker" d="M950.857 658.286c40.571 0 73.143-32.571 73.143-73.143s-32.571-73.143-73.143-73.143v-219.429c0-40-33.143-73.143-73.143-73.143-101.714 84.571-265.714 200.571-464 217.143-68-22.857-91.429-102.286-46.857-148-40-65.714 11.429-112 72-159.429-35.429-69.714-182.857-70.857-235.429-22.286-33.143 101.714-82.286 203.429-42.286 332h-69.714c-50.286 0-91.429 41.143-91.429 91.429v109.714c0 50.286 41.143 91.429 91.429 91.429h274.286c219.429 0 402.286 128 512 219.429 40 0 73.143-33.143 73.143-73.143v-219.429zM877.714 313.143v545.143c-149.143-114.286-293.714-180-438.857-196v-154.286c145.143-16 289.714-80.571 438.857-194.857z" />
|
||||
</font></defs></svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |