jfinn 4 gadus atpakaļ
vecāks
revīzija
85b77b33a5
100 mainītis faili ar 1981 papildinājumiem un 2907 dzēšanām
  1. 35
    15
      .github/ISSUE_TEMPLATE/1-bug-report.md
  2. 1
    1
      .github/ISSUE_TEMPLATE/2-feature-request.md
  3. 0
    10
      .github/ISSUE_TEMPLATE/2-help.md
  4. 5
    0
      .github/ISSUE_TEMPLATE/config.yml
  5. 1
    0
      .npmrc
  6. 96
    0
      CONTRIBUTING.md
  7. 2
    0
      Makefile
  8. 13
    19
      README.md
  9. 3
    5
      SECURITY.md
  10. 1
    378
      android/README.md
  11. 4
    7
      android/app/build.gradle
  12. 4
    1
      android/app/src/main/java/org/jitsi/meet/GoogleServicesHelper.java
  13. 2
    0
      android/build.gradle
  14. 2
    2
      android/gradle.properties
  15. 3
    0
      android/sdk/build.gradle
  16. 10
    2
      android/sdk/src/main/java/org/jitsi/meet/sdk/AmplitudeModule.java
  17. 1
    0
      android/sdk/src/main/java/org/jitsi/meet/sdk/AppInfoModule.java
  18. 10
    1
      android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeet.java
  19. 6
    3
      android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetActivity.java
  20. 0
    16
      android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetFragment.java
  21. 6
    0
      android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java
  22. 1
    0
      android/sdk/src/main/java/org/jitsi/meet/sdk/ReactInstanceManagerHolder.java
  23. 3
    1
      android/settings.gradle
  24. 1
    1
      app.js
  25. 217
    131
      conference.js
  26. 15
    0
      config.js
  27. 4
    3
      connection.js
  28. 1
    1
      connection_optimization/do_external_connect.js
  29. 1
    13
      css/_avatar.scss
  30. 75
    0
      css/_country-picker.scss
  31. 68
    0
      css/_labels.scss
  32. 182
    0
      css/_prejoin-dialog.scss
  33. 353
    0
      css/_prejoin.scss
  34. 1
    0
      css/_settings-button.scss
  35. 6
    2
      css/_video-preview.css
  36. 15
    4
      css/_welcome_page.scss
  37. 6
    0
      css/main.scss
  38. 1
    0
      css/modals/invite/_add-people.scss
  39. 0
    93
      css/modals/invite/_info.scss
  40. 252
    0
      css/modals/invite/_invite_more.scss
  41. 37
    0
      css/modals/security/_security.scss
  42. 0
    55
      css/modals/video-quality/_video-quality.scss
  43. 1
    1
      debian/control
  44. 1
    43
      doc/README.md
  45. 1
    617
      doc/api.md
  46. 0
    5
      doc/cloud-api.md
  47. 0
    93
      doc/coding-style.md
  48. 7
    0
      doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example
  49. 4
    0
      doc/debian/jitsi-meet-turn/turnserver.conf
  50. 9
    4
      doc/debian/jitsi-meet/jitsi-meet.example
  51. 11
    4
      doc/debian/jitsi-meet/jitsi-meet.example-apache
  52. 0
    82
      doc/development.md
  53. 0
    7
      doc/faq.md
  54. 0
    38
      doc/integrations.md
  55. 0
    270
      doc/manual-install.md
  56. 0
    28
      doc/mobile-dropbox.md
  57. 0
    22
      doc/mobile-google-auth.md
  58. 0
    107
      doc/mobile.md
  59. 1
    160
      doc/quick-install.md
  60. 0
    166
      doc/scalable-installation.md
  61. 0
    53
      doc/sipgw-config.md
  62. 0
    22
      doc/speakerstats-prosody.md
  63. 0
    15
      doc/turn.md
  64. 21
    4
      interface_config.js
  65. 1
    0
      ios/Podfile
  66. 11
    6
      ios/Podfile.lock
  67. 1
    204
      ios/README.md
  68. 15
    9
      ios/app/src/AppDelegate.m
  69. 2
    33
      ios/app/src/FIRUtilities.m
  70. 1
    1
      ios/app/src/Info.plist
  71. 2
    0
      ios/app/src/ViewController.h
  72. 7
    0
      ios/app/src/ViewController.m
  73. 1
    1
      ios/app/watchos/app/Info.plist
  74. 1
    1
      ios/app/watchos/extension/Info.plist
  75. 3
    0
      ios/fastlane/Fastfile
  76. 8
    0
      ios/sdk/sdk.xcodeproj/project.pbxproj
  77. 6
    2
      ios/sdk/src/AppInfo.m
  78. 1
    1
      ios/sdk/src/Info.plist
  79. 23
    0
      ios/sdk/src/InfoPlistUtil.h
  80. 52
    0
      ios/sdk/src/InfoPlistUtil.m
  81. 3
    0
      ios/sdk/src/JitsiMeet.h
  82. 6
    1
      ios/sdk/src/JitsiMeet.m
  83. 5
    15
      ios/sdk/src/picture-in-picture/PiPViewCoordinator.swift
  84. 40
    32
      lang/languages-ar.json
  85. 0
    27
      lang/languages-az.json
  86. 34
    0
      lang/languages-be.json
  87. 2
    1
      lang/languages-ca.json
  88. 12
    1
      lang/languages-de.json
  89. 42
    0
      lang/languages-el.json
  90. 34
    23
      lang/languages-enGB.json
  91. 8
    8
      lang/languages-eo.json
  92. 5
    3
      lang/languages-es.json
  93. 34
    0
      lang/languages-eu.json
  94. 33
    22
      lang/languages-fi.json
  95. 7
    5
      lang/languages-fr.json
  96. 6
    4
      lang/languages-frCA.json
  97. 34
    0
      lang/languages-fy.json
  98. 4
    2
      lang/languages-gl.json
  99. 37
    0
      lang/languages-he.json
  100. 0
    0
      lang/languages-hu.json

+ 35
- 15
.github/ISSUE_TEMPLATE/1-bug-report.md Parādīt failu

@@ -4,25 +4,45 @@ about: Create a report to help us improve
4 4
 
5 5
 ---
6 6
 
7
-*This Issue tracker is only for reporting bugs and tracking code related issues.*
7
+<!--
8 8
 
9
-Before posting, please make sure you check community.jitsi.org to see if the same or similar bugs have already been discussed.
10
-General questions, installation help, and feature requests can also be posted to community.jitsi.org.
9
+This issue tracker is only for reporting bugs and tracking issues related to the source code.
11 10
 
12
-## Description
13
----
11
+Before posting, please make sure to check if the same or similar bugs have already been discussed: https://github.com/jitsi/jitsi-meet/issues
14 12
 
15
-## Current behavior
16
----
13
+General questions regarding usage, installation, etc. should be posted at https://community.jitsi.org. They will be closed if posted here.
17 14
 
18
-## Expected Behavior
19
----
15
+-->
20 16
 
21
-## Possible Solution
22
----
17
+### Description:
23 18
 
24
-## Steps to reproduce
25
----
19
+<!-- Please describe the bug clearly and concisely. -->
26 20
 
27
-# Environment details
28
----
21
+### Steps to reproduce:
22
+
23
+1. <!-- Open '...' -->
24
+2. <!-- Click on '...' -->
25
+3. <!-- and so on... -->
26
+
27
+### Expected behavior:
28
+
29
+<!-- Please describe what should happen. -->
30
+
31
+### Actual behavior:
32
+
33
+<!-- Please describe what actually happens. -->
34
+<!-- Please attach screenshot if possible. -->
35
+
36
+### Server information:
37
+
38
+- Jitsi Meet version:
39
+- Operating System:
40
+
41
+### Client information:
42
+
43
+- Browser / app version:
44
+- Operating System:
45
+
46
+### Additional information:
47
+
48
+<!-- Please provide additional information about the bug, if any. -->

.github/ISSUE_TEMPLATE/3-feature-request.md → .github/ISSUE_TEMPLATE/2-feature-request.md Parādīt failu

@@ -9,7 +9,7 @@ Thank you for suggesting an idea to make Jitsi Meet better.
9 9
 
10 10
 Please fill in as much of the template below as you're able.
11 11
 
12
-Note that the ultimate decission for implementing features lies on the Jitsi team, not all feature requests shall be accepted.
12
+Note that the ultimate decision for implementing features lies on the Jitsi team, not all feature requests shall be accepted.
13 13
 -->
14 14
 
15 15
 **Is your feature request related to a problem you are facing?**

+ 0
- 10
.github/ISSUE_TEMPLATE/2-help.md Parādīt failu

@@ -1,10 +0,0 @@
1
----
2
-name: Need help with Jitsi Meet?
3
-about: Please ask it in our community at https://community.jitsi.org
4
-
5
----
6
-
7
-If you have a question about Jitsi Meet that is not a bug report or feature
8
-request, please post it in https://community.jitsi.org
9
-
10
-Questions posted to this repository will be closed.

+ 5
- 0
.github/ISSUE_TEMPLATE/config.yml Parādīt failu

@@ -0,0 +1,5 @@
1
+blank_issues_enabled: false
2
+contact_links:
3
+  - name: Need help with Jitsi Meet?
4
+    url: https://community.jitsi.org
5
+    about: Please ask it in our community.

+ 1
- 0
.npmrc Parādīt failu

@@ -0,0 +1 @@
1
+package-lock=true

+ 96
- 0
CONTRIBUTING.md Parādīt failu

@@ -27,3 +27,99 @@ in the agreement, unfortunately, we cannot accept your contribution.
27 27
 - Maintain a clean list of commits, squash them if necessary.
28 28
 - Rebase your topic branch on top of the master branch before creating the pull
29 29
  request.
30
+
31
+## Coding style
32
+
33
+### Comments
34
+
35
+* Comments documenting the source code are required.
36
+
37
+  * Comments from which documentation is automatically generated are **not**
38
+    subject to case-by-case decisions. Such comments are used, for example, on
39
+    types and their members. Examples of tools which automatically generate
40
+    documentation from such comments include JSDoc, Javadoc, Doxygen.
41
+
42
+  * Comments which are not automatically processed are strongly encouraged. They
43
+    are subject to case-by-case decisions. Such comments are often observed in
44
+    function bodies.
45
+
46
+* Comments should be formatted as proper English sentences. Such formatting pays
47
+  attention to, for example, capitalization and punctuation.
48
+
49
+### Duplication
50
+
51
+* Don't copy-paste source code. Reuse it.
52
+
53
+### Formatting
54
+
55
+* Line length is limited to 120 characters.
56
+
57
+* Sort by alphabetical order in order to make the addition of new entities as
58
+  easy as looking a word up in a dictionary. Otherwise, one risks duplicate
59
+  entries (with conflicting values in the cases of key-value pairs). For
60
+  example:
61
+
62
+  * Within an `import` of multiple names from a module, sort the names in
63
+    alphabetical order. (Of course, the default name stays first as required by
64
+    the `import` syntax.)
65
+
66
+    ````javascript
67
+    import {
68
+        DOMINANT_SPEAKER_CHANGED,
69
+        JITSI_CLIENT_CONNECTED,
70
+        JITSI_CLIENT_CREATED,
71
+        JITSI_CLIENT_DISCONNECTED,
72
+        JITSI_CLIENT_ERROR,
73
+        JITSI_CONFERENCE_JOINED,
74
+        MODERATOR_CHANGED,
75
+        PEER_JOINED,
76
+        PEER_LEFT,
77
+        RTC_ERROR
78
+    } from './actionTypes';
79
+    ````
80
+
81
+  * Within a group of imports (e.g. groups of imports delimited by an empty line
82
+    may be: third-party modules, then project modules, and eventually the
83
+    private files of a module), sort the module names in alphabetical order.
84
+
85
+    ````javascript
86
+    import React, { Component } from 'react';
87
+    import { connect } from 'react-redux';
88
+    ````
89
+
90
+### Indentation
91
+
92
+* Align `switch` and `case`/`default`. Don't indent the `case`/`default` more
93
+  than its `switch`.
94
+
95
+  ````javascript
96
+  switch (i) {
97
+  case 0:
98
+      ...
99
+      break;
100
+  default:
101
+      ...
102
+  }
103
+  ````
104
+
105
+### Naming
106
+
107
+* An abstraction should have one name within the project and across multiple
108
+  projects. For example:
109
+
110
+  * The instance of lib-jitsi-meet's `JitsiConnection` type should be named
111
+    `connection` or `jitsiConnection` in jitsi-meet, not `client`.
112
+
113
+  * The class `ReducerRegistry` should be defined in ReducerRegistry.js and its
114
+    imports in other files should use the same name. Don't define the class
115
+    `Registry` in ReducerRegistry.js and then import it as `Reducers` in other
116
+    files.
117
+
118
+* The names of global constants (including ES6 module-global constants) should
119
+  be written in uppercase with underscores to separate words. For example,
120
+  `BACKGROUND_COLOR`.
121
+
122
+* The underscore character at the beginning of a name signals that the
123
+  respective variable, function, property is non-public i.e. private, protected,
124
+  or internal. In contrast, the lack of an underscore at the beginning of a name
125
+  signals public API.

+ 2
- 0
Makefile Parādīt failu

@@ -21,6 +21,7 @@ compile:
21 21
 clean:
22 22
 	rm -fr $(BUILD_DIR)
23 23
 
24
+.NOTPARALLEL:
24 25
 deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
25 26
 
26 27
 deploy-init:
@@ -79,6 +80,7 @@ deploy-css:
79 80
 deploy-local:
80 81
 	([ ! -x deploy-local.sh ] || ./deploy-local.sh)
81 82
 
83
+.NOTPARALLEL:
82 84
 dev: deploy-init deploy-css deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac
83 85
 	$(WEBPACK_DEV_SERVER)
84 86
 

+ 13
- 19
README.md Parādīt failu

@@ -1,6 +1,6 @@
1 1
 # Jitsi Meet - Secure, Simple and Scalable Video Conferences
2 2
 
3
-Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, [secure](#security) and scalable video conferences. Jitsi Meet in action can be seen at [here at the session #482 of the VoIP Users Conference](http://youtu.be/7vFUVClsNh0).
3
+Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, [secure](https://jitsi.org/security) and scalable video conferences. Jitsi Meet in action can be seen at [here at the session #482 of the VoIP Users Conference](http://youtu.be/7vFUVClsNh0).
4 4
 
5 5
 The Jitsi Meet client runs in your browser, without installing anything else on your computer. You can try it out at https://meet.jit.si.
6 6
 
@@ -10,9 +10,11 @@ Jitsi Meet allows very efficient collaboration. Users can stream their desktop o
10 10
 
11 11
 On the client side, no installation is necessary. You just point your browser to the URL of your deployment. This section is about installing a Jitsi Meet suite on your server and hosting your own conferencing service.
12 12
 
13
-Installing Jitsi Meet is a simple experience. For Debian-based system, following the [quick-install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md) document, which uses the package system. You can also see a demonstration of the process in [this tutorial video](https://jitsi.org/tutorial).
13
+Installing Jitsi Meet is a simple experience. For Debian-based system, following the [quick install](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart) document, which uses the package system. You can also see a demonstration of the process in [this tutorial video](https://jitsi.org/tutorial).
14 14
 
15
-For other systems, or if you wish to install all components manually, see the [detailed manual installation instructions](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md).
15
+For other systems, or if you wish to install all components manually, see the [detailed manual installation instructions](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-manual).
16
+
17
+Installation with Docker is also available. Please see the [instruction](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker).
16 18
 
17 19
 ## Download
18 20
 
@@ -46,9 +48,13 @@ You can also sign up for our open beta testing here:
46 48
 * [Android](https://play.google.com/apps/testing/org.jitsi.meet)
47 49
 * [iOS](https://testflight.apple.com/join/isy6ja7S)
48 50
 
51
+## Release notes
52
+
53
+Release notes for Jitsi Meet are maintained on [this repository](https://github.com/jitsi/jitsi-meet-release-notes).
54
+
49 55
 ## Development
50 56
 
51
-For web development see [here](doc/development.md), and for mobile see [here](doc/mobile.md).
57
+For web development see [here](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-web), and for mobile see [here](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-mobile).
52 58
 
53 59
 ## Contributing
54 60
 
@@ -61,25 +67,13 @@ Jitsi Meet provides a very flexible way of embedding in external applications by
61 67
 
62 68
 ## Security
63 69
 
64
-WebRTC does not (yet) provide a way of conducting multi-party conversations with end-to-end encryption. 
65
-Unless you consistently compare DTLS fingerprints with your peers vocally, the same goes for one-to-one calls.
66
-As a result, your stream is encrypted on the network but decrypted on the machine that hosts the bridge when using Jitsi Meet.
70
+The security section here was starting to feel a bit too succinct for the complexity of the topic, so we created a post that covers the topic much more broadly here: https://jitsi.org/security
67 71
 
68
-The Jitsi Meet architecture allows you to deploy your own version, including
69
-all server components. In that case, your security guarantees will be roughly
70
-equivalent to a direct one-to-one WebRTC call. This is the uniqueness of
71
-Jitsi Meet in terms of security.
72
-
73
-The [meet.jit.si](https://meet.jit.si) service is maintained by the Jitsi team
74
-at [8x8](https://8x8.com).
72
+The section on end-to-end encryption in that document is likely going to be one of the key points of interest: https://jitsi.org/security/#e2ee
75 73
 
76 74
 ## Security issues
77 75
 
78
-We take security very seriously and develop all Jitsi projects to be secure and safe.
79
-
80
-If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
81
-
82
-**We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.**
76
+For information on reporting security vulnerabilities in Jitsi Meet, see [SECURITY.md](./SECURITY.md).
83 77
 
84 78
 ## Acknowledgements
85 79
 

.github/ISSUE_TEMPLATE/4-security-issues.md → SECURITY.md Parādīt failu

@@ -1,11 +1,9 @@
1
----
2
-name: Security issues
3
-about: Please email security@jitsi.org
1
+# Security
4 2
 
5
----
3
+## Reporting security issuess
6 4
 
7 5
 We take security very seriously and develop all Jitsi projects to be secure and safe.
8 6
 
9 7
 If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
10 8
 
11
-We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.
9
+**We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.**

+ 1
- 378
android/README.md Parādīt failu

@@ -1,380 +1,3 @@
1 1
 # Jitsi Meet SDK for Android
2 2
 
3
-## Sample applications using the SDK
4
-
5
-If you want to see how easy integrating the Jitsi Meet SDK into a native application is, take a look at the
6
-[sample applications repository](https://github.com/jitsi/jitsi-meet-sdk-samples).
7
-
8
-## Build your own, or use a pre-build SDK artifacts/binaries
9
-
10
-Jitsi conveniently provides a pre-build SDK artifacts/binaries in its Maven repository. When you do not require any
11
-modification to the SDK itself or any of its dependencies, it's suggested to use the pre-build SDK. This avoids the
12
-complexity of building and installing your own SDK artifacts/binaries.
13
-
14
-### Use pre-build SDK artifacts/binaries
15
-
16
-In your project, add the Maven repository
17
-`https://github.com/jitsi/jitsi-maven-repository/raw/master/releases` and the
18
-dependency `org.jitsi.react:jitsi-meet-sdk` into your `build.gradle` files.
19
-
20
-The repository typically goes into the `build.gradle` file in the root of your project:
21
-
22
-```gradle
23
-allprojects {
24
-    repositories {
25
-        google()
26
-        jcenter()
27
-        maven {
28
-            url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases"
29
-        }
30
-    }
31
-}
32
-```
33
-
34
-Dependency definitions belong in the individual module `build.gradle` files:
35
-
36
-```gradle
37
-dependencies {
38
-    // (other dependencies)
39
-    implementation ('org.jitsi.react:jitsi-meet-sdk:2.+') { transitive = true }
40
-}
41
-```
42
-
43
-### Build and use your own SDK artifacts/binaries
44
-
45
-<details>
46
-<summary>Show building instructions</summary>
47
-
48
-Start by making sure that your development environment [is set up correctly](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile.md).
49
-
50
-A note on dependencies: Apart from the SDK, Jitsi also publishes a binary Maven artifact for some of the SDK dependencies (that are not otherwise publicly available) to the Jitsi Maven repository. When you're planning to use a SDK that is built from source, you'll likely use a version of the source code that is newer (or at least _different_) than the version of the source that was used to create the binary SDK artifact. As a consequence, the dependencies that your project will need, might also be different from those that are published in the Jitsi Maven repository. This might lead to build problems, caused by dependencies that are unavailable.
51
-
52
-If you want to use a SDK that is built from source, you will likely benefit from composing a local Maven repository that contains these dependencies. The text below describes how you create a repository that includes both the SDK as well as these dependencies. For illustration purposes, we'll define the location of this local Maven repository as `/tmp/repo`
53
-
54
-In source code form, the Android SDK dependencies are locked/pinned by package.json and package-lock.json of the Jitsi Meet project. To obtain the data, execute NPM in the jitsi-meet project directory:
55
-
56
-    npm install
57
-
58
-This will pull in the dependencies in either binary format, or in source code format, somewhere under /node_modules/
59
-
60
-Third-party React Native _modules_, which Jitsi Meet SDK for Android depends on, are download by NPM in source code 
61
-or binary form. These need to be assembled into Maven artifacts, and then published to your local Maven repository.
62
-A script is provided to facilitate this. From the root of the jitsi-meet project repository, run:
63
-
64
-    ./android/scripts/release-sdk.sh /tmp/repo
65
-
66
-This will build and publish the SDK, and all of its dependencies to the specified Maven repository (`/tmp/repo`) in
67
-this example.
68
-
69
-You're now ready to use the artifacts. In _your_ project, add the Maven repository that you used above (`/tmp/repo`) into your top-level `build.gradle` file:
70
-
71
-    allprojects {
72
-        repositories {
73
-            maven { url "file:/tmp/repo" }
74
-            google()
75
-            jcenter()
76
-        }
77
-    }
78
-
79
-You can use your local repository to replace the Jitsi repository (`maven { url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases" }`) when you published _all_ subprojects. If you didn't do that, you'll have to add both repositories. Make sure your local repository is listed first!
80
-
81
-Then, define the dependency `org.jitsi.react:jitsi-meet-sdk` into the `build.gradle` file of your module:
82
-
83
-    implementation ('org.jitsi.react:jitsi-meet-sdk:+') { transitive = true }
84
-
85
-Note that there should not be a need to explicitly add the other dependencies, as they will be pulled in as transitive
86
-dependencies of `jitsi-meet-sdk`.
87
-
88
-</details>
89
-
90
-## Using the API
91
-
92
-Jitsi Meet SDK is an Android library which embodies the whole Jitsi Meet
93
-experience and makes it reusable by third-party apps.
94
-
95
-First, add Java 1.8 compatibility support to your project by adding the
96
-following lines into your `build.gradle` file:
97
-
98
-```
99
-compileOptions {
100
-    sourceCompatibility JavaVersion.VERSION_1_8
101
-    targetCompatibility JavaVersion.VERSION_1_8
102
-}
103
-```
104
-
105
-To get started, extends your `android.app.Activity` from
106
-`org.jitsi.meet.sdk.JitsiMeetActivity`:
107
-
108
-```java
109
-package org.jitsi.example;
110
-
111
-import org.jitsi.meet.sdk.JitsiMeetActivity;
112
-
113
-public class MainActivity extends JitsiMeetActivity {
114
-}
115
-```
116
-
117
-Alternatively, you can use the `org.jitsi.meet.sdk.JitsiMeetView` class which
118
-extends `android.view.View`.
119
-
120
-Note that this should only be needed when `JitsiMeetActivity` cannot be used for
121
-some reason. Extending `JitsiMeetView` requires manual wiring of the view to
122
-the activity, using a lot of boilerplate code. Using the Activity instead of the
123
-View is strongly recommended.
124
-
125
-<details>
126
-<summary>Show example</summary>
127
-
128
-```java
129
-package org.jitsi.example;
130
-
131
-import android.os.Bundle;
132
-import android.support.v4.app.FragmentActivity;
133
-
134
-import org.jitsi.meet.sdk.JitsiMeetView;
135
-import org.jitsi.meet.sdk.ReactActivityLifecycleCallbacks;
136
-
137
-// Example
138
-//
139
-public class MainActivity extends FragmentActivity implements JitsiMeetActivityInterface {
140
-    private JitsiMeetView view;
141
-
142
-    @Override
143
-    protected void onActivityResult(
144
-            int requestCode,
145
-            int resultCode,
146
-            Intent data) {
147
-        JitsiMeetActivityDelegate.onActivityResult(
148
-                this, requestCode, resultCode, data);
149
-    }
150
-
151
-    @Override
152
-    public void onBackPressed() {
153
-        JitsiMeetActivityDelegate.onBackPressed();
154
-    }
155
-
156
-    @Override
157
-    protected void onCreate(Bundle savedInstanceState) {
158
-        super.onCreate(savedInstanceState);
159
-
160
-        view = new JitsiMeetView(this);
161
-        JitsiMeetConferenceOptions options = new JitsiMeetConferenceOptions.Builder()
162
-            .setRoom("https://meet.jit.si/test123")
163
-            .build();
164
-        view.join(options);
165
-
166
-        setContentView(view);
167
-    }
168
-
169
-    @Override
170
-    protected void onDestroy() {
171
-        super.onDestroy();
172
-
173
-        view.dispose();
174
-        view = null;
175
-
176
-        JitsiMeetActivityDelegate.onHostDestroy(this);
177
-    }
178
-
179
-    @Override
180
-    public void onNewIntent(Intent intent) {
181
-        JitsiMeetActivityDelegate.onNewIntent(intent);
182
-    }
183
-
184
-    @Override
185
-    public void onRequestPermissionsResult(
186
-            final int requestCode,
187
-            final String[] permissions,
188
-            final int[] grantResults) {
189
-        JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
190
-    }
191
-
192
-    @Override
193
-    protected void onResume() {
194
-        super.onResume();
195
-
196
-        JitsiMeetActivityDelegate.onHostResume(this);
197
-    }
198
-
199
-    @Override
200
-    protected void onStop() {
201
-        super.onStop();
202
-
203
-        JitsiMeetActivityDelegate.onHostPause(this);
204
-    }
205
-}
206
-```
207
-
208
-</details>
209
-
210
-### JitsiMeetActivity
211
-
212
-This class encapsulates a high level API in the form of an Android `FragmentActivity`
213
-which displays a single `JitsiMeetView`. You can pass a URL as a `ACTION_VIEW`
214
-on the Intent when starting it and it will join the conference, and will be
215
-automatically terminated (finish() will be called on the activity) when the
216
-conference ends or fails.
217
-
218
-### JitsiMeetView
219
-
220
-The `JitsiMeetView` class is the core of Jitsi Meet SDK. It's designed to
221
-display a Jitsi Meet conference (or a welcome page).
222
-
223
-#### join(options)
224
-
225
-Joins the conference specified by the given `JitsiMeetConferenceOptions`.
226
-
227
-#### leave()
228
-
229
-Leaves the currently active conference. If the welcome page is enabled it will
230
-go back to it, otherwise a black window will be shown.
231
-
232
-#### dispose()
233
-
234
-Releases all resources associated with this view. This method MUST be called
235
-when the Activity holding this view is going to be destroyed, usually in the
236
-`onDestroy()` method.
237
-
238
-#### getListener()
239
-
240
-Returns the `JitsiMeetViewListener` instance attached to the view.
241
-
242
-#### setListener(listener)
243
-
244
-Sets the given listener (class implementing the `JitsiMeetViewListener`
245
-interface) on the view.
246
-
247
-### JitsiMeetConferenceOptions
248
-
249
-This object encapsulates all the options that can be tweaked when joining
250
-a conference.
251
-
252
-Example:
253
-
254
-```java
255
-JitsiMeetConferenceOptions options = new JitsiMeetConferenceOptions.Builder()
256
-    .setServerURL(new URL("https://meet.jit.si"))
257
-    .setRoom("test123")
258
-    .setAudioMuted(false)
259
-    .setVideoMuted(false)
260
-    .setAudioOnly(false)
261
-    .setWelcomePageEnabled(false)
262
-    .build();
263
-```
264
-
265
-See the `JitsiMeetConferenceOptions` implementation for all available options.
266
-
267
-### JitsiMeetActivityDelegate
268
-
269
-This class handles the interaction between `JitsiMeetView` and its enclosing
270
-`Activity`. Generally this shouldn't be consumed by users, because they'd be
271
-using `JitsiMeetActivity` instead, which is already completely integrated.
272
-
273
-All its methods are static.
274
-
275
-#### onActivityResult(...)
276
-
277
-Helper method to handle results of auxiliary activities launched by the SDK.
278
-Should be called from the activity method of the same name.
279
-
280
-#### onBackPressed()
281
-
282
-Helper method which should be called from the activity's `onBackPressed` method.
283
-If this function returns `true`, it means the action was handled and thus no
284
-extra processing is required; otherwise the app should call the parent's
285
-`onBackPressed` method.
286
-
287
-#### onHostDestroy(...)
288
-
289
-Helper method which should be called from the activity's `onDestroy` method.
290
-
291
-#### onHostResume(...)
292
-
293
-Helper method which should be called from the activity's `onResume` or `onStop`
294
-method.
295
-
296
-#### onHostStop(...)
297
-
298
-Helper method which should be called from the activity's `onSstop` method.
299
-
300
-#### onNewIntent(...)
301
-
302
-Helper method for integrating the *deep linking* functionality. If your app's
303
-activity is launched in "singleTask" mode this method should be called from the
304
-activity's `onNewIntent` method.
305
-
306
-#### onRequestPermissionsResult(...)
307
-
308
-Helper method to handle permission requests inside the SDK. It should be called
309
-from the activity method of the same name.
310
-
311
-#### onUserLeaveHint()
312
-
313
-Helper method for integrating automatic Picture-in-Picture. It should be called
314
-from the activity's `onUserLeaveHint` method.
315
-
316
-This is a static method.
317
-
318
-#### JitsiMeetViewListener
319
-
320
-`JitsiMeetViewListener` provides an interface apps can implement to listen to
321
-the state of the Jitsi Meet conference displayed in a `JitsiMeetView`.
322
-
323
-#### onConferenceJoined
324
-
325
-Called when a conference was joined.
326
-
327
-The `data` `Map` contains a "url" key with the conference URL.
328
-
329
-#### onConferenceTerminated
330
-
331
-Called when a conference was terminated either by user choice or due to a
332
-failure.
333
-
334
-The `data` `Map` contains an "error" key with the error and a "url" key
335
-with the conference URL. If the conference finished gracefully no `error`
336
-key will be present.
337
-
338
-#### onConferenceWillJoin
339
-
340
-Called before a conference is joined.
341
-
342
-The `data` `Map` contains a "url" key with the conference URL.
343
-
344
-## ProGuard rules
345
-
346
-When using the SDK on a project some proguard rules have to be added in order
347
-to avoid necessary code being stripped. Add the following to your project's
348
-rules file: https://github.com/jitsi/jitsi-meet/blob/master/android/app/proguard-rules.pro
349
-
350
-## Picture-in-Picture
351
-
352
-`JitsiMeetView` will automatically adjust its UI when presented in a
353
-Picture-in-Picture style scenario, in a rectangle too small to accommodate its
354
-"full" UI.
355
-
356
-## Dropbox integration
357
-
358
-To setup the Dropbox integration, follow these steps:
359
-
360
-1. Add the following to the app's AndroidManifest.xml and change `<APP_KEY>` to
361
-your Dropbox app key:
362
-```
363
-<activity
364
-    android:configChanges="keyboard|orientation"
365
-    android:launchMode="singleTask"
366
-    android:name="com.dropbox.core.android.AuthActivity">
367
-  <intent-filter>
368
-    <action android:name="android.intent.action.VIEW" />
369
-    <category android:name="android.intent.category.BROWSABLE" />
370
-    <category android:name="android.intent.category.DEFAULT" />
371
-    <data android:scheme="db-<APP_KEY>" />
372
-  </intent-filter>
373
-</activity>
374
-```
375
-
376
-2. Add the following to the app's strings.xml and change `<APP_KEY>` to your
377
-Dropbox app key:
378
-```
379
-<string name="dropbox_app_key"><APP_KEY></string>
380
-```
3
+This document has been moved to [The Handbook](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-android-sdk).

+ 4
- 7
android/app/build.gradle Parādīt failu

@@ -1,8 +1,5 @@
1 1
 apply plugin: 'com.android.application'
2 2
 
3
-boolean googleServicesEnabled \
4
-    = project.file('google-services.json').exists() && !rootProject.ext.libreBuild
5
-
6 3
 // Crashlytics integration is done as part of Firebase now, so it gets
7 4
 // automagically activated with google-services.json
8 5
 if (googleServicesEnabled) {
@@ -13,7 +10,7 @@ if (googleServicesEnabled) {
13 10
 // This lets us upload a new build at most every 10 seconds for the
14 11
 // next ~680 years.
15 12
 // https://stackoverflow.com/a/38643838
16
-def vcode = (int)(((new Date().getTime()/1000) - 1546297200) / 10)
13
+def vcode = (int) (((new Date().getTime() / 1000) - 1546297200) / 10)
17 14
 
18 15
 android {
19 16
     compileSdkVersion rootProject.ext.compileSdkVersion
@@ -143,8 +140,8 @@ gradle.projectsEvaluated {
143 140
         def targetName = variant.name.capitalize()
144 141
 
145 142
         def currentRunPackagerTask = tasks.create(
146
-                name: "run${targetName}ReactPackager",
147
-                type: Exec) {
143
+            name: "run${targetName}ReactPackager",
144
+            type: Exec) {
148 145
             group = "react"
149 146
             description = "Run the React packager."
150 147
 
@@ -175,5 +172,5 @@ gradle.projectsEvaluated {
175 172
 }
176 173
 
177 174
 if (googleServicesEnabled) {
178
-   apply plugin: 'com.google.gms.google-services'
175
+    apply plugin: 'com.google.gms.google-services'
179 176
 }

+ 4
- 1
android/app/src/main/java/org/jitsi/meet/GoogleServicesHelper.java Parādīt failu

@@ -7,6 +7,7 @@ import com.crashlytics.android.Crashlytics;
7 7
 import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
8 8
 import io.fabric.sdk.android.Fabric;
9 9
 
10
+import org.jitsi.meet.sdk.JitsiMeet;
10 11
 import org.jitsi.meet.sdk.JitsiMeetActivity;
11 12
 
12 13
 /**
@@ -21,7 +22,9 @@ final class GoogleServicesHelper {
21 22
         if (BuildConfig.GOOGLE_SERVICES_ENABLED) {
22 23
             Log.d(activity.getClass().getSimpleName(), "Initializing Google Services");
23 24
 
24
-            Fabric.with(activity, new Crashlytics());
25
+            if (!JitsiMeet.isCrashReportingDisabled(activity)) {
26
+                Fabric.with(activity, new Crashlytics());
27
+            }
25 28
 
26 29
             FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent())
27 30
                 .addOnSuccessListener(activity, pendingDynamicLinkData -> {

+ 2
- 0
android/build.gradle Parādīt failu

@@ -161,6 +161,8 @@ ext {
161 161
 
162 162
     // Libre build
163 163
     libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
164
+
165
+    googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
164 166
 }
165 167
 
166 168
 // Force the version of the Android build tools we have chosen on all

+ 2
- 2
android/gradle.properties Parādīt failu

@@ -20,5 +20,5 @@
20 20
 android.useAndroidX=true
21 21
 android.enableJetifier=true
22 22
 
23
-appVersion=20.2.0
24
-sdkVersion=2.8.0
23
+appVersion=20.3.0
24
+sdkVersion=2.8.2

+ 3
- 0
android/sdk/build.gradle Parādīt failu

@@ -14,11 +14,13 @@ android {
14 14
     buildTypes {
15 15
         debug {
16 16
             buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}"
17
+            buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${rootProject.ext.googleServicesEnabled}"
17 18
         }
18 19
         release {
19 20
             minifyEnabled false
20 21
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 22
             buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}"
23
+            buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${rootProject.ext.googleServicesEnabled}"
22 24
         }
23 25
     }
24 26
 
@@ -70,6 +72,7 @@ dependencies {
70 72
     implementation project(':react-native-calendar-events')
71 73
     implementation project(':react-native-community-async-storage')
72 74
     implementation project(':react-native-community_netinfo')
75
+    implementation project(':react-native-default-preference')
73 76
     implementation project(':react-native-immersive')
74 77
     implementation project(':react-native-keep-awake')
75 78
     implementation project(':react-native-linear-gradient')

+ 10
- 2
android/sdk/src/main/java/org/jitsi/meet/sdk/AmplitudeModule.java Parādīt failu

@@ -17,6 +17,8 @@
17 17
 package org.jitsi.meet.sdk;
18 18
 
19 19
 import android.annotation.SuppressLint;
20
+import android.content.Context;
21
+import android.content.SharedPreferences;
20 22
 import android.provider.Settings;
21 23
 import android.text.TextUtils;
22 24
 
@@ -40,6 +42,8 @@ class AmplitudeModule
40 42
         extends ReactContextBaseJavaModule {
41 43
 
42 44
     public static final String NAME = "Amplitude";
45
+    public static final String JITSI_PREFERENCES = "jitsi-preferences";
46
+    public static final String AMPLITUDE_DEVICE_ID_KEY = "amplitudeDeviceId";
43 47
 
44 48
     public AmplitudeModule(ReactApplicationContext reactContext) {
45 49
         super(reactContext);
@@ -58,10 +62,14 @@ class AmplitudeModule
58 62
         Amplitude.getInstance(instanceName).initialize(getCurrentActivity(), apiKey);
59 63
 
60 64
         // Set the device ID to something consistent.
61
-        String android_id
62
-            = Settings.Secure.getString(getReactApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
65
+        SharedPreferences sharedPreferences = getReactApplicationContext().getSharedPreferences(JITSI_PREFERENCES, Context.MODE_PRIVATE);
66
+        String android_id = sharedPreferences.getString(AMPLITUDE_DEVICE_ID_KEY, "");
63 67
         if (!TextUtils.isEmpty(android_id)) {
64 68
             Amplitude.getInstance(instanceName).setDeviceId(android_id);
69
+        } else {
70
+            String amplitudeId = Amplitude.getInstance(instanceName).getDeviceId();
71
+            SharedPreferences.Editor editor = sharedPreferences.edit();
72
+            editor.putString(JITSI_PREFERENCES, amplitudeId).apply();
65 73
         }
66 74
     }
67 75
 

+ 1
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/AppInfoModule.java Parādīt failu

@@ -76,6 +76,7 @@ class AppInfoModule
76 76
             "version",
77 77
             packageInfo == null ? "" : packageInfo.versionName);
78 78
         constants.put("LIBRE_BUILD", BuildConfig.LIBRE_BUILD);
79
+        constants.put("GOOGLE_SERVICES_ENABLED", BuildConfig.GOOGLE_SERVICES_ENABLED);
79 80
 
80 81
         return constants;
81 82
     }

+ 10
- 1
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeet.java Parādīt failu

@@ -16,11 +16,14 @@
16 16
  */
17 17
 package org.jitsi.meet.sdk;
18 18
 
19
+import android.content.Context;
20
+import android.content.SharedPreferences;
19 21
 import android.os.Bundle;
20 22
 
21 23
 import com.facebook.react.ReactInstanceManager;
22 24
 
23 25
 public class JitsiMeet {
26
+
24 27
     /**
25 28
      * Default {@link JitsiMeetConferenceOptions} which will be used for all conferences. When
26 29
      * joining a conference these options will be merged with the ones passed to
@@ -72,4 +75,10 @@ public class JitsiMeet {
72 75
             reactInstanceManager.showDevOptionsDialog();
73 76
         }
74 77
     }
75
-}
78
+
79
+    public static boolean isCrashReportingDisabled(Context context) {
80
+        SharedPreferences preferences = context.getSharedPreferences("jitsi-default-preferences", Context.MODE_PRIVATE);
81
+        String value = preferences.getString("isCrashReportingDisabled", "");
82
+        return Boolean.parseBoolean(value);
83
+    }
84
+}

+ 6
- 3
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetActivity.java Parādīt failu

@@ -20,6 +20,7 @@ import android.content.Context;
20 20
 import android.content.Intent;
21 21
 import android.net.Uri;
22 22
 import android.os.Bundle;
23
+
23 24
 import androidx.annotation.Nullable;
24 25
 import androidx.fragment.app.FragmentActivity;
25 26
 
@@ -67,6 +68,9 @@ public class JitsiMeetActivity extends FragmentActivity
67 68
 
68 69
         setContentView(R.layout.activity_jitsi_meet);
69 70
 
71
+        // Listen for conference events.
72
+        getJitsiView().setListener(this);
73
+
70 74
         if (!extraInitialize()) {
71 75
             initialize();
72 76
         }
@@ -151,9 +155,6 @@ public class JitsiMeetActivity extends FragmentActivity
151 155
     }
152 156
 
153 157
     protected void initialize() {
154
-        // Listen for conference events.
155
-        getJitsiView().setListener(this);
156
-
157 158
         // Join the room specified by the URL the app was launched with.
158 159
         // Joining without the room option displays the welcome page.
159 160
         join(getConferenceOptions(getIntent()));
@@ -164,6 +165,8 @@ public class JitsiMeetActivity extends FragmentActivity
164 165
 
165 166
     @Override
166 167
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
168
+        super.onActivityResult(requestCode, resultCode, data);
169
+
167 170
         JitsiMeetActivityDelegate.onActivityResult(this, requestCode, resultCode, data);
168 171
     }
169 172
 

+ 0
- 16
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetFragment.java Parādīt failu

@@ -57,22 +57,6 @@ public class JitsiMeetFragment extends Fragment {
57 57
         return view;
58 58
     }
59 59
 
60
-    @Override
61
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
62
-        JitsiMeetActivityDelegate.onActivityResult(
63
-                getActivity(), requestCode, resultCode, data);
64
-    }
65
-
66
-    @Override
67
-    public void onDestroyView() {
68
-        if (view != null) {
69
-            view.dispose();
70
-            view = null;
71
-        }
72
-
73
-        super.onDestroyView();
74
-    }
75
-
76 60
     @Override
77 61
     public void onDestroy() {
78 62
         super.onDestroy();

+ 6
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java Parādīt failu

@@ -201,4 +201,10 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
201 201
     protected void onExternalAPIEvent(String name, ReadableMap data) {
202 202
         onExternalAPIEvent(LISTENER_METHODS, name, data);
203 203
     }
204
+
205
+    @Override
206
+    protected void onDetachedFromWindow() {
207
+        dispose();
208
+        super.onDetachedFromWindow();
209
+    }
204 210
 }

+ 1
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/ReactInstanceManagerHolder.java Parādīt failu

@@ -190,6 +190,7 @@ class ReactInstanceManagerHolder {
190 190
                 new com.corbt.keepawake.KCKeepAwakePackage(),
191 191
                 new com.facebook.react.shell.MainReactPackage(),
192 192
                 new com.horcrux.svg.SvgPackage(),
193
+                new com.kevinresol.react_native_default_preference.RNDefaultPreferencePackage(),
193 194
                 new com.ocetnik.timer.BackgroundTimerPackage(),
194 195
                 new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
195 196
                 new com.reactnativecommunity.netinfo.NetInfoPackage(),

+ 3
- 1
android/settings.gradle Parādīt failu

@@ -9,6 +9,8 @@ include ':react-native-community-async-storage'
9 9
 project(':react-native-community-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
10 10
 include ':react-native-community_netinfo'
11 11
 project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
12
+include ':react-native-default-preference'
13
+project(':react-native-default-preference').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-default-preference/android')
12 14
 include ':react-native-google-signin'
13 15
 project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
14 16
 include ':react-native-immersive'
@@ -24,4 +26,4 @@ project(':react-native-svg').projectDir = new File(rootProject.projectDir, 	'../
24 26
 include ':react-native-webrtc'
25 27
 project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
26 28
 include ':react-native-webview'
27
-project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
29
+project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')

+ 1
- 1
app.js Parādīt failu

@@ -10,10 +10,10 @@ import 'jQuery-Impromptu';
10 10
 
11 11
 import conference from './conference';
12 12
 import API from './modules/API';
13
+import UI from './modules/UI/UI';
13 14
 import keyboardshortcut from './modules/keyboardshortcut/keyboardshortcut';
14 15
 import remoteControl from './modules/remotecontrol/RemoteControl';
15 16
 import translation from './modules/translation/translation';
16
-import UI from './modules/UI/UI';
17 17
 
18 18
 
19 19
 import * as jc2 from './rdev/jc2';

+ 217
- 131
conference.js Parādīt failu

@@ -1,20 +1,16 @@
1 1
 /* global $, APP, JitsiMeetJS, config, interfaceConfig */
2 2
 
3
-import { openConnection } from './connection';
3
+import EventEmitter from 'events';
4
+import Logger from 'jitsi-meet-logger';
4 5
 
6
+import * as JitsiMeetConferenceEvents from './ConferenceEvents';
7
+import { openConnection } from './connection';
5 8
 import { ENDPOINT_TEXT_MESSAGE_NAME } from './modules/API/constants';
6 9
 import AuthHandler from './modules/UI/authentication/AuthHandler';
7
-import Recorder from './modules/recorder/Recorder';
8
-
9
-import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
10
-
11
-import * as RemoteControlEvents
12
-    from './service/remotecontrol/RemoteControlEvents';
13
-import UIEvents from './service/UI/UIEvents';
14 10
 import UIUtil from './modules/UI/util/UIUtil';
11
+import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
12
+import Recorder from './modules/recorder/Recorder';
15 13
 import { createTaskQueue } from './modules/util/helpers';
16
-import * as JitsiMeetConferenceEvents from './ConferenceEvents';
17
-
18 14
 import {
19 15
     createDeviceChangedEvent,
20 16
     createStartSilentEvent,
@@ -27,9 +23,6 @@ import {
27 23
     redirectToStaticPage,
28 24
     reloadWithStoredParams
29 25
 } from './react/features/app';
30
-
31
-import EventEmitter from 'events';
32
-
33 26
 import {
34 27
     AVATAR_ID_COMMAND,
35 28
     AVATAR_URL_COMMAND,
@@ -79,7 +72,6 @@ import {
79 72
     setVideoAvailable,
80 73
     setVideoMuted
81 74
 } from './react/features/base/media';
82
-import { showNotification } from './react/features/notifications';
83 75
 import {
84 76
     dominantSpeakerChanged,
85 77
     getLocalParticipant,
@@ -117,22 +109,42 @@ import {
117 109
     maybeOpenFeedbackDialog,
118 110
     submitFeedback
119 111
 } from './react/features/feedback';
112
+import { showNotification } from './react/features/notifications';
120 113
 import { mediaPermissionPromptVisibilityChanged } from './react/features/overlay';
121 114
 import { suspendDetected } from './react/features/power-monitor';
115
+import {
116
+    initPrejoin,
117
+    isPrejoinPageEnabled,
118
+    isPrejoinPageVisible,
119
+    replacePrejoinAudioTrack,
120
+    replacePrejoinVideoTrack
121
+} from './react/features/prejoin';
122
+import { createRnnoiseProcessorPromise } from './react/features/rnnoise';
123
+import { toggleScreenshotCaptureEffect } from './react/features/screenshot-capture';
122 124
 import { setSharedVideoStatus } from './react/features/shared-video';
123 125
 import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
124 126
 import { createPresenterEffect } from './react/features/stream-effects/presenter';
125 127
 import { endpointMessageReceived } from './react/features/subtitles';
126
-import { createRnnoiseProcessorPromise } from './react/features/rnnoise';
127
-import { toggleScreenshotCaptureEffect } from './react/features/screenshot-capture';
128
+import UIEvents from './service/UI/UIEvents';
129
+import * as RemoteControlEvents
130
+    from './service/remotecontrol/RemoteControlEvents';
128 131
 
129
-const logger = require('jitsi-meet-logger').getLogger(__filename);
132
+const logger = Logger.getLogger(__filename);
130 133
 
131 134
 const eventEmitter = new EventEmitter();
132 135
 
133 136
 let room;
134 137
 let connection;
135 138
 
139
+/**
140
+ * The promise is used when the prejoin screen is shown.
141
+ * While the user configures the devices the connection can be made.
142
+ *
143
+ * @type {Promise<Object>}
144
+ * @private
145
+ */
146
+let _connectionPromise;
147
+
136 148
 /**
137 149
  * This promise is used for chaining mutePresenterVideo calls in order to avoid  calling GUM multiple times if it takes
138 150
  * a while to finish.
@@ -340,6 +352,7 @@ class ConferenceConnector {
340 352
         }
341 353
 
342 354
         case JitsiConferenceErrors.FOCUS_LEFT:
355
+        case JitsiConferenceErrors.ICE_FAILED:
343 356
         case JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
344 357
         case JitsiConferenceErrors.OFFER_ANSWER_FAILED:
345 358
             APP.store.dispatch(conferenceWillLeave(room));
@@ -471,28 +484,13 @@ export default {
471 484
     localVideo: null,
472 485
 
473 486
     /**
474
-     * Creates local media tracks and connects to a room. Will show error
475
-     * dialogs in case accessing the local microphone and/or camera failed. Will
476
-     * show guidance overlay for users on how to give access to camera and/or
477
-     * microphone.
478
-     * @param {string} roomName
479
-     * @param {object} options
480
-     * @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
481
-     * only audio track will be created and the audio only mode will be turned
482
-     * on.
483
-     * @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
484
-     * should start with screensharing instead of camera video.
485
-     * @param {boolean} options.startWithAudioMuted - will start the conference
486
-     * without any audio tracks.
487
-     * @param {boolean} options.startWithVideoMuted - will start the conference
488
-     * without any video tracks.
489
-     * @returns {Promise.<JitsiLocalTrack[], JitsiConnection>}
487
+     * Returns an object containing a promise which resolves with the created tracks &
488
+     * the errors resulting from that process.
489
+     *
490
+     * @returns {Promise<JitsiLocalTrack[]>, Object}
490 491
      */
491
-    createInitialLocalTracksAndConnect(roomName, options = {}) {
492
-        let audioAndVideoError,
493
-            audioOnlyError,
494
-            screenSharingError,
495
-            videoOnlyError;
492
+    createInitialLocalTracks(options = {}) {
493
+        const errors = {};
496 494
         const initialDevices = [ 'audio' ];
497 495
         const requestedAudio = true;
498 496
         let requestedVideo = false;
@@ -524,7 +522,7 @@ export default {
524 522
         // FIXME is there any simpler way to rewrite this spaghetti below ?
525 523
         if (options.startScreenSharing) {
526 524
             tryCreateLocalTracks = this._createDesktopTrack()
527
-                .then(desktopStream => {
525
+                .then(([ desktopStream ]) => {
528 526
                     if (!requestedAudio) {
529 527
                         return [ desktopStream ];
530 528
                     }
@@ -533,21 +531,21 @@ export default {
533 531
                         .then(([ audioStream ]) =>
534 532
                             [ desktopStream, audioStream ])
535 533
                         .catch(error => {
536
-                            audioOnlyError = error;
534
+                            errors.audioOnlyError = error;
537 535
 
538 536
                             return [ desktopStream ];
539 537
                         });
540 538
                 })
541 539
                 .catch(error => {
542 540
                     logger.error('Failed to obtain desktop stream', error);
543
-                    screenSharingError = error;
541
+                    errors.screenSharingError = error;
544 542
 
545 543
                     return requestedAudio
546 544
                         ? createLocalTracksF({ devices: [ 'audio' ] }, true)
547 545
                         : [];
548 546
                 })
549 547
                 .catch(error => {
550
-                    audioOnlyError = error;
548
+                    errors.audioOnlyError = error;
551 549
 
552 550
                     return [];
553 551
                 });
@@ -560,16 +558,16 @@ export default {
560 558
                     if (requestedAudio && requestedVideo) {
561 559
 
562 560
                         // Try audio only...
563
-                        audioAndVideoError = err;
561
+                        errors.audioAndVideoError = err;
564 562
 
565 563
                         return (
566 564
                             createLocalTracksF({ devices: [ 'audio' ] }, true));
567 565
                     } else if (requestedAudio && !requestedVideo) {
568
-                        audioOnlyError = err;
566
+                        errors.audioOnlyError = err;
569 567
 
570 568
                         return [];
571 569
                     } else if (requestedVideo && !requestedAudio) {
572
-                        videoOnlyError = err;
570
+                        errors.videoOnlyError = err;
573 571
 
574 572
                         return [];
575 573
                     }
@@ -580,7 +578,7 @@ export default {
580 578
                     if (!requestedAudio) {
581 579
                         logger.error('The impossible just happened', err);
582 580
                     }
583
-                    audioOnlyError = err;
581
+                    errors.audioOnlyError = err;
584 582
 
585 583
                     // Try video only...
586 584
                     return requestedVideo
@@ -592,7 +590,7 @@ export default {
592 590
                     if (!requestedVideo) {
593 591
                         logger.error('The impossible just happened', err);
594 592
                     }
595
-                    videoOnlyError = err;
593
+                    errors.videoOnlyError = err;
596 594
 
597 595
                     return [];
598 596
                 });
@@ -603,8 +601,44 @@ export default {
603 601
         // cases, when auth is rquired, for instance, that won't happen until
604 602
         // the user inputs their credentials, but the dialog would be
605 603
         // overshadowed by the overlay.
606
-        tryCreateLocalTracks.then(() =>
607
-            APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false)));
604
+        tryCreateLocalTracks.then(tracks => {
605
+            APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false));
606
+
607
+            return tracks;
608
+        });
609
+
610
+        return {
611
+            tryCreateLocalTracks,
612
+            errors
613
+        };
614
+    },
615
+
616
+    /**
617
+     * Creates local media tracks and connects to a room. Will show error
618
+     * dialogs in case accessing the local microphone and/or camera failed. Will
619
+     * show guidance overlay for users on how to give access to camera and/or
620
+     * microphone.
621
+     * @param {string} roomName
622
+     * @param {object} options
623
+     * @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
624
+     * only audio track will be created and the audio only mode will be turned
625
+     * on.
626
+     * @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
627
+     * should start with screensharing instead of camera video.
628
+     * @param {boolean} options.startWithAudioMuted - will start the conference
629
+     * without any audio tracks.
630
+     * @param {boolean} options.startWithVideoMuted - will start the conference
631
+     * without any video tracks.
632
+     * @returns {Promise.<JitsiLocalTrack[], JitsiConnection>}
633
+     */
634
+    createInitialLocalTracksAndConnect(roomName, options = {}) {
635
+        const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(options);
636
+        const {
637
+            audioAndVideoError,
638
+            audioOnlyError,
639
+            screenSharingError,
640
+            videoOnlyError
641
+        } = errors;
608 642
 
609 643
         return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
610 644
             .then(([ tracks, con ]) => {
@@ -636,105 +670,132 @@ export default {
636 670
             });
637 671
     },
638 672
 
673
+    startConference(con, tracks) {
674
+        tracks.forEach(track => {
675
+            if ((track.isAudioTrack() && this.isLocalAudioMuted())
676
+                || (track.isVideoTrack() && this.isLocalVideoMuted())) {
677
+                const mediaType = track.getType();
678
+
679
+                sendAnalytics(
680
+                    createTrackMutedEvent(mediaType, 'initial mute'));
681
+                logger.log(`${mediaType} mute: initially muted.`);
682
+                track.mute();
683
+            }
684
+        });
685
+        logger.log(`Initialized with ${tracks.length} local tracks`);
686
+
687
+        this._localTracksInitialized = true;
688
+        con.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED, _connectionFailedHandler);
689
+        APP.connection = connection = con;
690
+
691
+        // Desktop sharing related stuff:
692
+        this.isDesktopSharingEnabled
693
+            = JitsiMeetJS.isDesktopSharingEnabled();
694
+        eventEmitter.emit(JitsiMeetConferenceEvents.DESKTOP_SHARING_ENABLED_CHANGED, this.isDesktopSharingEnabled);
695
+
696
+        APP.store.dispatch(
697
+            setDesktopSharingEnabled(this.isDesktopSharingEnabled));
698
+
699
+        this._createRoom(tracks);
700
+        APP.remoteControl.init();
701
+
702
+        // if user didn't give access to mic or camera or doesn't have
703
+        // them at all, we mark corresponding toolbar buttons as muted,
704
+        // so that the user can try unmute later on and add audio/video
705
+        // to the conference
706
+        if (!tracks.find(t => t.isAudioTrack())) {
707
+            this.setAudioMuteStatus(true);
708
+        }
709
+
710
+        if (!tracks.find(t => t.isVideoTrack())) {
711
+            this.setVideoMuteStatus(true);
712
+        }
713
+
714
+        if (config.iAmRecorder) {
715
+            this.recorder = new Recorder();
716
+        }
717
+
718
+        if (config.startSilent) {
719
+            sendAnalytics(createStartSilentEvent());
720
+            APP.store.dispatch(showNotification({
721
+                descriptionKey: 'notify.startSilentDescription',
722
+                titleKey: 'notify.startSilentTitle'
723
+            }));
724
+        }
725
+
726
+        // XXX The API will take care of disconnecting from the XMPP
727
+        // server (and, thus, leaving the room) on unload.
728
+        return new Promise((resolve, reject) => {
729
+            (new ConferenceConnector(resolve, reject)).connect();
730
+        });
731
+    },
732
+
639 733
     /**
640
-     * Open new connection and join to the conference.
641
-     * @param {object} options
642
-     * @param {string} roomName - The name of the conference.
734
+     * Open new connection and join the conference when prejoin page is not enabled.
735
+     * If prejoin page is enabled open an new connection in the background
736
+     * and create local tracks.
737
+     *
738
+     * @param {{ roomName: string }} options
643 739
      * @returns {Promise}
644 740
      */
645
-    init(options) {
646
-        this.roomName = options.roomName;
741
+    async init({ roomName }) {
742
+        const initialOptions = {
743
+            startAudioOnly: config.startAudioOnly,
744
+            startScreenSharing: config.startScreenSharing,
745
+            startWithAudioMuted: config.startWithAudioMuted
746
+                || config.startSilent
747
+                || isUserInteractionRequiredForUnmute(APP.store.getState()),
748
+            startWithVideoMuted: config.startWithVideoMuted
749
+                || isUserInteractionRequiredForUnmute(APP.store.getState())
750
+        };
647 751
 
648
-        window.addEventListener('hashchange', this.onHashChange.bind(this), false);
752
+        this.roomName = roomName;
649 753
 
650
-        return (
754
+        window.addEventListener('hashchange', this.onHashChange.bind(this), false);
651 755
 
756
+        try {
652 757
             // Initialize the device list first. This way, when creating tracks
653 758
             // based on preferred devices, loose label matching can be done in
654 759
             // cases where the exact ID match is no longer available, such as
655 760
             // when the camera device has switched USB ports.
656 761
             // when in startSilent mode we want to start with audio muted
657
-            this._initDeviceList()
658
-                .catch(error => logger.warn(
659
-                    'initial device list initialization failed', error))
660
-                .then(() => this.createInitialLocalTracksAndConnect(
661
-                options.roomName, {
662
-                    startAudioOnly: config.startAudioOnly,
663
-                    startScreenSharing: config.startScreenSharing,
664
-                    startWithAudioMuted: config.startWithAudioMuted
665
-                    || config.startSilent
666
-                    || isUserInteractionRequiredForUnmute(APP.store.getState()),
667
-                    startWithVideoMuted: config.startWithVideoMuted
668
-                    || isUserInteractionRequiredForUnmute(APP.store.getState())
669
-                }))
670
-            .then(([ tracks, con ]) => {
671
-                tracks.forEach(track => {
672
-                    if ((track.isAudioTrack() && this.isLocalAudioMuted())
673
-                        || (track.isVideoTrack() && this.isLocalVideoMuted())) {
674
-                        const mediaType = track.getType();
675
-
676
-                        sendAnalytics(
677
-                            createTrackMutedEvent(mediaType, 'initial mute'));
678
-                        logger.log(`${mediaType} mute: initially muted.`);
679
-                        track.mute();
680
-                    }
681
-                });
682
-                logger.log(`initialized with ${tracks.length} local tracks`);
683
-                this._localTracksInitialized = true;
684
-                con.addEventListener(
685
-                    JitsiConnectionEvents.CONNECTION_FAILED,
686
-                    _connectionFailedHandler);
687
-                APP.connection = connection = con;
688
-
689
-                // Desktop sharing related stuff:
690
-                this.isDesktopSharingEnabled
691
-                    = JitsiMeetJS.isDesktopSharingEnabled();
692
-                eventEmitter.emit(
693
-                    JitsiMeetConferenceEvents.DESKTOP_SHARING_ENABLED_CHANGED,
694
-                    this.isDesktopSharingEnabled);
762
+            await this._initDeviceList();
763
+        } catch (error) {
764
+            logger.warn('initial device list initialization failed', error);
765
+        }
695 766
 
696
-                APP.store.dispatch(
697
-                    setDesktopSharingEnabled(this.isDesktopSharingEnabled));
767
+        if (isPrejoinPageEnabled(APP.store.getState())) {
768
+            _connectionPromise = connect(roomName);
698 769
 
699
-                this._createRoom(tracks);
700
-                APP.remoteControl.init();
770
+            const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
771
+            const tracks = await tryCreateLocalTracks;
701 772
 
702
-                // if user didn't give access to mic or camera or doesn't have
703
-                // them at all, we mark corresponding toolbar buttons as muted,
704
-                // so that the user can try unmute later on and add audio/video
705
-                // to the conference
706
-                if (!tracks.find(t => t.isAudioTrack())) {
707
-                    this.setAudioMuteStatus(true);
708
-                }
773
+            // Initialize device list a second time to ensure device labels
774
+            // get populated in case of an initial gUM acceptance; otherwise
775
+            // they may remain as empty strings.
776
+            this._initDeviceList(true);
709 777
 
710
-                if (!tracks.find(t => t.isVideoTrack())) {
711
-                    this.setVideoMuteStatus(true);
712
-                }
778
+            return APP.store.dispatch(initPrejoin(tracks, errors));
779
+        }
713 780
 
714
-                // Initialize device list a second time to ensure device labels
715
-                // get populated in case of an initial gUM acceptance; otherwise
716
-                // they may remain as empty strings.
717
-                this._initDeviceList(true);
781
+        const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(
782
+            roomName, initialOptions);
718 783
 
719
-                if (config.iAmRecorder) {
720
-                    this.recorder = new Recorder();
721
-                }
784
+        this._initDeviceList(true);
722 785
 
723
-                if (config.startSilent) {
724
-                    sendAnalytics(createStartSilentEvent());
725
-                    APP.store.dispatch(showNotification({
726
-                        descriptionKey: 'notify.startSilentDescription',
727
-                        titleKey: 'notify.startSilentTitle'
728
-                    }));
729
-                }
786
+        return this.startConference(con, tracks);
787
+    },
730 788
 
731
-                // XXX The API will take care of disconnecting from the XMPP
732
-                // server (and, thus, leaving the room) on unload.
733
-                return new Promise((resolve, reject) => {
734
-                    (new ConferenceConnector(resolve, reject)).connect();
735
-                });
736
-            })
737
-        );
789
+    /**
790
+     * Joins conference after the tracks have been configured in the prejoin screen.
791
+     *
792
+     * @param {Object[]} tracks - An array with the configured tracks
793
+     * @returns {Promise}
794
+     */
795
+    async prejoinStart(tracks) {
796
+        const con = await _connectionPromise;
797
+
798
+        return this.startConference(con, tracks);
738 799
     },
739 800
 
740 801
     /**
@@ -1352,6 +1413,18 @@ export default {
1352 1413
     useVideoStream(newStream) {
1353 1414
         return new Promise((resolve, reject) => {
1354 1415
             _replaceLocalVideoTrackQueue.enqueue(onFinish => {
1416
+                /**
1417
+                 * When the prejoin page is visible there is no conference object
1418
+                 * created. The prejoin tracks are managed separately,
1419
+                 * so this updates the prejoin video track.
1420
+                 */
1421
+                if (isPrejoinPageVisible(APP.store.getState())) {
1422
+                    return APP.store.dispatch(replacePrejoinVideoTrack(newStream))
1423
+                        .then(resolve)
1424
+                        .catch(reject)
1425
+                        .then(onFinish);
1426
+                }
1427
+
1355 1428
                 APP.store.dispatch(
1356 1429
                 replaceLocalTrack(this.localVideo, newStream, room))
1357 1430
                     .then(() => {
@@ -1405,6 +1478,18 @@ export default {
1405 1478
     useAudioStream(newStream) {
1406 1479
         return new Promise((resolve, reject) => {
1407 1480
             _replaceLocalAudioTrackQueue.enqueue(onFinish => {
1481
+                /**
1482
+                 * When the prejoin page is visible there is no conference object
1483
+                 * created. The prejoin tracks are managed separately,
1484
+                 * so this updates the prejoin audio stream.
1485
+                 */
1486
+                if (isPrejoinPageVisible(APP.store.getState())) {
1487
+                    return APP.store.dispatch(replacePrejoinAudioTrack(newStream))
1488
+                        .then(resolve)
1489
+                        .catch(reject)
1490
+                        .then(onFinish);
1491
+                }
1492
+
1408 1493
                 APP.store.dispatch(
1409 1494
                 replaceLocalTrack(this.localAudio, newStream, room))
1410 1495
                     .then(() => {
@@ -1816,7 +1901,7 @@ export default {
1816 1901
                 const desktopVideoStream = streams.find(stream => stream.getType() === MEDIA_TYPE.VIDEO);
1817 1902
 
1818 1903
                 if (desktopVideoStream) {
1819
-                    this.useVideoStream(desktopVideoStream);
1904
+                    await this.useVideoStream(desktopVideoStream);
1820 1905
                 }
1821 1906
 
1822 1907
                 this._desktopAudioStream = streams.find(stream => stream.getType() === MEDIA_TYPE.AUDIO);
@@ -2005,6 +2090,7 @@ export default {
2005 2090
                 logger.info(`My role changed, new role: ${role}`);
2006 2091
 
2007 2092
                 APP.store.dispatch(localParticipantRoleChanged(role));
2093
+                APP.API.notifyUserRoleChanged(id, role);
2008 2094
             } else {
2009 2095
                 APP.store.dispatch(participantRoleChanged(id, role));
2010 2096
             }
@@ -2829,7 +2915,7 @@ export default {
2829 2915
     leaveRoomAndDisconnect() {
2830 2916
         APP.store.dispatch(conferenceWillLeave(room));
2831 2917
 
2832
-        if (room.isJoined()) {
2918
+        if (room && room.isJoined()) {
2833 2919
             return room.leave().then(disconnect, disconnect);
2834 2920
         }
2835 2921
 

+ 15
- 0
config.js Parādīt failu

@@ -226,6 +226,14 @@ var config = {
226 226
     // disabled, then bandwidth estimations are disabled.
227 227
     // enableRemb: false,
228 228
 
229
+    // Enables ICE restart logic in LJM and displays the page reload overlay on
230
+    // ICE failure. Current disabled by default because it's causing issues with
231
+    // signaling when Octo is enabled. Also when we do an "ICE restart"(which is
232
+    // not a real ICE restart), the client maintains the TCC sequence number
233
+    // counter, but the bridge resets it. The bridge sends media packets with
234
+    // TCC sequence numbers starting from 0.
235
+    // enableIceRestart: false,
236
+
229 237
     // Defines the minimum number of participants to start a call (the default
230 238
     // is set in Jicofo and set to 2).
231 239
     // minParticipants: 2,
@@ -289,6 +297,9 @@ var config = {
289 297
     // and microsoftApiApplicationClientID
290 298
     // enableCalendarIntegration: false,
291 299
 
300
+    // When 'true', it shows an intermediate page before joining, where the user can  configure its devices.
301
+    // prejoinPageEnabled: false,
302
+
292 303
     // Stats
293 304
     //
294 305
 
@@ -368,6 +379,10 @@ var config = {
368 379
         // The Google Analytics Tracking ID:
369 380
         // googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1'
370 381
 
382
+        // Matomo configuration:
383
+        // matomoEndpoint: 'https://your-matomo-endpoint/',
384
+        // matomoSiteID: '42',
385
+
371 386
         // The Amplitude APP Key:
372 387
         // amplitudeAPPKey: '<APP_KEY>'
373 388
 

+ 4
- 3
connection.js Parādīt failu

@@ -1,8 +1,9 @@
1 1
 /* global APP, JitsiMeetJS, config */
2 2
 
3
-import AuthHandler from './modules/UI/authentication/AuthHandler';
4
-import jitsiLocalStorage from './modules/util/JitsiLocalStorage';
3
+import Logger from 'jitsi-meet-logger';
4
+import { jitsiLocalStorage } from 'js-utils';
5 5
 
6
+import AuthHandler from './modules/UI/authentication/AuthHandler';
6 7
 import {
7 8
     connectionEstablished,
8 9
     connectionFailed
@@ -13,7 +14,7 @@ import {
13 14
     JitsiConnectionEvents
14 15
 } from './react/features/base/lib-jitsi-meet';
15 16
 
16
-const logger = require('jitsi-meet-logger').getLogger(__filename);
17
+const logger = Logger.getLogger(__filename);
17 18
 
18 19
 /**
19 20
  * The feature announced so we can distinguish jibri participants.

+ 1
- 1
connection_optimization/do_external_connect.js Parādīt failu

@@ -1,7 +1,7 @@
1 1
 /* global config, createConnectionExternally */
2 2
 
3 3
 import getRoomName from '../react/features/base/config/getRoomName';
4
-import parseURLParams from '../react/features/base/config/parseURLParams';
4
+import { parseURLParams } from '../react/features/base/util/parseURLParams';
5 5
 
6 6
 /**
7 7
  * Implements external connect using createConnectionExternally function defined

+ 1
- 13
css/_avatar.scss Parādīt failu

@@ -20,18 +20,6 @@
20 20
     }
21 21
 }
22 22
 
23
-.avatar-foreign {
24
-    align-items: center;
25
-    bottom: 0;
26
-    display: flex;
27
-    font-size: 40pt;
28
-    justify-content: center;
29
-    left: 0;
30
-    position: absolute;
31
-    right: 0;
32
-    top: 0;
33
-}
34
-
35 23
 .avatar-svg {
36 24
     height: 100%;
37 25
     width: 100%;
@@ -63,4 +51,4 @@
63 51
         @include avatarBadge;
64 52
         background-color: $presence-idle;
65 53
     }
66
-}
54
+}

+ 75
- 0
css/_country-picker.scss Parādīt failu

@@ -0,0 +1,75 @@
1
+.cpick {
2
+    border: 1px solid #A4B8D1;
3
+    color: #fff;
4
+    display: flex;
5
+    font-size: 15px;
6
+    height: 38px;
7
+    line-height: 24px;
8
+
9
+    &-selector {
10
+        align-items: center;
11
+        background-color: #283447;
12
+        border-right: 1px solid #A4B8D1;
13
+        cursor: pointer;
14
+        display: flex;
15
+        padding: 8px 10px;
16
+        position: relative;
17
+        width: 88px;
18
+    }
19
+
20
+    &-icon {
21
+        margin-right: 8px;
22
+        position: absolute;
23
+        right: 0;
24
+        top: 12px;
25
+
26
+        & > svg {
27
+            fill: #fff;
28
+        }
29
+    }
30
+
31
+    &-input {
32
+        padding: 8px;
33
+        background: #1C2025;
34
+        border: 0;
35
+        margin: 0;
36
+        color: #fff;
37
+        caret-color: #0376DA;
38
+        flex-grow: 1;
39
+    }
40
+
41
+    &-dropdown {
42
+        height: 190px;
43
+        overflow-y: auto;
44
+        width: 343px;
45
+    }
46
+
47
+    &-dropdown-entry {
48
+        align-items: center;
49
+        cursor: pointer;
50
+        display: flex;
51
+        height: 40px;
52
+        padding: 0 10px;
53
+
54
+        &:hover {
55
+            background-color: #66768b;
56
+        }
57
+
58
+        &-text {
59
+            color: #fff;
60
+            flex-grow: 1;
61
+            font-size: 15px;
62
+            line-height: 24px;
63
+            overflow: hidden;
64
+            text-overflow: ellipsis;
65
+            white-space: nowrap;
66
+
67
+        }
68
+    }
69
+}
70
+
71
+// Override @Atlaskit/inline-dialog styles
72
+.cpick-container > div > div:nth-child(2) > div > div {
73
+    outline: none;
74
+    padding: 8px 0 0 0;
75
+}

+ 68
- 0
css/_labels.scss Parādīt failu

@@ -0,0 +1,68 @@
1
+.large-video-labels {
2
+    display: flex;
3
+    position: absolute;
4
+    top: 30px;
5
+    right: 30px;
6
+    transition: right 0.5s;
7
+    z-index: $zindex3;
8
+
9
+    .circular-label {
10
+        align-items: center;
11
+        color: white;
12
+        display: flex;
13
+        font-weight: bold;
14
+        justify-content: center;
15
+        margin-left: 8px;
16
+        opacity: 0.8;
17
+    }
18
+
19
+    .circular-label {
20
+        background: #B8C7E0;
21
+    }
22
+
23
+    .circular-label.e2ee {
24
+        align-items: center;
25
+        background: #76CF9C;
26
+        display: flex;
27
+        justify-content: center;
28
+    }
29
+
30
+    .circular-label.file {
31
+        background: #FF5630;
32
+    }
33
+
34
+    .circular-label.local-rec {
35
+        background: #FF5630;
36
+    }
37
+
38
+    .circular-label.stream {
39
+        background: #0065FF;
40
+    }
41
+
42
+    .circular-label.insecure {
43
+        background: $defaultWarningColor;
44
+    }
45
+
46
+    .recording-label.center-message {
47
+        background: $videoStateIndicatorBackground;
48
+        bottom: 50%;
49
+        display: block;
50
+        left: 50%;
51
+        padding: 10px;
52
+        position: fixed;
53
+        transform: translate(-50%, -50%);
54
+        z-index: $centeredVideoLabelZ;
55
+    }
56
+}
57
+
58
+.circular-label {
59
+    background: $videoStateIndicatorBackground;
60
+    border-radius: 50%;
61
+    box-sizing: border-box;
62
+    cursor: default;
63
+    font-size: 13px;
64
+    height: $videoStateIndicatorSize;
65
+    line-height: $videoStateIndicatorSize;
66
+    text-align: center;
67
+    min-width: $videoStateIndicatorSize;
68
+}

+ 182
- 0
css/_prejoin-dialog.scss Parādīt failu

@@ -0,0 +1,182 @@
1
+.prejoin-dialog {
2
+    background: #1C2025;
3
+    box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.5);
4
+    border-radius: 5px;
5
+    color: #fff;
6
+    height: 400px;
7
+    width: 375px;
8
+
9
+    &--small {
10
+        height: 300;
11
+        width: 400;
12
+    }
13
+
14
+    &-label {
15
+        font-size: 15px;
16
+        line-height: 24px;
17
+
18
+        &-num {
19
+            background: #2b3b4b;
20
+            border: 1px solid #A4B8D1;
21
+            border-radius: 50%;
22
+            color: #fff;
23
+            display: inline-block;
24
+            height: 24px;
25
+            margin-right: 8px;
26
+            width: 24px;
27
+        }
28
+    }
29
+
30
+    &-container {
31
+        align-items: center;
32
+        background: rgba(0,0,0,0.6);
33
+        display: flex;
34
+        height: 100vh;
35
+        justify-content: center;
36
+        left: 0;
37
+        position: absolute;
38
+        top: 0;
39
+        width: 100vw;
40
+        z-index: 3;
41
+    }
42
+
43
+    &-flag {
44
+        display: inline-block;
45
+        margin-right: 8px;
46
+        transform: scale(1.2);
47
+    }
48
+
49
+    &-title {
50
+        display: inline-block;
51
+        font-size: 24px;
52
+        line-height: 32px;
53
+    }
54
+
55
+    &-icon {
56
+        cursor: pointer;
57
+
58
+        > svg {
59
+            fill: #A4B8D1;
60
+        }
61
+    }
62
+
63
+    &-btn {
64
+        width: 309px;
65
+    }
66
+
67
+    &-dialin-container {
68
+        text-align: center;
69
+    }
70
+
71
+    &-delimiter {
72
+        background: #5f6266;
73
+        border: 0;
74
+        height: 1px;
75
+        margin: 0;
76
+        padding: 0;
77
+        width: 100%;
78
+
79
+        &-container {
80
+            margin: 16px 0 24px 0;
81
+            position: relative;
82
+        }
83
+
84
+        &-txt-container {
85
+            position: absolute;
86
+            text-align: center;
87
+            top: -8px;
88
+            width: 100%;
89
+        }
90
+
91
+        &-txt {
92
+            background: #1C2025;
93
+            color: #5f6266;
94
+            font-size: 11px;
95
+            text-transform: uppercase;
96
+            padding: 0 8px;
97
+        }
98
+    }
99
+}
100
+
101
+.prejoin-dialog-callout {
102
+    padding: 16px;
103
+
104
+    &-header {
105
+        display: flex;
106
+        justify-content: space-between;
107
+        margin-bottom: 24px;
108
+    }
109
+
110
+    &-picker {
111
+        margin: 8px 0 16px 0;
112
+    }
113
+}
114
+
115
+.prejoin-dialog-dialin {
116
+    text-align: center;
117
+
118
+    &-header {
119
+        align-items: center;
120
+        margin: 16px 0 32px 16px;
121
+        display: flex;
122
+    }
123
+
124
+    &-icon {
125
+        margin-right: 16px;
126
+    }
127
+
128
+    &-num {
129
+        background: #3e474f;
130
+        border-radius: 4px;
131
+        display: inline-block;
132
+        font-size: 15px;
133
+        line-height: 24px;
134
+        margin: 4px;
135
+        padding: 8px;
136
+
137
+        &-container {
138
+            min-height: 48px;
139
+            margin: 8px 0;
140
+        }
141
+    }
142
+
143
+    &-link {
144
+        color: #6FB1EA;
145
+        cursor: pointer;
146
+        display: inline-block;
147
+        font-size: 13px;
148
+        line-height: 20px;
149
+        margin-bottom: 24px;
150
+    }
151
+
152
+    &-spaced-label {
153
+        margin-bottom: 16px;
154
+        margin-top: 28px;
155
+    }
156
+
157
+    &-btns {
158
+        &> div {
159
+            margin-bottom: 16px;
160
+        }
161
+    }
162
+}
163
+
164
+.prejoin-dialog-calling {
165
+    padding: 16px;
166
+    text-align: center;
167
+
168
+    &-header {
169
+        text-align: right;
170
+    }
171
+
172
+    &-label {
173
+        font-size: 15px;
174
+        margin: 8px 0 16px 0;
175
+    }
176
+
177
+    &-number {
178
+        font-size: 19px;
179
+        line-height: 28px;
180
+        margin: 16px 0;
181
+    }
182
+}

+ 353
- 0
css/_prejoin.scss Parādīt failu

@@ -0,0 +1,353 @@
1
+.prejoin {
2
+    &-full-page {
3
+        background: #1C2025;
4
+        position: absolute;
5
+        width: 100%;
6
+        height: 100%;
7
+        z-index: $toolbarZ + 1;
8
+    }
9
+
10
+    &-input-area-container {
11
+        position: absolute;
12
+        bottom: 48px;
13
+        width: 100%;
14
+        z-index: 2;
15
+    }
16
+
17
+    &-input-area {
18
+        margin: 0 auto;
19
+        text-align: center;
20
+        width: 320px;
21
+    }
22
+
23
+    &-title {
24
+        color: #fff;
25
+        font-size: 24px;
26
+        line-height: 32px;
27
+        margin-bottom: 16px;
28
+    }
29
+
30
+    &-btn {
31
+        border-radius: 3px;
32
+        color: #fff;
33
+        cursor: pointer;
34
+        display: inline-block;
35
+        font-size: 15px;
36
+        line-height: 24px;
37
+        padding: 7px 16px;
38
+        position: relative;
39
+        text-align: center;
40
+        width: 286px;
41
+
42
+        &--primary {
43
+            background: #0376DA;
44
+            border: 1px solid #0376DA;
45
+        }
46
+
47
+        &--secondary {
48
+            background: #2A3A4B;
49
+            border: 1px solid #5E6D7A;
50
+        }
51
+
52
+        &--text {
53
+            width: auto;
54
+            font-size: 13px;
55
+            margin: 0;
56
+            padding: 0;
57
+        }
58
+
59
+        &--disabled {
60
+            background: #5E6D7A;
61
+            border: 1px solid #5E6D7A;
62
+            color: #AFB6BC;
63
+            cursor: initial;
64
+
65
+            .prejoin-btn-icon {
66
+                & > svg {
67
+                    fill: #AFB6BC;
68
+                }
69
+            }
70
+
71
+            .prejoin-btn-options {
72
+                border-left: 1px solid #AFB6BC;
73
+            }
74
+        }
75
+    }
76
+
77
+    &-btn-options {
78
+        align-items: center;
79
+        border-left: 1px solid #fff;
80
+        display: flex;
81
+        height: 100%;
82
+        justify-content: center;
83
+        position: absolute;
84
+        right: 0;
85
+        top: 0;
86
+        width: 40px;
87
+    }
88
+
89
+    &-text-btns {
90
+        display: flex;
91
+        justify-content: space-between;
92
+    }
93
+
94
+    &-input-label {
95
+        color: #A4B8D1;
96
+        font-size: 13px;
97
+        line-height: 20px;
98
+        margin-top: 32px 0 8px 0;
99
+        text-align: center;
100
+        width: 100%;
101
+    }
102
+
103
+    &-checkbox {
104
+        border: 0;
105
+        height: 16px;
106
+        margin-right: 8px;
107
+        padding: 0;
108
+        width: 16px;
109
+    }
110
+
111
+    &-checkbox-container {
112
+        align-items: center;
113
+        color: #fff;
114
+        display: none;
115
+        font-size: 13px;
116
+        justify-content: center;
117
+        line-height: 20px;
118
+        margin-top: 16px;
119
+        width: 100%;
120
+    }
121
+}
122
+
123
+@mixin name-placeholder {
124
+    color: #fff;
125
+    font-weight: 300;
126
+    opacity: 0.6;
127
+}
128
+
129
+.prejoin-preview {
130
+    height: 100%;
131
+    position: absolute;
132
+    width: 100%;
133
+
134
+    &--no-video {
135
+        background: radial-gradient(50% 50% at 50% 50%, #5B6F80 0%, #365067 100%), #FFFFFF;
136
+        text-align: center;
137
+    }
138
+
139
+    &-video {
140
+        height: 100%;
141
+        object-fit: cover;
142
+        position: absolute;
143
+        width: 100%;
144
+    }
145
+
146
+    &-name {
147
+        color: #fff;
148
+        font-size: 19px;
149
+        line-height: 28px;
150
+
151
+        &--editable {
152
+            background: none;
153
+            border: 0;
154
+            border-bottom: 1px solid #D1DBE8;
155
+            margin: 24px 0 16px 0;
156
+            outline: none;
157
+            text-align: center;
158
+            width: 100%;
159
+
160
+            &::-webkit-input-placeholder {
161
+                @include name-placeholder;
162
+            }
163
+            &::-moz-placeholder {
164
+                @include name-placeholder;
165
+            }
166
+            &:-ms-input-placeholder {
167
+                @include name-placeholder;
168
+            }
169
+        }
170
+
171
+        &--text {
172
+            margin: 16px 0;
173
+            outline: none;
174
+        }
175
+    }
176
+
177
+    &-avatar.avatar {
178
+        background: #A4B8D1;
179
+        margin: 200px auto 0 auto;
180
+    }
181
+
182
+    &-btn-container {
183
+        display: flex;
184
+        justify-content: center;
185
+        margin-top: 32px;
186
+        width: 100%;
187
+
188
+        &> div {
189
+            margin: 0 12px;
190
+        }
191
+
192
+        .settings-button-small-icon {
193
+            right: -8px;
194
+
195
+            &--hovered {
196
+                right: -10px;
197
+            }
198
+        }
199
+    }
200
+
201
+    &-overlay {
202
+        height: 100%;
203
+        position: absolute;
204
+        width: 100%;
205
+        z-index: 1;
206
+        background: linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3));
207
+    }
208
+
209
+    &-bottom-overlay {
210
+        background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.9) 100%);
211
+        bottom: 0;
212
+        height: 50%;
213
+        position: absolute;
214
+        width: 100%;
215
+        z-index: 1;
216
+    }
217
+
218
+    &-status {
219
+        align-items: center;
220
+        bottom: 0;
221
+        color: #fff;
222
+        display: flex;
223
+        font-size: 13px;
224
+        min-height: 24px;
225
+        justify-content: center;
226
+        position: absolute;
227
+        text-align: center;
228
+        width: 100%;
229
+        z-index: 1;
230
+
231
+        &--warning {
232
+            background: rgba(241, 173, 51, 0.5)
233
+        }
234
+        &--ok {
235
+            background: rgba(49, 183, 106, 0.5);
236
+        }
237
+    }
238
+
239
+    &-icon {
240
+        background-position: center;
241
+        background-repeat: no-repeat;
242
+        display: inline-block;
243
+        height: 16px;
244
+        margin-right: 8px;
245
+        width: 16px;
246
+    }
247
+
248
+    &-error-desc {
249
+        margin-right: 4px;
250
+    }
251
+
252
+    .settings-button-container {
253
+        width: 49px;
254
+        margin: 0 8px;
255
+    }
256
+
257
+    &-dropdown-btns {
258
+        width: 320px;
259
+        padding: 8px 0;
260
+    }
261
+
262
+    &-dropdown-btn {
263
+        align-items: center;
264
+        color: #1C2025;
265
+        cursor: pointer;
266
+        display: flex;
267
+        height: 40px;
268
+        font-size: 15px;
269
+        line-height: 24px;
270
+        padding: 0 16px;
271
+
272
+        &:hover {
273
+            background-color: #DAEBFA;
274
+        }
275
+    }
276
+
277
+    &-dropdown-icon {
278
+        display: inline-block;
279
+        margin-right: 16px;
280
+
281
+        & > svg {
282
+            fill:  #1C2025;
283
+        }
284
+    }
285
+
286
+    &-dropdown-container {
287
+        & > div > div:nth-child(2) > div > div {
288
+            background: #fff;
289
+            padding: 0;
290
+        }
291
+    }
292
+
293
+}
294
+
295
+.prejoin-copy {
296
+    &-meeting {
297
+        cursor: pointer;
298
+        color: #fff;
299
+        font-size: 15px;
300
+        font-weight: 300;
301
+        line-height: 24px;
302
+        position: relative;
303
+    }
304
+
305
+    &-url {
306
+        max-width: 278px;
307
+        padding: 8px 10px;
308
+        overflow: hidden;
309
+        text-overflow: ellipsis;
310
+    }
311
+
312
+    &-badge {
313
+        border-radius: 4px;
314
+        height: 100%;
315
+        line-height: 38px;
316
+        position: absolute;
317
+        padding-left: 10px;
318
+        text-align: left;
319
+        top: 0;
320
+        width: 100%;
321
+
322
+        &--hover {
323
+            background: #1C2025;
324
+        }
325
+
326
+        &--done {
327
+            background: #31B76A;
328
+        }
329
+    }
330
+
331
+    &-icon {
332
+        position: absolute;
333
+        right: 8px;
334
+        top: 8px;
335
+
336
+       &--white {
337
+           &> svg > path {
338
+               fill: #fff
339
+           }
340
+       }
341
+
342
+       &--light {
343
+           &> svg > path {
344
+               fill: #D1DBE8;
345
+           }
346
+       }
347
+    }
348
+
349
+    &-textarea {
350
+        position: absolute;
351
+        left: -9999px;
352
+    }
353
+}

+ 1
- 0
css/_settings-button.scss Parādīt failu

@@ -57,6 +57,7 @@
57 57
         width: 16px;
58 58
 
59 59
         &> svg {
60
+            fill: #5e6d7a;
60 61
             margin-top: 5px;
61 62
         }
62 63
 

+ 6
- 2
css/_video-preview.css Parādīt failu

@@ -1,7 +1,11 @@
1 1
 .video-preview {
2 2
     background: none;
3 3
     max-height: 290px;
4
-    overflow: auto;
4
+
5
+    &-container {
6
+        overflow: auto;
7
+        padding: 16px;
8
+    }
5 9
 
6 10
     &-entry {
7 11
         cursor: pointer;
@@ -61,6 +65,6 @@
61 65
     // Override @atlaskit/InlineDialog container which is made with styled components
62 66
     & > div > div:nth-child(2) > div > div {
63 67
         outline: none;
64
-        padding: 16px;
68
+        padding: 0;
65 69
     }
66 70
 }

+ 15
- 4
css/_welcome_page.scss Parādīt failu

@@ -71,9 +71,6 @@ body.welcome-page {
71 71
                 text-align: left;
72 72
                 color: #253858;
73 73
                 height: fit-content;
74
-                border-width: $welcomePageEnterRoomInputContainerBorderWidth;
75
-                border-style: $welcomePageEnterRoomInputContainerBorderStyle;
76
-                border-image: $welcomePageEnterRoomInputContainerBorderImage;
77 74
 
78 75
                 .enter-room-title {
79 76
                     display: $welcomePageEnterRoomTitleDisplay;
@@ -83,12 +80,26 @@ body.welcome-page {
83 80
                 }
84 81
 
85 82
                 .enter-room-input {
86
-                    border: none;
83
+                    border-width: $welcomePageEnterRoomInputContainerBorderWidth;
84
+                    border-style: $welcomePageEnterRoomInputContainerBorderStyle;
85
+                    border-image: $welcomePageEnterRoomInputContainerBorderImage;
87 86
                     display: inline-block;
88 87
                     width: 100%;
89 88
                     font-size: 14px;
90 89
                 }
91 90
 
91
+                .insecure-room-name-warning {
92
+                    align-items: center;
93
+                    color: $defaultWarningColor;
94
+                    display: flex;
95
+                    flex-direction: row;
96
+                    margin-top: 5px;
97
+
98
+                    svg {
99
+                        fill: $defaultWarningColor
100
+                    }
101
+                }
102
+
92 103
                 ::placeholder {
93 104
                     color: #253858;
94 105
                 }

+ 6
- 0
css/main.scss Parādīt failu

@@ -75,6 +75,7 @@ $flagsImagePath: "../images/";
75 75
 @import 'filmstrip/tile_view_overrides';
76 76
 @import 'filmstrip/vertical_filmstrip';
77 77
 @import 'filmstrip/vertical_filmstrip_overrides';
78
+@import 'labels';
78 79
 @import 'unsupported-browser/main';
79 80
 @import 'modals/invite/add-people';
80 81
 @import 'deep-linking/main';
@@ -90,5 +91,10 @@ $flagsImagePath: "../images/";
90 91
 @import 'meter';
91 92
 @import 'audio-preview';
92 93
 @import 'video-preview';
94
+@import 'prejoin';
95
+@import 'prejoin-dialog';
96
+@import 'country-picker';
97
+@import 'modals/invite/invite_more';
98
+@import 'modals/security/security';
93 99
 
94 100
 /* Modules END */

+ 1
- 0
css/modals/invite/_add-people.scss Parādīt failu

@@ -3,6 +3,7 @@
3 3
  */
4 4
 .modal-dialog-form {
5 5
     .add-people-form-wrap {
6
+        margin-top: 8px;
6 7
 
7 8
         .error {
8 9
             padding-left: 5px;

+ 0
- 93
css/modals/invite/_info.scss Parādīt failu

@@ -3,47 +3,6 @@
3 3
     display: flex;
4 4
     font-size: 14px;
5 5
 
6
-    .info-dialog-action-link {
7
-        display: inline-block;
8
-        line-height: 1.5em;
9
-
10
-        a {
11
-            cursor: pointer;
12
-            vertical-align: middle;
13
-        }
14
-    }
15
-
16
-    .info-dialog-action-link:before {
17
-        color: $linkFontColor;
18
-        content: '\2022';
19
-        font-size: 1.5em;
20
-        padding: 0 10px;
21
-        vertical-align: middle;
22
-    }
23
-
24
-    .info-dialog-action-link:first-child:before {
25
-        content: '';
26
-        padding: 0;
27
-    }
28
-
29
-    .info-dialog-action-links {
30
-        font-weight: bold;
31
-        margin-top: 10px;
32
-        white-space: nowrap;
33
-    }
34
-
35
-    .info-dialog-action-separator {
36
-        display: inline-block;
37
-    }
38
-
39
-    .info-dialog-copy-element {
40
-        opacity: 0;
41
-        pointer-events: none;
42
-        position: absolute;
43
-        -webkit-user-select: text;
44
-        user-select: text;
45
-    }
46
-
47 6
     .info-dialog-column {
48 7
         margin-right: 10px;
49 8
         overflow: hidden;
@@ -56,52 +15,6 @@
56 15
         }
57 16
     }
58 17
 
59
-    .info-dialog-conference-url,
60
-    .info-dialog-live-stream-url {
61
-        width: max-content;
62
-        width: -moz-max-content;
63
-        width: -webkit-max-content;
64
-        word-break: break-all;
65
-        max-width: 400px;
66
-        display: flex;
67
-        align-items: center;
68
-    }
69
-
70
-    .info-dialog-dial-in {
71
-        word-break: break-all;
72
-
73
-        .conference-id,
74
-        .phone-number {
75
-            user-select: text;
76
-        }
77
-    }
78
-
79
-    .info-dialog-icon {
80
-        color: #6453C0;
81
-        font-size: 16px;
82
-        min-width: 30px;
83
-    }
84
-
85
-    .info-dialog-url-text,
86
-    .info-dialog-url-text:hover {
87
-        color: inherit;
88
-        cursor: inherit;
89
-    }
90
-
91
-    .info-dialog-url-icon {
92
-        display: inline-block;
93
-        margin-left: 5px;
94
-
95
-        svg {
96
-            cursor: pointer;
97
-        }
98
-    }
99
-
100
-    .info-dialog-title {
101
-        font-weight: bold;
102
-        margin-bottom: 10px;
103
-    }
104
-
105 18
     .info-dialog-password,
106 19
     .info-password,
107 20
     .info-password-form {
@@ -223,10 +136,4 @@
223 136
         -moz-user-select: text;
224 137
         -webkit-user-select: text;
225 138
     }
226
-
227
-    .info-dialog-url-text-unselectable {
228
-        user-select: none;
229
-        -moz-user-select: none;
230
-        -webkit-user-select: none;
231
-    }
232 139
 }

+ 252
- 0
css/modals/invite/_invite_more.scss Parādīt failu

@@ -0,0 +1,252 @@
1
+.invite-more {
2
+    &-container {
3
+        color: #fff;
4
+        font-weight: 600;
5
+        position: absolute;
6
+        width: 100%;
7
+        text-align: center;
8
+        z-index: $zindex2;
9
+        background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
10
+
11
+        &.elevated {
12
+            z-index: $filmstripVideosZ + 1;
13
+        }
14
+    }
15
+
16
+    &-header {
17
+        font-size: 19px;
18
+        line-height: 28px;
19
+        margin: 24px 0 16px 0;
20
+    }
21
+
22
+    &-button {
23
+        display: flex;
24
+        justify-content: space-between;
25
+        align-items: center;
26
+        margin: auto;
27
+        padding: 8px 16px;
28
+        width: 152px;
29
+        height: 24px;
30
+        background: #0376DA;
31
+        border-radius: 3px;
32
+        font-size: 14px;
33
+        line-height: 24px;
34
+        cursor: pointer;
35
+
36
+        &:hover {
37
+            background: #278ADF;
38
+        }
39
+
40
+        &-text {
41
+            font-size: 15px;
42
+            line-height: 24px;
43
+        }
44
+    }
45
+    &-dialog {
46
+        color: #fff;
47
+        font-size: 15px;
48
+        line-height: 24px;
49
+
50
+        & > span {
51
+            font-weight: 600;
52
+        }
53
+
54
+        &.header {
55
+            display: flex;
56
+            justify-content: space-between;
57
+            margin: 16px 16px 24px;
58
+            width: calc(100% - 32px);
59
+            color: #fff;
60
+            font-weight: 600;
61
+            font-size: 24px;
62
+            line-height: 32px;
63
+
64
+            & > div > svg {
65
+                cursor: pointer;
66
+                fill: #A4B8D1;
67
+            }
68
+        }
69
+
70
+        &.copy-link {
71
+            display: flex;
72
+            justify-content: space-between;
73
+            align-items: center;
74
+            padding: 8px 8px 8px 16px;
75
+            margin-top: 8px;
76
+            width: calc(100% - 24px);
77
+            height: 24px;
78
+
79
+            background: #0376DA;
80
+            border-radius: 4px;
81
+            cursor: pointer;
82
+
83
+            &:hover {
84
+                background: #278ADF;
85
+                font-weight: 600;
86
+            }
87
+
88
+            &-text {
89
+                overflow: hidden;
90
+                text-overflow: ellipsis;
91
+                white-space: nowrap;
92
+                max-width: 292px;
93
+
94
+                &.selected {
95
+                    font-weight: 600;
96
+                }
97
+            }
98
+
99
+            &.clicked {
100
+                background: #31B76A;
101
+            }
102
+
103
+            & > div > svg > path {
104
+                fill: #fff;
105
+            }
106
+        }
107
+
108
+        &.separator {
109
+            margin: 24px 0 24px -20px;
110
+            padding: 0 20px;
111
+            width: 100%;
112
+            height: 1px;
113
+            background: #5E6D7A;
114
+        }
115
+
116
+        &.email-container {
117
+            display: flex;
118
+            justify-content: space-between;
119
+            align-items: center;
120
+            padding: 8px 8px 8px 16px;
121
+            margin-top: 24px;
122
+            width: calc(100% - 26px);
123
+            height: 22px;
124
+
125
+            background: #2A3A4B;
126
+            border: 1px solid #5E6D7A;
127
+            border-radius: 3px;
128
+            cursor: pointer;
129
+
130
+            &.active {
131
+                border-radius: 3px 3px 0 0;
132
+            }
133
+        }
134
+
135
+        &.icon-container {
136
+            display: none;
137
+
138
+            &.active {
139
+                display: flex;
140
+                width: calc(100% - 26px);
141
+                padding: 8px 8px 8px 16px;
142
+
143
+                background: #2A3A4B;
144
+                border: 1px solid #5E6D7A;
145
+                border-top: none;
146
+                border-radius: 0 0 3px 3px;
147
+
148
+                & > * {
149
+                    display: flex;
150
+                    justify-content: center;
151
+                    align-items: center;
152
+                    height: 40px;
153
+                    width: 40px;
154
+                    border-radius: 4px;
155
+                    cursor: pointer;
156
+                }
157
+    
158
+                &:hover > div:hover {
159
+                    background-color: rgba(255, 255, 255, 0.2);
160
+                }
161
+    
162
+                & > :not(:last-child) {
163
+                    margin-right: 16px;
164
+                }
165
+
166
+                .copy-invite-icon > div > svg > path {
167
+                    fill: #A4B8D1;
168
+                }
169
+            }
170
+        }
171
+
172
+        &.dial-in-display {
173
+            .info-label {
174
+                color: #A4B8D1;
175
+            }
176
+
177
+            .dial-in-copy {
178
+                display: inline-block;
179
+                vertical-align: middle;
180
+                margin-left: 21px;
181
+                cursor: pointer;
182
+            }
183
+        }
184
+
185
+        &.invite-buttons {
186
+            width: 100%;
187
+            text-align: right;
188
+            margin-top: 8px;
189
+
190
+            & > a {
191
+                display: inline-block;
192
+                height: 24px;
193
+                width: 48px;
194
+                border-radius: 3px;
195
+                text-align: center;
196
+                text-decoration: none;
197
+                cursor: pointer;
198
+            }
199
+
200
+            &-cancel {
201
+                margin-right: 16px;
202
+                padding: 7px 15px;
203
+                background: #2A3A4B;
204
+                border: 1px solid #5E6D7A;
205
+            }
206
+
207
+            &-add {
208
+                padding: 8px 16px;
209
+                background: #0376DA;
210
+            }
211
+        }
212
+
213
+        &.stream {
214
+            display: flex;
215
+            justify-content: space-between;
216
+            align-items: center;
217
+            padding: 8px 8px 8px 16px;
218
+            margin-top: 8px;
219
+            width: calc(100% - 26px);
220
+            height: 22px;
221
+
222
+            background: #2A3A4B;
223
+            border: 1px solid #5E6D7A;
224
+            border-radius: 3px;
225
+            cursor: pointer;
226
+
227
+            &:hover {
228
+                font-weight: 600;
229
+            }
230
+
231
+            &-text {
232
+                overflow: hidden;
233
+                text-overflow: ellipsis;
234
+                white-space: nowrap;
235
+                max-width: 292px;
236
+
237
+                &.selected {
238
+                    font-weight: 600;
239
+                }
240
+            }
241
+
242
+            &.clicked {
243
+                background: #31B76A;
244
+                border: 1px solid #31B76A;
245
+            }
246
+
247
+            & > div > svg > path {
248
+                fill: #fff;
249
+            }
250
+        }
251
+    }
252
+}

+ 37
- 0
css/modals/security/_security.scss Parādīt failu

@@ -0,0 +1,37 @@
1
+.security {
2
+    &-dialog {
3
+        color: #fff;
4
+        font-size: 15px;
5
+        line-height: 24px;
6
+        
7
+        &.password {
8
+            display: flex;
9
+            justify-content: space-between;
10
+            align-items: center;
11
+
12
+            &-actions {
13
+                a {
14
+                    cursor: pointer;
15
+                    text-decoration: none;
16
+                    font-size: 14px;
17
+                    color: #6FB1EA;
18
+                }
19
+
20
+                & > a + a {
21
+                    margin-left: 24px;
22
+                }
23
+            }
24
+        }
25
+    }
26
+}
27
+
28
+.new-toolbox .toolbox-content .toolbox-icon.security-toolbar-button,
29
+.new-toolbox .toolbox-content .toolbox-icon.toggled.security-toolbar-button {
30
+    background: rgba(241, 173, 51, 0.7);
31
+    border: 1px solid rgba(255, 255, 255, 0.4);
32
+
33
+    &:hover {
34
+        background: rgba(241, 173, 51, 0.7);
35
+        border: 1px solid rgba(255, 255, 255, 0.4);
36
+    }
37
+}

+ 0
- 55
css/modals/video-quality/_video-quality.scss Parādīt failu

@@ -144,58 +144,3 @@
144 144
 #videoResolutionLabel {
145 145
     z-index: $zindex3 + 1;
146 146
 }
147
-
148
-.large-video-labels {
149
-    display: flex;
150
-    position: absolute;
151
-    top: 30px;
152
-    right: 30px;
153
-    transition: right 0.5s;
154
-    z-index: $zindex3;
155
-
156
-    .circular-label {
157
-        color: white;
158
-        font-weight: bold;
159
-        margin-left: 8px;
160
-        opacity: 0.8;
161
-    }
162
-
163
-    .circular-label {
164
-        background: #B8C7E0;
165
-    }
166
-
167
-    .circular-label.file {
168
-        background: #FF5630;
169
-    }
170
-
171
-    .circular-label.local-rec {
172
-        background: #FF5630;
173
-    }
174
-
175
-    .circular-label.stream {
176
-        background: #0065FF;
177
-    }
178
-
179
-    .recording-label.center-message {
180
-        background: $videoStateIndicatorBackground;
181
-        bottom: 50%;
182
-        display: block;
183
-        left: 50%;
184
-        padding: 10px;
185
-        position: fixed;
186
-        transform: translate(-50%, -50%);
187
-        z-index: $centeredVideoLabelZ;
188
-    }
189
-}
190
-
191
-.circular-label {
192
-    background: $videoStateIndicatorBackground;
193
-    border-radius: 50%;
194
-    box-sizing: border-box;
195
-    cursor: default;
196
-    font-size: 13px;
197
-    height: $videoStateIndicatorSize;
198
-    line-height: $videoStateIndicatorSize;
199
-    text-align: center;
200
-    min-width: $videoStateIndicatorSize;
201
-}

+ 1
- 1
debian/control Parādīt failu

@@ -3,7 +3,7 @@ Section: net
3 3
 Priority: extra
4 4
 Maintainer: Jitsi Team <dev@jitsi.org>
5 5
 Uploaders: Emil Ivov <emcho@jitsi.org>, Damian Minkov <damencho@jitsi.org>
6
-Build-Depends: debhelper (>= 8.0.0)
6
+Build-Depends: debhelper (>= 8.0.0), nodejs
7 7
 Standards-Version: 3.9.6
8 8
 Homepage: https://jitsi.org/meet
9 9
 

+ 1
- 43
doc/README.md Parādīt failu

@@ -1,45 +1,3 @@
1 1
 # Documentation
2 2
 
3
-This document is the entrypoint to different guides, divided in three groups:
4
-
5
-* User guide: these documents are designed to help users of the service, to better
6
-understand all the available features and how to use them.
7
-
8
-* Developer guide: these documents are designed to help developers who want to either
9
-integrate the Jitsi Meet API / SDK in their products or want to improve Jitsi Meet
10
-itself by developing new features or fixing bugs.
11
-
12
-* DevOps guide: these documents are designed for DevOps folks, system administrators
13
-or anyone who wishes to deploy and operate their own Jitsi Meet instance.
14
-
15
-## User guide
16
-
17
-Work in progress.
18
-
19
-## Developer guide
20
-
21
-### Web
22
-
23
-* [iframe API](https://github.com/jitsi/jitsi-meet/blob/master/doc/api.md)
24
-* [Jitsi Meet development](https://github.com/jitsi/jitsi-meet/blob/master/doc/development.md)
25
-
26
-### Mobile
27
-
28
-* [Building the mobile apps](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile.md)
29
-* [SDK usage examples](https://github.com/jitsi/jitsi-meet-sdk-samples)
30
-* [Enabling Dropbox support](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile-dropbox.md)
31
-* [Enabling Google authentication](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile-google-auth.md)
32
-
33
-## DevOps guide
34
-
35
-* [Quick install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md)
36
-* [Docker install](https://github.com/jitsi/docker-jitsi-meet/blob/master/README.md)
37
-* [Google Calendar, MS Calendar, Dropbox integrations](https://github.com/jitsi/jitsi-meet/blob/master/doc/integrations.md)
38
-* [Video tutorials on deployment and scalability](https://jitsi.org/tutorials/)
39
-* [Configuring a video SIP gateway](https://github.com/jitsi/jitsi-meet/blob/master/doc/sipgw-config.md)
40
-* [Enabling speaker stats](https://github.com/jitsi/jitsi-meet/blob/master/doc/speakerstats-prosody.md)
41
-* [Enabling TURN](https://github.com/jitsi/jitsi-meet/blob/master/doc/turn.md)
42
-* [Networking FAQ](https://github.com/jitsi/jitsi-meet/blob/master/doc/faq.md)
43
-* [Cloud APIs](https://github.com/jitsi/jitsi-meet/blob/master/doc/cloud-api.md)
44
-* [Manual Installation](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md)
45
-* [Scalable Installation](https://github.com/jitsi/jitsi-meet/blob/master/doc/scalable-installation.md)
3
+The Jitsi documentation has been moved to [The Handbook](https://jitsi.github.io/handbook/).

+ 1
- 617
doc/api.md Parādīt failu

@@ -1,619 +1,3 @@
1 1
 # Jitsi Meet API
2 2
 
3
-You can use the Jitsi Meet API to embed Jitsi Meet in to your application. You are also welcome to use it for embedding the globally distributed and highly available deployment on meet.jit.si itself. The only thing we ask for in that case is that you please DO NOT remove the jitsi.org logo from the top left corner.
4
-
5
-## Installation
6
-
7
-To embed Jitsi Meet in your application you need to add the Jitsi Meet API library:
8
-
9
-```javascript
10
-<script src='https://meet.jit.si/external_api.js'></script>
11
-```
12
-## API
13
-
14
-### `api = new JitsiMeetExternalAPI(domain, options)`
15
-
16
-The next step for embedding Jitsi Meet is to create the Jitsi Meet API object.
17
-Its constructor gets a number of options:
18
-
19
-* **domain**: domain used to build the conference URL, 'meet.jit.si' for
20
-  example.
21
-* **options**: object with properties - the optional arguments:
22
-    * **roomName**: (optional) name of the room to join.
23
-    * **width**: (optional) width for the iframe which will be created. If a number is specified it's treated as pixel units. If a string is specified the format is number followed by 'px', 'em', 'pt' or '%'.
24
-    * **height**: (optional) height for the iframe which will be created. If a number is specified it's treated as pixel units. If a string is specified the format is number followed by 'px', 'em', 'pt' or '%'.
25
-    * **parentNode**: (optional) HTML DOM Element where the iframe will be added as a child.
26
-    * **configOverwrite**: (optional) JS object with overrides for options defined in [config.js].
27
-    * **interfaceConfigOverwrite**: (optional) JS object with overrides for options defined in [interface_config.js].
28
-    * **noSSL**: (optional, defaults to true) Boolean indicating if the server should be contacted using HTTP or HTTPS.
29
-    * **jwt**: (optional) [JWT](https://jwt.io/) token.
30
-    * **onload**: (optional) handler for the iframe onload event.
31
-    * **invitees**: (optional) Array of objects containing information about new participants that will be invited in the call.
32
-    * **devices**: (optional) A map containing information about the initial devices that will be used in the call.
33
-    * **userInfo**: (optional) JS object containing information about the participant opening the meeting, such as `email`.
34
-
35
-Example:
36
-
37
-```javascript
38
-const domain = 'meet.jit.si';
39
-const options = {
40
-    roomName: 'JitsiMeetAPIExample',
41
-    width: 700,
42
-    height: 700,
43
-    parentNode: document.querySelector('#meet')
44
-};
45
-const api = new JitsiMeetExternalAPI(domain, options);
46
-```
47
-
48
-You can set the initial media devices for the call:
49
-
50
-```javascript
51
-const domain = 'meet.jit.si';
52
-const options = {
53
-    ...
54
-    devices: {
55
-        audioInput: '<deviceLabel>',
56
-        audioOutput: '<deviceLabel>',
57
-        videoInput: '<deviceLabel>'
58
-    },
59
-    ...
60
-};
61
-const api = new JitsiMeetExternalAPI(domain, options);
62
-```
63
-
64
-You can overwrite options set in [config.js] and [interface_config.js].
65
-For example, to enable the filmstrip-only interface mode, you can use:
66
-
67
-```javascript
68
-const options = {
69
-    ...
70
-    interfaceConfigOverwrite: { filmStripOnly: true },
71
-    ...
72
-};
73
-const api = new JitsiMeetExternalAPI(domain, options);
74
-```
75
-
76
-You can also pass a jwt token to Jitsi Meet:
77
-
78
- ```javascript
79
-const options = {
80
-    ...
81
-    jwt: '<jwt_token>',
82
-    noSsl: false,
83
-    ...
84
-};
85
-const api = new JitsiMeetExternalAPI(domain, options);
86
- ```
87
-
88
-You can set the userInfo(email, display name) for the call:
89
-
90
-```javascript
91
-var domain = "meet.jit.si";
92
-var options = {
93
-    ...
94
-    userInfo: {
95
-        email: 'email@jitsiexamplemail.com',
96
-        displayName: 'John Doe'
97
-    }
98
-}
99
-var api = new JitsiMeetExternalAPI(domain, options);
100
-```
101
-
102
-### Controlling the embedded Jitsi Meet Conference
103
-
104
-Device management `JitsiMeetExternalAPI` methods:
105
-* **getAvailableDevices** - Retrieve a list of available devices.
106
-
107
-```javascript
108
-api.getAvailableDevices().then(devices => {
109
-    // devices = {
110
-    //     audioInput: [{
111
-    //         deviceId: 'ID'
112
-    //         groupId: 'grpID'
113
-    //         kind: 'audioinput'
114
-    //         label: 'label'
115
-    //     },....],
116
-    //     audioOutput: [{
117
-    //         deviceId: 'ID'
118
-    //         groupId: 'grpID'
119
-    //         kind: 'audioOutput'
120
-    //         label: 'label'
121
-    //     },....],
122
-    //     videoInput: [{
123
-    //         deviceId: 'ID'
124
-    //         groupId: 'grpID'
125
-    //         kind: 'videoInput'
126
-    //         label: 'label'
127
-    //     },....]
128
-    // }
129
-    ...
130
-});
131
-```
132
-* **getCurrentDevices** - Retrieve a list with the devices that are currently selected.
133
-
134
-```javascript
135
-api.getCurrentDevices().then(devices => {
136
-    // devices = {
137
-    //     audioInput: {
138
-    //         deviceId: 'ID'
139
-    //         groupId: 'grpID'
140
-    //         kind: 'videoInput'
141
-    //         label: 'label'
142
-    //     },
143
-    //     audioOutput: {
144
-    //         deviceId: 'ID'
145
-    //         groupId: 'grpID'
146
-    //         kind: 'videoInput'
147
-    //         label: 'label'
148
-    //     },
149
-    //     videoInput: {
150
-    //         deviceId: 'ID'
151
-    //         groupId: 'grpID'
152
-    //         kind: 'videoInput'
153
-    //         label: 'label'
154
-    //     }
155
-    // }
156
-    ...
157
-});
158
-```
159
-* **isDeviceChangeAvailable** - Resolves with true if the device change is available and with false if not.
160
-
161
-```javascript
162
-// The accepted deviceType values are - 'output', 'input' or undefined.
163
-api.isDeviceChangeAvailable(deviceType).then(isDeviceChangeAvailable => {
164
-    ...
165
-});
166
-```
167
-* **isDeviceListAvailable** - Resolves with true if the device list is available and with false if not.
168
-
169
-```javascript
170
-api.isDeviceListAvailable().then(isDeviceListAvailable => {
171
-    ...
172
-});
173
-```
174
-* **isMultipleAudioInputSupported** - Resolves with true if multiple audio input is supported and with false if not.
175
-
176
-```javascript
177
-api.isMultipleAudioInputSupported().then(isMultipleAudioInputSupported => {
178
-    ...
179
-});
180
-```
181
-* **setAudioInputDevice** - Sets the audio input device to the one with the label or id that is passed.
182
-
183
-```javascript
184
-api.setAudioInputDevice(deviceLabel, deviceId);
185
-```
186
-* **setAudioOutputDevice** - Sets the audio output device to the one with the label or id that is passed.
187
-
188
-```javascript
189
-api.setAudioOutputDevice(deviceLabel, deviceId);
190
-```
191
-* **setVideoInputDevice** - Sets the video input device to the one with the label or id that is passed.
192
-
193
-```javascript
194
-api.setVideoInputDevice(deviceLabel, deviceId);
195
-```
196
-
197
-You can control the embedded Jitsi Meet conference using the `JitsiMeetExternalAPI` object by using `executeCommand`:
198
-
199
-```javascript
200
-api.executeCommand(command, ...arguments);
201
-```
202
-
203
-The `command` parameter is String object with the name of the command. The following commands are currently supported:
204
-
205
-* **displayName** - Sets the display name of the local participant. This command requires one argument - the new display name to be set.
206
-```javascript
207
-api.executeCommand('displayName', 'New Nickname');
208
-```
209
-
210
-* **password** - Sets the password for the room. This command requires one argument - the password name to be set.
211
-```javascript
212
-api.executeCommand('password', 'The Password');
213
-```
214
-
215
-* **sendTones** - Play touch tones.
216
-```javascript
217
-api.executeCommand('sendTones', {
218
-    tones: string, // The dial pad touch tones to play. For example, '12345#'.
219
-    duration: number, // Optional. The number of milliseconds each tone should play. The default is 200.
220
-    pause: number // Optional. The number of milliseconds between each tone. The default is 200.
221
-});
222
-```
223
-
224
-* **subject** - Sets the subject of the conference. This command requires one argument - the new subject to be set.
225
-```javascript
226
-api.executeCommand('subject', 'New Conference Subject');
227
-```
228
-
229
-* **toggleAudio** - Mutes / unmutes the audio for the local participant. No arguments are required.
230
-```javascript
231
-api.executeCommand('toggleAudio');
232
-```
233
-
234
-* **toggleVideo** - Mutes / unmutes the video for the local participant. No arguments are required.
235
-```javascript
236
-api.executeCommand('toggleVideo');
237
-```
238
-
239
-* **toggleFilmStrip** - Hides / shows the filmstrip. No arguments are required.
240
-```javascript
241
-api.executeCommand('toggleFilmStrip');
242
-```
243
-
244
-* **toggleChat** - Hides / shows the chat. No arguments are required.
245
-```javascript
246
-api.executeCommand('toggleChat');
247
-```
248
-
249
-* **toggleShareScreen** - Starts / stops screen sharing. No arguments are required.
250
-```javascript
251
-api.executeCommand('toggleShareScreen');
252
-```
253
-
254
-* **toggleTileView** - Enter / exit tile view layout mode. No arguments are required.
255
-```javascript
256
-api.executeCommand('toggleTileView');
257
-```
258
-
259
-* **hangup** - Hangups the call. No arguments are required.
260
-```javascript
261
-api.executeCommand('hangup');
262
-```
263
-
264
-* **email** - Changes the local email address. This command requires one argument - the new email address to be set.
265
-```javascript
266
-api.executeCommand('email', 'example@example.com');
267
-```
268
-
269
-* **avatarUrl** - Changes the local avatar URL. This command requires one argument - the new avatar URL to be set.
270
-```javascript
271
-api.executeCommand('avatarUrl', 'https://avatars0.githubusercontent.com/u/3671647');
272
-```
273
-
274
-* **sendEndpointTextMessage** - Sends a text message to another participant through the datachannels.
275
-```javascript
276
-api.executeCommand('receiverParticipantId', 'text');
277
-```
278
-
279
-You can also execute multiple commands using the `executeCommands` method:
280
-```javascript
281
-api.executeCommands(commands);
282
-```
283
-The `commands` parameter is an object with the names of the commands as keys and the arguments for the commands as values:
284
-```javascript
285
-api.executeCommands({
286
-    displayName: [ 'nickname' ],
287
-    toggleAudio: []
288
-});
289
-```
290
-
291
-You can add event listeners to the embedded Jitsi Meet using the `addEventListener` method.
292
-**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods (`addListener` or `on`).**
293
-```javascript
294
-api.addEventListener(event, listener);
295
-```
296
-
297
-The `event` parameter is a String object with the name of the event.
298
-The `listener` parameter is a Function object with one argument that will be notified when the event occurs with data related to the event.
299
-
300
-The following events are currently supported:
301
-* **cameraError** - event notifications about Jitsi-Meet having failed to access the camera. The listener will receive an object with the following structure:
302
-```javascript
303
-{
304
-    type: string, // A constant representing the overall type of the error.
305
-    message: string // Additional information about the error.
306
-}
307
-```
308
-
309
-* **avatarChanged** - event notifications about avatar
310
-changes. The listener will receive an object with the following structure:
311
-```javascript
312
-{
313
-    id: string, // the id of the participant that changed his avatar.
314
-    avatarURL: string // the new avatar URL.
315
-}
316
-```
317
-
318
-* **audioAvailabilityChanged** - event notifications about audio availability status changes. The listener will receive an object with the following structure:
319
-```javascript
320
-{
321
-    available: boolean // new available status - boolean
322
-}
323
-```
324
-
325
-* **audioMuteStatusChanged** - event notifications about audio mute status changes. The listener will receive an object with the following structure:
326
-```javascript
327
-{
328
-    muted: boolean // new muted status - boolean
329
-}
330
-```
331
-
332
-* **endpointTextMessageReceived** - event notifications about a text message received through datachannels.
333
-The listener will receive an object with the following structure:
334
-```javascript
335
-{
336
-    senderInfo: {
337
-        jid: string, // the jid of the sender
338
-        id: string // the participant id of the sender
339
-    },
340
-    eventData: {
341
-        name: string // the name of the datachannel event: `endpoint-text-message`
342
-        text: string // the received text from the sender
343
-    }
344
-}
345
-```
346
-
347
-* **micError** - event notifications about Jitsi-Meet having failed to access the mic. The listener will receive an object with the following structure:
348
-```javascript
349
-{
350
-    type: string, // A constant representing the overall type of the error.
351
-    message: string // Additional information about the error.
352
-}
353
-```
354
-
355
-* **screenSharingStatusChanged** - receives event notifications about turning on/off the local user screen sharing. The listener will receive object with the following structure:
356
-```javascript
357
-{
358
-    on: boolean, //whether screen sharing is on
359
-    details: {
360
-
361
-        // From where the screen sharing is capturing, if known. Values which are
362
-        // passed include 'window', 'screen', 'proxy', 'device'. The value undefined
363
-        // will be passed if the source type is unknown or screen share is off.
364
-        sourceType: string|undefined
365
-    }
366
-}
367
-```
368
-
369
-* **dominantSpeakerChanged** - receives event notifications about change in the dominant speaker. The listener will receive object with the following structure:
370
-```javascript
371
-{
372
-    id: string //participantId of the new dominant speaker
373
-}
374
-```
375
-
376
-* **tileViewChanged** - event notifications about tile view layout mode being entered or exited. The listener will receive object with the following structure:
377
-```javascript
378
-{
379
-    enabled: boolean, // whether tile view is not displayed or not
380
-}
381
-```
382
-
383
-* **incomingMessage** - Event notifications about incoming
384
-messages. The listener will receive an object with the following structure:
385
-```javascript
386
-{
387
-    from: string, // The id of the user that sent the message
388
-    nick: string, // the nickname of the user that sent the message
389
-    message: string // the text of the message
390
-}
391
-```
392
-
393
-* **outgoingMessage** - Event notifications about outgoing
394
-messages. The listener will receive an object with the following structure:
395
-```javascript
396
-{
397
-    message: string // the text of the message
398
-}
399
-```
400
-
401
-* **displayNameChange** - event notifications about display name
402
-changes. The listener will receive an object with the following structure:
403
-```javascript
404
-{
405
-    id: string, // the id of the participant that changed his display name
406
-    displayname: string // the new display name
407
-}
408
-```
409
-
410
-* **deviceListChanged** - event notifications about device list changes. The listener will receive an object with the following structure:
411
-```javascript
412
-{
413
-    devices: Object // the new list of available devices.
414
-}
415
-```
416
-NOTE: The devices object has the same format as the getAvailableDevices result format.
417
-
418
-* **emailChange** - event notifications about email
419
-changes. The listener will receive an object with the following structure:
420
-```javascript
421
-{
422
-    id: string, // the id of the participant that changed his email
423
-    email: string // the new email
424
-}
425
-```
426
-* **feedbackSubmitted** - event notifications about conference feedback submission
427
-```javascript
428
-{
429
-    error: string // The error which occurred during submission, if any.
430
-}
431
-```
432
-
433
-* **filmstripDisplayChanged** - event notifications about the visibility of the filmstrip being updated.
434
-```javascript
435
-{
436
-    visible: boolean // Whether or not the filmstrip is displayed or hidden.
437
-}
438
-```
439
-
440
-* **participantJoined** - event notifications about new participants who join the room. The listener will receive an object with the following structure:
441
-```javascript
442
-{
443
-    id: string, // the id of the participant
444
-    displayName: string // the display name of the participant
445
-}
446
-```
447
-
448
-* **participantKickedOut** - event notifications about a participants being removed from the room. The listener will receive an object with the following structure:
449
-```javascript
450
-{
451
-    kicked: {
452
-        id: string, // the id of the participant removed from the room
453
-        local: boolean // whether or not the participant is the local particiapnt
454
-    },
455
-    kicker: {
456
-        id: string // the id of the participant who kicked out the other participant
457
-    }
458
-}
459
-```
460
-
461
-* **participantLeft** - event notifications about participants that leave the room. The listener will receive an object with the following structure:
462
-```javascript
463
-{
464
-    id: string // the id of the participant
465
-}
466
-```
467
-
468
-* **passwordRequired** - event notifications fired when failing to join a room because it has a password.
469
-
470
-* **videoConferenceJoined** - event notifications fired when the local user has joined the video conference. The listener will receive an object with the following structure:
471
-```javascript
472
-{
473
-    roomName: string, // the room name of the conference
474
-    id: string, // the id of the local participant
475
-    displayName: string, // the display name of the local participant
476
-    avatarURL: string // the avatar URL of the local participant
477
-}
478
-```
479
-
480
-* **videoConferenceLeft** - event notifications fired when the local user has left the video conference. The listener will receive an object with the following structure:
481
-```javascript
482
-{
483
-    roomName: string // the room name of the conference
484
-}
485
-```
486
-
487
-* **videoAvailabilityChanged** - event notifications about video availability status changes. The listener will receive an object with the following structure:
488
-```javascript
489
-{
490
-    available: boolean // new available status - boolean
491
-}
492
-```
493
-
494
-* **videoMuteStatusChanged** - event notifications about video mute status changes. The listener will receive an object with the following structure:
495
-```javascript
496
-{
497
-    muted: boolean // new muted status - boolean
498
-}
499
-```
500
-
501
-* **readyToClose** - event notification fired when Jitsi Meet is ready to be closed (hangup operations are completed).
502
-
503
-* **subjectChange** - event notifications about subject of conference changes.
504
-The listener will receive an object with the following structure:
505
-```javascript
506
-{
507
-    subject: string // the new subject
508
-}
509
-```
510
-
511
-* **suspendDetected** - event notifications about detecting suspend event in host computer.
512
-
513
-You can also add multiple event listeners by using `addEventListeners`.
514
-This method requires one argument of type Object. The object argument must
515
-have the names of the events as keys and the listeners of the events as values.
516
-**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods.**
517
-
518
-```javascript
519
-function incomingMessageListener(object)
520
-{
521
-// ...
522
-}
523
-
524
-function outgoingMessageListener(object)
525
-{
526
-// ...
527
-}
528
-
529
-api.addEventListeners({
530
-    incomingMessage: incomingMessageListener,
531
-    outgoingMessage: outgoingMessageListener
532
-});
533
-```
534
-
535
-If you want to remove a listener you can use `removeEventListener` method with argument the name of the event.
536
-**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods( `removeListener`).**
537
-```javascript
538
-api.removeEventListener('incomingMessage');
539
-```
540
-
541
-If you want to remove more than one event you can use `removeEventListeners` method with an Array with the names of the events as an argument.
542
-**NOTE: This method still exists but it is deprecated. JitsiMeetExternalAPI class extends [EventEmitter]. Use [EventEmitter] methods.**
543
-```javascript
544
-api.removeEventListeners([ 'incomingMessage', 'outgoingMessageListener' ]);
545
-```
546
-
547
-You can get the number of participants in the conference with the following API function:
548
-```javascript
549
-const numberOfParticipants = api.getNumberOfParticipants();
550
-```
551
-
552
-You can get the avatar URL of a participant in the conference with the following API function:
553
-```javascript
554
-const avatarURL = api.getAvatarURL(participantId);
555
-```
556
-
557
-You can get the display name of a participant in the conference with the following API function:
558
-```javascript
559
-const displayName = api.getDisplayName(participantId);
560
-```
561
-
562
-You can get the email of a participant in the conference with the following API function:
563
-```javascript
564
-const email = api.getEmail(participantId);
565
-```
566
-
567
-You can get the iframe HTML element where Jitsi Meet is loaded with the following API function:
568
-```javascript
569
-const iframe = api.getIFrame();
570
-```
571
-
572
-You can check whether the audio is muted with the following API function:
573
-```javascript
574
-api.isAudioMuted().then(muted => {
575
-    ...
576
-});
577
-```
578
-
579
-You can check whether the video is muted with the following API function:
580
-```javascript
581
-api.isVideoMuted().then(muted => {
582
-    ...
583
-});
584
-```
585
-
586
-You can check whether the audio is available with the following API function:
587
-```javascript
588
-api.isAudioAvailable().then(available => {
589
-    ...
590
-});
591
-```
592
-
593
-You can check whether the video is available with the following API function:
594
-```javascript
595
-api.isVideoAvailable().then(available => {
596
-    ...
597
-});
598
-```
599
-
600
-You can invite new participants to the call with the following API function:
601
-```javascript
602
-api.invite([ {...}, {...}, {...} ]).then(() => {
603
-    // success
604
-}).catch(() => {
605
-    // failure
606
-});
607
-```
608
-**NOTE: The format of the invitees in the array depends on the invite service used for the deployment.**
609
-
610
-You can remove the embedded Jitsi Meet Conference with the following API function:
611
-```javascript
612
-api.dispose();
613
-```
614
-
615
-NOTE: It's a good practice to remove the conference before the page is unloaded.
616
-
617
-[config.js]: https://github.com/jitsi/jitsi-meet/blob/master/config.js
618
-[interface_config.js]: https://github.com/jitsi/jitsi-meet/blob/master/interface_config.js
619
-[EventEmitter]: https://nodejs.org/api/events.html
3
+This document has been moved [here](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-iframe).

+ 0
- 5
doc/cloud-api.md Parādīt failu

@@ -1,5 +0,0 @@
1
-# Jitsi Meet Cloud API
2
-
3
-The Jitsi Meet Cloud API is a specification for services which can support the integration of Jitsi Meet into other applications, for mapping conferences for dial-in support, and for supporting directory search and user invitations to conferences.
4
-
5
-The swagger for these services is provided in [cloud-api.swagger](cloud-api.swagger) in this same repository and directory.

+ 0
- 93
doc/coding-style.md Parādīt failu

@@ -1,93 +0,0 @@
1
-# Comments
2
-
3
-* Comments documenting the source code are required.
4
-
5
-  * Comments from which documentation is automatically generated are **not**
6
-    subject to case-by-case decisions. Such comments are used, for example, on
7
-    types and their members. Examples of tools which automatically generate
8
-    documentation from such comments include JSDoc, Javadoc, Doxygen.
9
-
10
-  * Comments which are not automatically processed are strongly encouraged. They
11
-    are subject to case-by-case decisions. Such comments are often observed in
12
-    function bodies.
13
-
14
-* Comments should be formatted as proper English sentences. Such formatting pays
15
-  attention to, for example, capitalization and punctuation.
16
-
17
-# Duplication
18
-
19
-* Don't copy-paste source code. Reuse it.
20
-
21
-# Formatting
22
-
23
-* Line length is limited to 80 characters.
24
-
25
-* Sort by alphabetical order in order to make the addition of new entities as
26
-  easy as looking a word up in a dictionary. Otherwise, one risks duplicate
27
-  entries (with conflicting values in the cases of key-value pairs). For
28
-  example:
29
-
30
-  * Within an `import` of multiple names from a module, sort the names in
31
-    alphabetical order. (Of course, the default name stays first as required by
32
-    the `import` syntax.)
33
-
34
-    ````javascript
35
-    import {
36
-        DOMINANT_SPEAKER_CHANGED,
37
-        JITSI_CLIENT_CONNECTED,
38
-        JITSI_CLIENT_CREATED,
39
-        JITSI_CLIENT_DISCONNECTED,
40
-        JITSI_CLIENT_ERROR,
41
-        JITSI_CONFERENCE_JOINED,
42
-        MODERATOR_CHANGED,
43
-        PEER_JOINED,
44
-        PEER_LEFT,
45
-        RTC_ERROR
46
-    } from './actionTypes';
47
-    ````
48
-
49
-  * Within a group of imports (e.g. groups of imports delimited by an empty line
50
-    may be: third-party modules, then project modules, and eventually the
51
-    private files of a module), sort the module names in alphabetical order.
52
-
53
-    ````javascript
54
-    import React, { Component } from 'react';
55
-    import { connect } from 'react-redux';
56
-    ````
57
-
58
-# Indentation
59
-
60
-* Align `switch` and `case`/`default`. Don't indent the `case`/`default` more
61
-  than its `switch`.
62
-
63
-  ````javascript
64
-  switch (i) {
65
-  case 0:
66
-      ...
67
-      break;
68
-  default:
69
-      ...
70
-  }
71
-  ````
72
-
73
-# Naming
74
-
75
-* An abstraction should have one name within the project and across multiple
76
-  projects. For example:
77
-
78
-  * The instance of lib-jitsi-meet's `JitsiConnection` type should be named
79
-    `connection` or `jitsiConnection` in jitsi-meet, not `client`.
80
-
81
-  * The class `ReducerRegistry` should be defined in ReducerRegistry.js and its
82
-    imports in other files should use the same name. Don't define the class
83
-    `Registry` in ReducerRegistry.js and then import it as `Reducers` in other
84
-    files.
85
-
86
-* The names of global constants (including ES6 module-global constants) should
87
-  be written in uppercase with underscores to separate words. For example,
88
-  `BACKGROUND_COLOR`.
89
-
90
-* The underscore character at the beginning of a name signals that the
91
-  respective variable, function, property is non-public i.e. private, protected,
92
-  or internal. In contrast, the lack of an underscore at the beginning of a name
93
-  signals public API.

+ 7
- 0
doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example Parādīt failu

@@ -13,6 +13,13 @@ turncredentials = {
13 13
 
14 14
 cross_domain_bosh = false;
15 15
 consider_bosh_secure = true;
16
+-- https_ports = { }; -- Remove this line to prevent listening on port 5284
17
+
18
+-- https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.0g&guideline=5.4
19
+ssl = {
20
+  protocol = "tlsv1_2+";
21
+  ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
22
+}
16 23
 
17 24
 VirtualHost "jitmeet.example.com"
18 25
         -- enabled = false -- Remove this line to enable this host

+ 4
- 0
doc/debian/jitsi-meet-turn/turnserver.conf Parādīt failu

@@ -10,5 +10,9 @@ no-tcp
10 10
 listening-port=4446
11 11
 tls-listening-port=4445
12 12
 external-ip=__external_ip_address__
13
+no-tlsv1
14
+no-tlsv1_1
15
+# https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.0g&guideline=5.4
16
+cipher-list=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
13 17
 
14 18
 syslog

+ 9
- 4
doc/debian/jitsi-meet/jitsi-meet.example Parādīt failu

@@ -21,11 +21,16 @@ server {
21 21
     listen [::]:443 ssl;
22 22
     server_name jitsi-meet.example.com;
23 23
 
24
-    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
25
-    ssl_prefer_server_ciphers on;
26
-    ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED";
24
+# Mozilla Guideline v5.4, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration
25
+    ssl_protocols TLSv1.2 TLSv1.3;
26
+    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
27
+    ssl_prefer_server_ciphers off;
27 28
 
28
-    add_header Strict-Transport-Security "max-age=31536000";
29
+    ssl_session_timeout 1d;
30
+    ssl_session_cache shared:SSL:10m;  # about 40000 sessions
31
+    ssl_session_tickets off;
32
+
33
+    add_header Strict-Transport-Security "max-age=63072000" always;
29 34
 
30 35
     ssl_certificate /etc/jitsi/meet/jitsi-meet.example.com.crt;
31 36
     ssl_certificate_key /etc/jitsi/meet/jitsi-meet.example.com.key;

+ 11
- 4
doc/debian/jitsi-meet/jitsi-meet.example-apache Parādīt failu

@@ -11,14 +11,15 @@
11 11
 
12 12
   ServerName jitsi-meet.example.com
13 13
 
14
-  SSLProtocol TLSv1 TLSv1.1 TLSv1.2
14
+  # enable HTTP/2, if available
15
+  Protocols h2 http/1.1
16
+
15 17
   SSLEngine on
16 18
   SSLProxyEngine on
17 19
   SSLCertificateFile /etc/jitsi/meet/jitsi-meet.example.com.crt
18 20
   SSLCertificateKeyFile /etc/jitsi/meet/jitsi-meet.example.com.key
19
-  SSLCipherSuite "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED"
20
-  SSLHonorCipherOrder on
21
-  Header set Strict-Transport-Security "max-age=31536000"
21
+
22
+  Header always set Strict-Transport-Security "max-age=63072000"
22 23
 
23 24
   DocumentRoot "/usr/share/jitsi-meet"
24 25
   <Directory "/usr/share/jitsi-meet">
@@ -48,3 +49,9 @@
48 49
   RewriteEngine on
49 50
   RewriteRule ^/([a-zA-Z0-9]+)$ /index.html
50 51
 </VirtualHost>
52
+
53
+# Mozilla Guideline v5.4, Apache 2.4.41, OpenSSL 1.1.1d, intermediate configuration, no OCSP
54
+SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
55
+SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
56
+SSLHonorCipherOrder     off
57
+SSLSessionTickets       off

+ 0
- 82
doc/development.md Parādīt failu

@@ -1,82 +0,0 @@
1
-# Developing Jitsi Meet
2
-
3
-## Building the sources
4
-
5
-Node.js >= 10 and npm >= 6 are required.
6
-
7
-On Debian/Ubuntu systems, the required packages can be installed with:
8
-```
9
-sudo apt-get install npm nodejs
10
-cd jitsi-meet
11
-npm install
12
-```
13
-
14
-To build the Jitsi Meet application, just type
15
-```
16
-make
17
-```
18
-
19
-### Working with the library sources (lib-jitsi-meet)
20
-
21
-By default the library is build from its git repository sources. The default dependency path in package.json is :
22
-```json
23
-"lib-jitsi-meet": "jitsi/lib-jitsi-meet",
24
-```
25
-
26
-To work with local copy you must change the path to:
27
-```json
28
-"lib-jitsi-meet": "file:///Users/name/local-lib-jitsi-meet-copy",
29
-```
30
-
31
-To make the project you must force it to take the sources as 'npm update':
32
-```
33
-npm install lib-jitsi-meet --force && make
34
-```
35
-
36
-Or if you are making only changes to the library:
37
-```
38
-npm install lib-jitsi-meet --force && make deploy-lib-jitsi-meet
39
-```
40
-
41
-Alternative way is to use [npm link](https://docs.npmjs.com/cli/link).
42
-It allows to link `lib-jitsi-meet` dependency to local source in few steps:
43
-
44
-```bash
45
-cd lib-jitsi-meet
46
-
47
-#### create global symlink for lib-jitsi-meet package
48
-npm link
49
-
50
-cd ../jitsi-meet
51
-
52
-#### create symlink from the local node_modules folder to the global lib-jitsi-meet symlink
53
-npm link lib-jitsi-meet
54
-```
55
-
56
- 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.
57
-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.
58
-
59
-If you do not want to use local repository anymore you should run
60
-```bash
61
-cd jitsi-meet
62
-npm unlink lib-jitsi-meet
63
-npm install
64
-```
65
-### Running with webpack-dev-server for development
66
-
67
-Use it at the CLI, type
68
-```
69
-make dev
70
-```
71
-
72
-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:
73
-```
74
-export WEBPACK_DEV_SERVER_PROXY_TARGET=https://your-example-server.com
75
-make dev
76
-```
77
-
78
-The app should be running at https://localhost:8080/
79
-
80
-#### Chrome Privacy Error
81
-
82
-Newer versions of Chrome may block localhost under https and show `NET::ERR_CERT_INVALID` on the page. To solve this open [chrome://flags/#allow-insecure-localhost](chrome://flags/#allow-insecure-localhost) and select Enable, then press Relaunch or quit and restart Chrome.

+ 0
- 7
doc/faq.md Parādīt failu

@@ -1,7 +0,0 @@
1
-**1. How to tell if my server instance is behind NAT?**
2
-
3
-A. In general, if the tool ifconfig (or ipconfig) shows the assigned IP address to be some local address (10.x.x.x or 192.x.x.x) but you know that its public IP address is different from that, the server is most probably behind NAT
4
-
5
-**2. Clients could communicate well in room created at meet.jit.si . The same clients still could connect to my self-hosted instance but can neither hear nor see one another. What's wrong?**
6
-
7
-A. Most probably, the server is behind NAT. See this [resolved question](https://community.jitsi.org/t/cannot-see-video-or-hear-audio-on-self-hosted-instance/). You need to follow the steps detailed [here](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md#Advanced-configuration)

+ 0
- 38
doc/integrations.md Parādīt failu

@@ -1,38 +0,0 @@
1
-Document describing enabling various jitsi-meet integrations.
2
-
3
-## Creating the Google API client for Google Calendar and Youtube integration
4
-1. Log into a Google admin account.
5
-1. Go to Google cloud platform dashboard. https://console.cloud.google.com/apis/dashboard
6
-1. In the Select a Project dropdown, click New Project.
7
-1. Give the project a name.
8
-1. Proceed to the Credentials settings of the new project.
9
-1. In the Credentials tab of the Credentials settings, click Create Credentials and select the type OAuth client ID.
10
-1. Proceed with creating a Web application and add the domains (origins) on which the application will be hosted. Local development environments (http://localhost:8000 for example) can be added here.
11
-1. While still in the Google cloud platform dashboard, click the Library settings for the calendar project.
12
-1. Search for the Google Calendar API (used for calendar accessing), click its result, and enable it.
13
-1. Do the same for YouTube Data API v3
14
-
15
-## Creating the Microsoft app for Microsoft Outlook integration
16
-1. Go to https://apps.dev.microsoft.com/
17
-1. Proceed through the "Add an app" flow. Once created, a page with several Graph Permissions fields should display.
18
-1. Under "Platforms" add "Web"
19
-1. Add a redirect URL for the Microsoft auth flow to visit once a user has confirmed authentication. Target domain if available is just 'yourdomain.com' (the deployment address) and the redirect URL is `https://yourdomain.com/static/msredirect.html`.
20
-1. Add Microsoft Graph delegated permissions, if this option is available: Calendars.Read, Calendars.ReadWrite, Calendars.Read.Shared, Calendars.ReadWrite.Shared.
21
-1. Check `Allow Implicit Flow` (and `Restrict token issuing to this app` if available).
22
-1. Save the changes.
23
-
24
-## Creating the Dropbox app for Dropbox recording integration
25
-1. You need a Dropbox account (If you don't already have one, you can sign up for a free account [here](https://www.dropbox.com/register).)
26
-1. Create new App as described in [Getting Started Guide](https://www.dropbox.com/developers/reference/getting-started?_tk=guides_lp&_ad=guides2&_camp=get_started#app%20console) in App Console section.
27
-1. Choose
28
-    1. 'Dropbox API - For apps that need to access files in Dropbox.' 
29
-    1. 'App folder– Access to a single folder created specifically for your app.'
30
-    1. Fill in the name of your app
31
-1. You need only, the newly created App key, goes in config.js in 
32
-    ```
33
-        dropbox: {
34
-            appKey: '__dropbox_app_key__'
35
-        }
36
-    ```
37
-1. Add your Redirect URIs in the form `https://yourdeployment.com//static/oauth.html`
38
-1. Fill in Branding

+ 0
- 270
doc/manual-install.md Parādīt failu

@@ -1,270 +0,0 @@
1
-# Server Installation for Jitsi Meet
2
-
3
-:warning: **WARNING:** Manual installation is not recommended. We recommend following the [quick-install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md) document. The current document describes the steps that are needed to install a working deployment, but steps are easy to mess up, and the debian packages are more up-to-date, where this document is sometimes not updated to reflect latest changes.
4
-
5
-This describes configuring a server `jitsi.example.com` running Debian or a Debian Derivative. You will need to
6
-change references to that to match your host, and generate some passwords for
7
-`YOURSECRET1`, `YOURSECRET2` and `YOURSECRET3`.
8
-
9
-There are also some complete [example config files](https://github.com/jitsi/jitsi-meet/tree/master/doc/example-config-files/) available, mentioned in each section.
10
-
11
-There are additional configurations to be done for a [scalable installation](https://github.com/jitsi/jitsi-meet/tree/master/doc/scalable-installation.md)
12
-
13
-## Network description
14
-
15
-This is how the network looks:
16
-```
17
-                   +                           +
18
-                   |                           |
19
-                   |                           |
20
-                   v                           |
21
-                  443                          |
22
-               +-------+                       |
23
-               |       |                       |
24
-               | Nginx |                       |
25
-               |       |                       |
26
-               +--+-+--+                       |
27
-                  | |                          |
28
-+------------+    | |    +--------------+      |
29
-|            |    | |    |              |      |
30
-| jitsi-meet +<---+ +--->+ prosody/xmpp |      |
31
-|            |files 5280 |              |      |
32
-+------------+           +--------------+      v
33
-                     5222,5347^    ^5347   4443,10000
34
-                +--------+    |    |    +-------------+
35
-                |        |    |    |    |             |
36
-                | jicofo +----^    ^----+ videobridge |
37
-                |        |              |             |
38
-                +--------+              +-------------+
39
-```
40
-
41
-## Install prosody
42
-```sh
43
-apt-get install prosody
44
-```
45
-
46
-## Configure prosody
47
-Add config file in `/etc/prosody/conf.avail/jitsi.example.com.cfg.lua` :
48
-
49
-- add your domain virtual host section:
50
-
51
-```
52
-VirtualHost "jitsi.example.com"
53
-    authentication = "anonymous"
54
-    ssl = {
55
-        key = "/var/lib/prosody/jitsi.example.com.key";
56
-        certificate = "/var/lib/prosody/jitsi.example.com.crt";
57
-    }
58
-    modules_enabled = {
59
-        "bosh";
60
-        "pubsub";
61
-    }
62
-    c2s_require_encryption = false
63
-```
64
-- add domain with authentication for conference focus user:
65
-```
66
-VirtualHost "auth.jitsi.example.com"
67
-    ssl = {
68
-        key = "/var/lib/prosody/auth.jitsi.example.com.key";
69
-        certificate = "/var/lib/prosody/auth.jitsi.example.com.crt";
70
-    }
71
-    authentication = "internal_plain"
72
-```
73
-- add focus user to server admins:
74
-```
75
-admins = { "focus@auth.jitsi.example.com" }
76
-```
77
-- and finally configure components:
78
-```
79
-Component "conference.jitsi.example.com" "muc"
80
-Component "jitsi-videobridge.jitsi.example.com"
81
-    component_secret = "YOURSECRET1"
82
-Component "focus.jitsi.example.com"
83
-    component_secret = "YOURSECRET2"
84
-```
85
-
86
-Add link for the added configuration
87
-```sh
88
-ln -s /etc/prosody/conf.avail/jitsi.example.com.cfg.lua /etc/prosody/conf.d/jitsi.example.com.cfg.lua
89
-```
90
-
91
-Generate certs for the domain:
92
-```sh
93
-prosodyctl cert generate jitsi.example.com
94
-prosodyctl cert generate auth.jitsi.example.com
95
-```
96
-
97
-Add auth.jitsi.example.com to the trusted certificates on the local machine:
98
-```sh
99
-ln -sf /var/lib/prosody/auth.jitsi.example.com.crt /usr/local/share/ca-certificates/auth.jitsi.example.com.crt
100
-update-ca-certificates -f
101
-```
102
-Note that the `-f` flag is necessary if there are symlinks left from a previous installation.
103
-
104
-Create conference focus user:
105
-```sh
106
-prosodyctl register focus auth.jitsi.example.com YOURSECRET3
107
-```
108
-
109
-Restart prosody XMPP server with the new config
110
-```sh
111
-prosodyctl restart
112
-```
113
-
114
-## Install Nginx
115
-```sh
116
-apt-get install nginx
117
-```
118
-
119
-Add a new file `jitsi.example.com` in `/etc/nginx/sites-available` (see also the example config file):
120
-```
121
-server_names_hash_bucket_size 64;
122
-
123
-server {
124
-    listen 0.0.0.0:443 ssl http2;
125
-    listen [::]:443 ssl http2;
126
-    # tls configuration that is not covered in this guide
127
-    # we recommend the use of https://certbot.eff.org/
128
-    server_name jitsi.example.com;
129
-    # set the root
130
-    root /srv/jitsi-meet;
131
-    index index.html;
132
-    location ~ ^/([a-zA-Z0-9=\?]+)$ {
133
-        rewrite ^/(.*)$ / break;
134
-    }
135
-    location / {
136
-        ssi on;
137
-    }
138
-    # BOSH, Bidirectional-streams Over Synchronous HTTP
139
-    # https://en.wikipedia.org/wiki/BOSH_(protocol)
140
-    location /http-bind {
141
-        proxy_pass      http://localhost:5280/http-bind;
142
-        proxy_set_header X-Forwarded-For $remote_addr;
143
-        proxy_set_header Host $http_host;
144
-    }
145
-    # external_api.js must be accessible from the root of the
146
-    # installation for the electron version of Jitsi Meet to work
147
-    # https://github.com/jitsi/jitsi-meet-electron
148
-    location /external_api.js {
149
-        alias /srv/jitsi-meet/libs/external_api.min.js;
150
-    }
151
-}
152
-```
153
-
154
-Add link for the added configuration
155
-```sh
156
-cd /etc/nginx/sites-enabled
157
-ln -s ../sites-available/jitsi.example.com jitsi.example.com
158
-```
159
-
160
-## Install Jitsi Videobridge
161
-Visit https://download.jitsi.org/jitsi-videobridge/linux to determine the current build number, download and unzip it:
162
-```sh
163
-wget https://download.jitsi.org/jitsi-videobridge/linux/jitsi-videobridge-linux-{arch-buildnum}.zip
164
-unzip jitsi-videobridge-linux-{arch-buildnum}.zip
165
-```
166
-
167
-Install JRE if missing:
168
-```
169
-apt-get install openjdk-8-jre
170
-```
171
-
172
-_NOTE: When installing on older Debian releases keep in mind that you need JRE >= 1.7._
173
-
174
-Create `~/.sip-communicator/sip-communicator.properties` in the home folder of the user that will be starting Jitsi Videobridge:
175
-```sh
176
-mkdir -p ~/.sip-communicator
177
-cat > ~/.sip-communicator/sip-communicator.properties << EOF
178
-org.jitsi.impl.neomedia.transform.srtp.SRTPCryptoContext.checkReplay=false
179
-# The videobridge uses 443 by default with 4443 as a fallback, but since we're already
180
-# running nginx on 443 in this example doc, we specify 4443 manually to avoid a race condition
181
-org.jitsi.videobridge.TCP_HARVESTER_PORT=4443
182
-EOF
183
-```
184
-
185
-Start the videobridge with:
186
-```sh
187
-./jvb.sh --host=localhost --domain=jitsi.example.com --port=5347 --secret=YOURSECRET1 &
188
-```
189
-Or autostart it by adding the line in `/etc/rc.local`:
190
-```sh
191
-/bin/bash /root/jitsi-videobridge-linux-{arch-buildnum}/jvb.sh --host=localhost --domain=jitsi.example.com --port=5347 --secret=YOURSECRET1 </dev/null >> /var/log/jvb.log 2>&1
192
-```
193
-
194
-## Install Jitsi Conference Focus (jicofo)
195
-
196
-Install JDK and Maven if missing:
197
-```
198
-apt-get install openjdk-8-jdk maven
199
-```
200
-
201
-_NOTE: When installing on older Debian releases keep in mind that you need JDK >= 1.7._
202
-
203
-Clone source from Github repo:
204
-```sh
205
-git clone https://github.com/jitsi/jicofo.git
206
-```
207
-Build the package.
208
-```sh
209
-cd jicofo
210
-mvn package -DskipTests -Dassembly.skipAssembly=false
211
-```
212
-Run jicofo:
213
-```sh
214
-=======
215
-unzip target/jicofo-1.1-SNAPSHOT-archive.zip
216
-cd jicofo-1.1-SNAPSHOT-archive'
217
-./jicofo.sh --host=localhost --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
218
-```
219
-
220
-## Deploy Jitsi Meet
221
-Checkout and configure Jitsi Meet:
222
-```sh
223
-cd /srv
224
-git clone https://github.com/jitsi/jitsi-meet.git
225
-cd jitsi-meet
226
-npm install
227
-make
228
-```
229
-
230
-_NOTE: When installing on older distributions keep in mind that you need Node.js >= 10 and npm >= 6._
231
-
232
-Edit host names in `/srv/jitsi-meet/config.js` (see also the example config file):
233
-```
234
-var config = {
235
-    hosts: {
236
-        domain: 'jitsi.example.com',
237
-        muc: 'conference.jitsi.example.com',
238
-        bridge: 'jitsi-videobridge.jitsi.example.com',
239
-        focus: 'focus.jitsi.example.com'
240
-    },
241
-    useNicks: false,
242
-    bosh: '//jitsi.example.com/http-bind', // FIXME: use xep-0156 for that
243
-    //chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
244
-    //minChromeExtVersion: '0.1' // Required version of Chrome extension
245
-};
246
-```
247
-
248
-Verify that nginx config is valid and reload nginx:
249
-```sh
250
-nginx -t && nginx -s reload
251
-```
252
-
253
-## Running behind NAT
254
-Jitsi Videobridge can run behind a NAT, provided that both required ports are routed (forwarded) to the machine that it runs on. By default these ports are `TCP/4443` and `UDP/10000`.
255
-
256
-If you do not route these two ports, Jitsi Meet will only work with video for two people, breaking upon 3 or more people trying to show video.
257
-
258
-`TCP/443` is required for the webserver which can be running on another machine than the Jitsi Videobrige is running on.
259
-
260
-The following extra lines need to be added to the file `~/.sip-communicator/sip-communicator.properties` (in the home directory of the user running the videobridge):
261
-```
262
-org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=<Local.IP.Address>
263
-org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=<Public.IP.Address>
264
-```
265
-
266
-# Hold your first conference
267
-You are now all set and ready to have your first meet by going to http://jitsi.example.com
268
-
269
-## Enabling recording
270
-[Jibri](https://github.com/jitsi/jibri) is a set of tools for recording and/or streaming a Jitsi Meet conference.

+ 0
- 28
doc/mobile-dropbox.md Parādīt failu

@@ -1,28 +0,0 @@
1
-# Setting up Dropbox integration
2
-1. Create a Dropbox app.
3
-2. Add the following to ```ios/app/src/Info.plist``` by replacing `<APP_KEY>`
4
-   with your own Dropbox app key (which can be found in the
5
-   [App Console](https://www.dropbox.com/developers/apps)):
6
-```
7
-<key>CFBundleURLTypes</key>
8
-<array>
9
-  <dict>
10
-    <key>CFBundleURLName</key>
11
-    <string></string>
12
-    <key>CFBundleURLSchemes</key>
13
-    <array>
14
-      <string>db-<APP_KEY></string>
15
-    </array>
16
-  </dict>
17
-</array>
18
-<key>LSApplicationQueriesSchemes</key>
19
-<array>
20
-  <string>dbapi-2</string>
21
-  <string>dbapi-8-emm</string>
22
-</array>
23
-```
24
-
25
-**NOTE:** Both Android and iOS builds of the apps will parse the Dropbox app key
26
-from ```ios/app/src/Info.plist```.
27
-
28
-**NOTE:** See [Dropbox developer guide](https://www.dropbox.com/developers/reference/developer-guide) for more information

+ 0
- 22
doc/mobile-google-auth.md Parādīt failu

@@ -1,22 +0,0 @@
1
-# Setting up Google Authentication
2
-
3
-- Create a Firebase project here: https://firebase.google.com/. You'll need a
4
-signed Android build for that, that can be a debug self-signed build too, just
5
-retrieve the signing hash. The key hash of an already signed ap can be obtained
6
-as follows (on macOS): ```keytool -list -printcert -jarfile the-app.apk```
7
-- Place the generated ```google-services.json``` file in ```android/app```
8
-for Android and the ```GoogleService-Info.plist``` into ```ios/app``` for
9
-iOS (you can stop at that step, no need for the driver and the code changes they
10
-suggest in the wizard).
11
-- You may want to exclude these files in YOUR GIT config (do not exclude them in
12
-the ```.gitignore``` of the application itself!).
13
-- Your web client ID is auto generated during the Firebase project
14
- creation. Find them in the Google Developer console
15
- (https://console.developers.google.com/)
16
-- Make sure your config reflects this ID by setting
17
-```googleApiApplicationClientID``` in config.js.
18
-- Add your iOS client ID (the REVERSED_CLIENT_ID in the plist file) as an
19
-application URL schema into ```ios/app/src/Info.plist```
20
-(replacing placeholder).
21
-- Enable YouTube API access on the developer console (see above) to enable live
22
-streaming.

+ 0
- 107
doc/mobile.md Parādīt failu

@@ -1,107 +0,0 @@
1
-# Jitsi Meet apps for Android and iOS
2
-
3
-Jitsi Meet can be built as a standalone app for Android or iOS. It uses the
4
-[React Native] framework.
5
-
6
-**If you want to rebuild the SDK yourself look in [Android README] or [iOS README].**
7
-
8
-First make sure the [React Native dependencies] are installed.
9
-
10
-**NOTE**: This document assumes the app is being built on a macOS system.
11
-**NOTE**: Node 10.X and npm 6.X are recommended for building.
12
-
13
-
14
-## iOS
15
-
16
-1. Install some extra dependencies
17
-
18
-  - Install ios-deploy globally (in case you want to use the React Native CLI
19
-    to deploy the app to the device)
20
-
21
-    ```bash
22
-    npm install -g ios-deploy
23
-    ```
24
-
25
-  - Install main dependencies:
26
-
27
-    ```bash
28
-    npm install
29
-    ```
30
-
31
-  - Install the required pods (CocoaPods must be installled first, it can
32
-    be done with Homebrew: `brew install cocoapods`)
33
-
34
-    ```bash
35
-    cd ios
36
-    pod install
37
-    cd ..
38
-    ```
39
-
40
-2. Build the app
41
-
42
-    There are 2 ways to build the app: using the CLI or using Xcode.
43
-
44
-    Using the CLI:
45
-
46
-    ```bash
47
-    react-native run-ios --device
48
-    ```
49
-
50
-    When the app is launched from the CLI the output can be checked with the
51
-    following command:
52
-
53
-    ```bash
54
-    react-native log-ios
55
-    ```
56
-
57
-    Using Xcode
58
-
59
-    - Open **ios/jitsi-meet.xcworkspace** in Xcode. Make sure it's the workspace
60
-      file!
61
-
62
-    - Select your device from the top bar and hit the "play" button.
63
-
64
-    When the app is launched from Xcode the Debug console will show the output
65
-    logs the application creates.
66
-
67
-
68
-3. Other remarks
69
-
70
-    It's likely you'll need to change the bundle ID for deploying to a device.
71
-    This can be changed in the "General" tab.  Under "Identity" set
72
-    "Bundle Identifier" to a different value, and adjust the "Team" in the
73
-    "Signing" section to match your own.
74
-
75
-
76
-## Android
77
-
78
-The [React Native dependencies] page has very detailed information on how to
79
-setup [Android Studio] and the required components for getting the necessary
80
-build environment.  Make sure you follow it closely.
81
-
82
-1. Building the app
83
-
84
-    The app can be built using the CLI utility as follows:
85
-
86
-    ```bash
87
-    react-native run-android
88
-    ```
89
-
90
-    It will be launched on the connected Android device.
91
-
92
-## Debugging
93
-
94
-The official documentation on [debugging] is quite extensive and specifies the
95
-preferred method for debugging.
96
-
97
-**NOTE**: When using Chrome Developer Tools for debugging the JavaScript source
98
-code is being interpreted by Chrome's V8 engine, instead of JSCore which React
99
-Native uses. It's important to keep this in mind due to potential differences in
100
-supported JavaScript features.
101
-
102
-[Android README]: https://github.com/jitsi/jitsi-meet/blob/master/android/README.md
103
-[iOS README]: https://github.com/jitsi/jitsi-meet/blob/master/ios/README.md
104
-[Android Studio]: https://developer.android.com/studio/index.html
105
-[debugging]: https://facebook.github.io/react-native/docs/debugging.html
106
-[React Native]: https://facebook.github.io/react-native/
107
-[React Native dependencies]: https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies

+ 1
- 160
doc/quick-install.md Parādīt failu

@@ -1,162 +1,3 @@
1 1
 # Jitsi Meet quick install
2 2
 
3
-This guide helps you  ___host your own Jitsi server___. If you want to have a video conference without setting up any infrastructure, use https://meet.jit.si instead.
4
-
5
-This document describes the required steps for a quick Jitsi Meet installation on a Debian based GNU/Linux system. Debian 9 (Stretch) or later, and Ubuntu 18.04 (Bionic Beaver) or later are supported out-of-the-box.
6
-
7
-On Ubuntu systems, Jitsi requires dependencies from Ubuntu's `universe` package repository.  To ensure this is enabled, run `apt-add-repository universe` at the command-line.
8
-
9
-_Note_: Many of the installation steps require elevated privileges. If you are logged in using a regular user account, you may need to temporarily increase your permissions (for example, by using `sudo` for individual commands).
10
-
11
-## Basic Jitsi Meet install
12
-
13
-### Set up the Fully Qualified Domain Name (FQDN) (optional)
14
-
15
-If the machine used to host the Jitsi Meet instance has a FQDN (for example `meet.example.org`) already set up in DNS, `/etc/hostname` must contain this FQDN; if this is not the case yet, [change the hostname](https://wiki.debian.org/HowTo/ChangeHostname).
16
-
17
-Then add the same FQDN in the `/etc/hosts` file, associating it with the loopback address:
18
-
19
-    127.0.0.1 localhost meet.example.org
20
-
21
-Finally on the same machine test that you can ping the FQDN with: `ping "$(hostname)"`-
22
-
23
-### Add the Jitsi package repository
24
-```sh
25
-echo 'deb https://download.jitsi.org stable/' >> /etc/apt/sources.list.d/jitsi-stable.list
26
-wget -qO -  https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add -
27
-```
28
-### Open ports in your firewall
29
-
30
-Open the following ports in your firewall, to allow traffic to the machine running jitsi:
31
-
32
- - 80 TCP
33
- - 443 TCP
34
- - 10000 UDP
35
-
36
-
37
-### Install Jitsi Meet
38
-
39
-_Note_: The installer will check if [Nginx](https://nginx.org/) or [Apache](https://httpd.apache.org/) is present (in that order) and configure a virtualhost within the web server it finds to serve Jitsi Meet. If none of the above is found it then defaults to Nginx.
40
-If you are already running Nginx on port 443 on the same machine turnserver configuration will be skipped as it will conflict with your current port 443.
41
-
42
-```sh
43
-# Ensure support is available for apt repositories served via HTTPS
44
-apt-get install apt-transport-https
45
-
46
-# Retrieve the latest package versions across all repositories
47
-apt-get update
48
-
49
-# Perform jitsi-meet installation
50
-apt-get -y install jitsi-meet
51
-```
52
-
53
-During the installation, you will be asked to enter the hostname of the Jitsi Meet instance. If you have a [FQDN](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) for the instance already set up in DNS, enter it there. If you don't have a resolvable hostname, you can enter the IP address of the machine (if it is static or doesn't change).
54
-
55
-This hostname (or IP address) will be used for virtualhost configuration inside the Jitsi Meet and also, you and your correspondents will be using it to access the web conferences.
56
-
57
-### Generate a Let's Encrypt certificate (optional, recommended)
58
-
59
-In order to have encrypted communications, you need a [TLS certificate](https://en.wikipedia.org/wiki/Transport_Layer_Security). The easiest way is to use [Let's Encrypt](https://letsencrypt.org/).
60
-
61
-_Note_: Jitsi Meet mobile apps *require* a valid certificate signed by a trusted [Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority) (such as a Let's Encrypt certificate) and will not be able to connect to your server if you choose a self-signed certificate.
62
-
63
-Simply run the following in your shell:
64
-
65
-```sh
66
-/usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
67
-```
68
-
69
-Note that this script uses the [HTTP-01 challenge type](https://letsencrypt.org/docs/challenge-types/) and thus your instance needs to be accessible from the public internet. If you want to use a different challenge type, don't use this script and instead choose ___I want to use my own certificate___ during jitsi-meet installation.
70
-
71
-#### Advanced configuration
72
-If the installation is on a machine [behind NAT](https://github.com/jitsi/jitsi-meet/blob/master/doc/faq.md) jitsi-videobridge should configure itself automatically on boot. If three way call does not work further configuration of jitsi-videobridge is needed in order for it to be accessible from outside.
73
-Provided that all required ports are routed (forwarded) to the machine that it runs on. By default these ports are (TCP/443 or TCP/4443 and UDP/10000).
74
-The following extra lines need to be added to the file `/etc/jitsi/videobridge/sip-communicator.properties`:
75
-```
76
-org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=<Local.IP.Address>
77
-org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=<Public.IP.Address>
78
-```
79
-And comment the existing `org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES`.
80
-See [the documentation of ice4j](https://github.com/jitsi/ice4j/blob/master/doc/configuration.md)
81
-for details.
82
-
83
-Default deployments on systems using systemd will have low default values for maximum processes and open files. If the used bridge will expect higher number of participants the default values need to be adjusted (the default values are good for less than 100 participants).
84
-To update the values edit `/etc/systemd/system.conf` and make sure you have the following values:
85
-```
86
-DefaultLimitNOFILE=65000
87
-DefaultLimitNPROC=65000
88
-DefaultTasksMax=65000
89
-```
90
-To load the values and check them look [here](#systemd-details) for details.
91
-
92
-By default, anyone who has access to your jitsi instance will be able to start a conference: if your server is open to the world, anyone can have a chat with anyone else. If you want to limit the ability to start a conference to registered users, set up a "secure domain". Follow the instructions at https://github.com/jitsi/jicofo#secure-domain.
93
-
94
-### Confirm that your installation is working
95
-
96
-Launch a web browser (Chrome, Chromium or latest Opera) and enter the hostname or IP address from the previous step into the address bar.
97
-
98
-If you used a self-signed certificate (as opposed to using Let's Encrypt), your web browser will ask you to confirm that you trust the certificate.
99
-
100
-You should see a web page prompting you to create a new meeting.  Make sure that you can successfully create a meeting and that other participants are able to join the session.
101
-
102
-If this all worked, then congratulations!  You have an operational Jitsi conference service.
103
-
104
-## Adding sip-gateway to Jitsi Meet
105
-
106
-### Install Jigasi
107
-
108
-Jigasi is a server-side application acting as a gateway to Jitsi Meet conferences. It allows regular [SIP](https://en.wikipedia.org/wiki/Session_Initiation_Protocol) clients to join meetings and provides transcription capabilities.
109
-
110
-```sh
111
-apt-get -y install jigasi
112
-```
113
-or
114
-
115
-```sh
116
-wget https://download.jitsi.org/unstable/jigasi_1.0-107_amd64.deb
117
-dpkg -i jigasi_1.0-107_amd64.deb
118
-```
119
-
120
-During the installation, you will be asked to enter your SIP account and password. This account will be used to invite the other SIP participants.
121
-
122
-### Reload Jitsi Meet
123
-
124
-Launch again a browser with the Jitsi Meet URL and you'll see a telephone icon on the right end of the toolbar. Use it to invite SIP accounts to join the current conference.
125
-
126
-Enjoy!
127
-
128
-## Uninstall
129
-
130
-```sh
131
-apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-turnserver jitsi-meet-web jicofo jitsi-videobridge2
132
-```
133
-
134
-Sometimes the following packages will fail to uninstall properly:
135
-
136
-- jigasi
137
-- jitsi-videobridge
138
-
139
-When this happens, just run the uninstall command a second time and it should be ok.
140
-
141
-The reason for the failure is that sometimes the uninstall script is faster than the process that stops the daemons. The second run of the uninstall command fixes this, as by then the jigasi or jitsi-videobridge daemons are already stopped.
142
-
143
-#### Systemd details
144
-To reload the systemd changes on a running system execute `systemctl daemon-reload` and `service jitsi-videobridge2 restart`.
145
-To check the tasks part execute `service jitsi-videobridge2 status` and you should see `Tasks: XX (limit: 65000)`.
146
-To check the files and process part execute ```cat /proc/`cat /var/run/jitsi-videobridge/jitsi-videobridge.pid`/limits``` and you should see:
147
-```
148
-Max processes             65000                65000                processes
149
-Max open files            65000                65000                files
150
-```
151
-
152
-## Debugging problems
153
-
154
-If you run into problems, one thing to try is using a different web browser. Some versions of some browsers are known to have issues with Jitsi Meet. You can also visit https://test.webrtc.org to test your browser's [WebRTC](https://en.wikipedia.org/wiki/WebRTC) support.
155
-
156
-Another place to look is the various log files:
157
-
158
-```
159
-/var/log/jitsi/jvb.log
160
-/var/log/jitsi/jicofo.log
161
-/var/log/prosody/prosody.log
162
-```
3
+This document has been moved [here](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart).

+ 0
- 166
doc/scalable-installation.md Parādīt failu

@@ -1,166 +0,0 @@
1
-# Scalable Jitsi installation
2
-
3
-A single server Jitsi installation is good for a limited size of concurrent conferences.
4
-The first limiting factor is the videobridge component, that handles the actual video and audio traffic.
5
-It is easy to scale the video bridges horizontally by adding as many as needed.
6
-In a cloud based environment, additionally the bridges can be scaled up or down as needed.
7
-
8
-*NB*: The [Youtube Tutorial on Scaling](https://www.youtube.com/watch?v=LyGV4uW8km8) is outdated and describes an old configuration method.
9
-
10
-*NB*: Building a scalable infrastructure is not a task for beginning Jitsi Administrators.
11
-The instructions assume that you have installed a single node version successfully, and that
12
-you are comfortable installing, configuring and debugging Linux software.
13
-This is not a step-by-step guide, but will show you, which packages to install and which
14
-configurations to change. Use the [manual install](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md) for
15
-details on how to setup Jitsi on a single host.
16
-It is highly recommended to use configuration management tools like Ansible or Puppet to manage the
17
-installation and configuration.
18
-
19
-## Architecture (Single Jitsi-Meet, multiple videobridges)
20
-
21
-A first step is to split the functions of the central jitsi-meet instance (with nginx, prosody and jicofo) and
22
-videobridges.
23
-
24
-A simplified diagram (with open network ports) of an installation with one Jitsi-Meet instance and three
25
-videobridges that are load balanced looks as follows. Each box is a server/VM.
26
-
27
-```
28
-               +                                       +
29
-               |                                       |
30
-               |                                       |
31
-               v                                       v
32
-          80, 443 TCP                          443 TCP, 10000 UDP
33
-       +--------------+                     +---------------------+
34
-       |  nginx       |  5222, 5347 TCP     |                     |
35
-       |  jitsi-meet  |<-------------------+|  jitsi-videobridge  |
36
-       |  prosody     |         |           |                     |
37
-       |  jicofo      |         |           +---------------------+
38
-       +--------------+         |
39
-                                |           +---------------------+
40
-                                |           |                     |
41
-                                +----------+|  jitsi-videobridge  |
42
-                                |           |                     |
43
-                                |           +---------------------+
44
-                                |
45
-                                |           +---------------------+
46
-                                |           |                     |
47
-                                +----------+|  jitsi-videobridge  |
48
-                                            |                     |
49
-                                            +---------------------+
50
-```
51
-
52
-## Machine Sizing
53
-
54
-The Jitsi-Meet server will generally not have that much load (unless you have many) conferences
55
-going at the same time. A 4 CPU, 8 GB machine will probably be fine.
56
-
57
-The videobridges will have more load. 4 or 8 CPU with 8 GB RAM seems to be a good configuration.
58
-
59
-
60
-### Installation of Jitsi-Meet
61
-
62
-Assuming that the installation will run under the following FQDN: `meet.example.com` and you have
63
-SSL cert and key in `/etc/ssl/meet.example.com.{crt,key}`
64
-
65
-Set the following DebConf variables prior to installing the packages.
66
-(We are not installing the `jitsi-meet` package which would handle that for us)
67
-
68
-Install the `debconf-utils` package
69
-
70
-```
71
-$ cat << EOF | sudo debconf-set-selections
72
-jitsi-videobridge	jitsi-videobridge/jvb-hostname	string	meet.example.com
73
-jitsi-meet	jitsi-meet/jvb-serve	boolean	false
74
-jitsi-meet-prosody	jitsi-videobridge/jvb-hostname	string	meet.example.com
75
-jitsi-meet-web-config	jitsi-meet/cert-choice	select	I want to use my own certificate
76
-jitsi-meet-web-config	jitsi-meet/cert-path-crt	string	/etc/ssl/meet.example.com.crt
77
-jitsi-meet-web-config	jitsi-meet/cert-path-key	string	/etc/ssl/meet.example.com.key
78
-EOF
79
-```
80
-
81
-On the jitsi-meet server, install the following packages:
82
-
83
-* `nginx`
84
-* `prosody`
85
-* `jicofo`
86
-* `jitsi-meet-web`
87
-* `jitsi-meet-prosody`
88
-* `jitsi-meet-web-config`
89
-
90
-### Installation of Videobridge(s)
91
-
92
-For simplicities sake, set the same `debconf` variables as above and install
93
-
94
-* `jitsi-videobridge2`
95
-
96
-### Configuration of jitsi-meet
97
-
98
-#### Firewall
99
-
100
-Open the following ports:
101
-
102
-Open to world:
103
-
104
-* 80 TCP
105
-* 443 TCP
106
-
107
-Open to the videobridges only
108
-
109
-* 5222 TCP (for Prosody)
110
-* 5437 TCP (for Jicofo)
111
-
112
-
113
-#### NGINX
114
-
115
-Create the `/etc/nginx/sites-available/meet.example.com.conf` as usual
116
-
117
-#### Prosody
118
-
119
-Follow the steps in the [manual install](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md) for setup tasks
120
-
121
-You will need to adapt the following files (see the files in `example-config-files/scalable`)
122
-
123
-* `/etc/prosody/prosody.cfg.lua`
124
-* `/etc/prosody/conf.avail/meet.example.com.cfg.lua`
125
-
126
-#### Jitsi-Meet
127
-
128
-Adapt `/usr/share/jitsi-meet/config.js` and `/usr/share/jitsi-meet/interface-config.js` to your specific needs
129
-
130
-#### Jicofo
131
-
132
-You will need to adapt the following files (see the files in `example-config-files/scalable`)
133
-
134
-* `/etc/jitsi/jicofo/config` (hostname, jicofo_secret, jicofo_password)
135
-* `/etc/jitsi/jicofo/sip-communicator.properties` (hostname)
136
-
137
-### Configuration of the Videobridge
138
-
139
-#### Firewall
140
-
141
-Open the following ports:
142
-
143
-Open to world:
144
-
145
-* 443 TCP
146
-* 10000 UDP
147
-
148
-#### jitsi-videobridge2
149
-
150
-You will need to adapt the following files (see the files in `example-config-files/scalable`)
151
-
152
-Each videobridge will have to have it's own, unique nickname
153
-
154
-* `/etc/jitsi/videobridge/config` (hostname, password)
155
-* `/etc/jitsi/jicofo/sip-communicator.properties` (hostname of jitsi-meet, nickname of videobridge, vb_password)
156
-
157
-With the latest stable (April 2020) videobridge, it is no longer necessary to set public and private IP
158
-adresses in the `sip-communicator.properties` as the bridge will figure out the correct configuration by itself.
159
-
160
-## Testing
161
-
162
-After restarting all services (`prosody`, `jicofo` and all the `jitsi-videobridge2`) you can see in
163
-`/var/log/prosody/prosody.log` and
164
-`/var/log/jitsi/jicofo.log` that the videobridges connect to Prososy and that Jicofo picks them up.
165
-
166
-When a new conference starts, Jicofo picks a videobridge and schedules the conference on it.

+ 0
- 53
doc/sipgw-config.md Parādīt failu

@@ -1,53 +0,0 @@
1
-# Configuring sipgw jibri with jitsi-meet
2
-
3
-This document describes how you can configure jitsi-meet to use sipgw jibri and enable rooms in 'Add people dialog'
4
-You will need a working deployment of jibri configured to use a regular sip video device, for more info check out the [jibri documentation](https://github.com/jitsi/jibri/blob/master/README.md).
5
-
6
-This feature is available for non-guests of the system, so this relies on setting in config.js ``enableUserRolesBasedOnToken: true`` and providing a jwt token when accessing the conference.
7
-
8
-* Jicofo configuration:
9
-edit /etc/jitsi/jicofo/sip-communicator.properties (or similar), set the appropriate MUC to look for the Jibri Controllers. This should be the same MUC as is referenced in jibri's config.json file. Restart Jicofo after setting this property.
10
-
11
-```
12
-  org.jitsi.jicofo.jibri.SIP_BREWERY=TheSipBrewery@conference.yourdomain.com
13
- ```
14
-
15
-* Jitsi Meet configuration:
16
- - config.js: add 
17
-```
18
-  enableUserRolesBasedOnToken: true,
19
-  peopleSearchQueryTypes: ['conferenceRooms'],
20
-  peopleSearchUrl: 'https://api.yourdomain.com/testpath/searchpeople',
21
-```
22
-
23
-The combination of the above settings and providing a jwt token will enable a button under invite option which will show the dialog 'Add people'.
24
-
25
-## People search service
26
-
27
-When searching in the dialog, a request for results is made to the `peopleSearchUrl` service.
28
-
29
-The request is in the following format:
30
-```
31
-https://api.yourdomain.com/testpath/searchpeople?query=testroomname&queryTypes=[%22conferenceRooms%22]&jwt=somejwt
32
-```
33
-The parameters are:
34
- - query - The text entered by the user.
35
- - queryTypes - What type of results we want people, rooms, conferenceRooms. This is the value from config.js `peopleSearchQueryTypes`
36
- - jwt - The token used by the user to access the conference.
37
-
38
-The response of the service is a json in the following format:
39
-```
40
-[
41
-   {
42
-       "id": "address@sip.domain.com",
43
-       "name": "Some room name",
44
-       "type": "videosipgw"
45
-   },
46
-  {
47
-      "id": "address2@sip.domain.com",
48
-      "name": "Some room name2",
49
-      "type": "videosipgw"
50
-  }
51
-]
52
-```
53
-Type should be `videosipgw`, `name` is the name shown to the user and `id` is the sip address to be called by the sipgw jibri.

+ 0
- 22
doc/speakerstats-prosody.md Parādīt failu

@@ -1,22 +0,0 @@
1
-# Enabling speakerstats prosody module
2
-
3
-To enable the speaker stats we need to enable speakerstats module under the main
4
-virtual host, this is to enable the advertising the speaker stats component, 
5
-which address needs to be specified in `speakerstats_component` option.
6
-
7
-We need to also enable the component with the address specified in `speakerstats_component`.
8
-The component needs also to have the option with the muc component address in
9
-`muc_component` option.
10
-
11
-```lua
12
-VirtualHost "jitsi.example.com"
13
-    speakerstats_component = "speakerstats.jitsi.example.com"
14
-    modules_enabled = {
15
-        "speakerstats";
16
-    }
17
-
18
-Component "speakerstats.jitsi.example.com" "speakerstats_component"
19
-    muc_component = "conference.jitsi.example.com"
20
-
21
-Component "conference.jitsi.example.com" "muc"
22
-```

+ 0
- 15
doc/turn.md Parādīt failu

@@ -1,15 +0,0 @@
1
-One-to-one calls should avoid going throught the JVB for optimal performance and for optimal resource usage. This is why we've added the peer-to-peer mode where the two participants connect directly to each other. Unfortunately, a direct connection is not always possible between the participants. In those cases you can use a TURN server to relay the traffic (n.b. the JVB does much more than just relay the traffic, so this is not the same as using the JVB to "relay" the traffic).
2
-
3
-This document describes how to enable TURN server support in one-to-one calls in Jitsi Meet, even though it gives some hints how to configure [prosody](prosody.im) and [coTURN](https://github.com/coturn/coturn), it assumes a properly configured TURN server and a proprely configured XMPP server.
4
-
5
-One way to configure TURN support in meet with a static configuration. You can simply fill out the `p2p.stunServers` option with appropriate values, e.g.:
6
-
7
-    [
8
-        { urls: 'turn:turn.example.com1', credential: 'user', password: 'pass' },
9
-    ]
10
-
11
-This technique doesn't require any special configuration on the XMPP server, but it exposes the credentials to your TURN server and other people can use your bandwidth freely, so while it's simple to implement, it's not recommended.
12
-
13
-This [draft](https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00) escribes a proposed standard REST API for obtaining access to TURN services via ephemeral (i.e. time-limited) credentials. These credentials are vended by a web service over HTTP, and then supplied to and checked by a TURN server using the standard TURN protocol. The usage of ephemeral credentials ensures that access to the TURN server can be controlled even if the credentials can be discovered by the user.
14
-
15
-Jitsi Meet can fetch the TURN credentials from the XMPP server via [XEP-0215](https://xmpp.org/extensions/xep-0215.html). You can enable this functionality by setting `p2p.useStunTurn: true` in config.js. By properly configuring a common shared secret on your TURN server and your XMPP server, the XMPP server can deliver appropriate credentials and TURN urls to Jitsi Meet. coTURN natively supports shared secret authentication (--use-auth-secret-) and in prosody, you can use the [mod_turncredentials](https://modules.prosody.im/mod_turncredentials.html) module.

+ 21
- 4
interface_config.js Parādīt failu

@@ -48,11 +48,11 @@ var interfaceConfig = {
48 48
      */
49 49
     TOOLBAR_BUTTONS: [
50 50
         'microphone', 'camera', 'closedcaptions', 'desktop', 'fullscreen',
51
-        'fodeviceselection', 'hangup', 'profile', 'info', 'chat', 'recording',
51
+        'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
52 52
         'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
53 53
         'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
54 54
         'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone',
55
-        'e2ee'
55
+        'e2ee', 'security'
56 56
     ],
57 57
 
58 58
     SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ],
@@ -176,7 +176,7 @@ var interfaceConfig = {
176 176
     // has a suboptimal experience. Browsers which are not listed as optimal or
177 177
     // unsupported are considered suboptimal. Valid values are:
178 178
     // chrome, chromium, edge, electron, firefox, nwjs, opera, safari
179
-    OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron' ],
179
+    OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron', 'safari' ],
180 180
 
181 181
     // Browsers, in addition to those which do not fully support WebRTC, that
182 182
     // are not supported and should show the unsupported browser page.
@@ -212,7 +212,7 @@ var interfaceConfig = {
212 212
     /**
213 213
      * When enabled, the kick participant button will not be presented for users without a JWT
214 214
      */
215
-    // HIDE_KICK_BUTTON_FOR_GUESTS: false
215
+    // HIDE_KICK_BUTTON_FOR_GUESTS: false,
216 216
 
217 217
     /**
218 218
      * How many columns the tile view can expand to. The respected range is
@@ -230,6 +230,17 @@ var interfaceConfig = {
230 230
      */
231 231
     // MOBILE_DOWNLOAD_LINK_IOS: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905',
232 232
 
233
+    /**
234
+     * Specify Firebase dynamic link properties for the mobile apps.
235
+     */
236
+    // MOBILE_DYNAMIC_LINK: {
237
+    //    APN: 'org.jitsi.meet',
238
+    //    APP_CODE: 'w2atb',
239
+    //    CUSTOM_DOMAIN: undefined,
240
+    //    IBI: 'com.atlassian.JitsiMeet.ios',
241
+    //    ISI: '1165103905'
242
+    // },
243
+
233 244
     /**
234 245
      * Specify mobile app scheme for opening the app from the mobile browser.
235 246
      */
@@ -253,6 +264,12 @@ var interfaceConfig = {
253 264
      MOBILE_DYNAMIC_LINK
254 265
      PHONE_NUMBER_REGEX
255 266
     */
267
+
268
+    // Allow all above example options to include a trailing comma and
269
+    // prevent fear when commenting out the last value.
270
+    makeJsonParserHappy: 'even if last key had a trailing comma'
271
+
272
+    // no configuration value should follow this line.
256 273
 };
257 274
 
258 275
 /* eslint-enable no-unused-vars, no-var, max-len */

+ 1
- 0
ios/Podfile Parādīt failu

@@ -66,6 +66,7 @@ target 'JitsiMeet' do
66 66
   pod 'RNSound', :path => '../node_modules/react-native-sound'
67 67
   pod 'RNSVG', :path => '../node_modules/react-native-svg'
68 68
   pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
69
+  pod 'RNDefaultPreference', :path => '../node_modules/react-native-default-preference'
69 70
 
70 71
   # Native pod dependencies
71 72
   #

+ 11
- 6
ios/Podfile.lock Parādīt failu

@@ -353,6 +353,8 @@ PODS:
353 353
     - ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
354 354
   - RNCAsyncStorage (1.3.4):
355 355
     - React
356
+  - RNDefaultPreference (1.4.2):
357
+    - React
356 358
   - RNGoogleSignin (3.0.1):
357 359
     - GoogleSignIn (~> 5.0.0)
358 360
     - React
@@ -409,6 +411,7 @@ DEPENDENCIES:
409 411
   - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
410 412
   - ReactCommon/turbomodule (from `../node_modules/react-native/ReactCommon`)
411 413
   - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
414
+  - RNDefaultPreference (from `../node_modules/react-native-default-preference`)
412 415
   - "RNGoogleSignin (from `../node_modules/@react-native-community/google-signin`)"
413 416
   - RNSound (from `../node_modules/react-native-sound`)
414 417
   - RNSVG (from `../node_modules/react-native-svg`)
@@ -416,13 +419,11 @@ DEPENDENCIES:
416 419
   - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
417 420
 
418 421
 SPEC REPOS:
419
-  https://github.com/CocoaPods/Specs.git:
422
+  trunk:
420 423
     - Amplitude-iOS
424
+    - AppAuth
421 425
     - boost-for-react-native
422 426
     - CocoaLumberjack
423
-    - ObjectiveDropboxOfficial
424
-  trunk:
425
-    - AppAuth
426 427
     - Crashlytics
427 428
     - Fabric
428 429
     - Firebase
@@ -442,6 +443,7 @@ SPEC REPOS:
442 443
     - GTMAppAuth
443 444
     - GTMSessionFetcher
444 445
     - nanopb
446
+    - ObjectiveDropboxOfficial
445 447
     - PromisesObjC
446 448
 
447 449
 EXTERNAL SOURCES:
@@ -509,6 +511,8 @@ EXTERNAL SOURCES:
509 511
     :path: "../node_modules/react-native/ReactCommon"
510 512
   RNCAsyncStorage:
511 513
     :path: "../node_modules/@react-native-community/async-storage"
514
+  RNDefaultPreference:
515
+    :path: "../node_modules/react-native-default-preference"
512 516
   RNGoogleSignin:
513 517
     :path: "../node_modules/@react-native-community/google-signin"
514 518
   RNSound:
@@ -578,12 +582,13 @@ SPEC CHECKSUMS:
578 582
   React-RCTVibration: a1bcfcdc0b5a73a1b0829a34cee22bd0e95bacba
579 583
   ReactCommon: 675681aba4fecff5acbc0e440530cc422103c610
580 584
   RNCAsyncStorage: 8e31405a9f12fbf42c2bb330e4560bfd79c18323
585
+  RNDefaultPreference: 56a405ce61033ac77b95004dccd7ac54c2eb50d1
581 586
   RNGoogleSignin: 39336070b35fc4cea6a98cf111e00480317be0ae
582 587
   RNSound: c980916b596cc15c8dcd2f6ecd3b13c4881dbe20
583 588
   RNSVG: aac12785382e8fd4f28d072fe640612e34914631
584 589
   RNWatch: 09738b339eceb66e4d80a2371633ca5fb380fa42
585 590
   Yoga: 7b4209fda2441f99d54dd6cf4c82b094409bb68f
586 591
 
587
-PODFILE CHECKSUM: f615794fb9184757b00cd16e534824ba6ee2fc98
592
+PODFILE CHECKSUM: 082858daebbe170e7a490de433e7f2a99e0c3701
588 593
 
589
-COCOAPODS: 1.8.4
594
+COCOAPODS: 1.9.1

+ 1
- 204
ios/README.md Parādīt failu

@@ -1,206 +1,3 @@
1 1
 # Jitsi Meet SDK for iOS
2 2
 
3
-The Jitsi Meet iOS SDK provides the same user experience as the Jitsi Meet app,
4
-in a customizable way which you can embed in your apps.
5
-
6
-## Sample applications using the SDK
7
-
8
-If you want to see how easy integrating the Jitsi Meet SDK into a native application is, take a look at the
9
-[sample applications repository](https://github.com/jitsi/jitsi-meet-sdk-samples).
10
-
11
-## Usage
12
-
13
-There are 2 ways to integrate the SDK into your project:
14
-
15
-- Using CocoaPods
16
-- Building it yourself
17
-
18
-### Using CocoaPods
19
-
20
-Follow the instructions [here](https://github.com/jitsi/jitsi-meet-ios-sdk-releases/blob/master/README.md).
21
-
22
-### Building it yourself
23
-
24
-1. Install all required [dependencies](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile.md).
25
-
26
-2. `xcodebuild -workspace ios/jitsi-meet.xcworkspace -scheme JitsiMeet -destination='generic/platform=iOS' -configuration Release archive`
27
-
28
-After successfully building Jitsi Meet SDK for iOS, copy
29
-`ios/sdk/JitsiMeet.framework` (if the path points to a symbolic link, follow the
30
-symbolic link) and
31
-`node_modules/react-native-webrtc/ios/WebRTC.framework` into your project.
32
-
33
-## API
34
-
35
-JitsiMeet is an iOS framework which embodies the whole Jitsi Meet experience and
36
-makes it reusable by third-party apps.
37
-
38
-To get started:
39
-
40
-1. Add a `JitsiMeetView` to your app using a Storyboard or Interface Builder,
41
-   for example.
42
-
43
-2. Then, once the view has loaded, set the delegate in your controller and load
44
-   the desired URL:
45
-
46
-```objc
47
-- (void)viewDidLoad {
48
-  [super viewDidLoad];
49
-
50
-  JitsiMeetView *jitsiMeetView = (JitsiMeetView *) self.view;
51
-  jitsiMeetView.delegate = self;
52
-
53
-  JitsiMeetConferenceOptions *options = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
54
-      builder.serverURL = [NSURL URLWithString:@"https://meet.jit.si"];
55
-      builder.room = @"test123";
56
-      builder.audioOnly = YES;
57
-  }];
58
-
59
-  [jitsiMeetView join:options];
60
-}
61
-```
62
-
63
-### JitsiMeetView class
64
-
65
-The `JitsiMeetView` class is the entry point to the SDK. It a subclass of
66
-`UIView` which renders a full conference in the designated area.
67
-
68
-#### delegate
69
-
70
-Property to get/set the `JitsiMeetViewDelegate` on `JitsiMeetView`.
71
-
72
-#### join:JitsiMeetConferenceOptions
73
-
74
-Joins the conference specified by the given options.
75
-
76
-```objc
77
-  JitsiMeetConferenceOptions *options = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
78
-      builder.serverURL = [NSURL URLWithString:@"https://meet.jit.si"];
79
-      builder.room = @"test123";
80
-      builder.audioOnly = NO;
81
-      builder.audioMuted = NO;
82
-      builder.videoMuted = NO;
83
-      builder.welcomePageEnabled = NO;
84
-  }];
85
-
86
-  [jitsiMeetView join:options];
87
-```
88
-
89
-#### leave
90
-
91
-Leaves the currently active conference.
92
-
93
-#### Universal / deep linking
94
-
95
-In order to support Universal / deep linking, `JitsiMeet` offers 2 class
96
-methods that you app's delegate should call in order for the app to follow those
97
-links.
98
-
99
-If these functions return NO it means the URL wasn't handled by the SDK. This
100
-is useful when the host application uses other SDKs which also use linking.
101
-
102
-```objc
103
--  (BOOL)application:(UIApplication *)application
104
-continueUserActivity:(NSUserActivity *)userActivity
105
-  restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler
106
-{
107
-  return [[JitsiMeet sharedInstance] application:application
108
-               continueUserActivity:userActivity
109
-                 restorationHandler:restorationHandler];
110
-}
111
-```
112
-
113
-And also one of the following:
114
-
115
-```objc
116
-// See https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc
117
-- (BOOL)application:(UIApplication *)app
118
-            openURL:(NSURL *)url
119
-            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
120
-  return [[JitsiMeet sharedInstance] application:app
121
-                            openURL:url
122
-                            options: options];
123
-}
124
-```
125
-
126
-### JitsiMeetViewDelegate
127
-
128
-This delegate is optional, and can be set on the `JitsiMeetView` instance using
129
-the `delegate` property.
130
-
131
-It provides information about the conference state: was it joined, left, did it
132
-fail?
133
-
134
-All methods in this delegate are optional.
135
-
136
-#### conferenceJoined
137
-
138
-Called when a conference was joined.
139
-
140
-The `data` dictionary contains a "url" key with the conference URL.
141
-
142
-#### conferenceTerminated
143
-
144
-Called when a conference was terminated either by user choice or due to a
145
-failure.
146
-
147
-The `data` dictionary contains an "error" key with the error and a "url" key
148
-with the conference URL. If the conference finished gracefully no `error`
149
-key will be present.
150
-
151
-#### conferenceWillJoin
152
-
153
-Called before a conference is joined.
154
-
155
-The `data` dictionary contains a "url" key with the conference URL.
156
-
157
-#### enterPictureInPicture
158
-
159
-Called when entering Picture-in-Picture is requested by the user. The app should
160
-now activate its Picture-in-Picture implementation (and resize the associated
161
-`JitsiMeetView`. The latter will automatically detect its new size and adjust
162
-its user interface to a variant appropriate for the small size ordinarily
163
-associated with Picture-in-Picture.)
164
-
165
-The `data` dictionary is empty.
166
-
167
-### Picture-in-Picture
168
-
169
-`JitsiMeetView` will automatically adjust its UI when presented in a
170
-Picture-in-Picture style scenario, in a rectangle too small to accommodate its
171
-"full" UI.
172
-
173
-Jitsi Meet SDK does not currently implement native Picture-in-Picture on iOS. If
174
-desired, apps need to implement non-native Picture-in-Picture themselves and
175
-resize `JitsiMeetView`.
176
-
177
-If `delegate` implements `enterPictureInPicture:`, the in-call toolbar will
178
-render a button to afford the user to request entering Picture-in-Picture.
179
-
180
-## Dropbox integration
181
-
182
-To setup the Dropbox integration, follow these steps:
183
-
184
-1. Add the following to the app's Info.plist and change `<APP_KEY>` to your
185
-Dropbox app key:
186
-```
187
-<key>CFBundleURLTypes</key>
188
-<array>
189
-  <dict>
190
-    <key>CFBundleURLName</key>
191
-    <string></string>
192
-    <key>CFBundleURLSchemes</key>
193
-    <array>
194
-      <string>db-<APP_KEY></string>
195
-    </array>
196
-  </dict>
197
-</array>
198
-<key>LSApplicationQueriesSchemes</key>
199
-<array>
200
-  <string>dbapi-2</string>
201
-  <string>dbapi-8-emm</string>
202
-</array>
203
-```
204
-
205
-2. Make sure your app calls the Jitsi Meet SDK universal / deep linking delegate
206
-   methods.
3
+This document has been moved to [The Handbook](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-ios-sdk).

+ 15
- 9
ios/app/src/AppDelegate.m Parādīt failu

@@ -18,25 +18,17 @@
18 18
 #import "AppDelegate.h"
19 19
 #import "FIRUtilities.h"
20 20
 #import "Types.h"
21
+#import "ViewController.h"
21 22
 
22 23
 @import Crashlytics;
23 24
 @import Fabric;
24 25
 @import Firebase;
25 26
 @import JitsiMeet;
26 27
 
27
-
28 28
 @implementation AppDelegate
29 29
 
30 30
 -             (BOOL)application:(UIApplication *)application
31 31
   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
32
-
33
-    // Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
34
-    if ([FIRUtilities appContainsRealServiceInfoPlist]) {
35
-        NSLog(@"Enablign Crashlytics and Firebase");
36
-        [FIRApp configure];
37
-        [Fabric with:@[[Crashlytics class]]];
38
-    }
39
-
40 32
     JitsiMeet *jitsiMeet = [JitsiMeet sharedInstance];
41 33
 
42 34
     jitsiMeet.conferenceActivityType = JitsiMeetConferenceActivityType;
@@ -54,11 +46,25 @@
54 46
 #endif
55 47
     }];
56 48
 
49
+    // Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
50
+    if ([FIRUtilities appContainsRealServiceInfoPlist] && ![jitsiMeet isCrashReportingDisabled]) {
51
+        NSLog(@"Enabling Crashlytics and Firebase");
52
+        [FIRApp configure];
53
+        [Fabric with:@[[Crashlytics class]]];
54
+    }
55
+
57 56
     [jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
58 57
 
59 58
     return YES;
60 59
 }
61 60
 
61
+- (void) applicationWillTerminate:(UIApplication *)application {
62
+    NSLog(@"Application will terminate!");
63
+    // Try to leave the current meeting graceefully.
64
+    ViewController *rootController = (ViewController *)self.window.rootViewController;
65
+    [rootController terminate];
66
+}
67
+
62 68
 #pragma mark Linking delegate methods
63 69
 
64 70
 -    (BOOL)application:(UIApplication *)application

+ 2
- 33
ios/app/src/FIRUtilities.m Parādīt failu

@@ -16,12 +16,7 @@
16 16
 
17 17
 #import "FIRUtilities.h"
18 18
 
19
-// Plist file name.
20
-NSString *const kGoogleServiceInfoFileName = @"GoogleService-Info";
21
-// Plist file type.
22
-NSString *const kGoogleServiceInfoFileType = @"plist";
23
-NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID";
24
-
19
+@import JitsiMeet;
25 20
 
26 21
 @implementation FIRUtilities
27 22
 
@@ -30,37 +25,11 @@ NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID";
30 25
   static dispatch_once_t onceToken;
31 26
   dispatch_once(&onceToken, ^{
32 27
     NSBundle *bundle = [NSBundle mainBundle];
33
-    containsRealServiceInfoPlist = [self containsRealServiceInfoPlistInBundle:bundle];
28
+    containsRealServiceInfoPlist = [InfoPlistUtil containsRealServiceInfoPlistInBundle:bundle];
34 29
   });
35 30
   return containsRealServiceInfoPlist;
36 31
 }
37 32
 
38
-+ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle {
39
-  NSString *bundlePath = bundle.bundlePath;
40
-  if (!bundlePath.length) {
41
-    return NO;
42
-  }
43
-
44
-  NSString *plistFilePath = [bundle pathForResource:kGoogleServiceInfoFileName
45
-                                             ofType:kGoogleServiceInfoFileType];
46
-  if (!plistFilePath.length) {
47
-    return NO;
48
-  }
49
-
50
-  NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistFilePath];
51
-  if (!plist) {
52
-    return NO;
53
-  }
54
-
55
-  // Perform a very naive validation by checking to see if the plist has the dummy google app id
56
-  NSString *googleAppID = plist[kGoogleAppIDPlistKey];
57
-  if (!googleAppID.length) {
58
-    return NO;
59
-  }
60
-
61
-  return YES;
62
-}
63
-
64 33
 + (NSURL *)extractURL: (FIRDynamicLink*)dynamicLink {
65 34
   NSURL *url = nil;
66 35
   if (dynamicLink != nil) {

+ 1
- 1
ios/app/src/Info.plist Parādīt failu

@@ -17,7 +17,7 @@
17 17
 	<key>CFBundlePackageType</key>
18 18
 	<string>APPL</string>
19 19
 	<key>CFBundleShortVersionString</key>
20
-	<string>20.2.0</string>
20
+	<string>20.3.0</string>
21 21
 	<key>CFBundleSignature</key>
22 22
 	<string>????</string>
23 23
 	<key>CFBundleURLTypes</key>

+ 2
- 0
ios/app/src/ViewController.h Parādīt failu

@@ -20,4 +20,6 @@
20 20
 
21 21
 @interface ViewController : UIViewController<JitsiMeetViewDelegate>
22 22
 
23
+- (void)terminate;
24
+
23 25
 @end

+ 7
- 0
ios/app/src/ViewController.m Parādīt failu

@@ -102,4 +102,11 @@
102 102
 }
103 103
 #endif
104 104
 
105
+#pragma mark - Helpers
106
+
107
+- (void)terminate {
108
+    JitsiMeetView *view = (JitsiMeetView *) self.view;
109
+    [view leave];
110
+}
111
+
105 112
 @end

+ 1
- 1
ios/app/watchos/app/Info.plist Parādīt failu

@@ -17,7 +17,7 @@
17 17
 	<key>CFBundlePackageType</key>
18 18
 	<string>APPL</string>
19 19
 	<key>CFBundleShortVersionString</key>
20
-	<string>20.2.0</string>
20
+	<string>20.3.0</string>
21 21
 	<key>CFBundleVersion</key>
22 22
 	<string>1</string>
23 23
 	<key>UISupportedInterfaceOrientations</key>

+ 1
- 1
ios/app/watchos/extension/Info.plist Parādīt failu

@@ -17,7 +17,7 @@
17 17
 	<key>CFBundlePackageType</key>
18 18
 	<string>XPC!</string>
19 19
 	<key>CFBundleShortVersionString</key>
20
-	<string>20.2.0</string>
20
+	<string>20.3.0</string>
21 21
 	<key>CFBundleVersion</key>
22 22
 	<string>1</string>
23 23
 	<key>CLKComplicationPrincipalClass</key>

+ 3
- 0
ios/fastlane/Fastfile Parādīt failu

@@ -66,6 +66,9 @@ platform :ios do
66 66
       beta_app_feedback_email: ENV["JITSI_REVIEW_EMAIL"],
67 67
       beta_app_review_info: {
68 68
         contact_email: ENV["JITSI_REVIEW_EMAIL"],
69
+        contact_first_name: ENV["JITSI_REVIEW_NAME"],
70
+        contact_last_name: ENV["JITSI_REVIEW_SURNAME"],
71
+        contact_phone: ENV["JITSI_REVIEW_PHONE"],
69 72
         demo_account_name: ENV["JITSI_DEMO_ACCOUNT"],
70 73
         demo_account_password: ENV["JITSI_DEMO_PASSWORD"],
71 74
       },

+ 8
- 0
ios/sdk/sdk.xcodeproj/project.pbxproj Parādīt failu

@@ -42,6 +42,8 @@
42 42
 		C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69EFA0B209A0F660027712B /* JMCallKitListener.swift */; };
43 43
 		C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425E204EF76800E062DD /* DragGestureController.swift */; };
44 44
 		C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */; };
45
+		C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
46
+		C8AFD2802462C613000293D2 /* InfoPlistUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */; };
45 47
 		DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
46 48
 		DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AAC92317FFCD00290BEC /* LogUtils.h */; };
47 49
 		DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */; };
@@ -105,6 +107,8 @@
105 107
 		C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
106 108
 		C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
107 109
 		C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
110
+		C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
111
+		C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
108 112
 		DE438CD82350934700DD541D /* JavaScriptSandbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JavaScriptSandbox.m; sourceTree = "<group>"; };
109 113
 		DE65AAC92317FFCD00290BEC /* LogUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogUtils.h; sourceTree = "<group>"; };
110 114
 		DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetBaseLogHandler+Private.h"; sourceTree = "<group>"; };
@@ -223,6 +227,8 @@
223 227
 				DEFE535521FB2E8300011A3A /* ReactUtils.m */,
224 228
 				0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */,
225 229
 				0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */,
230
+				C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */,
231
+				C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */,
226 232
 			);
227 233
 			path = src;
228 234
 			sourceTree = "<group>";
@@ -303,6 +309,7 @@
303 309
 				DE81A2D42316AC4D00AE1940 /* JitsiMeetLogger.h in Headers */,
304 310
 				DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */,
305 311
 				DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */,
312
+				C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */,
306 313
 			);
307 314
 			runOnlyForDeploymentPostprocessing = 0;
308 315
 		};
@@ -482,6 +489,7 @@
482 489
 				0B93EF7F1EC9DDCD0030D24D /* RCTBridgeWrapper.m in Sources */,
483 490
 				0BA13D311EE83FF8007BEF7F /* ExternalAPI.m in Sources */,
484 491
 				0BCA49601EC4B6C600B793EE /* POSIX.m in Sources */,
492
+				C8AFD2802462C613000293D2 /* InfoPlistUtil.m in Sources */,
485 493
 				C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */,
486 494
 				DEFC743F21B178FA00E4DD96 /* LocaleDetector.m in Sources */,
487 495
 				0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,

+ 6
- 2
ios/sdk/src/AppInfo.m Parādīt failu

@@ -19,6 +19,8 @@
19 19
 #import <React/RCTBridgeModule.h>
20 20
 #import <React/RCTLog.h>
21 21
 
22
+#import "InfoPlistUtil.h"
23
+
22 24
 @interface AppInfo : NSObject<RCTBridgeModule>
23 25
 @end
24 26
 
@@ -67,13 +69,15 @@ RCT_EXPORT_MODULE();
67 69
         buildNumber = @"";
68 70
     }
69 71
 
72
+    BOOL isGoogleServiceEnabled = [InfoPlistUtil containsRealServiceInfoPlistInBundle:[NSBundle mainBundle]];
73
+    
70 74
     return @{
71 75
         @"calendarEnabled": [NSNumber numberWithBool:calendarEnabled],
72 76
         @"buildNumber": buildNumber,
73 77
         @"name": name,
74 78
         @"sdkBundlePath": sdkBundlePath,
75
-        @"version": version
79
+        @"version": version,
80
+        @"GOOGLE_SERVICES_ENABLED": [NSNumber numberWithBool:isGoogleServiceEnabled]
76 81
     };
77 82
 };
78
-
79 83
 @end

+ 1
- 1
ios/sdk/src/Info.plist Parādīt failu

@@ -15,7 +15,7 @@
15 15
 	<key>CFBundlePackageType</key>
16 16
 	<string>FMWK</string>
17 17
 	<key>CFBundleShortVersionString</key>
18
-	<string>2.8.0</string>
18
+	<string>2.8.1</string>
19 19
 	<key>CFBundleVersion</key>
20 20
 	<string>$(CURRENT_PROJECT_VERSION)</string>
21 21
 	<key>NSPrincipalClass</key>

+ 23
- 0
ios/sdk/src/InfoPlistUtil.h Parādīt failu

@@ -0,0 +1,23 @@
1
+/*
2
+* Copyright @ 2019-present 8x8, Inc.
3
+*
4
+* Licensed under the Apache License, Version 2.0 (the "License");
5
+* you may not use this file except in compliance with the License.
6
+* You may obtain a copy of the License at
7
+*
8
+*     http://www.apache.org/licenses/LICENSE-2.0
9
+*
10
+* Unless required by applicable law or agreed to in writing, software
11
+* distributed under the License is distributed on an "AS IS" BASIS,
12
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+* See the License for the specific language governing permissions and
14
+* limitations under the License.
15
+*/
16
+
17
+#import <Foundation/Foundation.h>
18
+
19
+@interface InfoPlistUtil : NSObject
20
+
21
++ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle;
22
+
23
+@end

+ 52
- 0
ios/sdk/src/InfoPlistUtil.m Parādīt failu

@@ -0,0 +1,52 @@
1
+/*
2
+* Copyright @ 2019-present 8x8, Inc.
3
+*
4
+* Licensed under the Apache License, Version 2.0 (the "License");
5
+* you may not use this file except in compliance with the License.
6
+* You may obtain a copy of the License at
7
+*
8
+*     http://www.apache.org/licenses/LICENSE-2.0
9
+*
10
+* Unless required by applicable law or agreed to in writing, software
11
+* distributed under the License is distributed on an "AS IS" BASIS,
12
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+* See the License for the specific language governing permissions and
14
+* limitations under the License.
15
+*/
16
+
17
+#import "InfoPlistUtil.h"
18
+
19
+// Plist file name.
20
+NSString *const kGoogleServiceInfoFileName = @"GoogleService-Info";
21
+// Plist file type.
22
+NSString *const kGoogleServiceInfoFileType = @"plist";
23
+NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID";
24
+
25
+@implementation InfoPlistUtil
26
+
27
++ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle {
28
+  NSString *bundlePath = bundle.bundlePath;
29
+  if (!bundlePath.length) {
30
+    return NO;
31
+  }
32
+
33
+  NSString *plistFilePath = [bundle pathForResource:kGoogleServiceInfoFileName
34
+                                             ofType:kGoogleServiceInfoFileType];
35
+  if (!plistFilePath.length) {
36
+    return NO;
37
+  }
38
+
39
+  NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistFilePath];
40
+  if (!plist) {
41
+    return NO;
42
+  }
43
+
44
+  // Perform a very naive validation by checking to see if the plist has the dummy google app id
45
+  NSString *googleAppID = plist[kGoogleAppIDPlistKey];
46
+  if (!googleAppID.length) {
47
+    return NO;
48
+  }
49
+
50
+  return YES;
51
+}
52
+@end

+ 3
- 0
ios/sdk/src/JitsiMeet.h Parādīt failu

@@ -20,6 +20,7 @@
20 20
 #import <JitsiMeet/JitsiMeetConferenceOptions.h>
21 21
 #import <JitsiMeet/JitsiMeetLogger.h>
22 22
 #import <JitsiMeet/JitsiMeetBaseLogHandler.h>
23
+#import <JitsiMeet/InfoPlistUtil.h>
23 24
 
24 25
 
25 26
 @interface JitsiMeet : NSObject
@@ -64,4 +65,6 @@
64 65
 
65 66
 - (JitsiMeetConferenceOptions *_Nonnull)getInitialConferenceOptions;
66 67
 
68
+- (BOOL)isCrashReportingDisabled;
69
+
67 70
 @end

+ 6
- 1
ios/sdk/src/JitsiMeet.m Parādīt failu

@@ -107,7 +107,7 @@
107 107
     JitsiMeetConferenceOptions *conferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
108 108
         builder.room = [url absoluteString];
109 109
     }];
110
-    
110
+
111 111
     return [JitsiMeetView setPropsInViews:[conferenceOptions asProps]];
112 112
 }
113 113
 
@@ -132,6 +132,11 @@
132 132
     return nil;
133 133
 }
134 134
 
135
+- (BOOL)isCrashReportingDisabled {
136
+    NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"jitsi-default-preferences"];
137
+    return [userDefaults stringForKey:@"isCrashReportingDisabled"];
138
+}
139
+
135 140
 - (JitsiMeetConferenceOptions *)optionsFromUserActivity:(NSUserActivity *)userActivity {
136 141
     NSString *activityType = userActivity.activityType;
137 142
 

+ 5
- 15
ios/sdk/src/picture-in-picture/PiPViewCoordinator.swift Parādīt failu

@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright @ 2017-present Atlassian Pty Ltd
2
+ * Copyright @ 2017-present 8x8, Inc.
3 3
  *
4 4
  * Licensed under the Apache License, Version 2.0 (the "License");
5 5
  * you may not use this file except in compliance with the License.
@@ -46,18 +46,9 @@ public class PiPViewCoordinator {
46 46
     
47 47
     public var initialPositionInSuperview = Position.lowerRightCorner
48 48
     
49
-    /// The size ratio of the view when in PiP mode
50
-    public var pipSizeRatio: CGFloat = {
51
-        let deviceIdiom = UIScreen.main.traitCollection.userInterfaceIdiom
52
-        switch deviceIdiom {
53
-        case .pad:
54
-            return 0.25
55
-        case .phone:
56
-            return 0.33
57
-        default:
58
-            return 0.25
59
-        }
60
-    }()
49
+    // Unused. Remove on the next major release.
50
+    @available(*, deprecated, message: "The PiP window size is now fixed to 150px.")
51
+    public var c: CGFloat = 0.0
61 52
     
62 53
     public weak var delegate: PiPViewCoordinatorDelegate?
63 54
 
@@ -212,8 +203,7 @@ public class PiPViewCoordinator {
212 203
 
213 204
         // resize to suggested ratio and position to the bottom right
214 205
         let adjustedBounds = bounds.inset(by: dragBoundInsets)
215
-        let size = CGSize(width: bounds.size.width * pipSizeRatio,
216
-                          height: bounds.size.height * pipSizeRatio)
206
+        let size = CGSize(width: 150, height: 150)
217 207
         let origin = initialPositionFor(pipSize: size, bounds: adjustedBounds)
218 208
         return CGRect(x: origin.x, y: origin.y, width: size.width, height: size.height)
219 209
     }

+ 40
- 32
lang/languages-ar.json Parādīt failu

@@ -1,34 +1,42 @@
1 1
 {
2
-    "en": "",
3
-    "af": "",
4
-    "bg": "",
5
-    "ca": "",
6
-    "cs": "",
7
-    "da": "",
8
-    "de": "",
9
-    "el": "",
10
-    "enGB": "",
11
-    "eo": "",
12
-    "es": "",
13
-    "esUS": "",
14
-    "et": "",
15
-    "fi": "",
16
-    "fr": "",
17
-    "frCA": "",
18
-    "hr": "",
19
-    "hu": "",
20
-    "hy": "",
21
-    "it": "",
22
-    "ja": "",
23
-    "ko": "",
24
-    "nl": "",
25
-    "oc": "",
26
-    "pl": "",
27
-    "ptBR": "",
28
-    "ru": "",
29
-    "sv": "",
30
-    "tr": "",
31
-    "vi": "",
32
-    "zhCN": "",
33
-    "zhTW": ""
2
+    "en": "الإنجليزية",
3
+    "af": "الأفريكانية",
4
+    "bg": "البلغارية",
5
+    "ca": "الكاتالانية",
6
+    "cs": "التشيكية",
7
+    "da": "الدنماركية",
8
+    "de": "الألمانية",
9
+    "el": "اليونانية",
10
+    "enGB": "الإنجليزية (المملكة المتحدة)",
11
+    "eo": "الإسبرانتو",
12
+    "es": "الإسبانية",
13
+    "esUS": "الإسبانية (أمريكا اللاتينية)",
14
+    "et": "الإستونية",
15
+    "fi": "الفنلندية",
16
+    "fr": "الفرنسية",
17
+    "frCA": "الفرنسية (الكندية)",
18
+    "hr": "الكرواتية",
19
+    "hu": "الهنغارية",
20
+    "hy": "الأرمنية",
21
+    "it": "الإيطالية",
22
+    "ja": "اليابانية",
23
+    "ko": "الكورية",
24
+    "nl": "الهولندية",
25
+    "oc": "القسطانية",
26
+    "pl": "البولندية",
27
+    "ptBR": "البرتغالية (البرازيل)",
28
+    "ru": "الروسية",
29
+    "sv": "السويدية",
30
+    "tr": "التركية",
31
+    "vi": "الفيتنامية",
32
+    "zhCN": "الصينية (الصين)",
33
+    "zhTW": "الصينية (تايوان)",
34
+    "th": "التايلندية",
35
+    "sc": "السردينية",
36
+    "eu": "الباسكية",
37
+    "uk": "الأوكرانية",
38
+    "sk": "السلوفاكية",
39
+    "lt": "الليتوانية",
40
+    "id": "الإندونيسية",
41
+    "he": "العبرية"
34 42
 }

+ 0
- 27
lang/languages-az.json Parādīt failu

@@ -1,27 +0,0 @@
1
-{
2
-    "en": "İngilis",
3
-    "af": "",
4
-    "az": "",
5
-    "bg": "Bolqar",
6
-    "cs": "",
7
-    "de": "Alman",
8
-    "el": "",
9
-    "eo": "",
10
-    "es": "İspan",
11
-    "fr": "Fransız",
12
-    "hy": "",
13
-    "it": "",
14
-    "ja": "",
15
-    "ko": "",
16
-    "nb": "",
17
-    "oc": "",
18
-    "pl": "",
19
-    "ptBR": "",
20
-    "ru": "",
21
-    "sk": "",
22
-    "sl": "",
23
-    "sv": "",
24
-    "tr": "",
25
-    "vi": "",
26
-    "zhCN": ""
27
-}

+ 34
- 0
lang/languages-be.json Parādīt failu

@@ -0,0 +1,34 @@
1
+{
2
+    "en": "Англійская",
3
+    "af": "Афрыкаанс",
4
+    "bg": "Балгарская",
5
+    "ca": "Каталанская",
6
+    "cs": "Чэшская",
7
+    "da": "Дацкая",
8
+    "de": "Нямецкая",
9
+    "el": "Грэцкая",
10
+    "enGB": "Англійская (Вялікабрытанія)",
11
+    "eo": "Эсперанта",
12
+    "es": "Іспанская",
13
+    "esUS": "Іспанская (Лацінская Амерыка)",
14
+    "et": "Эстонская",
15
+    "fi": "Фінская",
16
+    "fr": "Французская",
17
+    "frCA": "Французская (канадская)",
18
+    "hr": "Харвацкая",
19
+    "hu": "Венгерская",
20
+    "hy": "Армянская",
21
+    "it": "Італьянская",
22
+    "ja": "Японская",
23
+    "ko": "Карэйская",
24
+    "nl": "Галандская",
25
+    "oc": "Аксітанская",
26
+    "pl": "Польская",
27
+    "ptBR": "Партугальская (Бразілія)",
28
+    "ru": "Расійская",
29
+    "sv": "Шведская",
30
+    "tr": "Турэцкая",
31
+    "vi": "В'етнамская",
32
+    "zhCN": "Кітайская (Кітай)",
33
+    "zhTW": "Кітайская (Тайвань)"
34
+}

+ 2
- 1
lang/languages-ca.json Parādīt failu

@@ -29,5 +29,6 @@
29 29
     "tr": "Turc",
30 30
     "vi": "Vietnamita",
31 31
     "zhCN": "Xinès (Xina)",
32
-    "zhTW": "Xinès (Taiwan)"
32
+    "zhTW": "Xinès (Taiwan)",
33
+    "et": "Estonià"
33 34
 }

+ 12
- 1
lang/languages-de.json Parādīt failu

@@ -23,5 +23,16 @@
23 23
     "sv": "Schwedisch",
24 24
     "tr": "Türkisch",
25 25
     "vi": "Vietnamesisch",
26
-    "zhCN": "Chinesisch (China)"
26
+    "zhCN": "Chinesisch (China)",
27
+    "zhTW": "Chinesisch (Taiwan)",
28
+    "nl": "Niederländisch",
29
+    "hu": "Ungarisch",
30
+    "hr": "Kroatisch",
31
+    "frCA": "Französisch (Kanada)",
32
+    "fi": "Finnisch",
33
+    "et": "Estnisch",
34
+    "esUS": "Spanisch (Lateinamerika)",
35
+    "enGB": "Englisch (Vereinigtes Königreich)",
36
+    "da": "Dänisch",
37
+    "ca": "Katalanisch"
27 38
 }

+ 42
- 0
lang/languages-el.json Parādīt failu

@@ -0,0 +1,42 @@
1
+{
2
+    "en": "Αγγλικά",
3
+    "af": "Αφρικανικά",
4
+    "bg": "Βουλγάρικα",
5
+    "ca": "Καταλανικά",
6
+    "cs": "Τσέχικα",
7
+    "da": "Δανέζικα",
8
+    "de": "Γερμανικά",
9
+    "el": "Ελληνικά",
10
+    "enGB": "Αγγλικά (Ηνωμένου Βασιλείου)",
11
+    "eo": "Εσπεράντο",
12
+    "es": "Ισπανικά",
13
+    "esUS": "Ισπανικά (Λατινικής Αμερικής)",
14
+    "et": "Εσθονικά",
15
+    "eu": "Βάσκικα",
16
+    "fi": "Φινλανδικά",
17
+    "fr": "Γαλλικά",
18
+    "frCA": "Γαλλικά (Καναδικά)",
19
+    "he": "Εβραϊκά",
20
+    "hr": "Κροατικά",
21
+    "hu": "Ουγγρικά",
22
+    "hy": "Αρμένικα",
23
+    "id": "Ινδονησιακά",
24
+    "it": "Ιταλικά",
25
+    "ja": "Ιαπωνικά",
26
+    "ko": "Κορεάτικα",
27
+    "lt": "Λιθουανικά",
28
+    "nl": "Ολλανδικά",
29
+    "oc": "Οξιτανικά",
30
+    "pl": "Πολωνικά",
31
+    "ptBR": "Πορτογαλικά (Βραζιλίας)",
32
+    "ru": "Ρωσικά",
33
+    "sc": "Σαρδηνικά",
34
+    "sk": "Σλοβακικά",
35
+    "sv": "Σουηδικά",
36
+    "th": "Ταϊλανδικά",
37
+    "tr": "Τουρκικά",
38
+    "uk": "Ουκρανικά",
39
+    "vi": "Βιετναμέζικα",
40
+    "zhCN": "Κινέζικα (Κίνας)",
41
+    "zhTW": "Κινέζικα (Ταϊβάν)"
42
+}

+ 34
- 23
lang/languages-enGB.json Parādīt failu

@@ -1,27 +1,38 @@
1 1
 {
2
-    "en": "",
3
-    "af": "",
2
+    "en": "English",
3
+    "af": "Afrikaans",
4 4
     "az": "",
5
-    "bg": "",
6
-    "cs": "",
7
-    "de": "",
8
-    "el": "",
9
-    "eo": "",
10
-    "es": "",
11
-    "fr": "",
12
-    "hy": "",
13
-    "it": "",
14
-    "ja": "",
15
-    "ko": "",
5
+    "bg": "Bulgarian",
6
+    "cs": "Czech",
7
+    "de": "German",
8
+    "el": "Greek",
9
+    "eo": "Esperanto",
10
+    "es": "Spanish",
11
+    "fr": "French",
12
+    "hy": "Armenian",
13
+    "it": "Italian",
14
+    "ja": "Japanese",
15
+    "ko": "Korean",
16 16
     "nb": "",
17
-    "oc": "",
18
-    "pl": "",
19
-    "ptBR": "",
20
-    "ru": "",
17
+    "oc": "Occitan",
18
+    "pl": "Polish",
19
+    "ptBR": "Portuguese (Brazil)",
20
+    "ru": "Russian",
21 21
     "sk": "",
22
-    "sl": "",
23
-    "sv": "",
24
-    "tr": "",
25
-    "vi": "",
26
-    "zhCN": ""
27
-}
22
+    "sl": "Slovenian",
23
+    "sv": "Swedish",
24
+    "tr": "Turkish",
25
+    "vi": "Vietnamese",
26
+    "zhCN": "Chinese (China)",
27
+    "zhTW": "Chinese (Taiwan)",
28
+    "nl": "Dutch",
29
+    "hu": "Hungarian",
30
+    "hr": "Croatian",
31
+    "frCA": "French (Canadian)",
32
+    "fi": "Finnish",
33
+    "et": "Estonian",
34
+    "esUS": "Spanish (Latin America)",
35
+    "enGB": "English (United Kingdom)",
36
+    "da": "Danish",
37
+    "ca": "Catalan"
38
+}

+ 8
- 8
lang/languages-eo.json Parādīt failu

@@ -1,18 +1,18 @@
1 1
 {
2 2
     "en": "Angla",
3
-    "af": "",
4
-    "az": "",
3
+    "af": "Afrikansa",
4
+    "az": "Azera",
5 5
     "bg": "Bulgara",
6
-    "cs": "",
6
+    "cs": "Ĉeĥa",
7 7
     "de": "Germana",
8
-    "el": "",
8
+    "el": "Greka",
9 9
     "eo": "Esperanto",
10 10
     "es": "Hispana",
11 11
     "fr": "Franca",
12 12
     "hy": "Armena",
13 13
     "it": "Itala",
14
-    "ja": "",
15
-    "ko": "",
14
+    "ja": "Japana",
15
+    "ko": "Korea",
16 16
     "nb": "Norvega (Bukmola)",
17 17
     "oc": "Okcitana",
18 18
     "pl": "Pola",
@@ -22,6 +22,6 @@
22 22
     "sl": "Slovena",
23 23
     "sv": "Sveda",
24 24
     "tr": "Turka",
25
-    "vi": "",
25
+    "vi": "Vjetnama",
26 26
     "zhCN": "Ĉina (Ĉinuja)"
27
-}
27
+}

+ 5
- 3
lang/languages-es.json Parādīt failu

@@ -1,6 +1,6 @@
1 1
 {
2 2
     "en": "Inglés",
3
-    "af": "Africano",
3
+    "af": "Afrikáans",
4 4
     "bg": "Búlgaro",
5 5
     "ca": "Catalán",
6 6
     "cs": "Checo",
@@ -12,7 +12,7 @@
12 12
     "esUS": "Español (América Latina)",
13 13
     "fi": "Finlandés",
14 14
     "fr": "Francés",
15
-    "frCA": "Franco (Canadiense)",
15
+    "frCA": "Francés (Canadiense)",
16 16
     "he": "Hebreo",
17 17
     "hr": "Croata",
18 18
     "hu": "Húngaro",
@@ -30,5 +30,7 @@
30 30
     "tr": "Turco",
31 31
     "vi": "Vietnamita",
32 32
     "zhCN": "Chino (China)",
33
-    "zhTW": "Chino (Taiwan)"
33
+    "zhTW": "Chino (Taiwán)",
34
+    "et": "Estonio",
35
+    "da": "Danés"
34 36
 }

+ 34
- 0
lang/languages-eu.json Parādīt failu

@@ -0,0 +1,34 @@
1
+{
2
+    "en": "Ingelesa",
3
+    "af": "Afrikaans",
4
+    "bg": "Bulgariera",
5
+    "ca": "Katalana",
6
+    "cs": "Txekiera",
7
+    "da": "Daniera",
8
+    "de": "Alemana",
9
+    "el": "Greziera",
10
+    "enGB": "Ingelesa (Erresuma Batua)",
11
+    "eo": "Esperantoa",
12
+    "es": "Gaztelania",
13
+    "esUS": "Gaztelania (Latinamerika)",
14
+    "et": "Estoniera",
15
+    "fi": "Finlandiera",
16
+    "fr": "Frantsesa",
17
+    "frCA": "Frantsesa (Kanada)",
18
+    "hr": "Kroaziera",
19
+    "hu": "Hungariera",
20
+    "hy": "Armeniera",
21
+    "it": "Italiera",
22
+    "ja": "Japoniera",
23
+    "ko": "Koreera",
24
+    "nl": "Nederlandera",
25
+    "oc": "Okzitaniera",
26
+    "pl": "Poloniera",
27
+    "ptBR": "Portugesa (Brasil)",
28
+    "ru": "Errusiera",
29
+    "sv": "Suediera",
30
+    "tr": "Turkiera",
31
+    "vi": "Vietnamera",
32
+    "zhCN": "Txinera (Txina)",
33
+    "zhTW": "Txinera (Taiwan)"
34
+}

+ 33
- 22
lang/languages-fi.json Parādīt failu

@@ -1,27 +1,38 @@
1 1
 {
2
-    "en": "",
3
-    "af": "",
2
+    "en": "englanti",
3
+    "af": "afrikaans",
4 4
     "az": "",
5
-    "bg": "",
6
-    "cs": "",
7
-    "de": "",
8
-    "el": "",
9
-    "eo": "",
10
-    "es": "",
11
-    "fr": "",
12
-    "hy": "",
13
-    "it": "",
14
-    "ja": "",
15
-    "ko": "",
5
+    "bg": "bulgaria",
6
+    "cs": "tšekki",
7
+    "de": "saksa",
8
+    "el": "kreikka",
9
+    "eo": "esperanto",
10
+    "es": "espanja",
11
+    "fr": "ranska",
12
+    "hy": "armenia",
13
+    "it": "italia",
14
+    "ja": "japani",
15
+    "ko": "korea",
16 16
     "nb": "",
17
-    "oc": "",
18
-    "pl": "",
19
-    "ptBR": "",
20
-    "ru": "",
17
+    "oc": "oksitaani",
18
+    "pl": "puola",
19
+    "ptBR": "portugali (Brasilia)",
20
+    "ru": "venäjä",
21 21
     "sk": "",
22 22
     "sl": "",
23
-    "sv": "",
24
-    "tr": "",
25
-    "vi": "",
26
-    "zhCN": ""
27
-}
23
+    "sv": "ruotsi",
24
+    "tr": "turkki",
25
+    "vi": "vietnam",
26
+    "zhCN": "kiina (Kiina)",
27
+    "zhTW": "kiina (Taiwan)",
28
+    "nl": "hollanti",
29
+    "hu": "unkari",
30
+    "hr": "kroaatti",
31
+    "frCA": "ranska (Kanada)",
32
+    "fi": "suomi",
33
+    "et": "viro",
34
+    "esUS": "espanja (Latinalainen Amerikka)",
35
+    "enGB": "englanti (Yhdistynyt kuningaskunta)",
36
+    "da": "tanska",
37
+    "ca": "katalaani"
38
+}

+ 7
- 5
lang/languages-fr.json Parādīt failu

@@ -6,13 +6,13 @@
6 6
     "cs": "Tchèque",
7 7
     "de": "Allemand",
8 8
     "el": "Grec",
9
-    "enGB": "Anglais (Royaume-Uni) ",
9
+    "enGB": "Anglais (Royaume-Uni)",
10 10
     "eo": "Espéranto",
11 11
     "es": "Espagnol",
12 12
     "esUS": "Espagnol (Amérique latine)",
13
-    "fi": "Finlandais",
13
+    "fi": "Finnois",
14 14
     "fr": "Français",
15
-    "frCA": "Français (Canadien)",
15
+    "frCA": "Français (Canada)",
16 16
     "hr": "Croate",
17 17
     "hu": "Hongrois",
18 18
     "hy": "Arménien",
@@ -29,5 +29,7 @@
29 29
     "tr": "Turc",
30 30
     "vi": "Vietnamien",
31 31
     "zhCN": "Chinois (Chine)",
32
-    "zhTW": "Chinois (Taiwan)"
33
-}
32
+    "zhTW": "Chinois (Taiwan)",
33
+    "et": "Estonien",
34
+    "da": "Danois"
35
+}

+ 6
- 4
lang/languages-frCA.json Parādīt failu

@@ -6,11 +6,11 @@
6 6
     "cs": "Tchèque",
7 7
     "de": "Allemand",
8 8
     "el": "Grec",
9
-    "enGB": "Anglais (Royaume-Uni) ",
9
+    "enGB": "Anglais (Royaume-Uni)",
10 10
     "eo": "Espéranto",
11 11
     "es": "Espagnol",
12 12
     "esUS": "Espagnol (Amérique latine)",
13
-    "fi": "Finlandais",
13
+    "fi": "Finnois",
14 14
     "fr": "Français",
15 15
     "frCA": "Français (Canadien)",
16 16
     "hr": "Croate",
@@ -29,5 +29,7 @@
29 29
     "tr": "Turc",
30 30
     "vi": "Vietnamien",
31 31
     "zhCN": "Chinois (Chine)",
32
-    "zhTW": "Chinois (Taiwan)"
33
-}
32
+    "zhTW": "Chinois (Taiwan)",
33
+    "et": "Estonien",
34
+    "da": "Danois"
35
+}

+ 34
- 0
lang/languages-fy.json Parādīt failu

@@ -0,0 +1,34 @@
1
+{
2
+    "en": "",
3
+    "af": "",
4
+    "bg": "",
5
+    "ca": "",
6
+    "cs": "",
7
+    "da": "",
8
+    "de": "",
9
+    "el": "",
10
+    "enGB": "",
11
+    "eo": "",
12
+    "es": "",
13
+    "esUS": "",
14
+    "et": "",
15
+    "fi": "",
16
+    "fr": "",
17
+    "frCA": "",
18
+    "hr": "",
19
+    "hu": "",
20
+    "hy": "",
21
+    "it": "",
22
+    "ja": "",
23
+    "ko": "",
24
+    "nl": "",
25
+    "oc": "",
26
+    "pl": "",
27
+    "ptBR": "",
28
+    "ru": "",
29
+    "sv": "",
30
+    "tr": "",
31
+    "vi": "",
32
+    "zhCN": "",
33
+    "zhTW": ""
34
+}

+ 4
- 2
lang/languages-gl.json Parādīt failu

@@ -28,5 +28,7 @@
28 28
     "tr": "Turco",
29 29
     "vi": "Vietnamita",
30 30
     "zhCN": "Chinés (China)",
31
-    "zhTW": "Chinés (Taiwan)"
32
-}
31
+    "zhTW": "Chinés (Taiwan)",
32
+    "et": "Estoniano",
33
+    "da": "Dinamarqués"
34
+}

+ 37
- 0
lang/languages-he.json Parādīt failu

@@ -0,0 +1,37 @@
1
+{
2
+    "en": "אנגלית",
3
+    "af": "אפריקאית",
4
+    "bg": "בולגרית",
5
+    "ca": "קטלנית",
6
+    "cs": "קזחית",
7
+    "da": "דנית",
8
+    "de": "גרמנית",
9
+    "el": "יוונית",
10
+    "enGB": "אנגלית (בריטניה)",
11
+    "eo": "אספרנטו",
12
+    "es": "ספרדית",
13
+    "esUS": "ספרדית (אמריקה הלטינית)",
14
+    "et": "אסטונית",
15
+    "fi": "פינית",
16
+    "fr": "צרפתית",
17
+    "frCA": "צרפתית (קנדה)",
18
+    "he": "עברית",
19
+    "hr": "קראוטית",
20
+    "hu": "הונגרית",
21
+    "hy": "ארמנית",
22
+    "it": "איטלקית",
23
+    "ja": "יפנית",
24
+    "ko": "קוראנית",
25
+    "nl": "הולנדית",
26
+    "oc": "אוקיאנית",
27
+    "pl": "פולנית",
28
+    "ptBR": "פורטוגזית (ברזיל)",
29
+    "ru": "רוסית",
30
+    "sc": "סרבית",
31
+    "sk": "סלובקית",
32
+    "sv": "שוודית",
33
+    "tr": "טורקית",
34
+    "vi": "ויטנאמית",
35
+    "zhCN": "סינית (סין)",
36
+    "zhTW": "סינית (טיוואן)"
37
+}

+ 0
- 0
lang/languages-hu.json Parādīt failu


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels

Notiek ielāde…
Atcelt
Saglabāt