Compare commits

...

484 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
9f4c036174 fix(blur) fix model paths 2021-02-18 15:36:37 +01:00
Дамян Минков
8fcaea9e3d feat(load-test): Load test startmuted (#8629)
* feat(load-test): Senders unmute themselves if muted by policy.

* feat(load-test): Adds option to skip creating local audio track.

We currently create local audio track even when starting audio muted. Adding the option to control that can load test that for clients or signalling.
2021-02-17 10:28:01 -06:00
Pawel Domas
e0aab11f98 fix: TypeError: Cannot read property 'isAudioTrack' of undefined
When there's no jitsiTrack set on the base/tracks entry it means
a track is being created (get user media is in progress).
2021-02-17 09:25:09 -06:00
Tudor D. Pop
946339a52e feat(blur) replace BodyPix with TFLite
Use the Google Meet model and SIMD optimized WASM.
2021-02-17 16:03:33 +01:00
tmoldovan8x8
f71e8a9982 feat(mobile) adds actions and events for the chat 2021-02-17 16:26:40 +02:00
chipechop
af6080f173 fix(lang) update Italian translation 2021-02-17 13:25:23 +01:00
Jaya Allamsetty
b1080340ec chore(deps) lib-jitsi-meet@latest
* ref(QualityController): Split send and receive video constraints handling.
* fix: Save guards _features to be always empty and nver undefined. (#1493)

d1f0ab4d5a...c534f74884
2021-02-16 11:16:08 -05:00
damencho
684d121159 fix(load-test): Fixes keepalive url when using load-test. 2021-02-12 13:03:29 -06:00
Saúl Ibarra Corretgé
6740b0861e fix(rn,lobby) make sure the enable dialog follows the theme color 2021-02-12 16:40:56 +01:00
tmoldovan8x8
65c56669c4 feat refactors the chat flow so it has open and close functions 2021-02-12 13:18:16 +02:00
Дамян Минков
2cd43ba2e4 fix(load-test): Always create local audio track. (#8612)
* fix(load-test): Always create local audio track.

When audio mutes will mute the track. Also fixes previous change where we do not add any of the tracks to the room.

* squash: Fix lint errors.
2021-02-11 17:25:46 -06:00
Hristo Terezov
fec2641730 fix(popups): covered by labels. 2021-02-11 16:18:56 -06:00
damencho
04ee423257 fix(load-test): Create local tracks and then join.
Behaves now as the main client, and skips few unnecessary presences.
2021-02-11 15:14:31 -06:00
Hristo Terezov
460e137ee4 chore(deps) lib-jitsi-meet@latest
* fix(GUM-permissions): cache permissions on init.
* feat: Reuse billingId from localstorage as jitsiMeetId.
* fix(example) simplify
* feat(docs) mvoe API documentatrion to the handbook

84357ce1a8...d1f0ab4d5a
2021-02-11 13:56:46 -06:00
hmuresan
1a789130a3 feat (external_api) add command for kick participant 2021-02-11 07:33:26 -06:00
Nando Thomassen
16b00dc2af feat(flags) add feature flag for help button
Introduces a new feature flag ('help.enabled') and uses that to
determine the visibility of the 'Help' button in a call.
2021-02-10 22:34:13 +01:00
Saúl Ibarra Corretgé
c3a41b8cf3 fix(avatar) refactor preloading to avoid CORS issues
Fixes: https://github.com/jitsi/jitsi-meet/issues/8510

This basically reverts
a3fb996ff0
while retaining the same properties that prompted it's original intent, namely
avoiding sending the Referrer header.
2021-02-10 14:32:56 +01:00
damencho
f4d0ec1bb4 fix(load-test): Uses websocket if available and adds room param to the connection url. 2021-02-09 15:48:06 -06:00
tmoldovan8x8
ef6b641802 bugfix(ios) changes the participantInfo completion handler reference to strong.
When the method was called from Swift they were collected before calling them.
2021-02-09 18:03:25 +02:00
Saúl Ibarra Corretgé
579acbc570 feat(embed-meeting) add autoplay permission to iframe sample 2021-02-09 08:01:51 -06:00
niteshletxsoft
bca9a12df1 feat(external_ap) add api call to get live stream url 2021-02-09 12:43:38 +01:00
Shoolpani Dubey
a57b967f2e fix(external_api) add autoplay capabilities to created iframe
Should fix https://github.com/jitsi/jitsi-meet/issues/7037
2021-02-09 11:22:42 +01:00
Hristo Terezov
299927fcad docs: Add comment for initial GUM timeout values. 2021-02-08 15:53:38 -06:00
Hristo Terezov
7dc899ace1 ref(DeviceSelectionPopup): remove. 2021-02-08 15:53:38 -06:00
Hristo Terezov
a6c6cd6c56 fix: Add GUM timeout & improve device permissions 2021-02-08 15:53:38 -06:00
Hristo Terezov
7dc45c28a2 fix(AudioSlider): removed when volume is 0 2021-02-08 15:25:17 -06:00
Hristo Terezov
a215f9706a chore(deps) lib-jitsi-meet@latest
* fix(GUM): improve permissions logic.
* feat(GUM): timeout.
* ref: Remove pinEndpoint. (#1440)

30c8795770...84357ce1a8
2021-02-08 14:52:25 -06:00
Jonathan Lennox
4beca0d5dd Set receiver video constraint in load-test script, as-if tile view. (#8567) 2021-02-08 13:35:03 -05:00
Vlad Piersec
bfc4b2ac6f feat(vpaas): Send billing id to prosody 2021-02-08 12:49:55 +02:00
kazan417
53bdaa7928 fix(lang) update Russian translation 2021-02-07 12:44:20 +01:00
Tobias Kneidl
ba18b12024 add module proxy_wstunnel 2021-02-06 22:49:12 -06:00
Tobias Kneidl
a1438f1f21 change websocket url from http:// to ws:// 2021-02-06 22:49:04 -06:00
Julian1203
c856c20513 Update main-de.json
Small improvements (again)
2021-02-06 07:27:55 -06:00
Julian1203
cf92c964b4 Update main-de.json
Small improvements (again)
2021-02-05 22:15:51 -06:00
Julian1203
e69529867e Update main-de.json
Small improvements for the gender-neutral version and other small improvements.
2021-02-05 16:15:39 -06:00
Jaya Allamsetty
fd313c1af7 fix(tests): Add more checks so that test don't error out. 2021-02-05 16:30:58 -05:00
Jonathan Lennox
73c3feb8fa Improve load-test script. (#8563)
* In load-test, merge URL params into config.

* Honor config.testing.noAutoPlayVideo in load-test.
2021-02-05 16:00:28 -05:00
Дамян Минков
67a01364d3 Move load-test to resources (#8560)
* fix: Move load-test to resources.

* squash: Updates load-test dependencies.

* squash: Fix load-test build.
2021-02-05 09:12:45 -06:00
Saúl Ibarra Corretgé
7a64bf006e misc(tools) add script for updating mobile apps versions 2021-02-05 11:56:44 +01:00
Saúl Ibarra Corretgé
e5ea96fd4c feat(rn) update SDK version to 3.1.0 2021-02-05 11:56:44 +01:00
Saúl Ibarra Corretgé
c8ad04d0ff misc(tools) add script for updating SDK version 2021-02-05 11:56:44 +01:00
Saúl Ibarra Corretgé
c56afde00c feat(dev) bind to 0.0.0.0 on the dev server by default 2021-02-05 11:15:20 +01:00
tmoldovan8x8
9ed1969f7e feat(android) adds ability to disable the requestFocus on Android 2021-02-05 09:05:55 +02:00
Jonathan Lennox
12680c35ca Add lightweight load-test webpage, disabled by default (#8514)
Co-authored-by: Hristo Terezov <hristo@jitsi.org>
Co-authored-by: damencho <damencho@jitsi.org>
2021-02-04 18:04:36 -05:00
Jaya Allamsetty
0138f23755 feat(conference): Enable forced reload of client on bridge failure.
* feat(conference): Enable forced reload of client on bridge failure.
Force the client to reload when the bridge that is handling the media goes down.
This mitigates issues seen on the bridge because of a client re-joining the call with the same endpointId, BWE issues, etc.
This behavior is configurable through 'enableForcedReload' setting in config.js.
The client skips the pre-join page when the page reloads.

* squash: refactor the restart logic.

* squash: fix description

* squash: dispatch conferenceWillLeave action before reload.
2021-02-04 12:33:18 -05:00
Marc Seitz
16d88a288f feat: add ipados to list of Platform.OS (#8205)
* feat: add ipados list of Platform.OS
2021-02-04 10:34:44 -05:00
Jaya Allamsetty
210c4857fd deps: Update latest@lib-jitsi-meet.
Add the ability to configure different max bitrates for VP8 and VP9.
Set max bitrate for presenter to 2500 Kbps irrespective of the configured max bitrates for video.
479dd98...77978f0.
2021-02-04 09:50:32 -05:00
tmoldovan8x8
dca96f25f3 feat(mobile) adds feature flags for audioMute, videoMute and overflow… (#8537) 2021-02-04 15:32:09 +02:00
Mihai-Andrei Uscat
b69e93a900 fix(Safari): Fix mobile double tapping for toolbar and overflow.
* Create generic tooltip wrapper for mobile usability.
* Change overflow menu icon/font/padding sizes.
* Change overflow drawer expand icon.
2021-02-04 15:24:25 +02:00
tmoldovan8x8
d2568b874b feat(mobile) adds ability to retrieve participantsInfo array 2021-02-04 14:26:35 +02:00
Juan Searle
20c6115c38 Fix suspicious URL on Persian localization file 2021-02-03 20:39:08 -06:00
OctopusET
68b8ee5961 fix(lang) update korean translation 2021-02-03 15:52:59 +01:00
Andrei Gavrilescu
9895a04609 feat(rtcstats): send meeting uuid to rtcstats (#8526)
* send meeting uuid to rtcstats

* change ret description

* fix flow error

* update lib-jitsi-meet version
2021-02-03 12:28:39 +02:00
Andrzej Moskal
87f688dc8f fix(android) add ability to localize notification actions strings 2021-02-03 10:58:05 +01:00
Jaya Allamsetty
c58657c759 fix(test): Make sure test doesn't error out. 2021-02-01 11:49:45 -05:00
Ali Kazemkhanloo
687106818a Add Persian to languages-fa.json 2021-02-01 07:49:58 -06:00
Ali Kazemkhanloo
f228b4ecc1 Add Persian language to the list of languages 2021-02-01 07:49:58 -06:00
kichinosukey
8582b25d28 typo fix 2021-02-01 07:46:32 -06:00
Vlad Piersec
9418dbc2b1 fix(recents-list): Order recents by last used 2021-02-01 13:30:34 +02:00
Jonas Rittershofer
19bf027b8b Include xmpp and colibri proxy for apache
Signed-off-by: Jonas Rittershofer <jotoeri@users.noreply.github.com>
2021-01-30 10:06:22 -06:00
Mihai-Andrei Uscat
c370c05701 fix(Filmstrip): Prevent Toolbox from being shown indefinitely when hovering filmstrip 2021-01-29 15:34:37 +02:00
Emil Ivov
f034f179ff Merge pull request #8507 from saghul/readme-jaas
fix(docs) add JaaS link to README
2021-01-29 06:57:51 -06:00
Saúl Ibarra Corretgé
b94b18770c fix(docs) add JaaS link to README 2021-01-29 13:54:27 +01:00
Mihai-Andrei Uscat
3f93726c41 fix(Safari): Fix zoomed in mobile interface and cropped tile 2021-01-29 12:55:24 +02:00
Titus-Andrei Moldovan
af8072d9d2 chore(mobile) changes the name for screenShares to remoteScreenShares to better reflect it's content 2021-01-29 12:45:53 +02:00
Titus-Andrei Moldovan
45f4643469 feat(mobile) adds ToggleScreenShare event and action. 2021-01-29 12:45:53 +02:00
Avram Tudor
745879c447 Merge pull request #8503 from jitsi/tavram/dropbox
feat(external_api) allow dropbox option to be overwritten
2021-01-29 12:30:03 +02:00
Mihai-Andrei Uscat
4aab5e2054 feat(Dialog): Make dialog close button more mobile friendly.
* Remove pointless custom headers, fall back to ModalHeader instead.
2021-01-29 12:22:43 +02:00
Tudor-Ovidiu Avram
69971a0e90 feat(external_api) allow dropbox option to be overwritten 2021-01-29 11:44:16 +02:00
Pawel Domas
7c90f75ec9 fix(conference.js): crash on undefined
While on the prejoin screen, the local tracks are managed by the redux store and not conference.js, so localAudio is undefined.
2021-01-28 21:59:44 -05:00
damencho
bf714c1c8b feat: Allow star for room in moderated tenants. 2021-01-28 16:28:39 -06:00
Avram Tudor
8414e9d99f Merge pull request #8495 from jitsi/tavram/chat-updated
feat(external_api) add event for chat updates (unread counter, open s…
2021-01-28 16:42:06 +02:00
Tudor-Ovidiu Avram
dcaad41e69 feat(external_api) add event for chat updates (unread counter, open state) 2021-01-28 11:41:27 +02:00
Jonathan Lennox
63f0166f75 Add mime type mapping for wasm to default Debian nginx config. 2021-01-27 13:42:37 -06:00
Дамян Минков
79f3756d33 feat: Adds option to set ws keepalive url through config. (#8487)
* feat: Adds option to set ws keepalive url through config.

* chore(deps) lib-jitsi-meet@latest

* feat: Adds option to set ws keepalive url through config.
* fix VADAudioAnalyser: catch error

be18ff34be...9fdde46694
2021-01-27 11:13:32 -06:00
damencho
5ac30262a5 fix(debian): Improves handling db_get. 2021-01-26 09:49:03 -06:00
damencho
09315fa653 fix: Adds luasec as dependency.
This is in Recommended but we need it.
2021-01-26 09:49:03 -06:00
damencho
5f0dd903f6 fix(debian): Fixes enforce_apache option. 2021-01-26 09:49:03 -06:00
Steffen Kolmer
ef7d425859 feat(ui) update AtlasKit components 2021-01-26 16:47:55 +01:00
bgrozev
a9bb8e5e81 fix: Use internal_hashed everywhere. (#8485) 2021-01-26 09:33:41 -06:00
Mihai-Andrei Uscat
8cf4e15b23 Add config flag for tile responsiveness 2021-01-26 13:42:57 +02:00
Mihai-Andrei Uscat
db84889143 feat(tiles): Add responsive behaviour.
* Enforce fixed column number at various width breakpoints.
* Bring back the filmstrip at small sizes but hide it.
* Change default maximum columns to 7.
2021-01-26 13:42:57 +02:00
Ali Karpuzoglu
6ca3c6e43a fix(misc) typo 2021-01-26 12:38:49 +01:00
DeBuXer
6fd280a960 fix(lang) update Dutch translation 2021-01-26 11:27:42 +01:00
Jonas Rittershofer
6f9e65d348 Allow to enforce Apache via debconf
Signed-off-by: Jonas Rittershofer <jotoeri@users.noreply.github.com>
2021-01-25 16:27:01 -06:00
damencho
f1e06bff7b fix: Lobby display name set when preJoin is disabled. Fixes #8415. 2021-01-25 16:03:54 -06:00
Jaya Allamsetty
1cf7a361e9 feat: Implement aggressive layer suspension on RN.
RN doesn't support RTCRtpSender yet. Therefore, media is suspended on RN by changing the media direction in the SDP whenever the client receives an ideal height of 0 for sender constraints on the bridge channel.
LJM update - 3570339360...be18ff34be.
2021-01-25 15:21:16 -05:00
okyanusoz
e7990baa7d Fixed Turkish translation issues 2021-01-25 13:36:32 -06:00
Cedric Roijakkers
d35708815d fix(lang) corrected Dutch translation of toggleCamera 2021-01-22 17:39:20 +01:00
Jaya Allamsetty
270e52e402 deps(ljm): Restore local connection status.
831716c160...3570339360.
2021-01-22 10:44:01 -05:00
Saúl Ibarra Corretgé
635d283d5a chore(deps) react-native-callstats@3.70.1
Support processing stats in the spec-compliant format.
2021-01-22 14:06:10 +01:00
Balu
4affc68b50 Update main-de.json
Added missing "user" dialog parameter translation. Tried to stay gender neutral.
2021-01-22 06:24:42 -06:00
chipechop
dca262620b Update languages-it.json 2021-01-22 06:24:11 -06:00
as0bit
12c8258f56 Update main-de.json
lang: add missing fields to German translation
2021-01-22 06:22:22 -06:00
tmoldovan8x8
6a6aeb1d95 feat(mobile) adds more feature flags (#8450)
Features flags added:  
-tile-view.enabled
-filmstrip.enabled
-notifications.enabled
-toolbox.enabled
2021-01-22 12:03:39 +02:00
Дамян Минков
01c55bdb15 feat: Uses mod_external_services supporting urn:xmpp:extdisco:2. (#8455)
* feat: Uses mod_external_services supporting urn:xmpp:extdisco:2.

The old mod_turncredentials.lua is left to continue working for those using old installs.
New install will start using the new module which will no longer be needed with prosody 0.12.

https://hg.prosody.im/prosody-modules/file/4841cf3fded5/mod_external_services/mod_external_services.lua

* squash: Updates ljm to support urn:xmpp:extdisco:2.
2021-01-21 16:14:00 -06:00
bgrozev
5f891fd060 debian: Do not read jicofosecret. (#8454) 2021-01-21 13:19:39 -06:00
chipechop
a39905883f Update main-it.json
Added 4 missing lines in italian translation
2021-01-20 12:01:54 -06:00
Saúl Ibarra Corretgé
fe78f104bc feat(android) set compile/target SDK versions to 30 2021-01-20 15:14:09 +01:00
Saúl Ibarra Corretgé
9c13603489 feat(android) update native dependencies 2021-01-20 15:14:09 +01:00
tmoldovan8x8
61037b982b feat(mobile) adds ability to send and receive text messages (#8425) 2021-01-20 14:06:45 +02:00
Jaya Allamsetty
df21ec6f04 chore(deps) lib-jitsi-meet@latest (#8437)
https://github.com/jitsi/lib-jitsi-meet/compare/...94ac35ae818093896e639e74f5fc389b488206a0
2021-01-19 12:45:33 -06:00
Vlad Piersec
23574e9edc fix(vpaas): Store billing id in parent lolcaStorage on Safari 2021-01-18 09:56:03 +02:00
Dennis Scheiba
ec3130af0e make translation gender neutral 2021-01-16 21:56:22 -06:00
Filipe dos Santos Gundim
3b692dc502 fix join label in pt-br 2021-01-16 21:36:00 -06:00
Дамян Минков
6689aa3700 feat: Detects shard changed when using websockets.
* feat: Detects shard changed when using websockets. (#1462)

1009693f2e...cb484cf48c
2021-01-15 09:51:43 -06:00
Avram Tudor
13bc9863cb Merge pull request #8426 from jitsi/tavram/gradient-condition
fix(subject) remove gradient if no info in topbar
2021-01-15 16:26:19 +02:00
Tudor-Ovidiu Avram
7ff332b2bb fix(subject) remove gradient if no info in topbar 2021-01-15 16:02:50 +02:00
Mihai-Andrei Uscat
8aae2065dc fix(Toolbox): Fix toolbox display when accessing it via keyboard 2021-01-15 13:43:09 +02:00
Jaya Allamsetty
b65e61f633 feat: Add new codec selection mechanism.
When an endpoint that doesn't support the preferred codec (VP9) joins a conference, all the other endpoints fallback to VP8 until the endpoint leaves the call.
2021-01-14 18:01:38 -05:00
Saúl Ibarra Corretgé
88f1c218eb fix(rn,stats) fix incorrect bitrate calculation on mobile
Stats timestamps were incorrectly formatted, fixed upstream.

Fixes: https://github.com/jitsi/jitsi-meet/issues/8367
2021-01-14 14:59:22 +01:00
Boris Grozev
f6df76ab10 fix: Fix broken postinst reported by @wsldankers. 2021-01-14 07:55:50 -06:00
Saúl Ibarra Corretgé
85f1701393 fix(tile-view) avoid covering the logo
Reverts a8b2e6ffb3
2021-01-13 20:29:20 +01:00
damencho
2f7ff37472 fix: Fixes #8396, wrong ssi includes in offline static page. 2021-01-13 09:11:10 -06:00
Mihai-Andrei Uscat
c752ea13f1 feat(overflow): Add responsive drawer at small screen width.
* Implement opening toolbar and participant overflows as drawers when below certain width.
* Fix dial-in copy button displaying incorrectly.
2021-01-13 16:07:22 +01:00
tmoldovan8x8
5ef60c3a7d [WIP] adds BroadcastService (#8336)
feat(external_api) exposes more events from JS to native and adds the ability to send actions from native to JS.
2021-01-13 15:48:29 +02:00
hmuresan
1196ede961 feat(external-api) set privateMessage flag on incoming-message 2021-01-13 13:33:55 +01:00
Saúl Ibarra Corretgé
12877c7fce fix(settings) remove legacy compatibility code 2021-01-13 13:32:54 +01:00
Avram Tudor
c6bb600d4c Merge pull request #8400 from jitsi/tavram/shortcuts
feat(external_api) allow shortcuts to be disabled
2021-01-13 12:39:27 +02:00
Avram Tudor
845e23a947 Merge pull request #8399 from jitsi/tavram/overflowmenu
fix(menu) do not display overflow menu button if no items
2021-01-13 12:39:11 +02:00
Tudor-Ovidiu Avram
55ebb60f85 feat(external_api) allow shortcuts to be disabled 2021-01-13 12:10:27 +02:00
Tudor-Ovidiu Avram
8d3d94f568 fix(menu) do not display overflow menu button if no items 2021-01-13 11:55:38 +02:00
Avram Tudor
be24772e57 Merge pull request #8397 from jitsi/tavram/disable-jaas-directory
fix(jaas) disable directory integration
2021-01-13 11:38:05 +02:00
Tudor-Ovidiu Avram
a807f804a9 fix(jaas) disable directory integration 2021-01-13 11:13:04 +02:00
Hristo Terezov
db48dc3ed3 fix(Thumbnail): volume & audioLevel default values 2021-01-12 13:42:31 -06:00
Hristo Terezov
9bae7099dd fix(filmstrip): Import from base/tracks. 2021-01-12 13:42:31 -06:00
Hristo Terezov
e990f6984a fix(Thumbnail): Improve naming. 2021-01-12 13:42:31 -06:00
Hristo Terezov
9f321c988e style(isVideoPlayable): improve readability. 2021-01-12 13:42:31 -06:00
Hristo Terezov
2e5e9a3f79 fix(AudioTrack):Add check for NaN value for volume 2021-01-12 13:42:31 -06:00
Hristo Terezov
fdb8f76b90 fix(Thumbnail): imports. 2021-01-12 13:42:31 -06:00
Hristo Terezov
3d97bef308 style(Thumbnail): improve readability
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2021-01-12 13:42:31 -06:00
Hristo Terezov
5a55c7b965 style(AudioTrack): improve readability
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2021-01-12 13:42:31 -06:00
Hristo Terezov
e161cbc4bd fix(SmallVideo): computeDisplayModeInput
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2021-01-12 13:42:31 -06:00
Hristo Terezov
51e381a0b1 ref(Thumbnail): Create React component. 2021-01-12 13:42:31 -06:00
bgrozev
d8dd644f38 make sure extra plugin paths are enabled (#8390)
* fix: Make sure extra plugin_paths are not commented out.

* fix: Do not use "-e" as backup suffix.
2021-01-12 13:25:20 -06:00
Saúl Ibarra Corretgé
e30b2e14a5 fix(rn) stop room name generator when field is focused
Fixes: https://github.com/jitsi/jitsi-meet/issues/8307
2021-01-12 17:36:09 +01:00
Avram Tudor
7f1894dd57 Merge pull request #8379 from horymury/hmuresan/broadcast-screenshare
feat(external_api) add command and event listener for CS
2021-01-12 17:49:06 +02:00
hmuresan
4dda508708 feat(external_api) add command and event listener for CS 2021-01-12 17:23:40 +02:00
damencho
69c6463476 chore(deps) lib-jitsi-meet@latest
* fix: Disabling lobby when using tenant.

87c6e37475...7896fc8b92
2021-01-12 08:22:14 -06:00
Saúl Ibarra Corretgé
2763c2f5c9 fix(twa) update template
Set version to 1.0.0 with a very large version code so it's automatically kept
around when pushing new versions.

Additionally drop some no longer needed icon assets (bubblewrap did this).
2021-01-12 14:56:04 +01:00
Saúl Ibarra Corretgé
1ec8f70d55 fix(libre-build) skip spurious Firebase and GCM dependencies
Fixes: https://github.com/jitsi/jitsi-meet/issues/8353
2021-01-12 14:55:47 +01:00
Saúl Ibarra Corretgé
916208a5ff fix(libre-build) update react-native-device-info to 8.0.0
Will now work even if installreferrer or GCM are missing.
2021-01-12 14:55:47 +01:00
Mihai-Andrei Uscat
43e655b619 feat(chat): Improve responsiveness.
* Fix toolbox buttons not displaying properly when chat is open.
* Open chat in fullscreen dialog past custom thresholds when mobile/desktop toolbox would become unusable due to chat
* Remove mobile chat check when displaying toolbox
2021-01-12 15:24:55 +02:00
Avram Tudor
1ab0f1993a Merge pull request #8377 from jitsi/tavram/notifications
feat(external_api) allow notifications to be configured
2021-01-12 14:52:31 +02:00
Tudor-Ovidiu Avram
4cb7ebce70 feat(external_api) allow initial gUM requests to be disabled 2021-01-12 06:02:44 -06:00
hmuresan
0a5910f0b3 feat(external_api) set and cancel private chat through external API
- allow managing chat through API when chat button is not present on UI
2021-01-12 06:01:10 -06:00
Tudor-Ovidiu Avram
d91c546a1e feat(external_api) allow notifications to be configured 2021-01-12 11:22:53 +02:00
bgrozev
b6f7f8fba7 Remove the "focus" external component, use client_proxy instead. (#8381)
* feat: Add mod_client_proxy and mod_roster_command.

Taken from prosody-modules 4317:456b9f608fcf with the
mod_roster_command patch applied.

* feat: Use mod_client_proxy to proxy to jicofo.
2021-01-11 15:45:00 -06:00
Pawel Domas
6ebe2c2809 audio output selection in safari blocks the UI
It appears that at the time of this writing, creating audio tracks blocks
the browser's main thread for a long time on safari. Wasn't able to confirm
which part of track creation does the blocking exactly, but not creating
the tracks seems to help and makes the UI much more responsive.
2021-01-11 14:17:29 -05:00
Saygun ICYUZ
067610b3fd feat(recording) - Show recording started notification to the initiator (#8359)
* Show recording started notification to the initiator

* Translate 'recording.on' language key for English and Turkish
Translate 'liveStreaming.on' language key for English and Turkish
2021-01-11 08:21:33 -06:00
Avram Tudor
6f5534fcb6 Merge pull request #8352 from jitsi/tavram/allow-tileview-disabling
feat(jaas) allow tile view to be disabled
2021-01-08 16:03:21 +02:00
Tudor-Ovidiu Avram
dd8b220ff9 feat(jaas) allow tile view to be disabled 2021-01-08 12:00:13 +02:00
Avram Tudor
80d789879c Merge pull request #8356 from jitsi/tavram/top
feat(jaas) add config for displaying participants stats and conferenc…
2021-01-08 11:57:23 +02:00
Tudor-Ovidiu Avram
d49c5a6d8c feat(jaas) add config for displaying participants stats and conference subject 2021-01-08 10:21:07 +02:00
Mejans
9268255ca8 i18n: update Occitan language (#8346)
* Update main-oc.json

* Update languages-oc.json
2021-01-07 14:51:21 -06:00
Pawel Domas
a0806716ae fix(JitsiStreamPresenterEffect): frozen on Safari
Canvas rendering does not work as expected on Safari - the image stays
still on the first frame. Calling play() on the video tags seems to help.
2021-01-07 15:10:27 -05:00
Дамян Минков
3677a2f769 feat: Skip p2p when the participant is jigasi.
* feat: Skip p2p when the participant is jigasi.

1fd7256553...87c6e37475
2021-01-07 09:08:36 -06:00
Avram Tudor
3881da5db9 Merge pull request #8354 from jitsi/tavram/fix-filmstrip
fix(filmstrip) fix button not considering interface config settings
2021-01-07 15:20:22 +02:00
Tudor-Ovidiu Avram
35a586df3c fix(filmstrip) fix button not considering interface config settings 2021-01-07 14:53:11 +02:00
Saúl Ibarra Corretgé
dc5a776123 fix(ios) fix drag handle not rendering with latest react-native-svg
Fill must be properly specified.
2021-01-07 12:02:41 +01:00
Saúl Ibarra Corretgé
a3c6e690dd chore(deps) update react-native-svg to latest
Fixes icons not rendering on iOS 11.
2021-01-07 12:02:41 +01:00
Saúl Ibarra Corretgé
a1c197c73c fix(ios) fix crash on startup on iOS 11 2021-01-07 12:02:41 +01:00
damencho
e8c0c03e49 chore(deps) lib-jitsi-meet@latest
*  feat: Skips using disco-info for features. (#1450)
* sdp: improve sdp matching for simulcast lines (#1452)
* sdp: add missing colon to findLines calls (#1447)

310983c5b0...1fd7256553
2021-01-06 09:32:26 -06:00
Saúl Ibarra Corretgé
4798e0271b chore(android,ios) raise versions 2021-01-06 16:21:44 +01:00
Asif
cd29f10fa8 feat: emit raise hand event to external API (#8312)
* Expose raise hand event to external application

* Fix linting issues

* fix the app non existing issue
2021-01-06 08:49:10 -06:00
Pawel Domas
97dc07810c fix(setAudioOutputDeviceId): check if supported 2021-01-06 08:31:53 -06:00
damencho
28fa1f5dbe fix: Process pre-existing participants properties.
We were not processing properties which are set (fire properties updated) before the conference joined event is fired.
2021-01-05 14:29:34 -06:00
damencho
2ba6100e36 fix: Fixes showing phone icon for jigasi participants. 2021-01-05 14:29:34 -06:00
Shawn
060a8628ce fixed admin check for token verification 2021-01-05 12:56:33 -06:00
Christopher Engelhard
32fb08c56f Consistent formatting/indentation of files in ./doc (#8178)
* unify indentations (debian)

* unify indentations in example-config-files
2021-01-04 08:22:40 -06:00
Jakob Pfeiffer
4a3ff8ce2c fix(jitsi-meet-web-config.postinst) allow cert and key pre-selection (#8319)
* fix(jitsi-meet-web-config.postinst) allow cert and key pre-selection

* fix(jitsi-meet-web-config.postinst) jvb-hostname gets value from db_go instead of db_get

Co-authored-by: Jakob Pfeiffer <pgp-jkp@pfeiffer.ws>
2021-01-04 08:22:27 -06:00
yanglishuan
f32482539a fix(lang) update zhCN translation 2021-01-04 08:22:09 -06:00
53845714nF
f82088fb8f add systemd to letsencrypt installer (#8289)
* add systemd to letsencrypt

* Better readability of systemd change

Co-authored-by: Sebastian Feustel <sebastian.feustel@aei.mpg.de>
2021-01-04 08:21:47 -06:00
Vahid Zafari
76b4899c39 full support persian language (#8300) Fixes #8299 2020-12-23 08:29:07 -06:00
Marc Seitz
9b638a4052 fix(lang) update German translation 2020-12-23 11:07:10 +01:00
Saúl Ibarra Corretgé
a8b2e6ffb3 fix(tile-view) allow watermark to be covered 2020-12-23 11:05:30 +01:00
Saúl Ibarra Corretgé
aefd13ab1b fix(tile-view) reduce margins, take 2
Due to how the filmstrip size if computed I don't think there is a good way to
animate the change in size, so just ignore the toolbar, it will be hidden soon
enough.
2020-12-23 11:05:30 +01:00
Saúl Ibarra Corretgé
5e891caf94 fix(ios,fastlane) adjust scheme name after rename 2020-12-22 14:07:10 +01:00
Saúl Ibarra Corretgé
a01e3e9d8a fix(android) avoid crashes if view is null
This may happen due to API misuse, but also in complex applications where
activity lifetimes are not straightforward.
2020-12-22 13:53:39 +01:00
Saúl Ibarra Corretgé
687a6c31ee feat(analytics) unify Amplitude handlers across web and mobile
The amplitude-js library gained React Native support so there is no need to keep
separate implementations.
2020-12-22 10:36:10 +01:00
tmoldovan8x8
5ecb5717c7 feat(stats) add stats for mobile 2020-12-22 10:12:52 +01:00
Avram Tudor
8d813a499c Merge pull request #8293 from jitsi/tavram/update-jaas-rec
fix(jaas) update recording label and hide option for jaas users
2020-12-21 13:00:59 +02:00
Tudor-Ovidiu Avram
22384d9094 fix(jaas) update recording label and hide option for jaas users 2020-12-21 12:19:10 +02:00
eppesuig
b3f1f7f46e lang: Updating and uniforming italian translation (#8288)
* Updating and uniforming italian translation

- translate uniformly «meeting» to «conferenza», «chat» to «conversazione», ellipsys to «...», verbs in -ing with «in corso»
- correct a few typos
- update a message with old and unused placeholder
- translate some English messages

* typo

- add missing double quotes

* Fixed translation for "meeting" to "riunione"
2020-12-20 21:17:49 -06:00
xosecalvo
17350be16c Updated Galician translation
Updated original Weblate translation by https://github.com/meixome
2020-12-20 09:22:49 -06:00
Hristo Terezov
d4596889df feat(analytics): Adds metric for SS issues. 2020-12-18 15:27:43 -06:00
Mihai-Andrei Uscat
a5fe26bfdb fix(password): Fix add password button on Safari 2020-12-18 14:47:00 +02:00
Vlad Piersec
33e4324f6d fix(branding): Use config url for dynamic branding 2020-12-18 13:00:52 +01:00
Saúl Ibarra Corretgé
27d41604df fix(script) add commits list to update LJM message 2020-12-18 09:45:09 +01:00
Saúl Ibarra Corretgé
99ac60ed74 feat(ios) rename SDK target to JitsiMeetSDK
Swift has a longstanding bug where a framework and a type cannot be named the
same. We have somehow managed to not run into this, but it now seems to be
hitting us.

Since this is a breaking change, this starts the road for SDK 3.0.
2020-12-17 23:02:48 +01:00
Дамян Минков
4f52fd5e01 fix: Skip sending multiple times disco-info to jicofo.
* fix: Skip sending multiple times disco-info to jicofo.
* build(deps): bump ini from 1.3.5 to 1.3.7

9f65e8fab3...8bb653f1d6
2020-12-17 13:02:28 -06:00
bhlee
edf415a7da fix(welcome-page) fix .insecure-room-name-warning margin 2020-12-17 09:28:24 +01:00
bhlee
5637b37fd2 fix(main-ko) add keyboardShortcuts videoQuality (#8264)
* fix(main-ko.json) Update overall korean spelling & words

* fix(_welcome_page.css) update .insecure-room-name-warning_margin-top from 5px to 15px

* fix(_welcome_page.css) initialize .insecure-room-name-warning_margin-top from 15px to 5px

* fix(main-ko.json) add keyboardShortcuts videoQuality
2020-12-16 23:17:44 -06:00
bhlee
dc0c1f0d93 fix(main-ko.json) Update some korean spelling & words (#8253)
* fix(main-ko.json) Update overall korean spelling & words

* fix(_welcome_page.css) update .insecure-room-name-warning_margin-top from 5px to 15px

* fix(_welcome_page.css) initialize .insecure-room-name-warning_margin-top from 15px to 5px
2020-12-16 19:45:24 -06:00
Damien Fetis
5c1af8835b lang: update French translation (#7725) 2020-12-16 13:04:02 -06:00
AleFelix
c61c00171a feat: Update spanish translation (#8023)
* Update main-es.json

* Update main-esUS.json
2020-12-16 12:34:52 -06:00
roms2000
d025f51ce2 Update main-fr.json (#8114)
* Update main-fr.json

Update FR language, fix typos, alphabetical order and based from main.json

* Update main-fr.json
2020-12-16 10:10:29 -06:00
James E. Blair
bab2b0735c Etherpad on join (#8212)
* Add option to open Etherpad on join

For sites that focus on collaborative editing during meetings, add
an option which, when set, will automatically open etherpad when a
participant joins.

* Add openSharedDocumentOnJoin to config whitelist

This also adds some config file doc comments about the option,
including a note about the choice not to honor it in the mobile app.
2020-12-16 10:10:12 -06:00
bcvieira
2fa0c6c98f Update main-ptBR.json
Reordering and adding new translations.
2020-12-16 10:09:59 -06:00
Ivan Trubach
fa541a6768 Update main-ru.json 2020-12-16 10:09:48 -06:00
krakazyabra
1ed18c5be3 Fix #8095 (#8101) 2020-12-16 10:09:31 -06:00
JSHar
cf7cc84781 languages-ka.json
georgian Language
2020-12-16 10:09:05 -06:00
BustaFu
05cdec3b70 Update main-sv.json
Fix swedish translation
2020-12-16 10:08:56 -06:00
Jamil Bailony
c57fd643ea lang: Update Arabic translation 2020-12-16 10:08:47 -06:00
Julian1203
ad297c2470 Update main-de.json
Fixed typo.
2020-12-16 10:08:27 -06:00
vachan-maker
be1b6d71f5 lang:New translation malayalam(ml-in) 2020-12-16 10:08:17 -06:00
vachan-maker
d63be314c6 Added missing language malayalam(ml) (#7732) 2020-12-16 10:08:03 -06:00
tzm_web
ea13e3c346 Update main-zhCN.json,languages-zhCN.json. 2020-12-16 10:07:20 -06:00
Saúl Ibarra Corretgé
58bd4edb85 fix(remote-control) skip on mobile
Middlewares should not be loaded on mobile as there is no way to use the
functionality.
2020-12-16 13:59:41 +01:00
Saúl Ibarra Corretgé
01345d6d9d chore(ios) remove references to no longer used files 2020-12-16 10:28:30 +01:00
Saúl Ibarra Corretgé
28cd74077b fix(ios) fix joining a meeting when the app was closed
Weird timing issue in appDidFinishLaunching, make sure we store the
launchOptions before we touch any view code.
2020-12-16 10:28:30 +01:00
Hristo Terezov
af6c794fda ref(remote-control): Use React/Redux. 2020-12-15 18:09:58 -06:00
Pawel Domas
f88061db06 fix(conference.js): 2 tracks of the same media type
...caused by bad state as a result of timing issue around the prejoin flow.

If get user media call is delayed for a while and if user joins
the conference, when it hasn't completed then confrence.js will not assign
'localAudio' and 'localVideo' variables and will create additional media
tracks on unmute operation and add them to JitsiConference via replaceTracks
operation.
2020-12-15 14:11:00 -06:00
damencho
ec6abc1ce9 fix: Skip sending unnecessary signalling for raise hand. 2020-12-15 11:21:56 -06:00
sorinant
e261bb5616 feat(ios) added ability to use an external CXProvider and CXCallController 2020-12-15 12:21:53 +01:00
Saúl Ibarra Corretgé
b1a4b58f7a chore(deps) update react-native-webview 2020-12-15 12:05:59 +01:00
dependabot[bot]
42dabd4cdb chore(deps): bump react-native-webview from 10.9.0 to 11.0.0
Bumps [react-native-webview](https://github.com/react-native-community/react-native-webview) from 10.9.0 to 11.0.0.
- [Release notes](https://github.com/react-native-community/react-native-webview/releases)
- [Changelog](https://github.com/react-native-webview/react-native-webview/blob/master/.releaserc)
- [Commits](https://github.com/react-native-community/react-native-webview/compare/v10.9.0...v11.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-15 11:09:28 +01:00
qwertiko GmbH
89ebb4d918 fix(LoginDialog) added missing double quotes 2020-12-15 11:06:44 +01:00
damencho
fc54fc80d1 fix: Start p2p only when we have received all presences. 2020-12-14 18:21:46 -06:00
Hristo Terezov
87b1155180 fix(video):Always show avatar if video is inactive 2020-12-14 16:44:08 -06:00
Saúl Ibarra Corretgé
4ca02c1ebf feat(tile-view) optimize for less margins
- Lower the inter-tile margin to 2px
- Remove the 100px top/bottom margin when the toolbar is hidden
2020-12-14 21:27:13 +01:00
BasmaAwatef
70fcabd136 fix: the user placeholder translation issue #8219 (#8233)
* ✏️ user placeholder translation in authentication added

* Create node.js.yml

* Create npm-publish.yml

* Create deno.yml

* Create ci.yml

* Create stale.yml

* Delete deno.yml

* Delete npm-publish.yml

* Delete ci.yml

* Delete node.js.yml

* Delete ci.yml

* Create main.yml

* Delete stale.yml

* Delete main.yml

* Create ci.yml

* Create simpleCI.yml

* Update simpleCI.yml

* Revert "Delete stale.yml"

This reverts commit 27d88166b9.

* Revert "Delete main.yml"

This reverts commit 037cd96e71.

* Revert "Revert "Delete stale.yml""

This reverts commit 834d96e41c.

* Revert "Revert "Delete main.yml""

This reverts commit f69bc066f9.

* Revert "Revert "Revert "Delete stale.yml"""

This reverts commit d60372da56.

* Revert "Revert "Revert "Delete main.yml"""

This reverts commit 521ca60df3.

* Revert "Revert "Revert "Revert "Delete stale.yml""""

This reverts commit 1f2a9518e1.

* Revert "Revert "Revert "Revert "Delete main.yml""""

This reverts commit adf6c58f8e.

* Revert "Revert "Revert "Revert "Revert "Delete stale.yml"""""

This reverts commit 81c7ecc42f.

* Revert "Revert "Revert "Revert "Revert "Delete main.yml"""""

This reverts commit d1e1c03983.

* Revert "Revert "Revert "Revert "Revert "Revert "Delete stale.yml""""""

This reverts commit b5f16b3e4d.

* Revert "Revert "Revert "Revert "Revert "Revert "Delete main.yml""""""

This reverts commit f9ef5ab193.

* Revert "Revert "Revert "Revert "Revert "Revert "Revert "Delete stale.yml"""""""

This reverts commit b66bbf8698.

* Revert "Revert "Revert "Revert "Revert "Revert "Revert "Delete main.yml"""""""

This reverts commit 01a44daf95.

* Revert "Revert "Revert "Revert "Revert "Revert "Revert "Revert "Delete main.yml""""""""

This reverts commit eb896849a7.

* 🔥 modifications dropped for all languages except for English

* Delete simpleCI.yml

* Delete stale.yml
2020-12-11 07:35:20 -06:00
Marek Suchánek
25a238f4e4 feat: Update the Czech translation (#8133)
* Update the Czech translation of `addPeople`

* Update the Czech translation of `calendarSync`

* Update the Czech translation of `chat`

* Add the Czech translation of `chromeExtensionBanner`

* Update the Czech translation of `connectingOverlay` and `connection`

* Update the Czech translation of `connectionindicator`

* Update the Czech translation of `deepLinking`

* Update various strings in the Czech translation

* Update various strings in the Czech translation

* Fix a trailing comma that broke JSON

* Sort keys in main-cs.json to deduplicate the translation and make diffs from main.json more readable

* Add several missing strings in the Czech translation

* Add several missing strings in the Czech translation, mainly lobby mode

* Add several missing strings in the Czech translation, mainly `prejoin`

* Add the missing Czech translation of `recording` and `security`

* Update various strings in the Czech translation

* Add the missing Czech translation of `accessibilityLabel`

* Add the missing Czech translation of `toolbar`

* Update various strings in the Czech translation

* Update various strings in the Czech translation

* Various edits of the Czech translation and a spell check

* Add missing language names in the Czech translation
2020-12-11 06:43:37 -06:00
Jaya Allamsetty
26dbc9a78b fix: Fixes VP9 support on Chrome.
chore(deps) lib-jitsi-meet@latest
2020-12-10 15:01:25 -05:00
Hristo Terezov
79e517ed65 feat(analytics): Add tenant. 2020-12-10 13:57:13 -06:00
Avram Tudor
148234ea50 Merge pull request #8230 from jitsi/tavram/revert-fixroom
Revert "fix(external_api) replace special chars in roomName before co…
2020-12-10 14:59:52 +02:00
Tudor-Ovidiu Avram
b23f4b02ea Revert "fix(external_api) replace special chars in roomName before constructing URL"
This reverts commit 6f90458ff1.
2020-12-10 14:51:51 +02:00
damencho
e9200bab09 fix: Fixes detecting websocket disconnect by using xmpp pings. 2020-12-09 15:19:39 -06:00
Дамян Минков
97f47998ba feat: Exposes a method for checking is remote track received and played/testing. (#8186)
* feat: Exposes a method for checking is remote track received and played.

Used for some tests in torture.

* squash: Drop not matching string.

Duplicate translation key with not matching content.

* squash: Moves torture specific functions to features/base/testing.

Listens for media events from the video tag of the large video and stores them in redux.

* squash: Fix comments.

* feat: Listens for media events from the video tag of the remote videos and stores them in redux.

* squash: Fix undefined videoTrack if between switches.
2020-12-08 08:01:16 -06:00
Jaya Allamsetty
0019284b10 feat: Add option to force pc to use turn relay candidates.
Helps with testing turn relay cases.
2020-12-07 20:17:26 -05:00
Hristo Terezov
5cae5985c0 feat(ConferenceTimer): Add config option to hide. 2020-12-03 17:00:33 -06:00
bgrozev
d77c5ccb7d doc: Add docs for enableLipSync. (#8195)
* doc: Add docs for enableLipSync.
2020-12-03 14:10:30 -06:00
bgrozev
96af156465 Remove conference-wide RTX/REMB/TCC/opus-red options. (#8194)
* doc: Updates the docs for REMB, TCC, opus-red.
2020-12-03 14:10:17 -06:00
רטו
09aa486ff1 fix(lang) fix a few typos in Italian translation 2020-12-03 16:13:55 +01:00
bgrozev
0f2be8c642 fix(config) remove openBridgeChannel 2020-12-03 16:12:47 +01:00
Jaya Allamsetty
65562d1ef4 fix(tracks): Do not add a second audio track. 2020-12-02 14:02:04 -05:00
bgrozev
9535f84775 cleanup: Remove the startBitrate option. (#8193) 2020-12-01 14:19:17 -06:00
Boris Grozev
6c477cad9b cleanup: Remove obsolete config option. 2020-12-01 12:12:45 -06:00
Boris Grozev
2b6c7a51a3 cleanup: Remove unused code. 2020-12-01 08:32:26 -06:00
Boris Grozev
42d1389338 feat: Remove the min-participants config. 2020-12-01 08:32:01 -06:00
רטו
d74f93209c fix(lang) typo 2020-12-01 13:56:46 +01:00
Boris Grozev
6f61077a65 ref: Remove unused option from whitelist. 2020-12-01 06:09:20 -06:00
Saúl Ibarra Corretgé
997c3f75b5 chore(rn) raise SDK and app versions 2020-11-27 15:24:26 +01:00
Saúl Ibarra Corretgé
baa39896f1 fix(android) set stream type hardware buttons should control
Ref:
https://developer.android.com/reference/android/app/Activity#setVolumeControlStream(int)
2020-11-26 16:30:01 +01:00
Saúl Ibarra Corretgé
3725f698e4 fix(android) reset audio route after audio focus was lost
Looks like audio devices must be re-set after focus was lost and regained.
Otherwise some devices (tested on a Samsung Galaxy S9) are in a weird state
where the second microphone is not used when speakerphone is on.
2020-11-26 15:33:36 +01:00
Saúl Ibarra Corretgé
67002c903a fix(android) use modern API for requesting audio focus 2020-11-26 15:33:36 +01:00
chipechop
1b15820f01 fix(lang) update Italian translation 2020-11-26 13:39:44 +01:00
Titus-Andrei Moldovan
4cced3af07 fix(android) disables the RNWebViewFileProvider 2020-11-26 11:24:43 +01:00
Mihai-Andrei Uscat
a8db3c1b28 chore(popups): Move popup configs to electron-utils 2020-11-26 12:13:50 +02:00
Jaya Allamsetty
39cf8854af fix(TPC): Do not scale down desktop track in p2p/non-simulcast cases.
chore(deps) lib-jitsi-meet@latest
2020-11-25 17:13:13 -05:00
Saúl Ibarra Corretgé
57f3e8a3e8 fix(deps) update logger 2020-11-25 16:48:58 +01:00
Saúl Ibarra Corretgé
f6fa903f8f feat(rn) switch to XCFramework and WebRTC M87 2020-11-25 16:39:26 +01:00
Hristo Terezov
3796db20ea fix(connection-status): action 2020-11-24 16:03:18 -05:00
Saúl Ibarra Corretgé
911df4b18a fix(avatar) revert back to defaulting to Gravatar
While the base URL remains configurable, this patch reverts back to using
Gravatar.

We noticed high latency with libravatar and contacted them. They are in the
process of migrarting to a better infrastructure (it's a single personal server
at the moment) so we'll re-evaluate once that has happened.

As for why not leave the default and change it on the meet.jit.si installation,
we don't want to kill their server :-)
2020-11-24 11:43:26 +01:00
George Politis
1041cd8055 feat: Makes it possible to hide the "Save Logs" link. (#8143)
As per @fremzy, the "Save Logs" feature generates a json
file with a bevy of technical information about the
meeting. This log contains the server name, server IP
address, participant's IP addresses (only in p2p sessions)
e.t.c. While this may be a useful feature for the
admin-like 'moderator', it creates unnecessary exposure
when made readily available to all users in the meeting.

This commit fixes #8036 by a config.js option to enable
the link (disabled by default), thus giving the owner of
the deployment the choice of enabling it or not.
2020-11-24 10:49:10 +01:00
Andrei Bora
898eca86d5 Make jwt accept boolean values for features 2020-11-23 11:34:34 -06:00
Oskars G
e0d41a30ef feat: Include "Latvian" in the languages list (#8129) 2020-11-21 09:57:56 -06:00
Jaya Allamsetty
d6ab0a72a1 fix(lastN): select screenshare endpoint always when auto pinning.
When trying to auto pin screenshare, always select the endpoint even though it happens to be the large video participant in redux. The auto pin screenshare logic kicks in after the track is added.  If the screenshare endpoint is not among the forwarded endpoints from the bridge, it needs to be selected again.
2020-11-20 10:29:12 -05:00
Jaya Allamsetty
fc694641dc fix(lastN): Do not override channelLastN value.
If limitLastN values are specified and channelLastN < limitLastN, configure channelLastN on the conference.
2020-11-20 10:29:12 -05:00
damencho
1ee7e81918 fix: Fixes 404 page link when base is used. 2020-11-19 10:49:03 -06:00
Saúl Ibarra Corretgé
a7de8be0aa feat(avatar) add ability to customize Gravatar base URL
Also, default to libravatar.

Closes: https://github.com/jitsi/jitsi-meet/issues/4927
2020-11-18 00:05:49 +01:00
Jaya Allamsetty
696ec36c8c fix(UI): Add method for returning the video type of remote participants.
This is needed for the torture clients to determine the video type for the remote participants when testing desktop share.
2020-11-17 12:49:36 -06:00
Avram Tudor
76c9d96361 Merge pull request #8110 from jitsi/tavram/fix-double-slash
fix(jaas) replace only the first slash in a pathname
2020-11-16 11:26:09 +02:00
Tudor-Ovidiu Avram
b889bd5664 fix(jaas) replace only the first slash in a pathname 2020-11-16 11:01:31 +02:00
damencho
d97f46c163 feat: Skips the default tile view when jibri is loading.
Follows me and switching to tile view, still works.
2020-11-13 14:48:09 -06:00
Jaya Allamsetty
5510138944 fix(screenshare): do not reconfigure encodings for simulcast SS
chore(deps) lib-jitsi-meet@latest
2020-11-13 13:45:36 -05:00
Saúl Ibarra Corretgé
29fa4c935e fix(chat) stop using nicknames
We stopped providing a way to set them, so don't render them either.

Also cleanup some leftover config options.
2020-11-13 17:40:57 +01:00
damencho
7de1e6d89e Updates kick, fixes it after 4b8aae90. 2020-11-11 13:18:13 -06:00
Andrei Bora
c4ef7d8601 Fix get subdomain function 2020-11-11 08:37:35 -06:00
Mihai-Andrei Uscat
9379bb3c5b fix(Toolbox) Maintain overflow button visible at all times
* fix(Toolbox) Maintain overflow button visible at all times

* Make changes only on desktop browser
2020-11-11 16:11:51 +02:00
Vlad Piersec
101a40a8da fix(welcome_page): Fix background image url path 2020-11-11 15:37:16 +02:00
Jaya Allamsetty
36871fa37e fix(safari): Ensure simulcast stream resolutions don't change.
Safari 14.1 has a bug where it returns 720p for every simulcast stream when RTCRtpSender.getParameters is called even though the stream resolutions are different.
By using the encodings config used when source was added, on every RTCRtpSender.setParameters call, we ensure that simulcast stream resolutions don't change.
chore(deps) lib-jitsi-meet@latest
2020-11-11 07:55:58 -05:00
Vlad Piersec
c09ed4c8ef fix(welcome_page): Add max width to welcome card 2020-11-11 14:11:08 +02:00
Vlad Piersec
08dce76763 fix(vpaas): Make user media permission message more generic 2020-11-11 13:24:02 +02:00
Prime9999
d03173e827 fix(lang) update Japanese translations 2020-11-11 09:42:22 +01:00
Дамян Минков
12c835dd91 feat: Drops filmStripOnly mode. (#8074)
* feat: Drops filmStripOnly mode.

* squash: Let's make lint happy again.

* squash: Drop some css.
2020-11-10 16:21:07 -06:00
damencho
f6127d45e9 fix: Fix module allowners and moderated rooms. 2020-11-10 10:43:29 -06:00
Saúl Ibarra Corretgé
9219e80a2a fix(password) set input type to "password"
This will make browsers not cache results in cleartext.

Co-authored-by: Tim Dittler <t.dittler@heinlein-support.de>
2020-11-10 17:05:20 +01:00
tmoldovan8x8
71fb5aef6c feat(rn) add mute everyone / (else) capabilities 2020-11-10 15:49:38 +01:00
Vlad Piersec
721848da3f fix(welcome_page): Update header to latest design & use generic key name 2020-11-10 16:43:52 +02:00
Saúl Ibarra Corretgé
ad496ac245 feat(external_api) drop support for noSSL option
Bwrosers have not allowerd WebRTC on non-secure origins for a very long time
now.
2020-11-10 15:09:23 +01:00
Saúl Ibarra Corretgé
e271ec2e13 chore(deps) lib-jitsi-meet@latest 2020-11-10 15:09:09 +01:00
GreatMedivack
c601acd6a8 fix(lang) update Russian translation 2020-11-10 11:02:21 +01:00
Erik Demaine
58d38ca714 fix(build) fix webpack-dev-server on Windows
Allow path separator of \ in addition to / in jQuery's path name.
2020-11-10 11:01:00 +01:00
Steffen Kolmer
6f90458ff1 fix(external_api) replace special chars in roomName before constructing URL
Fixes: https://github.com/jitsi/jitsi-meet/issues/7900
2020-11-10 11:00:12 +01:00
chipechop
d08f3e1ab2 fix(lang) update Italian translation 2020-11-10 10:53:58 +01:00
chipechop
ce1a964d0f fix(lang) update Italian translation 2020-11-10 10:53:09 +01:00
Avram Tudor
48d0616ebf Merge pull request #8003 from jitsi/tavram/invite-url
fix(vpaas) fix invite url flicker for jaas users
2020-11-10 11:52:16 +02:00
sellth
af82c69bbb fix(lang) update German translation 2020-11-10 10:50:08 +01:00
Mejans
892e508b48 fix(lang) update for Occitan 2020-11-10 10:49:17 +01:00
gabrc52
b7b5f87e2b fix(lang) improve Spanish translations 2020-11-10 10:47:13 +01:00
Ottavio Campana
ec16774dd4 fix(lang) fix rendering accented characters in Italian
Part of main-it.json uses characters like è, but some places still uses the &egrave; equivalent. Those character are not correctly rendered in the browser, therefore they are switched to their counterparts, as it was already done for other texts.
2020-11-10 10:42:08 +01:00
Saúl Ibarra Corretgé
7682e49787 feat(BrowserCapabilities) drop supportsVideo
It has been `true` for a very long time.
2020-11-10 10:33:00 +01:00
Jaya Allamsetty
1e07385ac0 ref(presenter): refactor the desktop resize logic for presenter. 2020-11-09 11:07:01 -05:00
Vlad Piersec
68d97f6d9d fix(welcome_page): Fix mobile version
* Fix layout
* Change background color & show image
2020-11-09 14:23:32 +02:00
Emil Ivov
da7383f89c Merge pull request #8053 from jitsi/fix-calendar-svg
fix(CalendarList): calendar.svg path.
2020-11-08 09:13:08 -06:00
Hristo Terezov
b8444ff1bf fix(CalendarList): calendar.svg path. 2020-11-08 09:07:53 -06:00
Jaya Allamsetty
3381cf4422 fix(screenshare): Fixes for the blurry desktop share issues.
Do not resize the desktop share to 720p by default when the desktop track resolution is higher than 720p. This is causing bluriness when presenter is turned on.
Remove the 'detail' contentHint setting for the desktop+presenter canvas stream as it forcing chrome to send only 5 fps stream for high resolution desktop tracks.
Move the desktop resizing logic behind a config.js option - videoQuality.resizeDesktopForPresenter.
2020-11-06 17:04:00 -05:00
damencho
895c92217a fix: Optimizes hot paths in prosody modules, string comparisons. 2020-11-06 13:33:14 -06:00
damencho
0934fffa25 feat: Drop enableUserRolesBasedOnToken and isGuest. 2020-11-06 08:12:59 -06:00
damencho
20ce38bd4c feat: Show cc button for ongoing transcribed meetings for guests 2020-11-06 08:12:59 -06:00
damencho
c4ba97e87c feat: Drop lockRoomGuestEnabled. 2020-11-06 08:12:59 -06:00
damencho
4b8aae90e0 feat: Drop HIDE_KICK_BUTTON_FOR_GUESTS setting.
The main config contains disableRemoteMute and remoteVideoMenu: { disableKick: true} options, which can be used.
2020-11-06 08:12:59 -06:00
damencho
c2539bf615 feat: Drop buttons tooltips specific to guests. 2020-11-06 08:12:59 -06:00
damencho
4fdd4b66f7 fix: Hide copy password if it is not available. Fixes #7783 2020-11-06 08:12:59 -06:00
damencho
9fa29d7353 feat: Profile tab does not depend on isGuest.
Introduced a config property to disable profile.
2020-11-06 08:12:59 -06:00
damencho
c14f639639 feat: Drops SHOW_JITSI_WATERMARK_FOR_GUESTS and SHOW_WATERMARK_FOR_GUESTS. 2020-11-06 08:12:59 -06:00
damencho
c007477ee9 fix: Show livestream button only for moderators. 2020-11-06 08:12:59 -06:00
Andrei Bora
50997ae6ac Stringify boolean values from jwt user context 2020-11-06 06:15:45 -06:00
Vlad Piersec
f8a41aea9c feat(welcome_page): Redesign welcome page 2020-11-06 13:50:30 +02:00
Avram Tudor
88c02fb658 Merge pull request #8039 from jitsi/tavram/fix-double-slash
fix(jaas) fix double slash for branded invite urls
2020-11-05 16:04:59 +02:00
Tudor-Ovidiu Avram
0f64c66f91 fix(jaas) fix double slash for branded invite urls 2020-11-05 15:43:53 +02:00
Дамян Минков
9f65ae52f1 fix: Prosody modules - drop unused and duplicate code and drop chatty debug statements (#8027)
* chore: Updates mod_smacks.lua version to latest.

https://hg.prosody.im/prosody-modules/file/db75772afb28/mod_smacks/mod_smacks.lua

* Drop unused modules.

* Update docs.

* Move utility functions away from domain mapper.

* Remove some chatty debug log messages.

* Drops not needed patch for mod_websocket.
2020-11-04 08:25:03 -06:00
Vlad Piersec
a242e86b23 chore(deps) amplitude 7.3.1 2020-11-04 16:18:06 +02:00
Saúl Ibarra Corretgé
4211db0893 fix(rn, screen-sharing) don't render own screen-share in large view 2020-11-04 14:45:16 +01:00
Titus-Andrei Moldovan
9a35026d6a feat(android) add screen-sharing support
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
Co-authored-by: zycwind <391321232@qq.com>
2020-11-04 14:45:16 +01:00
slauth
9742e90bb5 allow wildcard in token issuer verification 2020-11-03 10:45:47 -06:00
Saúl Ibarra Corretgé
2a01d3550c fix(conference) remove no longer needed code
There is no need for setting the availability of desktop sharing anymore. It can
now be detected on the spot.

The reson for the previous code was that way back when browser extensions were
needed, it was possible to start a conference without desktopo sharing support
and get it afterwards. This is no longer the case.
2020-11-03 16:15:01 +01:00
rugk
efce5a831b feat(misc) automatically assign feature-request tag to issues
…if they are reported as a feature request, of course.
2020-11-03 09:41:20 +01:00
damencho
e0117e03e8 feat: Reduce pings and adds xmpp ping config. 2020-11-02 16:57:45 -06:00
Hristo Terezov
1648e4b407 ref(thumbnail): mutedWhileDisconnected -> redux 2020-11-02 13:49:36 -06:00
Vlad Piersec
b02136d013 feat(prejoin): Add name from jwt to prejoin screen 2020-10-30 13:09:18 -05:00
damencho
734631a7a4 fix: Avoids storing lobby room instance in the main room object.
We sometimes see "error   Top-level error, please report:
                  /usr/lib/prosody/util/serialization.lua:38: Can't serialize table: table has multiple references".
This also slows down restarting prosody.
2020-10-30 12:52:08 -05:00
Vlad Piersec
9fbb35b6e1 feat(vpaas): Track vpaas conference join 2020-10-30 09:26:21 +02:00
Hristo Terezov
f45af351d8 ref(thumbnail): use connectionStatus from redux. 2020-10-29 12:05:40 -05:00
JB Joatton
1f4cd22875 fix(lang): update fr translation 2020-10-29 16:27:47 +01:00
Adão Santos
53cc724b3b fix(lang) update ptBR translation 2020-10-29 13:56:06 +01:00
Tudor-Ovidiu Avram
8f1cb7ded2 fix(vpaas) fix invite url flicker for jaas users 2020-10-29 14:20:46 +02:00
Hristo Terezov
b9ccc3ad8c fix(StatusIndicators): Improve isScreenSharing check
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2020-10-27 13:19:52 -05:00
Hristo Terezov
68a0bdce2c ref(StatusIndicators): isScreenSharing -> redux. 2020-10-27 13:19:52 -05:00
Hristo Terezov
b71d92a139 ref(StatusIndicators): Use audio muted from redux. 2020-10-27 10:16:16 -05:00
Jaya Allamsetty
30fc04ba61 fix(logging): Add more details to onerror and onunhandledrejection errors. 2020-10-27 10:17:59 -04:00
Jaya Allamsetty
d2046c2c8f fix(screenshare): bring back 'x-google-flag:conference' flag in remote description for SS.
chore(deps) lib-jitsi-meet@latest
2020-10-26 18:02:00 -04:00
Hristo Terezov
35b5f6df06 s/isLocalVideoTrackMuted/isLocalCameraTrackMuted/ 2020-10-26 14:03:40 -05:00
Hristo Terezov
ca2343c31a ref(StatusIndicators): Use video muted from redux. 2020-10-26 11:03:31 -05:00
Jaya Allamsetty
3657c19e60 fix(video-quality): set lastN to 1 when screenshare is added to call in audio-only mode.
This fixes an issue where lastN is not bumped to 1 on an audio-only client when a screenshare source is added to the call.
2020-10-26 10:28:00 -04:00
Hristo Terezov
007183c151 fix(deviceChange):Dont create video track if muted 2020-10-23 13:04:02 -05:00
Hristo Terezov
9c10ac3028 fix(conference): start muted values on initial GUM
Take into account the start muted values stored in local storage.
2020-10-23 13:04:02 -05:00
Jaya Allamsetty
4b429112f2 fix(iFrame): capturScreenshot - check if the remote participant has a track attached.
Participants that join video muted do not have video tracks attached. Fixes https://github.com/jitsi/jitsi-meet/issues/7942.
2020-10-22 17:22:54 -04:00
Saúl Ibarra Corretgé
d067c4e731 fix(pwa) move manifest to the root
It must be served from the same origin, so we need to bypass the CDN we use for
meet.jit.si. See the code comments for the rationale on the workaround.
2020-10-22 16:17:18 +02:00
Saúl Ibarra Corretgé
07d8611988 fix(pwa) remove no longer used file 2020-10-22 16:17:18 +02:00
Jaya Allamsetty
b0d55f9450 fix(xmpp): Update previd value when trying to resume connection.
lib-jitsi-meet@latest
2020-10-22 09:47:36 -04:00
Saúl Ibarra Corretgé
5f2ee6d951 fix(android) fix runtime WebRTC issue
https://github.com/jitsi/jitsi-meet/issues/7911#issuecomment-714323255
2020-10-22 12:04:41 +02:00
Vlad Piersec
ddea7d0294 fix(prejoin): Fix moving content when device status bar is toggled 2020-10-22 09:28:26 +03:00
Saúl Ibarra Corretgé
348c6416e5 fix(pwa) fix PWA worker script origin
Looks like the base it's still applied, so use a full URL.
2020-10-21 15:15:17 +02:00
Saúl Ibarra Corretgé
ad265d5815 fix(pwa) fix auto-generated TWA icons 2020-10-21 10:49:50 +02:00
Saúl Ibarra Corretgé
d5b2da02c1 fix(pwa) fix loading the service worker
We typically use a base URL for static assets using a CDN so loading the worker
from there won't work since it's a different origin. Using a URL relative to the
origin of the page will make it be loaded from the right place.
2020-10-21 10:49:50 +02:00
Jaya Allamsetty
fbfaed07b2 feat(iFrame): Add recording options for RTMP streaming.
Add methods for start/stop recording in addition to the commands that we already have.
2020-10-20 16:15:52 -04:00
emrah
da33d8a033 fix: speakerstats_component, attempt to index (a nil value) 2020-10-20 07:48:23 -05:00
Saúl Ibarra Corretgé
830817d7b4 chore(deps) run npm audit fix 2020-10-20 13:59:03 +02:00
Avram Tudor
8c67f1fdf3 Merge pull request #7938 from jitsi/tavram/twa
Tavram/twa
2020-10-20 12:58:36 +03:00
Saúl Ibarra Corretgé
b57da04553 feat(pwa) update TWA Android project 2020-10-20 11:37:32 +02:00
Tudor-Ovidiu Avram
b428c3bca8 feat(pwa) do not display chrome extension banner for TWA 2020-10-20 12:26:05 +03:00
Tudor-Ovidiu Avram
96c34b7774 chore(deps) lib-jitsi-meet@latest 2020-10-20 12:08:59 +03:00
Saúl Ibarra Corretgé
f2bbc874b3 feat(pwa) add fastlane integration for building TWA APK 2020-10-20 11:03:37 +02:00
Saúl Ibarra Corretgé
b18398f016 feat(pwa) update mask icon
Make it a 512 square and specify its purpose as just "maskable" since this can't
go anywhere.
2020-10-20 11:03:37 +02:00
Hristo Terezov
a6e58c3101 fix(thumbnail): cleanup unused hover properties. 2020-10-16 16:33:26 -05:00
Saúl Ibarra Corretgé
c5f6df5210 fix(avatar) remove participant's "avatarID"
Through several avatar work iterations it's no longer used.
2020-10-16 14:44:10 +02:00
Tudor-Ovidiu Avram
e67c08d837 fix(pwa) move logic for registering pwa worker 2020-10-16 14:43:40 +02:00
Tudor-Ovidiu Avram
d854b2cd3d fix(pwa) remove window.load event handler for pwa registrator 2020-10-16 12:10:18 +02:00
paweldomas
ab5c8d49c3 fix(flow): ignore contentHint
I don't know how to modify built-in MediaStreamTrack type, so ignore the error.
2020-10-15 15:10:40 -04:00
paweldomas
820d9b2ba8 feat(presenter): apply 'text' contentHint
...so that the text is more readable in the presenter mode. Chrome by
default uses 'detail' for screen sharing. I went with the 'text' here,
because the docs[1] say "may take advantage of encoder tools that
optimize for text rendering." - whether that's good specifically for
the presenter mode I don't know. It looked good for me when tested
on Chrome.

https://www.w3.org/TR/mst-content-hint/
2020-10-15 15:10:40 -04:00
Tudor-Ovidiu Avram
e4c1046d7c fix(pwa) bypass loading in electron. ensure same origin with registrator 2020-10-15 18:54:12 +02:00
Jaya Allamsetty
223187c640 fix(UI): Do not re-compute the container width when chat window is closed.
Since the external API now sets preferredWidth/preferredHeight for resizing the large video, we don't need to add chat width to the computed window width when the chat window is closed.
Fixes https://github.com/jitsi/jitsi-meet/issues/7889
2020-10-15 10:00:28 -04:00
Saúl Ibarra Corretgé
35e8821679 chore(deps) update Olm to 3.2.1 2020-10-15 10:38:39 +02:00
Tudor-Ovidiu Avram
3125345793 fix(pwa) improve upon pwa specs 2020-10-15 10:38:23 +02:00
Aaron van Meerten
5e6c4d67ed Merge pull request #7904 from saghul/preload-avatars-refer
fix(avatars) refactor preloading
2020-10-14 15:22:17 -05:00
Saúl Ibarra Corretgé
a3fb996ff0 fix(avatars) refactor preloading
Use fetch(), which gives us better control over headers.
2020-10-14 21:58:28 +02:00
Saúl Ibarra Corretgé
65a9de346f fix(rn) use a RN-friendly URL polyfill
The previous one no llonger works out of the box with RN.
2020-10-14 21:29:01 +02:00
Saúl Ibarra Corretgé
036d810d46 fix(rejoin) fix adding track parameters to rejoin URL
The URL polyfill we were using didn't support taking a URL object in the
constructor, the updated one does.
2020-10-14 18:05:19 +02:00
Saúl Ibarra Corretgé
b5f9b575ca chore(git) update gitignore 2020-10-14 16:32:34 +02:00
Saúl Ibarra Corretgé
a7fa9d8a97 feat(pwa) update generated Android project 2020-10-14 16:32:34 +02:00
Saúl Ibarra Corretgé
4762d5a153 feat(pwa) move twa manifest to twa/ 2020-10-14 16:32:34 +02:00
Saúl Ibarra Corretgé
e8c2c89343 feat(pwa) update twa manifest with new (old) colors and manifest path 2020-10-14 16:32:34 +02:00
Saúl Ibarra Corretgé
d77a7cac3a feat(pwa) use current icons 2020-10-14 16:32:34 +02:00
Saúl Ibarra Corretgé
6030c32272 feat(pwa) add TWA generated files 2020-10-14 16:32:34 +02:00
tmoldovan8x8
8e19597e38 feat(mobile) add splash screen 2020-10-14 11:26:47 +02:00
Tudor-Ovidiu Avram
bf6a1540df fix(prejoin) guard case for locationUrl being falsy in prejoin screen 2020-10-14 12:23:59 +03:00
Saúl Ibarra Corretgé
9434d3c349 fix(deps) update react-native to fix iOS 14 icons
This update doesn't touch thousands of lines of package-lock which caused a
runtime breakage on both platforms.
2020-10-14 10:50:45 +02:00
Saúl Ibarra Corretgé
b891a7526d Revert "fix(ios) fix not rendering images on iOS 14"
This reverts commit cd68c72338.
2020-10-14 10:50:45 +02:00
Hristo Terezov
5bf20517e7 feat(prejoin): handle disabled precall test. 2020-10-13 15:52:43 -05:00
Tudor-Ovidiu Avram
0d7a730497 feat(pwa) add pwa specifics 2020-10-13 13:40:31 +02:00
Vlad Piersec
59caa0cf42 fix(vpaas): Count endpoint only when there are 2 or more participants 2020-10-12 16:19:09 +03:00
Saúl Ibarra Corretgé
bdda8c56c7 fix(VideoLayout) make thumbnail iteration more resilient
If a failure occurs while we are still setting up the UI it's possible the local
thumbnail is still null, and none of the code assumes it may be null, so skip
it.
2020-10-09 19:30:20 +02:00
Saúl Ibarra Corretgé
c239ba71e6 chore(android) update gradle plugin to version 4.0.2 2020-10-09 12:53:27 +02:00
Tudor-Ovidiu Avram
1005f8f498 fix(prejoin) allow libs loaded in prejoin.html to be cached 2020-10-09 12:46:51 +02:00
Saúl Ibarra Corretgé
f6e2bd1249 fix(build) increase external_api bundle size
We are off my 1KB oh well.
2020-10-09 12:34:56 +02:00
Saúl Ibarra Corretgé
cd68c72338 fix(ios) fix not rendering images on iOS 14
Fixed by patching react-native:
e7ee500660

(backport from upstream)
2020-10-09 12:34:56 +02:00
Hristo Terezov
1740aaf973 fix(video-quality-dialog): Initial value.
Fixes an issue when the video quality dialog is opened for first time
and config.videoQuality.persist is true there isn't any selected option.
2020-10-08 10:32:10 -05:00
Tudor-Ovidiu Avram
a270e4300a fix(native) add missing function 2020-10-08 13:10:45 +02:00
Mihai Uscat
5e2ee3bdcd fix: Show focus indicator only when navigating via keyboard 2020-10-08 10:41:26 +02:00
Saúl Ibarra Corretgé
bdd2845917 deps,misc: fix package-lock conflicts 2020-10-08 10:17:53 +02:00
Saúl Ibarra Corretgé
f9888e5dbb rn,remote-video-menu: make UI consistent with other menus 2020-10-08 10:17:53 +02:00
Saúl Ibarra Corretgé
44d7828e9c rn,overflow-menu: improve drag icon 2020-10-08 10:17:53 +02:00
Saúl Ibarra Corretgé
82b14ba7f1 deps: update react-native-svg
Watch out when updating beyond this version:
https://github.com/react-native-community/react-native-svg/issues/1354
2020-10-08 10:17:53 +02:00
Saúl Ibarra Corretgé
63fe1de789 rn,recent-list: replace swipe options with long-press sheet
This change serves 2 purposes:

- (Hopefully) make the recent list entry options easier to discover
- Remove the (now unmaintained) swipeout dependency
2020-10-08 10:17:53 +02:00
Jaya Allamsetty
39af6f5943 fix(video-quality): Add the ability to request Ultra HD resolutions
Change the preferredVideoQuality and maxReceiverVideoQuality values to Ultra HD resolutions. The requested resolution can be as high as 4K to facilitate VPaaS customers to request 4K. The sender video resolution will always max out at the value specified in the video constraints from config.js settings.
2020-10-07 15:07:14 -04:00
Anand Parshuramka
f01869c21c Adding the flags to enable/disable Kick out option in RemoteVideoMenu 2020-10-07 10:54:13 -05:00
Tudor-Ovidiu Avram
6d2f8ae37d feat(prejoin) show connection status in exported prejoin screen 2020-10-07 17:23:49 +02:00
Saúl Ibarra Corretgé
35bea1a1d0 fix(misc) update update-ljm script commit message 2020-10-07 16:31:47 +02:00
Saúl Ibarra Corretgé
afa4306ae8 chore(deps) lib-jitsi-meet@latest 2020-10-07 16:31:47 +02:00
Saúl Ibarra Corretgé
1d9daa8da7 fix(config) drop useStunTurn
Always attempt to discover the configured STUN/TURN servers.
2020-10-07 16:31:47 +02:00
Tudor-Ovidiu Avram
478f1a731e feat(prejoin) improve ux 2020-10-07 14:53:49 +02:00
Titus-Andrei Moldovan
9f9e192c3c fix(android) - separates the invocation of the gradle tasks. It was noticed on some configurations that the publish task was executed before assembleRelease finished 2020-10-07 14:01:26 +02:00
Titus-Andrei Moldovan
943996e5b6 fix(android) - adds the import for the VersionName, since on some configurations it is not automatically imported 2020-10-07 14:01:26 +02:00
Hristo Terezov
bfde13cb15 chore(lib-jitsi-meet): Update. 2020-10-06 12:58:27 -05:00
George Politis
5939820271 fix: Makes the code more defensive to prevent an error. (#7837) 2020-10-05 16:56:46 +02:00
George Politis
b5310573fc feat: Adds more debug information in the GSM bars popover (#7627) 2020-10-02 15:20:24 +02:00
Jaya Allamsetty
aa488cb75c deps: lib-jitsi-meet@latest
Disable RTX on FF
2020-10-01 18:53:12 -04:00
Jaya Allamsetty
de8e62ac51 deps: lib-jitsi-meet@latest 2020-10-01 15:03:00 -04:00
damencho
f6d375f565 tests: Do not close lobby notifications when testing. 2020-10-01 10:44:01 -05:00
Titus-Andrei Moldovan
c54fed78c8 fix(android) excludes hermes related libs from the apk 2020-10-01 15:58:28 +02:00
Saúl Ibarra Corretgé
3d7ea52416 fix(e2ee) handle Olm initialization error
If the WASM code could not be loaded, fail to initialize if and remove it from
globals so the E2EE option becomes unavailable, since it will be non-functional.
2020-10-01 15:14:00 +02:00
Dhruv Awasthi
0c4d649459 chore(typo) fix 2020-09-30 11:54:27 +02:00
ondrej-zary
af416ad487 fix(lang) update Slovak translation 2020-09-30 11:53:27 +02:00
Yasin İsa YILDIRIM
1cd6f2b4da fix(lang) update turkish translation 2020-09-30 11:52:31 +02:00
kormang
1fb37a0216 fix(lang) add basic support for serbian 2020-09-30 11:50:50 +02:00
Saúl Ibarra Corretgé
c261682a29 fix(rn,config) increase config load timeout to 10 seconds 2020-09-30 10:08:52 +02:00
Hristo Terezov
49548ba564 doc(app.js): fix typo.
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2020-09-29 17:58:17 -05:00
Hristo Terezov
dc6d3daef7 feat(external-local-storage): support 2020-09-29 17:58:17 -05:00
Saúl Ibarra Corretgé
014f3b615f fix(android) increase gradle JVM heap size 2020-09-29 17:35:35 +02:00
Jaya Allamsetty
25271d7eec fix(presenter): Do not change the video mute state on presenter mute.
This fixes the issue where the local preview appears muted when presenter camera is turned on and then off while screenshare is in progress.
2020-09-29 08:35:42 -04:00
Saúl Ibarra Corretgé
7ef4de9c1c chore(deps,android) bump leakcanary 2020-09-29 14:32:41 +02:00
Saúl Ibarra Corretgé
e6e088d197 fix(crashlytics) add missing dependency
Looks like the "Firebase Analytics" dependency is needed when migrating to the
new Firebase Crashlytics SDK. We are only interested in the "latest iversion
crash-free users" stat, which seems to require this. The documentartion is
somewhat confusing though.
2020-09-29 14:32:41 +02:00
Andrei Gavrilescu
0e034a686f deps: lib-jitsi-meet support rtcstats p2p meta 2020-09-29 15:18:23 +03:00
Saúl Ibarra Corretgé
d9f85c70f1 chore(deps,rn) react-native-webview@10.9.0 2020-09-29 14:16:36 +02:00
Titus-Andrei Moldovan
de8079cc98 fix(android) update Gradle and the plugin to the latest versions 2020-09-29 14:16:36 +02:00
Titus-Andrei Moldovan
2a9805f9b1 feat(android) revert to JSC as our JS engine
JSC wasn't the cause for the crash we were hunting after all. RN doesn't set
HErmes as the default, neither does Expo, so the jury is still out on Hermes,
and it looks like JSC is still the safest bet.

In addition, the way Hermes is packaged (as a standalone AARs, instead of a
local "Maven repo") complicates the SDK build and can make the resulting build
bloated.
2020-09-29 14:16:36 +02:00
Saúl Ibarra Corretgé
00ec0f03a6 chore(deps) run npm audit fix 2020-09-29 13:51:07 +02:00
Дамян Минков
91f636a813 debian: Don't break those still using ALPN multiplex (Fixes #7794) (#7796)
* fix: Don't break those still using ALPN multiplex (Fixes #7794)

* squash: Update doc/debian/jitsi-meet/jitsi-meet.conf

Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>

Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2020-09-29 06:17:42 -05:00
roms2000
fa4df19733 fix(lang) update French translation 2020-09-29 10:22:50 +02:00
DecaTec
1d17cc91e0 fix(lang) typo in German translation 2020-09-29 10:22:05 +02:00
Дамян Минков
93f4098dc0 feat: Enable bridge websockets by default for new installs (#7781)
* feat: Drops multiplexing support by default.

* fix: Fix purge of jitsi-meet-prosody.

Clean the accounts when there is a - in the domain name.
Removes the certificate so reinstall will not cause problems.

* feat: Enables bridge websockets by default.

* fix: External-ip conflicts with denied-peer-ip.

In cases where the bridge and coturn are on the same machine and the local address is any of the networks from denied-peer-ip, coturn is not using its public address to probe it and communication fails as the other address is deneid.

* squash: Fix a comment.
2020-09-25 13:15:58 -05:00
Saúl Ibarra Corretgé
11ae187ece fix(chat) prevent homograph attacks
Decode URLs using punycode when rendering, so when http://ebаy.com is sent
we render http://xn--eby-7cd.com/ instead.

Ref: https://github.com/tasti/react-linkify/issues/84
2020-09-25 12:46:29 +02:00
Jaya Allamsetty
0f9e01a7cf feat(iFrame): Add method for pinning a participant on stage view 2020-09-24 21:42:58 -04:00
Saúl Ibarra Corretgé
ddbd3f292a fix(analytics) clarify log line 2020-09-24 13:39:41 +02:00
Saúl Ibarra Corretgé
b153bf2fb8 fix(analytics) make handler loading more resilient
- Don't initialize handler's is their API key is not set
- Don't swallow exceptions when creating handlers
- Don't remove all handlers if an external one fails
- Dispose the analytics subsystem if no handlers are registered
2020-09-24 13:39:41 +02:00
Saúl Ibarra Corretgé
919be21912 fix(analytics) make sure rtcstats is not enabled on mobile 2020-09-24 13:39:41 +02:00
Saúl Ibarra Corretgé
1a339100ab fix(analytics) avoid Amplitude initialization failure on mobile 2020-09-24 13:39:41 +02:00
Tudor-Ovidiu Avram
ce4ef96941 fix(vpaas) hide embed meeting for vpaas users 2020-09-24 12:06:51 +02:00
Tudor-Ovidiu Avram
993ded9936 fix(vpaas) fix vpaas redirect 2020-09-24 12:06:28 +02:00
Jaya Allamsetty
a8b9ae2b12 fix(callstats): Use callStatsThreshold for % of users instead of conferences 2020-09-23 18:58:38 -04:00
paweldomas
812af33a4d fix(mediaDeviceHelper): fix typo in dispatch 2020-09-23 12:57:53 -04:00
paweldomas
7f17c2eceb fix(LargeVideoManager): large video resizing
Distinguish between preferred and calculated width/height
values.
2020-09-23 12:54:26 -04:00
Jaya Allamsetty
09124ad7e9 fix(iframe): Use largeVideo video element for screenshot.
Get the existing HTMLVideoElement for large video instead of creating a new video element for capturing the screenshot.
This should prevent the video player from getting displayed on mobile Safari.
2020-09-23 10:35:36 -04:00
Jaya Allamsetty
7a9a6855b7 fix(UI): Re-compute large-video width only once if the chat window is open.
Deduct the chat window width from large-video width only once if we keep toggling between stage view and grid view while the chat window is open.
2020-09-22 17:44:49 -04:00
Дамян Минков
8dcf04897a feat: Throttle out call attempts to the max number per minute (#7742)
* feat: Make possible to reload config for filter rayo iq.

* feat: Throttle out call attempts to the max number per minute

* squash: Updates comment about config
2020-09-22 10:53:43 -05:00
Saúl Ibarra Corretgé
69b7301b9d fix(build) reduce bundle size by about 700K
app.bundle.js before: 3851549 after: 4506493.

The culprit for the bloat was Olm. It feature-detects the environment in order
to pick a suitable random byte generator, and alas Webpack includes the None
crypto pollyfill. This is due to the existence of the "node" block in our
Webpack configuration file.

The solution is to provide empty modules to make bundling work, as we did
already for the fs module, since we know they are not used at runtime.
2020-09-22 10:59:55 +02:00
Jaya Allamsetty
794713b930 fix(iFrame): Make resizeLargeVideo only available on web 2020-09-21 19:54:45 -04:00
Jaya Allamsetty
89cd6e8e3e feat(stats): Add the ability to enable callStats for certain % of confs 2020-09-21 13:20:01 -04:00
Saúl Ibarra Corretgé
7a7937c072 fix(ios,version) versions must match 2020-09-18 21:02:51 +02:00
Saúl Ibarra Corretgé
4765ab9d63 chore(rn,version) bump app and sdk versions 2020-09-18 17:55:41 +02:00
Jaya Allamsetty
1d5decc14f feat(iFrame): Add a method for capturing screenshot of the large video (#7717) 2020-09-18 11:53:27 -04:00
Saúl Ibarra Corretgé
119b79fd84 fix(SmallVideo) screen-sharing indicator
The stream is attached before the video type change event is fired, so comparing
them is too late. Unconditionally update the screen-sharing indicator, and
perform the check for a change right there, to avoid re-renders.
2020-09-18 17:17:30 +02:00
Saúl Ibarra Corretgé
188771751d fix(config) remove unused options (#7723)
* fix(config) remove unused options

* Update configWhitelist.js
2020-09-18 08:55:09 -05:00
Vlad Piersec
d2ec0ea6f3 fix(branding): Fix dynamic logo display
* Display of the logo has been reworked (simplified).
* The logo will not be displayed if the call to `branding` endpoint fails.
* Add more docs.
2020-09-18 16:38:44 +03:00
Saúl Ibarra Corretgé
ed6e75b241 fix(ios) add local network usage description for iOS 14 2020-09-18 12:54:11 +02:00
Saúl Ibarra Corretgé
dedd3f4ef0 fix(config) remove no longer valid option 2020-09-18 12:31:55 +02:00
Jaya Allamsetty
bbb4fbd5f8 feat(iFrame): Add a method for resizing large video container from iFrame 2020-09-17 23:41:19 -04:00
Saúl Ibarra Corretgé
92235ae535 fix(android,calendar) avoid crash 2020-09-17 18:45:04 +02:00
Josh Brown
ebb1b8d76b fix(background-blur) refactor to improve performance 2020-09-17 18:25:06 +02:00
Saúl Ibarra Corretgé
42d559de93 deps: replace node-sass with sass
The former is no longer actively maintained.

Fixes: https://github.com/jitsi/jitsi-meet/issues/6427
2020-09-17 16:44:01 +02:00
Julian Vos
2838aefccc lang: fix Dutch dialog.kickTitle 2020-09-17 16:29:18 +02:00
Saúl Ibarra Corretgé
ca306f47b6 deps: react-native-background-timer@2.4.0
We hadn't updated in a while.
2020-09-17 13:15:04 +02:00
Saúl Ibarra Corretgé
56da400f19 ios: stop using react-native-background-timer
Ever since https://github.com/facebook/react-native/pull/23674 landed it has
been possible to run timers in the background, assuming your app is allowed to
run in the background already, as is our case. So, stop using the library on
iOS, which will avoid creatring needless backgound tasks.
2020-09-17 13:15:04 +02:00
Manuel Garcia
ab21e3cd5e fix(embed): remove legacy attribute from embed meeting code 2020-09-17 09:11:41 +02:00
damencho
2c026754ef fix: Fix ws reconnect piling up previd param. 2020-09-16 16:43:48 -05:00
Jaya Allamsetty
8dbe3e37b9 feat(iFrame): add a method for getting the participants info 2020-09-16 15:03:47 -04:00
Tudor-Ovidiu Avram
7f67f78db6 fix(embed) fix embed meeting code 2020-09-16 06:59:41 -05:00
Saúl Ibarra Corretgé
312949eef6 ios: update Crashlytics dependency 2020-09-15 21:22:50 +02:00
Saúl Ibarra Corretgé
41ea94c0c2 android: update AndroidX core library dependencies 2020-09-15 21:22:50 +02:00
Saúl Ibarra Corretgé
e70adef2ef android: update Crashlytics dependency 2020-09-15 21:22:50 +02:00
Saúl Ibarra Corretgé
57bbe3f75a android: fix crash when requesting permissions
The RN Permissions module calls this in a non-UI thread. What we observe is a
crash in ViewGroup.dispatchCancelPendingInputEvents, which is called on the
calling (ie, non-UI) thread. This doesn't look very safe, so try to avoid a
crash by pretending the permission was denied.
2020-09-15 16:17:46 +02:00
Tudor-Ovidiu Avram
e2731ce73e feat(loggin) forward logs to external api 2020-09-15 09:44:50 +02:00
yjhgull
d5dae945a8 lang: update Korean translation 2020-09-15 09:33:35 +02:00
Jaya Allamsetty
4d1dba937f feat(external_api): Add method for displaying participant on large video 2020-09-14 19:39:19 -04:00
Jaya Allamsetty
b6792db65f feat(external_api): Add cmd for selecting a user to be displayed in large video 2020-09-14 19:39:19 -04:00
Saúl Ibarra Corretgé
9815b633fc deps: lib-jitsi-meet@latest
Avoids CORS issues with the E2EE worker.
2020-09-11 16:13:12 +02:00
Joris Bodin
b4bf82429c lang: update French translation 2020-09-11 10:07:41 +02:00
Aaron van Meerten
53d485b397 Merge pull request #7679 from jitsi/mod-token-update
fix: Updates docs and verification to halt joining process.
2020-09-10 12:46:28 -05:00
damencho
0354dbe889 fix: Updates docs and verification to halt joining process.
When returning the error and showing to user not allowed screen we were not completely halting the prejoin operation when token verification fails on room join and the token is valid in general.
2020-09-10 10:07:30 -05:00
Saúl Ibarra Corretgé
7cafa205ee e2ee: stage 2
Adapt to E2EE changes in lib-jitsi-meet. Notably:

---
    e2ee: introduce per-participant randomly generated keys

    This the second stage in our E2EE journey.

    Instead of using a single pre-shared passphrase for deriving the key used for
    E2EE, we now establish a secure E2EE communication channel amongst peers.

    This channel is implemented using libolm, using XMPP groupchat or JVB channels
    as the transport.

    Once the secure E2EE channel has been established each participant will generate
    a random 32 byte key and exchange it over this channel.

    Keys are rotated (well, just re-created at the moment) when a participant joins
    or leaves.
---
2020-09-10 16:06:25 +02:00
Saúl Ibarra Corretgé
2b4f33bef8 e2ee: use a separate bundle for the worker 2020-09-10 16:06:25 +02:00
Selyan Slimane Amiri
31dee0bb68 lang: update kabyle translations 2020-09-10 10:30:09 +02:00
630 changed files with 32168 additions and 17380 deletions

View File

@@ -6,6 +6,8 @@ build/*
flow-typed/*
libs/*
react/features/stream-effects/blur/vendor/*
# ESLint will by default ignore its own configuration file. However, there does
# not seem to be a reason why we will want to risk being inconsistent with our
# remaining JavaScript source code.

View File

@@ -1,7 +1,9 @@
---
name: "Feature request"
about: Suggest an idea for this project
title: ''
labels: 'feature-request'
assignees: ''
---
<!--

7
.gitignore vendored
View File

@@ -69,6 +69,7 @@ buck-out/
*.framework
android/app/debug
android/app/release
ios/sdk/out
# precommit-hook
.jshintignore
@@ -85,3 +86,9 @@ ios/app/dropbox.key
ios/app/GoogleService-Info.plist
.vscode
# TWA
twa/*.apk
twa/*.aab
twa/assetlinks.json

View File

@@ -1,11 +0,0 @@
/**
* Notifies interested parties that hangup procedure will start.
*/
export const BEFORE_HANGUP = 'conference.before_hangup';
/**
* Notifies interested parties that desktop sharing enable/disable state is
* changed.
*/
export const DESKTOP_SHARING_ENABLED_CHANGED
= 'conference.desktop_sharing_enabled_changed';

View File

@@ -3,8 +3,11 @@ CLEANCSS = ./node_modules/.bin/cleancss
DEPLOY_DIR = libs
LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet/
LIBFLAC_DIR = node_modules/libflacjs/dist/min/
OLM_DIR = node_modules/olm
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist/
NODE_SASS = ./node_modules/.bin/node-sass
TFLITE_WASM = react/features/stream-effects/blur/vendor/tflite
MEET_MODELS_DIR = react/features/stream-effects/blur/vendor/models/
NODE_SASS = ./node_modules/.bin/sass
NPM = npm
OUTPUT_DIR = .
STYLES_BUNDLE = css/all.bundle.css
@@ -15,14 +18,17 @@ WEBPACK_DEV_SERVER = ./node_modules/.bin/webpack-dev-server
all: compile deploy clean
compile:
compile: compile-load-test
$(WEBPACK) -p
compile-load-test:
${NPM} install --prefix resources/load-test && ${NPM} run build --prefix resources/load-test
clean:
rm -fr $(BUILD_DIR)
.NOTPARALLEL:
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-tflite deploy-meet-models deploy-lib-jitsi-meet deploy-libflac deploy-olm deploy-css deploy-local
deploy-init:
rm -fr $(DEPLOY_DIR)
@@ -38,8 +44,6 @@ deploy-appbundle:
$(BUILD_DIR)/external_api.min.map \
$(BUILD_DIR)/flacEncodeWorker.min.js \
$(BUILD_DIR)/flacEncodeWorker.min.map \
$(BUILD_DIR)/device_selection_popup_bundle.min.js \
$(BUILD_DIR)/device_selection_popup_bundle.min.map \
$(BUILD_DIR)/dial_in_info_bundle.min.js \
$(BUILD_DIR)/dial_in_info_bundle.min.map \
$(BUILD_DIR)/alwaysontop.min.js \
@@ -59,6 +63,7 @@ deploy-lib-jitsi-meet:
cp \
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.min.js \
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.min.map \
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.e2ee-worker.js \
$(LIBJITSIMEET_DIR)/connection_optimization/external_connect.js \
$(LIBJITSIMEET_DIR)/modules/browser/capabilities.json \
$(DEPLOY_DIR)
@@ -69,11 +74,26 @@ deploy-libflac:
$(LIBFLAC_DIR)/libflac4-1.3.2.min.js.mem \
$(DEPLOY_DIR)
deploy-olm:
cp \
$(OLM_DIR)/olm.wasm \
$(DEPLOY_DIR)
deploy-rnnoise-binary:
cp \
$(RNNOISE_WASM_DIR)/rnnoise.wasm \
$(DEPLOY_DIR)
deploy-tflite:
cp \
$(TFLITE_WASM)/*.wasm \
$(DEPLOY_DIR)
deploy-meet-models:
cp \
$(MEET_MODELS_DIR)/*.tflite \
$(DEPLOY_DIR)
deploy-css:
$(NODE_SASS) $(STYLES_MAIN) $(STYLES_BUNDLE) && \
$(CLEANCSS) --skip-rebase $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
@@ -83,7 +103,7 @@ deploy-local:
([ ! -x deploy-local.sh ] || ./deploy-local.sh)
.NOTPARALLEL:
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-tflite deploy-meet-models deploy-lib-jitsi-meet deploy-libflac deploy-olm
$(WEBPACK_DEV_SERVER) --detect-circular-deps
source-package:

View File

@@ -6,6 +6,8 @@ The Jitsi Meet client runs in your browser, without installing anything else on
Jitsi Meet allows very efficient collaboration. Users can stream their desktop or only some windows. It also supports shared document editing with Etherpad.
**NOTE:** If you are looking for Jitsi as a Service (JaaS) please start [here](https://jaas.8x8.vc).
## Installation
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.

View File

@@ -3,7 +3,7 @@ apply plugin: 'com.android.application'
// Crashlytics integration is done as part of Firebase now, so it gets
// automagically activated with google-services.json
if (googleServicesEnabled) {
apply plugin: 'io.fabric'
apply plugin: 'com.google.firebase.crashlytics'
}
// Use the number of seconds/10 since Jan 1 2019 as the versionCode.
@@ -16,6 +16,10 @@ android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
packagingOptions {
exclude 'lib/*/libhermes*.so'
}
defaultConfig {
applicationId 'org.jitsi.meet'
versionCode vcode
@@ -70,16 +74,11 @@ android {
}
}
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-5'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'
if (!rootProject.ext.libreBuild) {
implementation 'com.google.android.gms:play-services-auth:16.0.1'
@@ -87,9 +86,9 @@ dependencies {
// Firebase
// - Crashlytics
// - Dynamic Links
implementation 'com.google.firebase:firebase-core:16.0.6'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'
implementation 'com.google.firebase:firebase-dynamic-links:16.1.5'
implementation 'com.google.firebase:firebase-analytics:17.5.0'
implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
implementation 'com.google.firebase:firebase-dynamic-links:19.1.0'
}
implementation project(':sdk')

View File

@@ -85,8 +85,4 @@
# ^^^ We added the above when we switched minifyEnabled on.
# Rule to avoid build errors related to SVGs.
-keep public class com.horcrux.svg.** {*;}
# Hermes
-keep class com.facebook.hermes.unicode.** { *; }
-keep public class com.horcrux.svg.** {*;}

View File

@@ -3,9 +3,8 @@ package org.jitsi.meet;
import android.net.Uri;
import android.util.Log;
import com.crashlytics.android.Crashlytics;
import com.google.firebase.crashlytics.FirebaseCrashlytics;
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
import io.fabric.sdk.android.Fabric;
import org.jitsi.meet.sdk.JitsiMeet;
import org.jitsi.meet.sdk.JitsiMeetActivity;
@@ -22,10 +21,7 @@ final class GoogleServicesHelper {
if (BuildConfig.GOOGLE_SERVICES_ENABLED) {
Log.d(activity.getClass().getSimpleName(), "Initializing Google Services");
if (!JitsiMeet.isCrashReportingDisabled(activity)) {
Fabric.with(activity, new Crashlytics());
}
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!JitsiMeet.isCrashReportingDisabled(activity));
FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent())
.addOnSuccessListener(activity, pendingDynamicLinkData -> {
Uri dynamicLink = null;

View File

@@ -27,6 +27,7 @@ import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import androidx.annotation.Nullable;
import org.jitsi.meet.sdk.JitsiMeet;
@@ -37,7 +38,7 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
/**
* The one and only Activity that the Jitsi Meet app needs. The
@@ -78,6 +79,12 @@ public class MainActivity extends JitsiMeetActivity {
// JitsiMeetActivity overrides
//
@Override
protected void onCreate(Bundle savedInstanceState) {
JitsiMeet.showSplashScreen(this);
super.onCreate(savedInstanceState);
}
@Override
protected boolean extraInitialize() {
Log.d(this.getClass().getSimpleName(), "LIBRE_BUILD="+BuildConfig.LIBRE_BUILD);
@@ -176,8 +183,8 @@ public class MainActivity extends JitsiMeetActivity {
}
@Override
public void onConferenceTerminated(Map<String, Object> data) {
Log.d(TAG, "Conference terminated: " + data);
protected void onConferenceTerminated(HashMap<String, Object> extraData) {
Log.d(TAG, "Conference terminated: " + extraData);
}
// Activity lifecycle method overrides

View File

@@ -0,0 +1,70 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="262.91376dp"
android:height="262.91376dp"
android:viewportWidth="262.91376"
android:viewportHeight="262.91376">
<group>
<clip-path
android:pathData="m0,0 l262.914,-0L262.914,262.914 0,262.914 0,0Z"/>
<path
android:pathData="m142.646,105.099c0.117,0.026 0.255,0.036 0.406,0.036 3.186,-0 10.297,-4.615 11.617,-6.721l0.1,-0.17 0.153,-0.135c0.451,-0.441 1.746,-2.773 2.374,-4.17 -6.751,-2.023 -7.49,-5.677 -8.153,-8.919 -0.069,-0.376 -0.138,-0.717 -0.204,-1.019 -0.074,-0.397 -0.153,-0.8 -0.226,-1.112C138.668,86.221 135.593,88.094 133.921,89.483 133.056,90.201 132.542,92.251 135.042,97.926 136.323,100.816 140.727,104.733 142.646,105.099"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m115.413,146.042c5.934,-0 18.464,-3.543 26.748,-5.887 1.21,-0.336 2.33,-0.66 3.351,-0.944 0.166,-0.046 0.321,-0.091 0.472,-0.124 -0.463,-0.461 -1.239,-1.159 -2.497,-2.216 -5.521,-3.741 -10.736,-5.484 -16.403,-5.484 -1.237,-0 -2.522,0.071 -3.923,0.231 -4.801,0.55 -8.8,1.69 -10.722,2.237 -0.967,0.284 -1.263,0.366 -1.567,0.366 -0.58,-0 -1.079,-0.341 -1.273,-0.878 -0.194,-0.534 -0.027,-1.121 0.425,-1.507l0.024,-0.011c3.316,-2.784 9.489,-7.951 21.198,-10.256 2.027,-0.401 4.202,-0.605 6.454,-0.605 5.242,-0 10.67,1.086 16.125,3.219 7.436,2.899 12.521,6.625 16.602,9.62 2.199,1.609 4.105,3.007 5.755,3.771 0.421,0.2 0.637,0.255 0.746,0.265 0.074,-0.095 0.23,-0.365 0.474,-1.069 0.066,-0.185 0.529,-2.161 -2.806,-13.374 -1.931,-6.51 -4.264,-13.156 -5.479,-16.104 -2.356,-5.711 -1.778,-9.76 -1.051,-12.125 -1.999,0.735 -4.033,1.87 -6.174,3.446L161.758,98.711C160.694,99.506 159.599,100.404 158.426,101.454 151.517,107.64 146.344,110.864 143.035,111.04l-0.093,0.004 -0.093,-0.009c-2.912,-0.245 -7.324,-4.489 -9.133,-6.634 -0.373,-0.251 -0.8,-0.366 -1.366,-0.366 -0.564,-0 -1.202,0.116 -1.82,0.235C130.086,104.354 129.623,104.441 129.167,104.489 127.708,104.632 125.668,105.106 123.694,105.561 122.746,105.777 121.762,106.005 120.864,106.189 120.851,106.19 120.463,106.272 119.774,106.454 114.903,107.891 111.228,109.55 109.432,111.111 109.414,111.127 109.352,111.174 109.266,111.242 108.048,112.105 105.124,114.567 104.248,118.762L104.237,118.795C102.398,126.516 105.187,136.087 108.892,141.554 110.636,144.125 112.513,145.727 114.048,145.959 114.437,146.015 114.891,146.042 115.413,146.042"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m90.093,173.175c-1.252,-1.472 -1.783,-3.324 -1.574,-5.521 0.884,-10.642 -0.329,-13.215 -0.891,-13.829 -0.131,-0.144 -0.207,-0.144 -0.265,-0.144 -0.022,-0 -0.041,0.003 -0.064,0.003 -1.044,0.248 -8.066,5.002 -9.615,19.171 -0.749,6.845 0.561,15.63 1.679,20.974 0.897,-3.155 2.314,-6.624 5.057,-10.204 2.556,-3.326 5.345,-5.955 8.801,-8.253C92.143,174.93 90.991,174.235 90.093,173.175"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m94.906,156.389c-0.03,2.229 -0.326,4.36 -0.61,6.445 -0.151,1.119 -0.314,2.286 -0.434,3.46 -0.161,2.341 0.346,3.166 0.571,3.406 0.127,0.136 0.326,0.287 0.76,0.287 0.339,-0 0.741,-0.091 1.161,-0.268 4.202,-1.756 8.195,-4.815 10.115,-6.515C103.522,161.892 98.995,159.058 94.906,156.389"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m154.002,81.595c-0.031,0.074 -0.065,0.148 -0.101,0.216 -0.821,2.403 0.306,5.664 2.419,6.898 0.561,0.327 1.106,0.526 1.624,0.596 0.072,0.006 0.148,0.009 0.219,0.009 1.645,-0 2.971,-1.199 3.961,-3.561C162.752,83.959 162.836,81.827 162.37,79.904 162.003,78.409 161.057,76.627 160.453,75.738 159.332,76.509 157.111,78.207 155.585,79.553 154.518,80.582 154.136,81.229 154.002,81.595"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M148.97,77.699C153.957,73.194 156.988,65.754 158.253,61.334 153.915,65.513 148.633,67.758 145.25,69.198 144.084,69.695 143.08,70.124 142.477,70.476 142.224,70.623 141.965,70.77 141.708,70.919 139.654,72.109 136.55,73.905 136.1,75.011l-0.012,0.036 -0.012,0.034c-1.406,2.956 -2.199,7.401 -2.457,9.95 3.266,-1.99 6.625,-3.322 9.416,-4.42C145.628,79.585 147.863,78.703 148.97,77.699"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m164.464,51.921c-0.84,5.539 -2.205,10.799 -4.751,16.347 2.781,-3.144 4.396,-6.568 4.941,-10.401C164.886,56.275 165.097,54.756 164.464,51.921"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M148.749,142.639C148.718,142.598 148.684,142.56 148.658,142.519 148.523,142.539 148.307,142.584 147.972,142.683l-0.14,0.04c-1.726,0.644 -4.899,1.708 -8.556,2.946 -4.396,1.479 -9.365,3.154 -13.526,4.649 -5.297,1.975 -7.021,2.755 -7.557,3.024 -0.098,0.266 -0.203,0.599 -0.327,0.965 -1.254,3.816 -4.125,12.541 -18.276,18.653 2.928,2.956 9.289,8.27 21.809,8.27 1.082,-0 2.21,-0.036 3.341,-0.12 9.451,-0.666 18.342,-4.855 25.026,-11.78 6.087,-6.291 9.538,-14.136 9.585,-21.7C157.876,147.509 155.367,147.135 153.043,146.033 153.014,146.02 150.361,144.745 148.749,142.639"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m189.478,117.853c-0.523,9.749 -2.122,18.424 -4.744,25.8 -2.128,5.988 -4.94,11.134 -8.356,15.316 -5.676,6.931 -11.555,9.256 -12.804,9.304 -0.866,-0 -1.313,-0.309 -3.046,-1.528 -0.17,-0.114 -0.37,-0.252 -0.581,-0.4 -3.313,5.953 -8.505,11.097 -15.065,14.959 -7.079,4.144 -15.297,6.423 -23.157,6.423 -9.078,-0 -17.13,-2.924 -23.341,-8.456 -7.467,4.799 -12.31,9.074 -16.267,27.005l-1.363,6.17 -2.971,-5.564c-0.424,-0.786 -1.929,-3.731 -3.332,-8.887 -1.934,-7.104 -2.86,-15.181 -2.758,-24.01 0.117,-10.049 3.154,-16.526 5.68,-20.186 2.98,-4.314 6.837,-6.994 10.076,-6.994 0.216,-0 0.428,0.006 0.616,0.035 5.159,0.575 8.435,2.75 14.396,6.686l1.899,1.252c2.059,1.344 4.481,2.7 5.259,2.989 0.54,-0.284 1.749,-2.3 2.155,-5.271l0.069,-0.451c0.005,-0.045 0.009,-0.091 0.014,-0.131 -0.036,-0.02 -0.065,-0.029 -0.094,-0.041 -4.008,-1.375 -9.539,-7.7 -12.364,-17.134 -2.684,-9.382 -2.129,-17.185 1.644,-23.193 6.12,-9.736 19.198,-11.974 23.466,-12.702 1.331,-0.266 2.716,-0.511 4.041,-0.717 0.255,-0.061 0.469,-0.121 0.642,-0.168 -0.031,-0.126 -0.071,-0.265 -0.114,-0.43 -0.108,-0.417 -0.23,-0.891 -0.354,-1.447 -1.345,-6.035 -0.664,-11.069 0.181,-15.193 0.928,-4.546 1.489,-7.287 3.747,-9.936 3.029,-4.165 8.319,-5.936 11.479,-6.991 0.746,-0.249 1.511,-0.509 1.894,-0.689 8.988,-4.31 11.82,-8.739 12.615,-11.694 0.656,-2.451 1.699,-8.884 1.251,-13.335 -0.085,-0.805 0.129,-1.521 0.621,-2.065 0.45,-0.505 1.101,-0.794 1.778,-0.794 1.515,-0 2.82,-0 7.511,14.598 2.481,7.698 0.645,14.903 -5.45,21.424l-0.226,0.231c0.024,0.044 0.049,0.09 0.08,0.144 2.57,4.236 3.963,9.54 3.553,13.51 -0.099,0.906 -0.265,1.775 -0.419,2.549 -0.003,0.01 -0.003,0.016 -0.004,0.029 0.516,-0.032 1.119,-0.055 1.775,-0.055 3.052,-0 7.435,0.474 10.989,2.735 2.135,1.352 4.845,3.439 6.835,7.615C189.223,102.942 190.076,109.575 189.478,117.853m4.77,-23.191c-2.916,-6.1 -6.989,-9.177 -9.793,-10.96 -2.355,-1.494 -5.064,-2.584 -8.077,-3.24l-0.676,-0.146 -0.111,-0.689c-0.339,-2.119 -0.918,-4.275 -1.715,-6.406l-0.185,-0.49 0.292,-0.434c5.095,-7.594 6.323,-16.17 3.54,-24.802 -2.191,-6.824 -3.895,-11.211 -5.341,-13.799 -2.954,-5.305 -7.006,-6.417 -9.891,-6.417 -2.964,-0 -5.8,1.261 -7.789,3.457 -2.043,2.254 -2.993,5.207 -2.678,8.31 0.316,3.134 -0.494,8.516 -1.014,10.439 -0.04,0.117 -0.975,2.929 -8.201,6.428 -0.162,0.056 -0.512,0.179 -1.053,0.359 -3.729,1.246 -10.666,3.571 -15.258,9.64 -3.465,4.205 -4.332,8.441 -5.338,13.346 -0.586,2.865 -1.236,6.744 -1.079,11.344l0.026,0.841 -0.824,0.188c-11.646,2.585 -20.025,7.835 -24.909,15.605 -5.054,8.04 -5.919,18.055 -2.543,29.853 0.063,0.204 0.126,0.407 0.189,0.615l0.527,1.608 -1.665,-0.286c-0.561,-0.101 -1.135,-0.18 -1.729,-0.241 -0.493,-0.06 -1.001,-0.082 -1.509,-0.082 -5.633,-0 -11.663,3.585 -16.128,9.592 -3.451,4.641 -7.588,12.849 -7.735,25.601 -0.114,9.573 0.906,18.401 3.038,26.228 1.581,5.795 3.326,9.329 4.004,10.577l13.306,24.94 6.096,-27.619c2.454,-11.09 4.864,-15.262 7.725,-18.111l0.561,-0.563 0.679,0.411c6.605,3.977 14.466,6.084 22.73,6.084 9.286,-0 18.965,-2.682 27.259,-7.551 5.38,-3.16 9.974,-7.036 13.649,-11.531l0.45,-0.369 0.85,-0.02c2.156,-0.068 5.16,-1.164 8.222,-3.004 2.6,-1.555 6.543,-4.428 10.501,-9.262 3.997,-4.884 7.274,-10.854 9.716,-17.734 2.876,-8.073 4.625,-17.489 5.204,-28.004 0.689,-9.668 -0.434,-17.641 -3.327,-23.704"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m180.026,98.414c-1.67,-2.596 -3.771,-4.206 -5.475,-4.206 -0.313,-0 -0.613,0.051 -0.895,0.161 -0.911,0.361 -2.356,4.532 -1.714,7.566 0.434,2.066 2.938,9.04 4.151,12.394 0.456,1.281 0.68,1.91 0.754,2.142 0.064,0.183 0.145,0.448 0.256,0.774 0.97,2.971 3.467,10.586 4.206,16.761 1.549,-6.579 2.424,-14.512 2.085,-23.997C183.235,105.662 182.04,101.538 180.026,98.414"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M168.088,142.604C169.896,142.111 171.33,141.705 172.398,141.395 170.213,139.874 167.689,137.979 164.247,135.304c-8.418,-6.546 -17.449,-9.87 -26.839,-9.87 -5.135,-0 -9.611,0.991 -13.156,2.186 0.882,-0.05 1.779,-0.079 2.7,-0.079 1.1,-0 2.247,0.04 3.411,0.119 3.652,0.246 13.061,1.901 21.565,12.047 1.714,2.039 3.559,3.73 8.794,3.73 1.873,-0 4.051,-0.207 6.662,-0.645C167.544,142.751 167.793,142.678 168.088,142.604"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m164.3,147.583c-0.122,1.563 -0.376,4.509 -0.782,6.76 -0.495,2.719 -1.31,5.02 -1.791,6.226 0.85,0.786 1.694,1.553 2.247,2.043 2.214,-1.447 9.47,-6.96 14.483,-19.474C176.847,144.229 174.59,145.178 171.671,146.018 168.701,146.861 165.82,147.357 164.3,147.583"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
</group>
</vector>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/ic_jitsi_logosvg"/>
</RelativeLayout>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#17A0DB</color>
<color name="colorPrimaryDark">#1081B2</color>
</resources>

View File

@@ -2,6 +2,6 @@
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:navigationBarColor">#1081B2</item>
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
</style>
</resources>

View File

@@ -1,4 +1,5 @@
import groovy.json.JsonSlurper
import org.gradle.util.VersionNumber
// Top-level build file where you can add configuration options common to all
// sub-projects/modules.
@@ -7,26 +8,46 @@ buildscript {
repositories {
google()
jcenter()
repositories {
maven { url 'https://maven.fabric.io/public' }
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'io.fabric.tools:gradle:1.28.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files.
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.google.gms:google-services:4.3.4'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'
}
}
ext {
buildToolsVersion = "30.0.3"
compileSdkVersion = 30
minSdkVersion = 23
targetSdkVersion = 30
supportLibVersion = "28.0.0"
// The Maven artifact groupdId of the third-party react-native modules which
// Jitsi Meet SDK for Android depends on and which are not available in
// third-party Maven repositories so we have to deploy to a Maven repository
// of ours.
moduleGroupId = 'com.facebook.react'
// Maven repo where artifacts will be published
mavenRepo = System.env.MVN_REPO ?: ""
mavenUser = System.env.MVN_USER ?: ""
mavenPassword = System.env.MVN_PASSWORD ?: ""
// Libre build
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
}
allprojects {
repositories {
google()
jcenter()
// React Native (JS, Obj-C sources, Android binaries) is installed from npm.
maven { url "$rootDir/../node_modules/react-native/android" }
// Android JSC is installed from npm.
maven { url("$rootDir/../node_modules/jsc-android/dist") }
}
// Make sure we use the react-native version in node_modules and not the one
@@ -141,30 +162,6 @@ allprojects {
}
}
ext {
buildToolsVersion = "29.0.3"
compileSdkVersion = 29
minSdkVersion = 23
targetSdkVersion = 29
supportLibVersion = "28.0.0"
// The Maven artifact groupdId of the third-party react-native modules which
// Jitsi Meet SDK for Android depends on and which are not available in
// third-party Maven repositories so we have to deploy to a Maven repository
// of ours.
moduleGroupId = 'com.facebook.react'
// Maven repo where artifacts will be published
mavenRepo = System.env.MVN_REPO ?: ""
mavenUser = System.env.MVN_USER ?: ""
mavenPassword = System.env.MVN_PASSWORD ?: ""
// Libre build
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
}
// Force the version of the Android build tools we have chosen on all
// subprojects. The forcing was introduced for react-native and the third-party
// modules that we utilize such as react-native-background-timer.

View File

@@ -10,15 +10,20 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# This one fixes a weird WebRTC runtime problem on some devices.
# https://github.com/jitsi/jitsi-meet/issues/7911#issuecomment-714323255
android.enableDexingArtifactTransform.desugaring=false
android.useAndroidX=true
android.enableJetifier=true
appVersion=20.4.0
sdkVersion=2.10.0
appVersion=21.0.0
sdkVersion=3.1.0

View File

@@ -1,6 +1,6 @@
#Fri Mar 08 13:36:51 CET 2019
#Wed Sep 23 11:48:00 EEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip

View File

@@ -10,7 +10,7 @@ MVN_HTTP=0
DEFAULT_SDK_VERSION=$(grep sdkVersion ${THIS_DIR}/../gradle.properties | cut -d"=" -f2)
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
RN_VERSION=$(jq -r '.version' ${THIS_DIR}/../../node_modules/react-native/package.json)
HERMES_VERSION=$(jq -r '.dependencies."hermes-engine"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -c 2-)
JSC_VERSION="r"$(jq -r '.dependencies."jsc-android"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -d . -f 1 | cut -c 2-)
DO_GIT_TAG=${GIT_TAG:-0}
if [[ $THE_MVN_REPO == http* ]]; then
@@ -38,19 +38,17 @@ if [[ $MVN_HTTP == 1 ]]; then
-DgeneratePom=false \
-DpomFile=react-native-${RN_VERSION}.pom || true
popd
# Push Hermes
echo "Pushing Hermes ${HERMES_VERSION} to the Maven repo"
pushd ${THIS_DIR}/../../node_modules/hermes-engine/android/
# Push JSC
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
mvn \
deploy:deploy-file \
-Durl=${MVN_REPO} \
-DrepositoryId=${MVN_REPO_ID} \
-Dfile=hermes-release.aar \
-Dfile=android-jsc-${JSC_VERSION}.aar \
-Dpackaging=aar \
-DgroupId=com.facebook \
-DartifactId=hermes \
-Dversion=${HERMES_VERSION} \
-DgeneratePom=true || true
-DgeneratePom=false \
-DpomFile=android-jsc-${JSC_VERSION}.pom || true
popd
else
# Push React Native, if necessary
@@ -67,19 +65,17 @@ else
popd
fi
# Push Hermes, if necessary
if [[ ! -d ${MVN_REPO}/com/facebook/hermes/${HERMES_VERSION} ]]; then
echo "Pushing Hermes ${HERMES_VERSION} to the Maven repo"
pushd ${THIS_DIR}/../../node_modules/hermes-engine/android/
# Push JSC, if necessary
if [[ ! -d ${MVN_REPO}/org/webkit/android-jsc/${JSC_VERSION} ]]; then
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
mvn \
deploy:deploy-file \
-Durl=${MVN_REPO} \
-Dfile=hermes-release.aar \
-Dfile=android-jsc-${JSC_VERSION}.aar \
-Dpackaging=aar \
-DgroupId=com.facebook \
-DartifactId=hermes \
-Dversion=${HERMES_VERSION} \
-DgeneratePom=true
-DgeneratePom=false \
-DpomFile=android-jsc-${JSC_VERSION}.pom
popd
fi
@@ -93,7 +89,9 @@ fi
# Now build and publish the Jitsi Meet SDK and its dependencies
echo "Building and publishing the Jitsi Meet SDK"
pushd ${THIS_DIR}/../
./gradlew clean assembleRelease publish
./gradlew clean
./gradlew assembleRelease
./gradlew publish
popd
if [[ $DO_GIT_TAG == 1 ]]; then

View File

@@ -1,5 +1,3 @@
import groovy.json.JsonSlurper
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
@@ -27,50 +25,47 @@ android {
sourceSets {
main {
java {
if (rootProject.ext.libreBuild) {
srcDir "src"
exclude "**/AmplitudeModule.java"
}
exclude "test/"
}
}
}
packagingOptions {
pickFirst '**/libc++_shared.so'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.fragment:fragment:1.2.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.fragment:fragment:1.2.5'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
//noinspection GradleDynamicVersion
api 'com.facebook.react:react-native:+'
// Hermes JS engine
def hermesPath = "../../node_modules/hermes-engine/android/"
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
//noinspection GradleDynamicVersion
implementation 'org.webkit:android-jsc:+'
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.squareup.duktape:duktape-android:1.3.0'
implementation 'com.google.code.gson:gson:2.8.6'
if (!rootProject.ext.libreBuild) {
implementation 'com.amplitude:android-sdk:2.14.1'
if (rootProject.ext.libreBuild) {
implementation(project(':react-native-device-info')) {
exclude group: 'com.google.firebase'
exclude group: 'com.google.android.gms'
exclude group: 'com.android.installreferrer'
}
} else {
implementation project(':react-native-device-info')
implementation(project(":react-native-google-signin")) {
exclude group: 'com.google.android.gms'
exclude group: 'androidx'
}
}
implementation project(':react-native-async-storage')
implementation project(':react-native-background-timer')
implementation project(':react-native-calendar-events')
implementation project(':react-native-community-async-storage')
implementation project(':react-native-community_netinfo')
implementation project(':react-native-default-preference')
implementation project(':react-native-immersive')
@@ -80,6 +75,7 @@ dependencies {
implementation project(':react-native-svg')
implementation project(':react-native-webrtc')
implementation project(':react-native-webview')
implementation project(':react-native-splash-screen')
testImplementation 'junit:junit:4.12'
}
@@ -153,7 +149,7 @@ android.libraryVariants.all { def variant ->
mergeResourcesTask.dependsOn(currentBundleTask)
mergeAssetsTask.doLast {
def assetsDir = mergeAssetsTask.outputDir
def assetsDir = mergeAssetsTask.outputDir.get()
// Bundle sounds
//
@@ -187,7 +183,7 @@ android.libraryVariants.all { def variant ->
if (currentBundleTask.enabled) {
copy {
from(resourcesDir)
into(mergeResourcesTask.outputDir)
into(mergeResourcesTask.outputDir.get())
}
}
}
@@ -227,14 +223,6 @@ publishing {
dependency.appendNode('artifactId', artifactId)
dependency.appendNode('version', it.moduleVersion)
}
// Add Hermes dependency.
def hermesPkg = new File("$rootDir/../node_modules/hermes-engine/package.json")
def hermesVersion = new JsonSlurper().parseText(hermesPkg.text).version
def hermesDependency = dependencies.appendNode('dependency')
hermesDependency.appendNode('groupId', "com.facebook")
hermesDependency.appendNode('artifactId', "hermes")
hermesDependency.appendNode('version', hermesVersion)
}
}

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.jitsi.meet.sdk">
<!-- XXX ACCESS_NETWORK_STATE is required by WebRTC. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -12,7 +13,7 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-feature
android:glEsVersion="0x00020000"
@@ -34,8 +35,7 @@
android:launchMode="singleTask"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:windowSoftInputMode="adjustResize">
</activity>
android:windowSoftInputMode="adjustResize"/>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<service
@@ -46,7 +46,16 @@
</intent-filter>
</service>
<service android:name="org.jitsi.meet.sdk.JitsiMeetOngoingConferenceService" />
<service
android:name="org.jitsi.meet.sdk.JitsiMeetOngoingConferenceService"
android:foregroundServiceType="mediaProjection" />
<provider
android:name="com.reactnativecommunity.webview.RNCWebViewFileProvider"
android:authorities="${applicationId}.fileprovider"
android:enabled="false"
tools:replace="android:authorities">
</provider>
</application>
</manifest>

View File

@@ -1,122 +0,0 @@
/*
* Copyright @ 2019-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.meet.sdk;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings;
import android.text.TextUtils;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.amplitude.api.Amplitude;
import com.facebook.react.module.annotations.ReactModule;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Implements the react-native module for the Amplitude integration.
*/
@ReactModule(name = AmplitudeModule.NAME)
class AmplitudeModule
extends ReactContextBaseJavaModule {
public static final String NAME = "Amplitude";
public static final String JITSI_PREFERENCES = "jitsi-preferences";
public static final String AMPLITUDE_DEVICE_ID_KEY = "amplitudeDeviceId";
public AmplitudeModule(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* Initializes the Amplitude SDK.
*
* @param instanceName The name of the Amplitude instance. Should
* be used only for multi-project logging.
* @param apiKey The API_KEY of the Amplitude project.
*/
@ReactMethod
@SuppressLint("HardwareIds")
public void init(String instanceName, String apiKey) {
Amplitude.getInstance(instanceName).initialize(getCurrentActivity(), apiKey);
// Set the device ID to something consistent.
SharedPreferences sharedPreferences = getReactApplicationContext().getSharedPreferences(JITSI_PREFERENCES, Context.MODE_PRIVATE);
String android_id = sharedPreferences.getString(AMPLITUDE_DEVICE_ID_KEY, "");
if (!TextUtils.isEmpty(android_id)) {
Amplitude.getInstance(instanceName).setDeviceId(android_id);
} else {
String amplitudeId = Amplitude.getInstance(instanceName).getDeviceId();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(JITSI_PREFERENCES, amplitudeId).apply();
}
}
/**
* Sets the user ID for an Amplitude instance.
*
* @param instanceName The name of the Amplitude instance.
* @param userId The new value for the user ID.
*/
@ReactMethod
public void setUserId(String instanceName, String userId) {
Amplitude.getInstance(instanceName).setUserId(userId);
}
/**
* Sets the user properties for an Amplitude instance.
*
* @param instanceName The name of the Amplitude instance.
* @param userProps JSON string with user properties to be set.
*/
@ReactMethod
public void setUserProperties(String instanceName, ReadableMap userProps) {
if (userProps != null) {
Amplitude.getInstance(instanceName).setUserProperties(
new JSONObject(userProps.toHashMap()));
}
}
/**
* Log an analytics event.
*
* @param instanceName The name of the Amplitude instance.
* @param eventType The event type.
* @param eventPropsString JSON string with the event properties.
*/
@ReactMethod
public void logEvent(String instanceName, String eventType, String eventPropsString) {
try {
JSONObject eventProps = new JSONObject(eventPropsString);
Amplitude.getInstance(instanceName).logEvent(eventType, eventProps);
} catch (JSONException e) {
JitsiMeetLogger.e(e, "Error logging event");
}
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -16,8 +16,11 @@
package org.jitsi.meet.sdk;
import android.media.AudioAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;
import java.util.HashSet;
import java.util.Set;
@@ -60,7 +63,7 @@ class AudioDeviceHandlerGeneric implements
private AudioManager audioManager;
/**
* {@link Runnable} for running audio device detection the main thread.
* {@link Runnable} for running audio device detection in the audio thread.
* This is only used on Android >= M.
*/
private final Runnable onAudioDeviceChangeRunner = new Runnable() {
@@ -142,7 +145,7 @@ class AudioDeviceHandlerGeneric implements
// Some other application potentially stole our audio focus
// temporarily. Restore our mode.
if (audioFocusLost) {
module.updateAudioRoute();
module.resetAudioRoute();
}
audioFocusLost = false;
break;
@@ -216,8 +219,24 @@ class AudioDeviceHandlerGeneric implements
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setMicrophoneMute(false);
if (audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN)
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
int gotFocus;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
gotFocus = audioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(this)
.build()
);
} else {
gotFocus = audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
}
if (gotFocus == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
JitsiMeetLogger.w(TAG + " Audio focus request failed");
return false;
}

View File

@@ -16,6 +16,7 @@
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
@@ -256,7 +257,7 @@ class AudioModeModule extends ReactContextBaseJavaModule {
if (mode != -1) {
JitsiMeetLogger.i(TAG + " User selected device set to: " + device);
userSelectedDevice = device;
updateAudioRoute(mode);
updateAudioRoute(mode, false);
}
}
});
@@ -276,13 +277,22 @@ class AudioModeModule extends ReactContextBaseJavaModule {
return;
}
Activity currentActivity = getCurrentActivity();
if (currentActivity != null) {
if (mode == DEFAULT) {
currentActivity.setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
} else {
currentActivity.setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
}
runInAudioThread(new Runnable() {
@Override
public void run() {
boolean success;
try {
success = updateAudioRoute(mode);
success = updateAudioRoute(mode, false);
} catch (Throwable e) {
success = false;
JitsiMeetLogger.e(e, TAG + " Failed to update audio route for mode: " + mode);
@@ -321,7 +331,7 @@ class AudioModeModule extends ReactContextBaseJavaModule {
* @return {@code true} if the audio route was updated successfully;
* {@code false}, otherwise.
*/
private boolean updateAudioRoute(int mode) {
private boolean updateAudioRoute(int mode, boolean force) {
JitsiMeetLogger.i(TAG + " Update audio route for mode: " + mode);
if (!audioDeviceHandler.setMode(mode)) {
@@ -356,7 +366,7 @@ class AudioModeModule extends ReactContextBaseJavaModule {
// If the previously selected device and the current default one
// match, do nothing.
if (selectedDevice != null && selectedDevice.equals(audioDevice)) {
if (!force && selectedDevice != null && selectedDevice.equals(audioDevice)) {
return true;
}
@@ -421,7 +431,16 @@ class AudioModeModule extends ReactContextBaseJavaModule {
*/
void updateAudioRoute() {
if (mode != -1) {
updateAudioRoute(mode);
updateAudioRoute(mode, false);
}
}
/**
* Re-sets the current audio route. Needed when focus is lost and regained.
*/
void resetAudioRoute() {
if (mode != -1) {
updateAudioRoute(mode, true);
}
}

View File

@@ -99,6 +99,7 @@ public abstract class BaseReactView<ListenerT>
* The listener (e.g. {@link JitsiMeetViewListener}) instance for reporting
* events occurring in Jitsi Meet.
*/
@Deprecated
private ListenerT listener;
/**
@@ -167,6 +168,7 @@ public abstract class BaseReactView<ListenerT>
*
* @return The listener set on this {@code BaseReactView}.
*/
@Deprecated
public ListenerT getListener() {
return listener;
}
@@ -179,8 +181,10 @@ public abstract class BaseReactView<ListenerT>
* @param data - The details of the event associated with/specific to the
* specified {@code name}.
*/
@Deprecated
protected abstract void onExternalAPIEvent(String name, ReadableMap data);
@Deprecated
protected void onExternalAPIEvent(
Map<String, Method> listenerMethods,
String name, ReadableMap data) {
@@ -215,6 +219,7 @@ public abstract class BaseReactView<ListenerT>
*
* @param listener The listener to set on this {@code BaseReactView}.
*/
@Deprecated
public void setListener(ListenerT listener) {
this.listener = listener;
}

View File

@@ -0,0 +1,90 @@
package org.jitsi.meet.sdk;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.bridge.WritableNativeMap;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.util.HashMap;
/**
* Wraps the name and extra data for events that were broadcasted locally.
*/
public class BroadcastAction {
private static final String TAG = BroadcastAction.class.getSimpleName();
private final Type type;
private final HashMap<String, Object> data;
public BroadcastAction(Intent intent) {
this.type = Type.buildTypeFromAction(intent.getAction());
this.data = buildDataFromBundle(intent.getExtras());
}
public Type getType() {
return this.type;
}
public HashMap<String, Object> getData() {
return this.data;
}
public WritableNativeMap getDataAsWritableNativeMap() {
WritableNativeMap nativeMap = new WritableNativeMap();
for (String key : this.data.keySet()) {
try {
// TODO add support for different types of objects
nativeMap.putString(key, this.data.get(key).toString());
} catch (Exception e) {
JitsiMeetLogger.w(TAG + " invalid extra data in event", e);
}
}
return nativeMap;
}
private static HashMap<String, Object> buildDataFromBundle(Bundle bundle) {
HashMap<String, Object> map = new HashMap<>();
if (bundle != null) {
for (String key : bundle.keySet()) {
map.put(key, bundle.get(key));
}
}
return map;
}
enum Type {
SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
HANG_UP("org.jitsi.meet.HANG_UP"),
SEND_ENDPOINT_TEXT_MESSAGE("org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE"),
TOGGLE_SCREEN_SHARE("org.jitsi.meet.TOGGLE_SCREEN_SHARE"),
RETRIEVE_PARTICIPANTS_INFO("org.jitsi.meet.RETRIEVE_PARTICIPANTS_INFO"),
OPEN_CHAT("org.jitsi.meet.OPEN_CHAT"),
CLOSE_CHAT("org.jitsi.meet.CLOSE_CHAT"),
SEND_CHAT_MESSAGE("org.jitsi.meet.SEND_CHAT_MESSAGE");
private final String action;
Type(String action) {
this.action = action;
}
public String getAction() {
return action;
}
private static Type buildTypeFromAction(String action) {
for (Type type : Type.values()) {
if (type.action.equalsIgnoreCase(action)) {
return type;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,30 @@
package org.jitsi.meet.sdk;
import android.content.Context;
import android.content.Intent;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.facebook.react.bridge.ReadableMap;
/**
* Class used to emit events through the LocalBroadcastManager, called when events
* from JS occurred. Takes an action name from JS, builds and broadcasts the {@link BroadcastEvent}
*/
public class BroadcastEmitter {
private final LocalBroadcastManager localBroadcastManager;
public BroadcastEmitter(Context context) {
localBroadcastManager = LocalBroadcastManager.getInstance(context);
}
public void sendBroadcast(String name, ReadableMap data) {
BroadcastEvent event = new BroadcastEvent(name, data);
Intent intent = event.buildIntent();
if (intent != null) {
localBroadcastManager.sendBroadcast(intent);
}
}
}

View File

@@ -0,0 +1,150 @@
package org.jitsi.meet.sdk;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.bridge.ReadableMap;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.util.HashMap;
/**
* Wraps the name and extra data for the events that occur on the JS side and are
* to be broadcasted.
*/
public class BroadcastEvent {
private static final String TAG = BroadcastEvent.class.getSimpleName();
private final Type type;
private final HashMap<String, Object> data;
public BroadcastEvent(String name, ReadableMap data) {
this.type = Type.buildTypeFromName(name);
this.data = data.toHashMap();
}
public BroadcastEvent(Intent intent) {
this.type = Type.buildTypeFromAction(intent.getAction());
this.data = buildDataFromBundle(intent.getExtras());
}
public Type getType() {
return this.type;
}
public HashMap<String, Object> getData() {
return this.data;
}
public Intent buildIntent() {
if (type != null && type.action != null) {
Intent intent = new Intent(type.action);
for (String key : this.data.keySet()) {
try {
intent.putExtra(key, this.data.get(key).toString());
} catch (Exception e) {
JitsiMeetLogger.w(TAG + " invalid extra data in event", e);
}
}
return intent;
}
return null;
}
private static HashMap<String, Object> buildDataFromBundle(Bundle bundle) {
if (bundle != null) {
try {
HashMap<String, Object> map = new HashMap<>();
for (String key : bundle.keySet()) {
map.put(key, bundle.get(key));
}
return map;
} catch (Exception e) {
JitsiMeetLogger.w(TAG + " invalid extra data", e);
}
}
return null;
}
public enum Type {
CONFERENCE_JOINED("org.jitsi.meet.CONFERENCE_JOINED"),
CONFERENCE_TERMINATED("org.jitsi.meet.CONFERENCE_TERMINATED"),
CONFERENCE_WILL_JOIN("org.jitsi.meet.CONFERENCE_WILL_JOIN"),
AUDIO_MUTED_CHANGED("org.jitsi.meet.AUDIO_MUTED_CHANGED"),
PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"),
PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"),
ENDPOINT_TEXT_MESSAGE_RECEIVED("org.jitsi.meet.ENDPOINT_TEXT_MESSAGE_RECEIVED"),
SCREEN_SHARE_TOGGLED("org.jitsi.meet.SCREEN_SHARE_TOGGLED"),
PARTICIPANTS_INFO_RETRIEVED("org.jitsi.meet.PARTICIPANTS_INFO_RETRIEVED"),
CHAT_MESSAGE_RECEIVED("org.jitsi.meet.CHAT_MESSAGE_RECEIVED"),
CHAT_TOGGLED("org.jitsi.meet.CHAT_TOGGLED");
private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
private static final String CONFERENCE_TERMINATED_NAME = "CONFERENCE_TERMINATED";
private static final String AUDIO_MUTED_CHANGED_NAME = "AUDIO_MUTED_CHANGED";
private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED";
private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT";
private static final String ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME = "ENDPOINT_TEXT_MESSAGE_RECEIVED";
private static final String SCREEN_SHARE_TOGGLED_NAME = "SCREEN_SHARE_TOGGLED";
private static final String PARTICIPANTS_INFO_RETRIEVED_NAME = "PARTICIPANTS_INFO_RETRIEVED";
private static final String CHAT_MESSAGE_RECEIVED_NAME = "CHAT_MESSAGE_RECEIVED";
private static final String CHAT_TOGGLED_NAME = "CHAT_TOGGLED";
private final String action;
Type(String action) {
this.action = action;
}
public String getAction() {
return action;
}
private static Type buildTypeFromAction(String action) {
for (Type type : Type.values()) {
if (type.action.equalsIgnoreCase(action)) {
return type;
}
}
return null;
}
private static Type buildTypeFromName(String name) {
switch (name) {
case CONFERENCE_WILL_JOIN_NAME:
return CONFERENCE_WILL_JOIN;
case CONFERENCE_JOINED_NAME:
return CONFERENCE_JOINED;
case CONFERENCE_TERMINATED_NAME:
return CONFERENCE_TERMINATED;
case AUDIO_MUTED_CHANGED_NAME:
return AUDIO_MUTED_CHANGED;
case PARTICIPANT_JOINED_NAME:
return PARTICIPANT_JOINED;
case PARTICIPANT_LEFT_NAME:
return PARTICIPANT_LEFT;
case ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME:
return ENDPOINT_TEXT_MESSAGE_RECEIVED;
case SCREEN_SHARE_TOGGLED_NAME:
return SCREEN_SHARE_TOGGLED;
case PARTICIPANTS_INFO_RETRIEVED_NAME:
return PARTICIPANTS_INFO_RETRIEVED;
case CHAT_MESSAGE_RECEIVED_NAME:
return CHAT_MESSAGE_RECEIVED;
case CHAT_TOGGLED_NAME:
return CHAT_TOGGLED;
}
return null;
}
}
}

View File

@@ -0,0 +1,43 @@
package org.jitsi.meet.sdk;
import android.content.Intent;
public class BroadcastIntentHelper {
public static Intent buildSetAudioMutedIntent(boolean muted) {
Intent intent = new Intent(BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
intent.putExtra("muted", muted);
return intent;
}
public static Intent buildHangUpIntent() {
return new Intent(BroadcastAction.Type.HANG_UP.getAction());
}
public static Intent buildSendEndpointTextMessageIntent(String to, String message) {
Intent intent = new Intent(BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
intent.putExtra("to", to);
intent.putExtra("message", message);
return intent;
}
public static Intent buildToggleScreenShareIntent() {
return new Intent(BroadcastAction.Type.TOGGLE_SCREEN_SHARE.getAction());
}
public static Intent buildOpenChatIntent(String participantId) {
Intent intent = new Intent(BroadcastAction.Type.OPEN_CHAT.getAction());
intent.putExtra("to", participantId);
return intent;
}
public static Intent buildCloseChatIntent() {
return new Intent(BroadcastAction.Type.CLOSE_CHAT.getAction());
}
public static Intent buildSendChatMessageIntent(String participantId, String message) {
Intent intent = new Intent(BroadcastAction.Type.SEND_CHAT_MESSAGE.getAction());
intent.putExtra("to", participantId);
intent.putExtra("message", message);
return intent;
}
}

View File

@@ -0,0 +1,34 @@
package org.jitsi.meet.sdk;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
/**
* Listens for {@link BroadcastAction}s on LocalBroadcastManager. When one occurs,
* it emits it to JS.
*/
public class BroadcastReceiver extends android.content.BroadcastReceiver {
public BroadcastReceiver(Context context) {
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
IntentFilter intentFilter = new IntentFilter();
for (BroadcastAction.Type type : BroadcastAction.Type.values()) {
intentFilter.addAction(type.getAction());
}
localBroadcastManager.registerReceiver(this, intentFilter);
}
@Override
public void onReceive(Context context, Intent intent) {
BroadcastAction action = new BroadcastAction(intent);
String actionName = action.getType().getAction();
ReactInstanceManagerHolder.emitEvent(actionName, action.getDataAsWritableNativeMap());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright @ 2017-present Atlassian Pty Ltd
* Copyright @ 2017-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,9 @@ import com.facebook.react.module.annotations.ReactModule;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.util.HashMap;
import java.util.Map;
/**
* Module implementing an API for sending events from JavaScript to native code.
*/
@@ -35,6 +38,9 @@ class ExternalAPIModule
private static final String TAG = NAME;
private final BroadcastEmitter broadcastEmitter;
private final BroadcastReceiver broadcastReceiver;
/**
* Initializes a new module instance. There shall be a single instance of
* this module throughout the lifetime of the app.
@@ -44,6 +50,11 @@ class ExternalAPIModule
*/
public ExternalAPIModule(ReactApplicationContext reactContext) {
super(reactContext);
broadcastEmitter = new BroadcastEmitter(reactContext);
broadcastReceiver = new BroadcastReceiver(reactContext);
ParticipantsService.init(reactContext);
}
/**
@@ -56,6 +67,28 @@ class ExternalAPIModule
return NAME;
}
/**
* Gets a mapping with the constants this module is exporting.
*
* @return a {@link Map} mapping the constants to be exported with their
* values.
*/
@Override
public Map<String, Object> getConstants() {
Map<String, Object> constants = new HashMap<>();
constants.put("SET_AUDIO_MUTED", BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
constants.put("HANG_UP", BroadcastAction.Type.HANG_UP.getAction());
constants.put("SEND_ENDPOINT_TEXT_MESSAGE", BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
constants.put("TOGGLE_SCREEN_SHARE", BroadcastAction.Type.TOGGLE_SCREEN_SHARE.getAction());
constants.put("RETRIEVE_PARTICIPANTS_INFO", BroadcastAction.Type.RETRIEVE_PARTICIPANTS_INFO.getAction());
constants.put("OPEN_CHAT", BroadcastAction.Type.OPEN_CHAT.getAction());
constants.put("CLOSE_CHAT", BroadcastAction.Type.CLOSE_CHAT.getAction());
constants.put("SEND_CHAT_MESSAGE", BroadcastAction.Type.SEND_CHAT_MESSAGE.getAction());
return constants;
}
/**
* Dispatches an event that occurred on the JavaScript side of the SDK to
* the specified {@link BaseReactView}'s listener.
@@ -79,7 +112,8 @@ class ExternalAPIModule
JitsiMeetLogger.d(TAG + " Sending event: " + name + " with data: " + data);
try {
view.onExternalAPIEvent(name, data);
} catch(Exception e) {
broadcastEmitter.sendBroadcast(name, data);
} catch (Exception e) {
JitsiMeetLogger.e(e, TAG + " onExternalAPIEvent: error sending event");
}
}

View File

@@ -1,6 +1,5 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
* Copyright @ 2017-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +15,16 @@
*/
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import com.facebook.react.ReactInstanceManager;
import org.devio.rn.splashscreen.SplashScreen;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
public class JitsiMeet {
/**
@@ -81,4 +84,17 @@ public class JitsiMeet {
String value = preferences.getString("isCrashReportingDisabled", "");
return Boolean.parseBoolean(value);
}
/**
* Helper method to show the SplashScreen.
*
* @param activity - The activity on which to show the SplashScreen {@link Activity}.
*/
public static void showSplashScreen(Activity activity) {
try {
SplashScreen.show(activity);
} catch (Exception e) {
JitsiMeetLogger.e(e, "Failed to show splash screen");
}
}
}

View File

@@ -16,33 +16,41 @@
package org.jitsi.meet.sdk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.facebook.react.modules.core.PermissionListener;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.util.Map;
import java.util.HashMap;
/**
* A base activity for SDK users to embed. It uses {@link JitsiMeetFragment} to do the heavy
* lifting and wires the remaining Activity lifecycle methods so it works out of the box.
*/
public class JitsiMeetActivity extends FragmentActivity
implements JitsiMeetActivityInterface, JitsiMeetViewListener {
implements JitsiMeetActivityInterface {
protected static final String TAG = JitsiMeetActivity.class.getSimpleName();
private static final String ACTION_JITSI_MEET_CONFERENCE = "org.jitsi.meet.CONFERENCE";
private static final String JITSI_MEET_CONFERENCE_OPTIONS = "JitsiMeetConferenceOptions";
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
onBroadcastReceived(intent);
}
};
// Helpers for starting the activity
//
@@ -68,8 +76,7 @@ public class JitsiMeetActivity extends FragmentActivity
setContentView(R.layout.activity_jitsi_meet);
// Listen for conference events.
getJitsiView().setListener(this);
registerForBroadcastMessages();
if (!extraInitialize()) {
initialize();
@@ -91,6 +98,8 @@ public class JitsiMeetActivity extends FragmentActivity
}
JitsiMeetOngoingConferenceService.abort(this);
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
@@ -107,26 +116,39 @@ public class JitsiMeetActivity extends FragmentActivity
protected JitsiMeetView getJitsiView() {
JitsiMeetFragment fragment
= (JitsiMeetFragment) getSupportFragmentManager().findFragmentById(R.id.jitsiFragment);
return fragment.getJitsiView();
return fragment != null ? fragment.getJitsiView() : null;
}
public void join(@Nullable String url) {
JitsiMeetConferenceOptions options
= new JitsiMeetConferenceOptions.Builder()
.setRoom(url)
.build();
.setRoom(url)
.build();
join(options);
}
public void join(JitsiMeetConferenceOptions options) {
getJitsiView().join(options);
JitsiMeetView view = getJitsiView();
if (view != null) {
view.join(options);
} else {
JitsiMeetLogger.w("Cannot join, view is null");
}
}
public void leave() {
getJitsiView().leave();
JitsiMeetView view = getJitsiView();
if (view != null) {
view.leave();
} else {
JitsiMeetLogger.w("Cannot leave, view is null");
}
}
private @Nullable JitsiMeetConferenceOptions getConferenceOptions(Intent intent) {
private @Nullable
JitsiMeetConferenceOptions getConferenceOptions(Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_VIEW.equals(action)) {
@@ -145,7 +167,7 @@ public class JitsiMeetActivity extends FragmentActivity
* Helper function called during activity initialization. If {@code true} is returned, the
* initialization is delayed and the {@link JitsiMeetActivity#initialize()} method is not
* called. In this case, it's up to the subclass to call the initialize method when ready.
*
* <p>
* This is mainly required so we do some extra initialization in the Jitsi Meet app.
*
* @return {@code true} if the initialization will be delayed, {@code false} otherwise.
@@ -160,6 +182,37 @@ public class JitsiMeetActivity extends FragmentActivity
join(getConferenceOptions(getIntent()));
}
protected void onConferenceJoined(HashMap<String, Object> extraData) {
JitsiMeetLogger.i("Conference joined: " + extraData);
// Launch the service for the ongoing notification.
JitsiMeetOngoingConferenceService.launch(this);
}
protected void onConferenceTerminated(HashMap<String, Object> extraData) {
JitsiMeetLogger.i("Conference terminated: " + extraData);
finish();
}
protected void onConferenceWillJoin(HashMap<String, Object> extraData) {
JitsiMeetLogger.i("Conference will join: " + extraData);
}
protected void onParticipantJoined(HashMap<String, Object> extraData) {
try {
JitsiMeetLogger.i("Participant joined: ", extraData);
} catch (Exception e) {
JitsiMeetLogger.w("Invalid participant joined extraData", e);
}
}
protected void onParticipantLeft(HashMap<String, Object> extraData) {
try {
JitsiMeetLogger.i("Participant left: ", extraData);
} catch (Exception e) {
JitsiMeetLogger.w("Invalid participant left extraData", e);
}
}
// Activity lifecycle methods
//
@@ -191,7 +244,11 @@ public class JitsiMeetActivity extends FragmentActivity
@Override
protected void onUserLeaveHint() {
getJitsiView().enterPictureInPicture();
JitsiMeetView view = getJitsiView();
if (view != null) {
view.enterPictureInPicture();
}
}
// JitsiMeetActivityInterface
@@ -207,24 +264,37 @@ public class JitsiMeetActivity extends FragmentActivity
JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
// JitsiMeetViewListener
//
private void registerForBroadcastMessages() {
IntentFilter intentFilter = new IntentFilter();
@Override
public void onConferenceJoined(Map<String, Object> data) {
JitsiMeetLogger.i("Conference joined: " + data);
// Launch the service for the ongoing notification.
JitsiMeetOngoingConferenceService.launch(this);
for (BroadcastEvent.Type type : BroadcastEvent.Type.values()) {
intentFilter.addAction(type.getAction());
}
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter);
}
@Override
public void onConferenceTerminated(Map<String, Object> data) {
JitsiMeetLogger.i("Conference terminated: " + data);
finish();
}
private void onBroadcastReceived(Intent intent) {
if (intent != null) {
BroadcastEvent event = new BroadcastEvent(intent);
@Override
public void onConferenceWillJoin(Map<String, Object> data) {
JitsiMeetLogger.i("Conference will join: " + data);
switch (event.getType()) {
case CONFERENCE_JOINED:
onConferenceJoined(event.getData());
break;
case CONFERENCE_WILL_JOIN:
onConferenceWillJoin(event.getData());
break;
case CONFERENCE_TERMINATED:
onConferenceTerminated(event.getData());
break;
case PARTICIPANT_JOINED:
onParticipantJoined(event.getData());
break;
case PARTICIPANT_LEFT:
onParticipantLeft(event.getData());
break;
}
}
}
}

View File

@@ -24,6 +24,8 @@ import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.core.PermissionListener;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
/**
* Helper class to encapsulate the work which needs to be done on
* {@link Activity} lifecycle methods in order for the React side to be aware of
@@ -177,6 +179,16 @@ public class JitsiMeetActivityDelegate {
public static void requestPermissions(Activity activity, String[] permissions, int requestCode, PermissionListener listener) {
permissionListener = listener;
activity.requestPermissions(permissions, requestCode);
// The RN Permissions module calls this in a non-UI thread. What we observe is a crash in ViewGroup.dispatchCancelPendingInputEvents,
// which is called on the calling (ie, non-UI) thread. This doesn't look very safe, so try to avoid a crash by pretending the permission
// was denied.
try {
activity.requestPermissions(permissions, requestCode);
} catch (Exception e) {
JitsiMeetLogger.e(e, "Error requesting permissions");
onRequestPermissionsResult(requestCode, permissions, new int[0]);
}
}
}

View File

@@ -21,11 +21,13 @@ import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.IBinder;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
/**
* This class implements an Android {@link Service}, a foreground one specifically, and it's
@@ -35,19 +37,18 @@ import org.jitsi.meet.sdk.log.JitsiMeetLogger;
* See: https://developer.android.com/guide/components/services
*/
public class JitsiMeetOngoingConferenceService extends Service
implements OngoingConferenceTracker.OngoingConferenceListener {
implements OngoingConferenceTracker.OngoingConferenceListener {
private static final String TAG = JitsiMeetOngoingConferenceService.class.getSimpleName();
static final class Actions {
static final String START = TAG + ":START";
static final String HANGUP = TAG + ":HANGUP";
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver();
private boolean isAudioMuted;
static void launch(Context context) {
OngoingNotification.createOngoingConferenceNotificationChannel();
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
intent.setAction(Actions.START);
intent.setAction(Action.START.getName());
ComponentName componentName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -70,11 +71,16 @@ public class JitsiMeetOngoingConferenceService extends Service
super.onCreate();
OngoingConferenceTracker.getInstance().addListener(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BroadcastEvent.Type.AUDIO_MUTED_CHANGED.getAction());
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(broadcastReceiver, intentFilter);
}
@Override
public void onDestroy() {
OngoingConferenceTracker.getInstance().removeListener(this);
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
@@ -86,26 +92,37 @@ public class JitsiMeetOngoingConferenceService extends Service
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
if (Actions.START.equals(action)) {
Notification notification = OngoingNotification.buildOngoingConferenceNotification();
if (notification == null) {
final String actionName = intent.getAction();
final Action action = Action.fromName(actionName);
switch (action) {
case UNMUTE:
case MUTE:
Intent muteBroadcastIntent = BroadcastIntentHelper.buildSetAudioMutedIntent(action == Action.MUTE);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(muteBroadcastIntent);
break;
case START:
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
if (notification == null) {
stopSelf();
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
} else {
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
JitsiMeetLogger.i(TAG + " Service started");
}
break;
case HANGUP:
JitsiMeetLogger.i(TAG + " Hangup requested");
Intent hangupBroadcastIntent = BroadcastIntentHelper.buildHangUpIntent();
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(hangupBroadcastIntent);
stopSelf();
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
} else {
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
JitsiMeetLogger.i(TAG + " Service started");
}
} else if (Actions.HANGUP.equals(action)) {
JitsiMeetLogger.i(TAG + " Hangup requested");
// Abort all ongoing calls
if (AudioModeModule.useConnectionService()) {
ConnectionService.abortConnections();
}
stopSelf();
} else {
JitsiMeetLogger.w(TAG + " Unknown action received: " + action);
stopSelf();
break;
default:
JitsiMeetLogger.w(TAG + " Unknown action received: " + action);
stopSelf();
break;
}
return START_NOT_STICKY;
@@ -118,4 +135,46 @@ public class JitsiMeetOngoingConferenceService extends Service
JitsiMeetLogger.i(TAG + "Service stopped");
}
}
public enum Action {
START(TAG + ":START"),
HANGUP(TAG + ":HANGUP"),
MUTE(TAG + ":MUTE"),
UNMUTE(TAG + ":UNMUTE");
private final String name;
Action(String name) {
this.name = name;
}
public static Action fromName(String name) {
for (Action action : Action.values()) {
if (action.name.equalsIgnoreCase(name)) {
return action;
}
}
return null;
}
public String getName() {
return name;
}
}
private class BroadcastReceiver extends android.content.BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
isAudioMuted = Boolean.parseBoolean(intent.getStringExtra("muted"));
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
if (notification == null) {
stopSelf();
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
} else {
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
JitsiMeetLogger.i(TAG + " Service started");
}
}
}
}

View File

@@ -197,6 +197,7 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
* by/associated with the specified {@code name}.
*/
@Override
@Deprecated
protected void onExternalAPIEvent(String name, ReadableMap data) {
onExternalAPIEvent(LISTENER_METHODS, name, data);
}

View File

@@ -21,6 +21,7 @@ import java.util.Map;
/**
* Interface for listening to events coming from Jitsi Meet.
*/
@Deprecated
public interface JitsiMeetViewListener {
/**
* Called when a conference was joined.

View File

@@ -32,6 +32,7 @@ import java.util.regex.Pattern;
* Utility methods for helping with transforming {@link ExternalAPIModule}
* events into listener methods. Used with descendants of {@link BaseReactView}.
*/
@Deprecated
public final class ListenerUtils {
/**
* Extracts the methods defined in a listener and creates a mapping of this

View File

@@ -23,13 +23,14 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.util.Random;
/**
* Helper class for creating the ongoing notification which is used with
* {@link JitsiMeetOngoingConferenceService}. It allows the user to easily get back to the app
@@ -43,7 +44,6 @@ class OngoingNotification {
static final int NOTIFICATION_ID = new Random().nextInt(99999) + 10000;
static void createOngoingConferenceNotificationChannel() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return;
@@ -56,7 +56,7 @@ class OngoingNotification {
}
NotificationManager notificationManager
= (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel
= notificationManager.getNotificationChannel(CHANNEL_ID);
@@ -73,7 +73,7 @@ class OngoingNotification {
notificationManager.createNotificationChannel(channel);
}
static Notification buildOngoingConferenceNotification() {
static Notification buildOngoingConferenceNotification(boolean isMuted) {
Context context = ReactInstanceManagerHolder.getCurrentActivity();
if (context == null) {
JitsiMeetLogger.w(TAG + " Cannot create notification: no current context");
@@ -83,12 +83,7 @@ class OngoingNotification {
Intent notificationIntent = new Intent(context, context.getClass());
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
NotificationCompat.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(context, CHANNEL_ID);
} else {
builder = new NotificationCompat.Builder(context);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
builder
.setCategory(NotificationCompat.CATEGORY_CALL)
@@ -99,21 +94,28 @@ class OngoingNotification {
.setOngoing(true)
.setAutoCancel(false)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setUsesChronometer(true)
.setOnlyAlertOnce(true)
.setSmallIcon(context.getResources().getIdentifier("ic_notification", "drawable", context.getPackageName()));
// Add a "hang-up" action only if we are using ConnectionService.
if (AudioModeModule.useConnectionService()) {
Intent hangupIntent = new Intent(context, JitsiMeetOngoingConferenceService.class);
hangupIntent.setAction(JitsiMeetOngoingConferenceService.Actions.HANGUP);
PendingIntent hangupPendingIntent
= PendingIntent.getService(context, 0, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action hangupAction = new NotificationCompat.Action(0, "Hang up", hangupPendingIntent);
NotificationCompat.Action hangupAction = createAction(context, JitsiMeetOngoingConferenceService.Action.HANGUP, R.string.ongoing_notification_action_hang_up);
builder.addAction(hangupAction);
}
JitsiMeetOngoingConferenceService.Action toggleAudioAction = isMuted
? JitsiMeetOngoingConferenceService.Action.UNMUTE : JitsiMeetOngoingConferenceService.Action.MUTE;
int toggleAudioTitle = isMuted ? R.string.ongoing_notification_action_unmute : R.string.ongoing_notification_action_mute;
NotificationCompat.Action audioAction = createAction(context, toggleAudioAction, toggleAudioTitle);
builder.addAction(hangupAction);
builder.addAction(audioAction);
return builder.build();
}
private static NotificationCompat.Action createAction(Context context, JitsiMeetOngoingConferenceService.Action action, @StringRes int titleId) {
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
intent.setAction(action.getName());
PendingIntent pendingIntent
= PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
String title = context.getString(titleId);
return new NotificationCompat.Action(0, title, pendingIntent);
}
}

View File

@@ -0,0 +1,27 @@
package org.jitsi.meet.sdk;
import com.google.gson.annotations.SerializedName;
public class ParticipantInfo {
@SerializedName("participantId")
public String id;
@SerializedName("displayName")
public String displayName;
@SerializedName("avatarUrl")
public String avatarUrl;
@SerializedName("email")
public String email;
@SerializedName("name")
public String name;
@SerializedName("isLocal")
public boolean isLocal;
@SerializedName("role")
public String role;
}

View File

@@ -0,0 +1,90 @@
package org.jitsi.meet.sdk;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
public class ParticipantsService extends android.content.BroadcastReceiver {
private static final String TAG = ParticipantsService.class.getSimpleName();
private static final String REQUEST_ID = "requestId";
private final Map<String, WeakReference<ParticipantsInfoCallback>> participantsInfoCallbackMap = new HashMap<>();
private static ParticipantsService instance;
@Nullable
public static ParticipantsService getInstance() {
return instance;
}
private ParticipantsService(Context context) {
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BroadcastEvent.Type.PARTICIPANTS_INFO_RETRIEVED.getAction());
localBroadcastManager.registerReceiver(this, intentFilter);
}
static void init(Context context) {
instance = new ParticipantsService(context);
}
public void retrieveParticipantsInfo(ParticipantsInfoCallback participantsInfoCallback) {
String callbackKey = UUID.randomUUID().toString();
this.participantsInfoCallbackMap.put(callbackKey, new WeakReference<>(participantsInfoCallback));
String actionName = BroadcastAction.Type.RETRIEVE_PARTICIPANTS_INFO.getAction();
WritableMap data = Arguments.createMap();
data.putString(REQUEST_ID, callbackKey);
ReactInstanceManagerHolder.emitEvent(actionName, data);
}
@Override
public void onReceive(Context context, Intent intent) {
BroadcastEvent event = new BroadcastEvent(intent);
switch (event.getType()) {
case PARTICIPANTS_INFO_RETRIEVED:
try {
List<ParticipantInfo> participantInfoList = new Gson().fromJson(
event.getData().get("participantsInfo").toString(),
new TypeToken<ArrayList<ParticipantInfo>>() {
}.getType());
ParticipantsInfoCallback participantsInfoCallback = this.participantsInfoCallbackMap.get(event.getData().get(REQUEST_ID).toString()).get();
if (participantsInfoCallback != null) {
participantsInfoCallback.onReceived(participantInfoList);
this.participantsInfoCallbackMap.remove(participantsInfoCallback);
}
} catch (Exception e) {
JitsiMeetLogger.w(TAG + "error parsing participantsList", e);
}
break;
}
}
public interface ParticipantsInfoCallback {
void onReceived(List<ParticipantInfo> participantInfoList);
}
}

View File

@@ -43,6 +43,7 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
private static final String TAG = NAME;
private static boolean isSupported;
private boolean isDisabled;
public PictureInPictureModule(ReactApplicationContext reactContext) {
super(reactContext);
@@ -83,6 +84,10 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
*/
@TargetApi(Build.VERSION_CODES.O)
public void enterPictureInPicture() {
if (isDisabled) {
return;
}
if (!isSupported) {
throw new IllegalStateException("Picture-in-Picture not supported");
}
@@ -126,6 +131,11 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void setPictureInPictureDisabled(Boolean disabled) {
this.isDisabled = disabled;
}
public boolean isPictureInPictureSupported() {
return isSupported;
}

View File

@@ -20,21 +20,21 @@ import android.app.Activity;
import androidx.annotation.Nullable;
import com.facebook.hermes.reactexecutor.HermesExecutorFactory;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.devsupport.DevInternalSettings;
import com.facebook.react.jscexecutor.JSCExecutorFactory;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader;
import com.oney.WebRTCModule.RTCVideoViewManager;
import com.oney.WebRTCModule.WebRTCModule;
import org.devio.rn.splashscreen.SplashScreenModule;
import org.webrtc.SoftwareVideoDecoderFactory;
import org.webrtc.SoftwareVideoEncoderFactory;
import org.webrtc.audio.AudioDeviceModule;
@@ -68,6 +68,7 @@ class ReactInstanceManagerHolder {
new JavaScriptSandboxModule(reactContext),
new LocaleDetector(reactContext),
new LogBridgeModule(reactContext),
new SplashScreenModule(reactContext),
new PictureInPictureModule(reactContext),
new ProximityModule(reactContext),
new WiFiStatsModule(reactContext),
@@ -90,14 +91,6 @@ class ReactInstanceManagerHolder {
nativeModules.add(new WebRTCModule(reactContext, options));
try {
Class<?> amplitudeModuleClass = Class.forName("org.jitsi.meet.sdk.AmplitudeModule");
Constructor constructor = amplitudeModuleClass.getConstructor(ReactApplicationContext.class);
nativeModules.add((NativeModule)constructor.newInstance(reactContext));
} catch (Exception e) {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
}
return nativeModules;
}
@@ -191,6 +184,7 @@ class ReactInstanceManagerHolder {
new com.facebook.react.shell.MainReactPackage(),
new com.horcrux.svg.SvgPackage(),
new com.kevinresol.react_native_default_preference.RNDefaultPreferencePackage(),
new com.learnium.RNDeviceInfo.RNDeviceInfo(),
new com.ocetnik.timer.BackgroundTimerPackage(),
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
new com.reactnativecommunity.netinfo.NetInfoPackage(),
@@ -216,8 +210,9 @@ class ReactInstanceManagerHolder {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
}
// Use the Hermes JavaScript engine.
HermesExecutorFactory jsFactory = new HermesExecutorFactory();
// Keep on using JSC, the jury is out on Hermes.
JSCExecutorFactory jsFactory
= new JSCExecutorFactory("", "");
reactInstanceManager
= ReactInstanceManager.builder()

View File

@@ -3,4 +3,7 @@
<string name="dropbox_app_key"></string>
<string name="ongoing_notification_title">Ongoing meeting</string>
<string name="ongoing_notification_text">You are currently in a meeting. Tap to return to it.</string>
<string name="ongoing_notification_action_hang_up">Hang up</string>
<string name="ongoing_notification_action_mute">Mute</string>
<string name="ongoing_notification_action_unmute">Unmute</string>
</resources>

View File

@@ -1,16 +1,18 @@
rootProject.name = 'jitsi-meet'
include ':app', ':sdk'
include ':react-native-async-storage'
project(':react-native-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-async-storage/async-storage/android')
include ':react-native-background-timer'
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
include ':react-native-calendar-events'
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
include ':react-native-community-async-storage'
project(':react-native-community-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
include ':react-native-community_netinfo'
project(':react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
include ':react-native-default-preference'
project(':react-native-default-preference').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-default-preference/android')
include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-google-signin'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/google-signin/android')
include ':react-native-immersive'
@@ -21,6 +23,8 @@ include ':react-native-linear-gradient'
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
include ':react-native-sound'
project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
include ':react-native-splash-screen'
project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android')
include ':react-native-svg'
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
include ':react-native-webrtc'

19
app.js
View File

@@ -4,13 +4,29 @@ import 'jquery';
import 'jquery-contextmenu';
import 'jQuery-Impromptu';
import 'olm';
import 'focus-visible';
// We need to setup the jitsi-local-storage as early as possible so that we can start using it.
// NOTE: If jitsi-local-storage is used before the initial setup is performed this will break the use case when we use
// the local storage from the parent page when the localStorage is disabled. Also the setup is relying that
// window.location is not changed and still has all URL parameters.
import './react/features/base/jitsi-local-storage/setup';
import conference from './conference';
import API from './modules/API';
import UI from './modules/UI/UI';
import keyboardshortcut from './modules/keyboardshortcut/keyboardshortcut';
import remoteControl from './modules/remotecontrol/RemoteControl';
import translation from './modules/translation/translation';
// Initialize Olm as early as possible.
if (window.Olm) {
window.Olm.init().catch(e => {
console.error('Failed to initialize Olm, E2EE will be disabled', e);
delete window.Olm;
});
}
window.APP = {
API,
conference,
@@ -32,7 +48,6 @@ window.APP = {
},
keyboardshortcut,
remoteControl,
translation,
UI
};

View File

@@ -3,7 +3,6 @@
import EventEmitter from 'events';
import Logger from 'jitsi-meet-logger';
import * as JitsiMeetConferenceEvents from './ConferenceEvents';
import { openConnection } from './connection';
import { ENDPOINT_TEXT_MESSAGE_NAME } from './modules/API/constants';
import AuthHandler from './modules/UI/authentication/AuthHandler';
@@ -24,7 +23,6 @@ import {
reloadWithStoredParams
} from './react/features/app/actions';
import {
AVATAR_ID_COMMAND,
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
authStatusChanged,
@@ -35,6 +33,7 @@ import {
conferenceLeft,
conferenceSubjectChanged,
conferenceTimestampChanged,
conferenceUniqueIdSet,
conferenceWillJoin,
conferenceWillLeave,
dataChannelOpened,
@@ -42,8 +41,7 @@ import {
lockStateChanged,
onStartMutedPolicyChanged,
p2pStatusChanged,
sendLocalParticipant,
setDesktopSharingEnabled
sendLocalParticipant
} from './react/features/base/conference';
import {
checkAndNotifyForNewDevice,
@@ -55,6 +53,7 @@ import {
updateDeviceList
} from './react/features/base/devices';
import {
browser,
isFatalJitsiConnectionError,
JitsiConferenceErrors,
JitsiConferenceEvents,
@@ -66,6 +65,8 @@ import {
JitsiTrackEvents
} from './react/features/base/lib-jitsi-meet';
import {
getStartWithAudioMuted,
getStartWithVideoMuted,
isVideoMutedByUser,
MEDIA_TYPE,
setAudioAvailable,
@@ -85,7 +86,8 @@ import {
participantMutedUs,
participantPresenceChanged,
participantRoleChanged,
participantUpdated
participantUpdated,
updateRemoteParticipantFeatures
} from './react/features/base/participants';
import {
getUserSelectedCameraDeviceId,
@@ -97,20 +99,17 @@ import {
destroyLocalTracks,
getLocalJitsiAudioTrack,
getLocalJitsiVideoTrack,
isLocalVideoTrackMuted,
isLocalCameraTrackMuted,
isLocalTrackMuted,
isUserInteractionRequiredForUnmute,
replaceLocalTrack,
trackAdded,
trackRemoved
} from './react/features/base/tracks';
import {
getBackendSafePath,
getJitsiMeetGlobalNS
} from './react/features/base/util';
import { downloadJSON } from './react/features/base/util/downloadJSON';
import { getConferenceOptions } from './react/features/conference/functions';
import { showDesktopPicker } from './react/features/desktop-picker';
import { appendSuffix } from './react/features/display-name';
import { setE2EEKey } from './react/features/e2ee';
import {
maybeOpenFeedbackDialog,
submitFeedback
@@ -124,15 +123,13 @@ import {
isPrejoinPageVisible,
makePrecallTest
} from './react/features/prejoin';
import { createRnnoiseProcessorPromise } from './react/features/rnnoise';
import { disableReceiver, stopReceiver } from './react/features/remote-control';
import { toggleScreenshotCaptureEffect } from './react/features/screenshot-capture';
import { setSharedVideoStatus } from './react/features/shared-video';
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
import { createPresenterEffect } from './react/features/stream-effects/presenter';
import { endpointMessageReceived } from './react/features/subtitles';
import UIEvents from './service/UI/UIEvents';
import * as RemoteControlEvents
from './service/remotecontrol/RemoteControlEvents';
const logger = Logger.getLogger(__filename);
@@ -173,7 +170,6 @@ window.JitsiMeetScreenObtainer = {
* Known custom conference commands.
*/
const commands = {
AVATAR_ID: AVATAR_ID_COMMAND,
AVATAR_URL: AVATAR_URL_COMMAND,
CUSTOM_ROLE: 'custom-role',
EMAIL: EMAIL_COMMAND,
@@ -445,17 +441,8 @@ export default {
* the tracks won't exist).
*/
_localTracksInitialized: false,
isSharingScreen: false,
/**
* Indicates if the desktop sharing functionality has been enabled.
* It takes into consideration the status returned by
* {@link JitsiMeetJS.isDesktopSharingEnabled()}. The latter can be false
* either if the desktop sharing is not supported by the current browser
* or if it was disabled through lib-jitsi-meet specific options (check
* config.js for listed options).
*/
isDesktopSharingEnabled: false,
isSharingScreen: false,
/**
* The local audio track (if any).
@@ -486,8 +473,8 @@ export default {
*/
createInitialLocalTracks(options = {}) {
const errors = {};
const initialDevices = [ 'audio' ];
const requestedAudio = true;
const initialDevices = config.disableInitialGUM ? [] : [ 'audio' ];
const requestedAudio = !config.disableInitialGUM;
let requestedVideo = false;
// Always get a handle on the audio input device so that we have statistics even if the user joins the
@@ -498,22 +485,30 @@ export default {
this.muteAudio(true, true);
}
if (!options.startWithVideoMuted
if (!config.disableInitialGUM
&& !options.startWithVideoMuted
&& !options.startAudioOnly
&& !options.startScreenSharing) {
initialDevices.push('video');
requestedVideo = true;
}
JitsiMeetJS.mediaDevices.addEventListener(
JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN,
browser =>
APP.store.dispatch(
mediaPermissionPromptVisibilityChanged(true, browser))
);
if (!config.disableInitialGUM) {
JitsiMeetJS.mediaDevices.addEventListener(
JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN,
browserName =>
APP.store.dispatch(
mediaPermissionPromptVisibilityChanged(true, browserName))
);
}
let tryCreateLocalTracks;
// On Electron there is no permission prompt for granting permissions. That's why we don't need to
// spend much time displaying the overlay screen. If GUM is not resolved withing 15 seconds it will
// probably never resolve.
const timeout = browser.isElectron() ? 15000 : 60000;
// FIXME is there any simpler way to rewrite this spaghetti below ?
if (options.startScreenSharing) {
tryCreateLocalTracks = this._createDesktopTrack()
@@ -522,7 +517,10 @@ export default {
return [ desktopStream ];
}
return createLocalTracksF({ devices: [ 'audio' ] }, true)
return createLocalTracksF({
devices: [ 'audio' ],
timeout
}, true)
.then(([ audioStream ]) =>
[ desktopStream, audioStream ])
.catch(error => {
@@ -536,7 +534,10 @@ export default {
errors.screenSharingError = error;
return requestedAudio
? createLocalTracksF({ devices: [ 'audio' ] }, true)
? createLocalTracksF({
devices: [ 'audio' ],
timeout
}, true)
: [];
})
.catch(error => {
@@ -548,15 +549,33 @@ export default {
// Resolve with no tracks
tryCreateLocalTracks = Promise.resolve([]);
} else {
tryCreateLocalTracks = createLocalTracksF({ devices: initialDevices }, true)
tryCreateLocalTracks = createLocalTracksF({
devices: initialDevices,
timeout
}, true)
.catch(err => {
if (requestedAudio && requestedVideo) {
// Try audio only...
errors.audioAndVideoError = err;
if (err.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
// In this case we expect that the permission prompt is still visible. There is no point of
// executing GUM with different source. Also at the time of writting the following
// inconsistency have been noticed in some browsers - if the permissions prompt is visible
// and another GUM is executed the prompt does not change its content but if the user
// clicks allow the user action isassociated with the latest GUM call.
errors.audioOnlyError = err;
errors.videoOnlyError = err;
return [];
}
return (
createLocalTracksF({ devices: [ 'audio' ] }, true));
createLocalTracksF({
devices: [ 'audio' ],
timeout
}, true));
} else if (requestedAudio && !requestedVideo) {
errors.audioOnlyError = err;
@@ -577,7 +596,10 @@ export default {
// Try video only...
return requestedVideo
? createLocalTracksF({ devices: [ 'video' ] }, true)
? createLocalTracksF({
devices: [ 'video' ],
timeout
}, true)
: [];
})
.catch(err => {
@@ -608,6 +630,42 @@ export default {
};
},
/**
* Displays error notifications according to the state carried by {@code errors} object returned
* by {@link createInitialLocalTracks}.
* @param {Object} errors - the errors (if any) returned by {@link createInitialLocalTracks}.
*
* @returns {void}
* @private
*/
_displayErrorsForCreateInitialLocalTracks(errors) {
const {
audioAndVideoError,
audioOnlyError,
screenSharingError,
videoOnlyError
} = errors;
// FIXME If there will be microphone error it will cover any screensharing dialog, but it's still better than in
// the reverse order where the screensharing dialog will sometimes be closing the microphone alert
// ($.prompt.close(); is called). Need to figure out dialogs chaining to fix that.
if (screenSharingError) {
this._handleScreenSharingError(screenSharingError);
}
if (audioAndVideoError || audioOnlyError) {
if (audioOnlyError || videoOnlyError) {
// If both requests for 'audio' + 'video' and 'audio' only failed, we assume that there are some
// problems with user's microphone and show corresponding dialog.
APP.store.dispatch(notifyMicError(audioOnlyError));
APP.store.dispatch(notifyCameraError(videoOnlyError));
} else {
// If request for 'audio' + 'video' failed, but request for 'audio' only was OK, we assume that we had
// problems with camera and show corresponding dialog.
APP.store.dispatch(notifyCameraError(audioAndVideoError));
}
}
},
/**
* Creates local media tracks and connects to a room. Will show error
* dialogs in case accessing the local microphone and/or camera failed. Will
@@ -628,38 +686,11 @@ export default {
*/
createInitialLocalTracksAndConnect(roomName, options = {}) {
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(options);
const {
audioAndVideoError,
audioOnlyError,
screenSharingError,
videoOnlyError
} = errors;
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
.then(([ tracks, con ]) => {
// FIXME If there will be microphone error it will cover any
// screensharing dialog, but it's still better than in
// the reverse order where the screensharing dialog will
// sometimes be closing the microphone alert ($.prompt.close();
// is called). Need to figure out dialogs chaining to fix that.
if (screenSharingError) {
this._handleScreenSharingError(screenSharingError);
}
if (audioAndVideoError || audioOnlyError) {
if (audioOnlyError || videoOnlyError) {
// If both requests for 'audio' + 'video' and 'audio'
// only failed, we assume that there are some problems
// with user's microphone and show corresponding dialog.
APP.store.dispatch(notifyMicError(audioOnlyError));
APP.store.dispatch(notifyCameraError(videoOnlyError));
} else {
// If request for 'audio' + 'video' failed, but request
// for 'audio' only was OK, we assume that we had
// problems with camera and show corresponding dialog.
APP.store.dispatch(
notifyCameraError(audioAndVideoError));
}
}
this._displayErrorsForCreateInitialLocalTracks(errors);
return [ tracks, con ];
});
@@ -683,16 +714,7 @@ export default {
con.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED, _connectionFailedHandler);
APP.connection = connection = con;
// Desktop sharing related stuff:
this.isDesktopSharingEnabled
= JitsiMeetJS.isDesktopSharingEnabled();
eventEmitter.emit(JitsiMeetConferenceEvents.DESKTOP_SHARING_ENABLED_CHANGED, this.isDesktopSharingEnabled);
APP.store.dispatch(
setDesktopSharingEnabled(this.isDesktopSharingEnabled));
this._createRoom(tracks);
APP.remoteControl.init();
// if user didn't give access to mic or camera or doesn't have
// them at all, we mark corresponding toolbar buttons as muted,
@@ -737,17 +759,15 @@ export default {
const initialOptions = {
startAudioOnly: config.startAudioOnly,
startScreenSharing: config.startScreenSharing,
startWithAudioMuted: config.startWithAudioMuted
startWithAudioMuted: getStartWithAudioMuted(APP.store.getState())
|| config.startSilent
|| isUserInteractionRequiredForUnmute(APP.store.getState()),
startWithVideoMuted: config.startWithVideoMuted
startWithVideoMuted: getStartWithVideoMuted(APP.store.getState())
|| isUserInteractionRequiredForUnmute(APP.store.getState())
};
this.roomName = roomName;
window.addEventListener('hashchange', this.onHashChange.bind(this), false);
try {
// Initialize the device list first. This way, when creating tracks
// based on preferred devices, loose label matching can be done in
@@ -778,7 +798,15 @@ export default {
// they may remain as empty strings.
this._initDeviceList(true);
return APP.store.dispatch(initPrejoin(tracks, errors));
if (isPrejoinPageVisible(APP.store.getState())) {
return APP.store.dispatch(initPrejoin(tracks, errors));
}
logger.debug('Prejoin screen no longer displayed at the time when tracks were created');
this._displayErrorsForCreateInitialLocalTracks(errors);
return this._setLocalAudioVideoStreams(tracks);
}
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(
@@ -817,7 +845,7 @@ export default {
isLocalVideoMuted() {
// If the tracks are not ready, read from base/media state
return this._localTracksInitialized
? isLocalVideoTrackMuted(
? isLocalCameraTrackMuted(
APP.store.getState()['features/base/tracks'])
: isVideoMutedByUser(APP.store);
},
@@ -1140,20 +1168,6 @@ export default {
return room ? room.getParticipantById(id) : null;
},
/**
* Get participant connection status for the participant.
*
* @param {string} id participant's identifier(MUC nickname)
*
* @returns {ParticipantConnectionStatus|null} the status of the participant
* or null if no such participant is found or participant is the local user.
*/
getParticipantConnectionStatus(id) {
const participant = this.getParticipantById(id);
return participant ? participant.getConnectionStatus() : null;
},
/**
* Gets the display name foe the <tt>JitsiParticipant</tt> identified by
* the given <tt>id</tt>.
@@ -1224,47 +1238,8 @@ export default {
// this can be called from console and will not have reference to this
// that's why we reference the global var
const logs = APP.connection.getLogs();
const data = encodeURIComponent(JSON.stringify(logs, null, ' '));
const elem = document.createElement('a');
elem.download = filename;
elem.href = `data:application/json;charset=utf-8,\n${data}`;
elem.dataset.downloadurl
= [ 'text/json', elem.download, elem.href ].join(':');
elem.dispatchEvent(new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: false
}));
},
/**
* Handled location hash change events.
*/
onHashChange() {
const items = {};
const parts = window.location.hash.substr(1).split('&');
for (const part of parts) {
const param = part.split('=');
const key = param[0];
if (!key) {
continue; // eslint-disable-line no-continue
}
items[key] = param[1];
}
if (typeof items.e2eekey !== 'undefined') {
APP.store.dispatch(setE2EEKey(items.e2eekey));
// Clean URL in browser history.
const cleanUrl = window.location.href.split('#')[0];
history.replaceState(history.state, document.title, cleanUrl);
}
downloadJSON(logs, filename);
},
/**
@@ -1360,53 +1335,7 @@ export default {
},
_getConferenceOptions() {
const options = config;
const { email, name: nick } = getLocalParticipant(APP.store.getState());
const state = APP.store.getState();
const { locationURL } = state['features/base/connection'];
const { tenant } = state['features/base/jwt'];
if (tenant) {
options.siteID = tenant;
}
if (options.enableDisplayNameInStats && nick) {
options.statisticsDisplayName = nick;
}
if (options.enableEmailInStats && email) {
options.statisticsId = email;
}
options.applicationName = interfaceConfig.APP_NAME;
options.getWiFiStatsMethod = this._getWiFiStatsMethod;
options.confID = `${locationURL.host}${getBackendSafePath(locationURL.pathname)}`;
options.createVADProcessor = createRnnoiseProcessorPromise;
// Disable CallStats, if requessted.
if (options.disableThirdPartyRequests) {
delete options.callStatsID;
delete options.callStatsSecret;
delete options.getWiFiStatsMethod;
}
return options;
},
/**
* Returns the result of getWiFiStats from the global NS or does nothing
* (returns empty result).
* Fixes a concurrency problem where we need to pass a function when creating
* JitsiConference, but that method is added to the context later.
*
* @returns {Promise}
* @private
*/
_getWiFiStatsMethod() {
const gloabalNS = getJitsiMeetGlobalNS();
return gloabalNS.getWiFiStats ? gloabalNS.getWiFiStats() : Promise.resolve('{}');
return getConferenceOptions(APP.store.getState());
},
/**
@@ -1550,11 +1479,8 @@ export default {
async _turnScreenSharingOff(didHaveVideo) {
this._untoggleScreenSharing = null;
this.videoSwitchInProgress = true;
const { receiver } = APP.remoteControl;
if (receiver) {
receiver.stop();
}
APP.store.dispatch(stopReceiver());
this._stopProxyConnection();
if (config.enableScreenshotCapture) {
@@ -1637,9 +1563,8 @@ export default {
if (this.videoSwitchInProgress) {
return Promise.reject('Switch in progress.');
}
if (!this.isDesktopSharingEnabled) {
return Promise.reject(
'Cannot toggle screen sharing: not supported.');
if (!JitsiMeetJS.isDesktopSharingEnabled()) {
return Promise.reject('Cannot toggle screen sharing: not supported.');
}
if (this.isAudioOnly()) {
@@ -1729,8 +1654,10 @@ export default {
*/
async _createPresenterStreamEffect(height = null, cameraDeviceId = null) {
if (!this.localPresenterVideo) {
const camera = cameraDeviceId ?? getUserSelectedCameraDeviceId(APP.store.getState());
try {
this.localPresenterVideo = await createLocalPresenterTrack({ cameraDeviceId }, height);
this.localPresenterVideo = await createLocalPresenterTrack({ cameraDeviceId: camera }, height);
} catch (err) {
logger.error('Failed to create a camera track for presenter', err);
@@ -1771,38 +1698,38 @@ export default {
// Create a new presenter track and apply the presenter effect.
if (!this.localPresenterVideo && !mute) {
let { aspectRatio, height } = this.localVideo.track.getSettings();
const { width } = this.localVideo.track.getSettings();
let desktopResizeConstraints = {};
let resizeDesktopStream = false;
const { height, width } = this.localVideo.track.getSettings() ?? this.localVideo.track.getConstraints();
const isPortrait = height >= width;
const DESKTOP_STREAM_CAP = 720;
// Determine the constraints if the desktop track needs to be resized.
// Resizing is needed when the resolution cannot be determined or when
// the window is bigger than 720p.
if (height && width) {
aspectRatio = aspectRatio ?? (width / height).toPrecision(4);
const advancedConstraints = [ { aspectRatio } ];
const isPortrait = height >= width;
// Config.js setting for resizing high resolution desktop tracks to 720p when presenter is turned on.
const resizeEnabled = config.videoQuality && config.videoQuality.resizeDesktopForPresenter;
const highResolutionTrack
= (isPortrait && width > DESKTOP_STREAM_CAP) || (!isPortrait && height > DESKTOP_STREAM_CAP);
// Resizing the desktop track for presenter is causing blurriness of the desktop share on chrome.
// Disable resizing by default, enable it only when config.js setting is enabled.
// Firefox doesn't return width and height for desktop tracks. Therefore, track needs to be resized
// for creating the canvas for presenter.
const resizeDesktopStream = browser.isFirefox() || (highResolutionTrack && resizeEnabled);
// Determine which dimension needs resizing and resize only that side
// keeping the aspect ratio same as before.
if (isPortrait && width > DESKTOP_STREAM_CAP) {
resizeDesktopStream = true;
advancedConstraints.push({ width: DESKTOP_STREAM_CAP });
} else if (!isPortrait && height > DESKTOP_STREAM_CAP) {
resizeDesktopStream = true;
advancedConstraints.push({ height: DESKTOP_STREAM_CAP });
}
desktopResizeConstraints.advanced = advancedConstraints;
} else {
resizeDesktopStream = true;
desktopResizeConstraints = {
width: 1280,
height: 720
};
}
if (resizeDesktopStream) {
let desktopResizeConstraints = {};
if (height && width) {
const advancedConstraints = [ { aspectRatio: (width / height).toPrecision(4) } ];
const constraint = isPortrait ? { width: DESKTOP_STREAM_CAP } : { height: DESKTOP_STREAM_CAP };
advancedConstraints.push(constraint);
desktopResizeConstraints.advanced = advancedConstraints;
} else {
desktopResizeConstraints = {
width: 1280,
height: 720
};
}
// Apply the contraints on the desktop track.
try {
await this.localVideo.track.applyConstraints(desktopResizeConstraints);
} catch (err) {
@@ -1810,20 +1737,22 @@ export default {
return;
}
height = this.localVideo.track.getSettings().height ?? DESKTOP_STREAM_CAP;
}
const defaultCamera = getUserSelectedCameraDeviceId(APP.store.getState());
const trackHeight = resizeDesktopStream
? this.localVideo.track.getSettings().height ?? DESKTOP_STREAM_CAP
: height;
let effect;
try {
effect = await this._createPresenterStreamEffect(height,
defaultCamera);
effect = await this._createPresenterStreamEffect(trackHeight);
} catch (err) {
logger.error('Failed to unmute Presenter Video');
logger.error('Failed to unmute Presenter Video', err);
maybeShowErrorDialog(err);
return;
}
// Replace the desktop track on the peerconnection.
try {
await this.localVideo.setEffect(effect);
APP.store.dispatch(setVideoMuted(mute, MEDIA_TYPE.PRESENTER));
@@ -1969,13 +1898,18 @@ export default {
APP.store.dispatch(conferenceLeft(room, ...args));
});
room.on(
JitsiConferenceEvents.CONFERENCE_UNIQUE_ID_SET,
(...args) => APP.store.dispatch(conferenceUniqueIdSet(room, ...args)));
room.on(
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
(authEnabled, authLogin) =>
APP.store.dispatch(authStatusChanged(authEnabled, authLogin)));
room.on(JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED,
user => APP.UI.onUserFeaturesChanged(user));
room.on(JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED, user => {
APP.store.dispatch(updateRemoteParticipantFeatures(user));
});
room.on(JitsiConferenceEvents.USER_JOINED, (id, user) => {
// The logic shared between RN and web.
commonUserJoinedHandling(APP.store, room, user);
@@ -1984,6 +1918,7 @@ export default {
return;
}
APP.store.dispatch(updateRemoteParticipantFeatures(user));
logger.log(`USER ${id} connnected:`, user);
APP.UI.addUser(user);
});
@@ -2116,7 +2051,6 @@ export default {
formattedDisplayName
|| interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME)
});
APP.UI.changeDisplayName(id, formattedDisplayName);
}
);
room.on(
@@ -2154,35 +2088,8 @@ export default {
JitsiConferenceEvents.LOCK_STATE_CHANGED,
(...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
APP.remoteControl.on(RemoteControlEvents.ACTIVE_CHANGED, isActive => {
room.setLocalParticipantProperty(
'remoteControlSessionStatus',
isActive
);
APP.UI.setLocalRemoteControlActiveChanged();
});
/* eslint-disable max-params */
room.on(
JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
(participant, name, oldValue, newValue) => {
switch (name) {
case 'remoteControlSessionStatus':
APP.UI.setRemoteControlActiveStatus(
participant.getId(),
newValue);
break;
default:
// ignore
}
});
room.on(JitsiConferenceEvents.KICKED, participant => {
APP.UI.hideStats();
APP.store.dispatch(kickedOut(room, participant));
// FIXME close
});
room.on(JitsiConferenceEvents.PARTICIPANT_KICKED, (kicker, kicked) => {
@@ -2227,16 +2134,6 @@ export default {
}));
});
room.addCommandListener(this.commands.defaults.AVATAR_ID,
(data, from) => {
APP.store.dispatch(
participantUpdated({
conference: room,
id: from,
avatarID: data.value
}));
});
APP.UI.addListener(UIEvents.NICKNAME_CHANGED,
this.changeLocalDisplayName.bind(this));
@@ -2388,7 +2285,7 @@ export default {
return this.useAudioStream(stream);
})
.then(() => {
if (hasDefaultMicChanged) {
if (this.localAudio && hasDefaultMicChanged) {
// workaround for the default device to be shown as selected in the
// settings even when the real device id was passed to gUM because of the
// above mentioned chrome bug.
@@ -2522,33 +2419,11 @@ export default {
_onConferenceJoined() {
APP.UI.initConference();
APP.keyboardshortcut.init();
if (!config.disableShortcuts) {
APP.keyboardshortcut.init();
}
APP.store.dispatch(conferenceJoined(room));
const displayName
= APP.store.getState()['features/base/settings'].displayName;
APP.UI.changeDisplayName('localVideoContainer', displayName);
},
/**
* Adds any room listener.
* @param {string} eventName one of the JitsiConferenceEvents
* @param {Function} listener the function to be called when the event
* occurs
*/
addConferenceListener(eventName, listener) {
room.on(eventName, listener);
},
/**
* Removes any room listener.
* @param {string} eventName one of the JitsiConferenceEvents
* @param {Function} listener the listener to be removed.
*/
removeConferenceListener(eventName, listener) {
room.off(eventName, listener);
},
/**
@@ -2705,6 +2580,20 @@ export default {
// https://bugs.chromium.org/p/chromium/issues/detail?id=997689
const hasDefaultMicChanged = newDevices.audioinput === 'default';
// This is the case when the local video is muted and a preferred device is connected.
if (requestedInput.video && this.isLocalVideoMuted()) {
// We want to avoid creating a new video track in order to prevent turning on the camera.
requestedInput.video = false;
APP.store.dispatch(updateSettings({ // Update the current selected camera for the device selection dialog.
cameraDeviceId: newDevices.videoinput
}));
delete newDevices.videoinput;
// Removing the current video track in order to force the unmute to select the preferred device.
this.useVideoStream(null);
}
promises.push(
mediaDeviceHelper.createLocalTracksAfterDeviceListChanged(
createLocalTracksF,
@@ -2736,7 +2625,7 @@ export default {
// Use the new stream or null if we failed to obtain it.
return useStream(tracks.find(track => track.getType() === mediaType) || null)
.then(() => {
if (hasDefaultMicChanged) {
if (this.localAudio && hasDefaultMicChanged) {
// workaround for the default device to be shown as selected in the
// settings even when the real device id was passed to gUM because of
// the above mentioned chrome bug.
@@ -2819,7 +2708,7 @@ export default {
* requested
*/
hangup(requestFeedback = false) {
eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
APP.store.dispatch(disableReceiver());
this._stopProxyConnection();
@@ -2836,7 +2725,6 @@ export default {
}
APP.UI.removeAllListeners();
APP.remoteControl.removeAllListeners();
let requestFeedbackPromise;
@@ -3013,33 +2901,6 @@ export default {
APP.store.dispatch(updateSettings({
displayName: formattedNickname
}));
if (room) {
APP.UI.changeDisplayName(id, formattedNickname);
}
},
/**
* Returns the desktop sharing source id or undefined if the desktop sharing
* is not active at the moment.
*
* @returns {string|undefined} - The source id. If the track is not desktop
* track or the source id is not available, undefined will be returned.
*/
getDesktopSharingSourceId() {
return this.localVideo.sourceId;
},
/**
* Returns the desktop sharing source type or undefined if the desktop
* sharing is not active at the moment.
*
* @returns {'screen'|'window'|undefined} - The source type. If the track is
* not desktop track or the source type is not available, undefined will be
* returned.
*/
getDesktopSharingSourceType() {
return this.localVideo.sourceType;
},
/**
@@ -3126,7 +2987,7 @@ export default {
* @param {boolean} muted - New muted status.
*/
setVideoMuteStatus(muted) {
APP.UI.setVideoMuted(this.getMyUserId(), muted);
APP.UI.setVideoMuted(this.getMyUserId());
APP.API.notifyVideoMutedStatusChanged(muted);
},

193
config.js
View File

@@ -14,12 +14,6 @@ var config = {
// Domain for authenticated users. Defaults to <domain>.
// authdomain: 'jitsi-meet.example.com',
// Jirecon recording component domain.
// jirecon: 'jirecon.jitsi-meet.example.com',
// Call control component (Jigasi).
// call_control: 'callcontrol.jitsi-meet.example.com',
// Focus component domain. Defaults to focus.<domain>.
// focus: 'focus.jitsi-meet.example.com',
@@ -67,6 +61,11 @@ var config = {
// adjusted to 2.5 Mbps. This takes a value between 0 and 1 which determines
// the probability for this to be enabled.
// capScreenshareBitrate: 1 // 0 to disable
// Enable callstats only for a percentage of users.
// This takes a value between 0 and 100 which determines the probability for
// the callstats to be enabled.
// callStatsThreshold: 5 // enable callstats for 5% of the users.
},
// Disables ICE/UDP by filtering out local and remote UDP candidates in
@@ -92,6 +91,11 @@ var config = {
// input and will suggest another valid device if one is present.
enableNoAudioDetection: true,
// Enabling this will show a "Save Logs" link in the GSM popover that can be
// used to collect debug information (XMPP IQs, SDP offer/answer cycles)
// about the call.
// enableSaveLogs: false,
// Enabling this will run the lib-jitsi-meet noise detection module which will
// notify the user if there is noise, other than voice, coming from the current
// selected microphone. The purpose it to let the user know that the input could
@@ -118,7 +122,7 @@ var config = {
// Valid values are in the range 6000 to 510000
// opusMaxAverageBitrate: 20000,
// Enables redundancy for Opus
// Enables support for opus-red (redundancy for Opus).
// enableOpusRed: false
// Video
@@ -257,9 +261,16 @@ var config = {
// // the available bandwidth calculated by the browser, but it will be capped by the values specified here.
// // This is currently not implemented on app based clients on mobile.
// maxBitratesVideo: {
// low: 200000,
// standard: 500000,
// high: 1500000
// VP8 : {
// low: 200000,
// standard: 500000,
// high: 1500000
// },
// VP9: {
// low: 100000,
// standard: 300000,
// high: 1200000
// }
// },
//
// // The options can be used to override default thresholds of video thumbnail heights corresponding to
@@ -273,9 +284,13 @@ var config = {
// // at least 360 pixels tall. If the thumbnail height reaches 720 pixels then the application will switch to
// // the high quality.
// minHeightForQualityLvl: {
// 360: 'standard,
// 360: 'standard',
// 720: 'high'
// }
// },
//
// // Provides a way to resize the desktop track to 720p (if it is greater than 720p) before creating a canvas
// // for the presenter mode (camera picture-in-picture mode with screenshare).
// resizeDesktopForPresenter: false
// },
// // Options for the recording limit notification.
@@ -296,18 +311,11 @@ var config = {
// Disables or enables RTX (RFC 4588) (defaults to false).
// disableRtx: false,
// Disables or enables TCC (the default is in Jicofo and set to true)
// (draft-holmer-rmcat-transport-wide-cc-extensions-01). This setting
// affects congestion control, it practically enables send-side bandwidth
// estimations.
// Disables or enables TCC support in this client (default: enabled).
// enableTcc: true,
// Disables or enables REMB (the default is in Jicofo and set to false)
// (draft-alvestrand-rmcat-remb-03). This setting affects congestion
// control, it practically enables recv-side bandwidth estimations. When
// both TCC and REMB are enabled, TCC takes precedence. When both are
// disabled, then bandwidth estimations are disabled.
// enableRemb: false,
// Disables or enables REMB support in this client (default: enabled).
// enableRemb: true,
// Enables ICE restart logic in LJM and displays the page reload overlay on
// ICE failure. Current disabled by default because it's causing issues with
@@ -317,29 +325,22 @@ var config = {
// TCC sequence numbers starting from 0.
// enableIceRestart: false,
// Defines the minimum number of participants to start a call (the default
// is set in Jicofo and set to 2).
// minParticipants: 2,
// Use the TURN servers discovered via XEP-0215 for the jitsi-videobridge
// connection
// useStunTurn: true,
// Enables forced reload of the client when the call is migrated as a result of
// the bridge going down. Currently enabled by default as call migration through
// session-terminate is causing siganling issues when Octo is enabled.
// enableForcedReload: true,
// Use TURN/UDP servers for the jitsi-videobridge connection (by default
// we filter out TURN/UDP because it is usually not needed since the
// bridge itself is reachable via UDP)
// useTurnUdp: false
// Enables / disables a data communication channel with the Videobridge.
// Values can be 'datachannel', 'websocket', true (treat it as
// 'datachannel'), undefined (treat it as 'datachannel') and false (don't
// open any channel).
// openBridgeChannel: true,
// UI
//
// Disables responsive tiles.
// disableResponsiveTiles: false,
// Hides lobby button
// hideLobbyButton: false,
@@ -350,6 +351,13 @@ var config = {
// will be joined when no room is specified.
enableWelcomePage: true,
// Disable app shortcuts that are registered upon joining a conference
// disableShortcuts: false,
// Disable initial browser getUserMedia requests.
// This is useful for scenarios where users might want to start a conference for screensharing only
// disableInitialGUM: false,
// Enabling the close page will ignore the welcome page redirection when
// a call is hangup.
// enableClosePage: false,
@@ -360,17 +368,12 @@ var config = {
// Default language for the user interface.
// defaultLanguage: 'en',
// If true all users without a token will be considered guests and all users
// with token will be considered non-guests. Only guests will be allowed to
// edit their profile.
enableUserRolesBasedOnToken: false,
// Disables profile and the edit of all fields from the profile settings (display name and email)
// disableProfile: false,
// Whether or not some features are checked based on token.
// enableFeaturesBasedOnToken: false,
// Enable lock room for all moderators, even when userRolesBasedOnToken is enabled and participants are guests.
// lockRoomGuestEnabled: false,
// When enabled the password used for locking a room is restricted to up to the number of digits specified
// roomPasswordNumberOfDigits: 10,
// default: roomPasswordNumberOfDigits: false,
@@ -386,6 +389,13 @@ var config = {
// When 'true', it shows an intermediate page before joining, where the user can configure their devices.
// prejoinPageEnabled: false,
// If etherpad integration is enabled, setting this to true will
// automatically open the etherpad when a participant joins. This
// does not affect the mobile app since opening an etherpad
// obscures the conference controls -- it's better to let users
// choose to open the pad on their own in that case.
// openSharedDocumentOnJoin: false,
// If true, shows the unsafe room name warning label when a room name is
// deemed unsafe (due to the simplicity in the name) and a password is not
// set or the lobby is not enabled.
@@ -395,6 +405,9 @@ var config = {
// Document should be focused for this option to work
// enableAutomaticUrlCopy: false,
// Base URL for a Gravatar-compatible service. Defaults to libravatar.
// gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/';
// Stats
//
@@ -439,9 +452,6 @@ var config = {
// connection.
enabled: true,
// Use XEP-0215 to fetch STUN and TURN servers.
// useStunTurn: true,
// The STUN servers that will be used in the peer to peer connections
stunServers: [
@@ -510,6 +520,9 @@ var config = {
// ],
},
// Logs that should go be passed through the 'log' event if a handler is defined for it
// apiLogLevels: ['warn', 'log', 'error', 'info', 'debug'],
// Information about the jitsi-meet instance we are connecting to, including
// the user region as seen by the server.
deploymentInfo: {
@@ -607,6 +620,9 @@ var config = {
// If set to true all muting operations of remote participants will be disabled.
// disableRemoteMute: true,
// Enables support for lip-sync for this client (if the browser supports it).
// enableLipSync: false
/**
External API url used to receive branding specific information.
If there is no url set or there are missing fields, the defaults are applied.
@@ -622,18 +638,31 @@ var config = {
logoImageUrl: 'https://example.com/logo-img.png'
}
*/
// brandingDataUrl: '',
// dynamicBrandingUrl: '',
// The URL of the moderated rooms microservice, if available. If it
// is present, a link to the service will be rendered on the welcome page,
// otherwise the app doesn't render it.
// moderatedRoomServiceUrl: 'https://moderated.jitsi-meet.example.com',
// If true, tile view will not be enabled automatically when the participants count threshold is reached.
// disableTileView: true,
// Hides the conference subject
// hideConferenceSubject: true
// Hides the conference timer.
// hideConferenceTimer: true,
// Hides the participants stats
// hideParticipantsStats: true
// Sets the conference subject
// subject: 'Conference Subject',
// List of undocumented settings used in jitsi-meet
/**
_immediateReloadThreshold
autoRecord
autoRecordToken
debug
debugAudioLevels
deploymentInfo
@@ -677,15 +706,75 @@ var config = {
disableAP
disableHPF
disableNS
enableLipSync
enableTalkWhileMuted
forceJVB121Ratio
forceTurnRelay
hiddenDomain
ignoreStartMuted
nick
startBitrate
websocketKeepAlive
websocketKeepAliveUrl
*/
/**
Use this array to configure which notifications will be shown to the user
The items correspond to the title or description key of that notification
Some of these notifications also depend on some other internal logic to be displayed or not,
so adding them here will not ensure they will always be displayed
A falsy value for this prop will result in having all notifications enabled (e.g null, undefined, false)
*/
// notifications: [
// 'connection.CONNFAIL', // shown when the connection fails,
// 'dialog.cameraNotSendingData', // shown when there's no feed from user's camera
// 'dialog.kickTitle', // shown when user has been kicked
// 'dialog.liveStreaming', // livestreaming notifications (pending, on, off, limits)
// 'dialog.lockTitle', // shown when setting conference password fails
// 'dialog.maxUsersLimitReached', // shown when maximmum users limit has been reached
// 'dialog.micNotSendingData', // shown when user's mic is not sending any audio
// 'dialog.passwordNotSupportedTitle', // shown when setting conference password fails due to password format
// 'dialog.recording', // recording notifications (pending, on, off, limits)
// 'dialog.remoteControlTitle', // remote control notifications (allowed, denied, start, stop, error)
// 'dialog.reservationError',
// 'dialog.serviceUnavailable', // shown when server is not reachable
// 'dialog.sessTerminated', // shown when there is a failed conference session
// 'dialog.sessionRestarted', // show when a client reload is initiated because of bridge migration
// 'dialog.tokenAuthFailed', // show when an invalid jwt is used
// 'dialog.transcribing', // transcribing notifications (pending, off)
// 'dialOut.statusMessage', // shown when dial out status is updated.
// 'liveStreaming.busy', // shown when livestreaming service is busy
// 'liveStreaming.failedToStart', // shown when livestreaming fails to start
// 'liveStreaming.unavailableTitle', // shown when livestreaming service is not reachable
// 'lobby.joinRejectedMessage', // shown when while in a lobby, user's request to join is rejected
// 'lobby.notificationTitle', // shown when lobby is toggled and when join requests are allowed / denied
// 'localRecording.localRecording', // shown when a local recording is started
// 'notify.disconnected', // shown when a participant has left
// 'notify.grantedTo', // shown when moderator rights were granted to a participant
// 'notify.invitedOneMember', // shown when 1 participant has been invited
// 'notify.invitedThreePlusMembers', // shown when 3+ participants have been invited
// 'notify.invitedTwoMembers', // shown when 2 participants have been invited
// 'notify.kickParticipant', // shown when a participant is kicked
// 'notify.mutedRemotelyTitle', // shown when user is muted by a remote party
// 'notify.mutedTitle', // shown when user has been muted upon joining,
// 'notify.newDeviceAudioTitle', // prompts the user to use a newly detected audio device
// 'notify.newDeviceCameraTitle', // prompts the user to use a newly detected camera
// 'notify.passwordRemovedRemotely', // shown when a password has been removed remotely
// 'notify.passwordSetRemotely', // shown when a password has been set remotely
// 'notify.raisedHand', // shown when a partcipant used raise hand,
// 'notify.startSilentTitle', // shown when user joined with no audio
// 'prejoin.errorDialOut',
// 'prejoin.errorDialOutDisconnected',
// 'prejoin.errorDialOutFailed',
// 'prejoin.errorDialOutStatus',
// 'prejoin.errorStatusCode',
// 'prejoin.errorValidation',
// 'recording.busy', // shown when recording service is busy
// 'recording.failedToStart', // shown when recording fails to start
// 'recording.unavailableTitle', // shown when recording service is not reachable
// 'toolbar.noAudioSignalTitle', // shown when a broken mic is detected
// 'toolbar.noisyAudioInputTitle', // shown when noise is detected for the current microphone
// 'toolbar.talkWhileMutedPopup', // shown when user tries to speak while muted
// 'transcribing.failedToStart' // shown when transcribing fails to start
// ]
// Allow all above example options to include a trailing comma and
// prevent fear when commenting out the last value.

View File

@@ -94,6 +94,10 @@ function connect(id, password, roomName) {
// in future). It's included for the time being for Jitsi Meet and lib-jitsi-meet versions interoperability.
connectionConfig.serviceUrl = connectionConfig.bosh = serviceUrl;
if (connectionConfig.websocketKeepAliveUrl) {
connectionConfig.websocketKeepAliveUrl += `?room=${roomName}`;
}
const connection = new JitsiMeetJS.JitsiConnection(null, jwt, connectionConfig);
if (config.iAmRecorder) {

View File

@@ -2,49 +2,58 @@
* Move the @atlaskit/flag container up a little bit so it does not cover the
* toolbar with the first notification.
*/
.jIMojv{
.atlaskit-portal > #notifications-container {
bottom: calc(#{$newToolbarSizeWithPadding}) !important;
}
/**
* Disable the slide-in animation for @atlaskit/flag due to the animation
* repeating for each queued flag once it becomes the top flag.
*/
.mIBKA:first-child {
animation: cbfRuT 0s !important;
-webkit-animation: cbfRuT 0s !important;
}
.modal-dialog-form {
/**
* Update the @atlaskit/dropdown-menu trigger wrapper to make sure it looks
* click-able.
*/
.cjJUnw {
cursor: pointer;
}
/**
* Override @atlaskit/dropdown-menu styling when in a modal because the
* dropdown backgrounds clash with the modal backgrounds.
*/
.cksvax[data-role=droplistContent] {
border: 1px solid #455166;
.dropdown-menu div[style*="transform"] {
outline: 1px solid #455166;
}
}
/**
* Override @atlaskit/modal-dialog header styling
*/
.atlaskit-portal [role="dialog"] header {
.jitsi-icon {
cursor: pointer;
}
.jitsi-icon svg {
fill: #B8C7E0;
}
}
/**
* Make header close button more easily tappable on mobile.
*/
.mobile-browser .atlaskit-portal [role="dialog"] header .jitsi-icon {
display: grid;
place-items: center;
height: 48px;
width: 48px;
background: #2a3a4b;
border-radius: 3px;
}
/**
* Override @atlaskit/theme styling for the top toolbar so it displays over
* the video thumbnail while obscuring as little as possible.
*/
.videocontainer .tOoji {
.videocontainer__toptoolbar > div > div {
background: none;
}
/**
* Override @atlaskit/InlineDialog styling for the overflowmenu so it displays
* with the correct height.
* Keep overflow menu within screen vertical bounds and make it scrollable.
*/
.toolbox-button-wth-dialog .eYJELv {
max-height: initial;
}
.toolbox-button-wth-dialog > div:nth-child(2) {
max-height: calc(100vh - #{$newToolbarSizeWithPadding} - 46px);
overflow-y: auto;
}

View File

@@ -143,8 +143,8 @@
top: 18px;
}
// Override @atlaskit/InlineDialog container which is made with styled components
& > div > div:nth-child(2) > div > div {
// Override @atlaskit/InlineDialog container which is made with styled components
& > div:nth-child(2) {
outline: none;
padding: 0;
}

View File

@@ -17,6 +17,7 @@ textarea {
html {
height: 100%;
width: 100%;
overflow: hidden;
}
body {
@@ -28,9 +29,14 @@ body {
overflow: hidden;
color: $defaultColor;
background: $defaultBackground;
&.filmstrip-only {
background: transparent;
}
}
/**
* This will hide the focus indicator if an element receives focus via the mouse,
* but it will still show up on keyboard focus, thus preserving accessibility.
*/
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
/**
@@ -39,20 +45,12 @@ body {
* pad the modal container in order for the modals to be centered
* while also taking the chat size into consideration.
*/
@media (min-width: 480px + $sidebarWidth) {
.shift-right [class^="Modal__FillScreen"] {
@media (min-width: 581px) {
.shift-right .atlaskit-portal > div:not(.Tooltip) {
padding-left: $sidebarWidth;
}
}
/**
* Similarly, we offset the notifications when the chat is open by
* padding the container.
*/
.shift-right [class^="styledFlagGroup-"] {
padding-left: $sidebarWidth;
}
.jitsi-icon svg {
fill: white;
}
@@ -62,16 +60,6 @@ body {
cursor: pointer;
}
/**
* AtlasKitThemeProvider sets a background color on an app-wrapping div, thereby
* preventing transparency in filmstrip-only mode. The selector chosen to
* override this behavior is specific to where the AtlasKitThemeProvider might
* be placed within the app hierarchy.
*/
.filmstrip-only #react > .ckAJgx {
background: transparent;
}
p {
margin: 0;
}

View File

@@ -103,25 +103,22 @@
position: relative;
width: 100%;
z-index: 1;
display: flex;
justify-content: space-between;
padding: 16px;
align-items: center;
box-sizing: border-box;
color: #fff;
font-weight: 600;
font-size: 24px;
line-height: 32px;
.chat-close {
align-items: center;
bottom: 8px;
color: white;
.jitsi-icon {
cursor: pointer;
display: flex;
font-size: 18px;
height: 40px;
justify-content: center;
line-height: 15px;
padding: 4px;
position: absolute;
right: 5px;
width: 40px;
}
&:hover {
color: rgba(255, 255, 255, 0.8);
}
.jitsi-icon > svg {
fill: #A4B8D1;
}
}
@@ -184,6 +181,10 @@
text-overflow: ellipsis;
overflow: hidden;
}
@media (max-width: 580px) {
display: none !important;
}
}
.chatmessage {
@@ -379,3 +380,47 @@
}
}
}
.chat-dialog {
display: flex;
flex-direction: column;
height: 100%;
margin-top: -5px; // Margin set by atlaskit.
&-header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 16px 16px 24px;
width: calc(100% - 32px);
box-sizing: border-box;
color: #fff;
font-weight: 600;
font-size: 24px;
line-height: 32px;
.jitsi-icon {
cursor: pointer;
}
.jitsi-icon > svg {
fill: #A4B8D1;
}
}
#chatconversation {
width: 100%;
}
}
/**
* Make header close button more easily tappable on mobile.
*/
.mobile-browser .chat-dialog-header .jitsi-icon {
display: grid;
place-items: center;
height: 48px;
width: 48px;
background: #2a3a4b;
border-radius: 3px;
}

View File

@@ -45,10 +45,8 @@
@extend .connection-info__icon;
}
.showmore {
display: block;
.connection-actions {
margin: 10px auto;
text-align: center;
width: 90px;
}
}

View File

@@ -1,30 +1,30 @@
.con-status {
position: absolute;
top: 40px;
top: 24px;
width: 100%;
z-index: $toolbarZ + 3;
&-container {
background: rgba(28, 32, 37, .5);
border-radius: 3px;
color: #fff;
font-size: 13px;
line-height: 20px;
line-height: 13px;
margin: 0 auto;
width: 304px;
width: 320px;
}
&-header {
background: rgba(28, 32, 37, .5);
align-items: center;
display: flex;
justify-content: space-between;
padding: 8px;
}
&-circle {
border-radius: 50%;
display: inline-block;
padding: 4px;
margin: 8px;
}
&--good {
@@ -40,6 +40,16 @@
}
&-arrow {
height: 36px;
width: 36px;
border-radius: 3px;
margin-left: 8px;
margin-right: 2px;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.16s ease-out;
&--up {
transform: rotate(180deg);
}
@@ -47,6 +57,10 @@
&>svg {
cursor: pointer;
}
&:hover {
background-color: rgba(1,1,1, 0.1);
}
}
&-text {
@@ -54,7 +68,17 @@
}
&-details {
background: rgba(28, 32, 37, .5);
border-top: 1px solid #5E6D7A;
padding: 16px;
transition: opacity 0.16s ease-out;
&-visible {
opacity: 1;
}
&-hidden {
opacity: 0;
}
}
}

View File

@@ -69,7 +69,7 @@
}
// Override @Atlaskit/inline-dialog styles
.cpick-container > div > div:nth-child(2) > div > div {
.cpick-container > div:nth-child(2) {
outline: none;
padding: 8px 0 0 0;
}

134
css/_drawer.scss Normal file
View File

@@ -0,0 +1,134 @@
.drawer-portal {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: $drawerZ;
}
.drawer-menu {
padding: 0 16px;
max-height: 50vh;
background: #242528;
border-radius: 16px 16px 0 0;
overflow-y: auto;
&.expanded {
max-height: 80vh;
}
.drawer-toggle {
display: flex;
justify-content: center;
align-items: center;
height: 44px;
cursor: pointer;
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: $overflowMenuItemHoverBG;
}
}
svg {
fill: none;
}
}
.popupmenu {
margin: auto;
width: 100%;
}
.popupmenu__item {
height: 48px;
}
&#{&} .overflow-menu {
margin: auto;
font-size: 1.2em;
list-style-type: none;
padding: 0;
.overflow-menu-item {
box-sizing: border-box;
height: 48px;
padding: 12px 16px;
align-items: center;
color: $overflowMenuItemColor;
cursor: pointer;
display: flex;
font-size: 16px;
div {
display: flex;
flex-direction: row;
align-items: center;
}
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: $overflowMenuItemHoverBG;
color: $overflowMenuItemHoverColor;
}
}
&.unclickable {
cursor: default;
}
@media (hover: hover) and (pointer: fine) {
&.unclickable:hover {
background: inherit;
}
}
&.disabled {
cursor: initial;
color: #3b475c;
}
}
.beta-tag {
background: $overflowMenuItemColor;
border-radius: 2px;
color: $overflowMenuBG;
font-size: 11px;
font-weight: bold;
margin-left: 8px;
padding: 0 6px;
}
.overflow-menu-item-icon {
margin-right: 16px;
i {
display: inline;
font-size: 24px;
}
@media (hover: hover) and (pointer: fine) {
i:hover {
background-color: initial;
}
}
img {
max-width: 24px;
max-height: 24px;
}
svg {
fill: #B8C7E0 !important;
height: 20px;
width: 20px;
}
}
.profile-text {
max-width: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}

View File

@@ -1,7 +1,6 @@
#e2ee-section {
.title {
font-weight: 700;
}
display: flex;
flex-direction: column;
.description {
font-size: 13px;
@@ -13,29 +12,15 @@
}
}
.key-field {
align-items: center;
.control-row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 15px;
label {
font-size: 14px;
font-weight: 700;
}
input {
background-color: inherit;
border: none;
color: inherit;
flex: 1;
padding: 0 5px;
}
a {
color: #6FB1EA;
cursor: pointer;
font-size: 14px;
text-decoration: none;
font-weight: bold;
}
}
}

View File

@@ -27,84 +27,4 @@
font-size: 50px;
}
&-filmstrip-only {
background-color: $inlayFilmstripOnlyBg;
color: $inlayFilmstripOnlyColor;
margin-left: 20px;
margin-right: 20px;
margin-top: 20px;
bottom: 30px;
position: absolute;
display: flex;
max-height: 120px;
height: 80%;
right: 0px;
border-radius: 4px;
overflow: hidden;
&__content {
padding: 20px;
display: flex;
justify-content: center;
position: relative;
> .button-control {
align-self: center;
}
> #reloadProgressBar {
position: absolute;
left: 0px;
bottom: 0px;
margin-bottom: 0px;
width: 100%;
border-radius: 0px;
}
}
&__title {
font-size: 18px;
font-weight: 600;
}
&__container {
align-self: center;
}
&__text {
margin-top: 10px;
font-size: 14px;
font-weight: 600;
}
&__icon {
font-size: 50px;
align-self: center;
color: $inlayIconColor;
opacity: 0.6;
}
&__icon-container {
text-align: center;
display: flex;
justify-content: center;
position: absolute;
width: 100%;
height: 100%;
top: 0px;
}
&__avatar-container {
height: 100%;
position: relative;
> img {
height: 100%;
}
}
&__icon-background {
background: $inlayIconBg;
opacity: 0.6;
position: absolute;
width: 100%;
height: 100%;
top: 0px;
}
}
}

View File

@@ -4,7 +4,7 @@
top: 30px;
right: 30px;
transition: right 0.5s;
z-index: $filmstripVideosZ + 1;
z-index: $labelsZ;
.circular-label {
align-items: center;

View File

@@ -14,19 +14,6 @@
margin: 10px;
}
}
.form {
align-items: stretch;
display: flex;
flex-direction: column;
min-width: 400px;
}
.participant-info {
align-items: center;
display: flex;
flex-direction: column;
}
}
}
@@ -100,19 +87,6 @@
}
}
input {
align-self: stretch;
background-color: transparent;
border: 1px solid #B8C7E0;
border-radius: 4px;
color: white;
padding: 12px 8px;
&:focus {
border-color: rgb(3, 118, 218);
}
}
button {
align-self: stretch;
margin: 8px 0;

View File

@@ -7,9 +7,8 @@
display: flex;
flex-direction: column;
position: relative;
width: 100%;
height: 100%;
overflow: auto;
width: 100%;
.meetings-list-empty {
text-align: center;
@@ -20,11 +19,34 @@
flex-direction: column;
.description {
font-size: 16px;
padding: 20px;
color: #2f3237;
font-size: 14px;
line-height: 18px;
margin-bottom: 16px;
max-width: 436px;
}
}
.meetings-list-empty-image {
text-align: center;
margin: 24px 0 20px 0;
}
.meetings-list-empty-button {
align-items: center;
color: #0163FF;
cursor: pointer;
display: flex;
font-size: 14px;
line-height: 18px;
margin: 24px 0 32px 0;
}
.meetings-list-empty-icon {
display: inline-block;
margin-right: 8px;
}
.button {
background: #0074E0;
border-radius: 4px;
@@ -32,7 +54,7 @@
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
padding: 8px;
cursor: pointer;
}
@@ -43,12 +65,13 @@
}
.item {
background: rgba(255,255,255,0.50);
background: #fff;
box-sizing: border-box;
border-radius: 4px;
display: inline-flex;
margin-top: 5px;
min-height: 92px;
width: 100%;
margin: 4px 4px 0 4px;
min-height: 60px;
width: calc(100% - 8px);
word-break: break-word;
display: flex;
flex-direction: row;
@@ -61,37 +84,41 @@
.left-column {
display: flex;
flex-direction: column;
width: 140px;
flex-grow: 0;
padding-left: 30px;
padding-top: 25px;
.date {
font-weight: bold;
padding-bottom: 5px;
}
padding-left: 16px;
padding-top: 13px;
}
.right-column {
display: flex;
flex-direction: column;
flex-grow: 1;
padding-left: 30px;
padding-top: 25px;
.title {
font-size: 16px;
font-weight: bold;
padding-bottom: 5px;
}
padding-left: 16px;
padding-top: 13px;
position: relative;
}
.title {
font-size: 12px;
font-weight: 600;
line-height: 16px;
padding-bottom: 4px;
}
.subtitle {
color: #5E6D7A;
font-weight: normal;
font-size: 12px;
line-height: 16px;
}
.actions {
display: flex;
align-items: center;
justify-content: center;
flex-grow: 0;
padding-right: 30px;
margin-right: 16px;
}
&.with-click-handler {
@@ -99,7 +126,7 @@
}
&.with-click-handler:hover {
background-color: #75A7E7;
background-color: #c7ddff;
}
.add-button {
@@ -120,4 +147,20 @@
display: block
}
}
.delete-meeting {
display: none;
margin-right: 16px;
position: absolute;
&> svg {
fill: #0074e0;
}
}
.item:hover {
.delete-meeting {
display: block;
}
}
}

View File

@@ -47,4 +47,5 @@
border-radius: 3px;
margin: -16px -24px;
padding: 16px 24px;
z-index: $popoverZ;
}

View File

@@ -3,7 +3,6 @@
&-input-area {
margin: 0 auto;
text-align: center;
width: 320px;
}
&-title {
@@ -42,9 +41,11 @@
&-error {
color: white;
background-color: rgba(229, 75, 75, 0.5);
background-color: rgba(225, 45, 45, 0.6);
border-radius: 3px;
width: 100%;
padding: 3px;
padding: 2px;
box-sizing: border-box;
margin-top: 4px;
font-size: 13px;
text-align: center;
@@ -58,84 +59,18 @@
}
.prejoin-preview {
height: 100%;
position: absolute;
width: 100%;
&--no-video {
background: radial-gradient(50% 50% at 50% 50%, #5B6F80 0%, #365067 100%), #FFFFFF;
text-align: center;
}
&-video {
height: 100%;
object-fit: cover;
position: absolute;
width: 100%;
}
&-name {
color: #fff;
font-size: 19px;
line-height: 28px;
&--editable {
background: none;
border: 0;
border-bottom: 1px solid #D1DBE8;
margin: 24px 0 16px 0;
outline: none;
text-align: center;
width: 100%;
&::-webkit-input-placeholder {
@include name-placeholder;
}
&::-moz-placeholder {
@include name-placeholder;
}
&:-ms-input-placeholder {
@include name-placeholder;
}
}
&--text {
margin: 16px 0;
outline: none;
}
}
&-avatar.avatar {
background: #A4B8D1;
margin: 200px auto 0 auto;
}
&-overlay {
height: 100%;
position: absolute;
width: 100%;
z-index: 1;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3));
}
&-bottom-overlay {
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.9) 100%);
bottom: 0;
height: 50%;
position: absolute;
width: 100%;
z-index: 1;
}
&-status {
align-items: center;
align-self: stretch;
bottom: 0;
color: #fff;
display: flex;
font-size: 13px;
min-height: 24px;
justify-content: center;
position: absolute;
text-align: center;
width: 100%;
z-index: 1;
&--warning {
@@ -194,7 +129,7 @@
}
&-dropdown-container {
& > div > div:nth-child(2) > div > div {
& > div:nth-child(2) {
background: #fff;
padding: 0;
}

View File

@@ -12,12 +12,23 @@
.premeeting-screen {
align-items: stretch;
background: radial-gradient(50% 50% at 50% 50%, #5D95C7 0%, #376288 100%), #FFFFFF;
background: radial-gradient(50% 50% at 50% 50%, #2A3A4B 20.83%, #1E2A36 100%);
display: flex;
flex-direction: column;
font-size: 1.3em;
z-index: $toolbarZ + 1;
&-avatar {
background-color: #A4B8D1;
margin-bottom: 24px;
text {
fill: black;
font-size: 26px;
font-weight: 400;
}
}
.action-btn {
border-radius: 3px;
color: #fff;
@@ -59,22 +70,26 @@
fill: #AFB6BC;
}
}
.options {
border-left: 1px solid #AFB6BC;
}
}
.options {
border-radius: 3px;
align-items: center;
border-left: 1px solid #fff;
display: flex;
height: 100%;
justify-content: center;
position: absolute;
right: 0;
top: 0;
width: 40px;
width: 36px;
&:hover {
background-color: #0262B6;
}
svg {
pointer-events: none;
}
}
}
@@ -89,6 +104,7 @@
flex: 1;
flex-direction: column;
justify-content: flex-end;
padding-bottom: 24px;
z-index: $toolbarZ + 2;
.title {
@@ -111,12 +127,14 @@
margin-bottom: 16px;
.url {
background: rgba(28, 32, 37, 0.5);
border-radius: 4px;
display: flex;
padding: 8px 10px;
transition: background 0.16s ease-out;
&:hover {
background: #1C2025;
border-radius: 4px;
}
&.done {
@@ -149,20 +167,23 @@
}
input.field {
background-color: transparent;
border: 1px solid transparent;
color: white;
outline-width: 0;
background-color: white;
border: none;
outline: none;
border-radius: 3px;
font-size: 15px;
line-height: 24px;
color: #1C2025;
padding: 8px 0;
text-align: center;
width: 100%;
width: 320px;
&.focused {
border-bottom: 1px solid white;
&.error {
box-shadow: 0px 0px 4px 3px rgba(225, 45, 45, 0.4);
}
&.error::placeholder {
color: $defaultWarningColor;
&.focused {
box-shadow: 0px 0px 4px 3px #0376DA;
}
}
}
@@ -170,7 +191,7 @@
.media-btn-container {
display: flex;
justify-content: center;
margin: 32px 0;
margin: 24px 0 16px 0;
width: 100%;
&> div {
@@ -233,6 +254,7 @@
font-size: 13px;
height: 40px;
margin: 0 auto;
transition: background 0.16s ease-out;
width: 320px;
@include flex-centered();
@@ -242,7 +264,7 @@
}
&:hover {
background: #1C2025;
background: rgba(255, 255, 255, 0.1);
@include icon-container(#A4B8D1, #1C2025);
}
@@ -261,14 +283,6 @@
}
&--toggled {
background: #75757A;
&:hover {
background: #75757A;
@include icon-container(#A4B8D1, #75757A);
}
@include icon-container(#A4B8D1, #75757A);
@include icon-container(white, #1C2025);
}
}

View File

@@ -1,9 +1,4 @@
@media only screen and (max-width: $smallScreen) {
.watermark {
width: 20%;
height: 20%;
}
@mixin small-button-size() {
.new-toolbox {
.toolbox-content {
.button-group-center, .button-group-left, .button-group-right {
@@ -29,15 +24,7 @@
}
}
@media only screen and (max-width: $verySmallScreen) {
#videoResolutionLabel {
display: none;
}
.desktop-browser {
.vertical-filmstrip .filmstrip {
display: none;
}
}
@mixin very-small-button-size() {
.new-toolbox {
.toolbox-content {
.button-group-center, .button-group-left, .button-group-right {
@@ -64,7 +51,139 @@
}
}
}
.chrome-extension-banner {
display: none;
}
@mixin full-size-modal-positioner() {
height: 100%;
left: 0;
position: fixed;
top: 0;
max-width: 100%;
width: 100%;
}
@mixin full-size-modal-dialog() {
height: 100%;
max-height: 100%;
border-radius: 0;
}
@media only screen and (max-width: $verySmallScreen) {
.welcome {
display: block;
#enter_room {
position: relative;
height: 42px;
.welcome-page-button {
font-size: 16px;
left: 0;
position: absolute;
top: 68px;
text-align: center;
width: 100%;
}
}
.header {
background-color: #002637;
#enter_room {
.enter-room-input-container {
padding-right: 0;
}
.warning-without-link,
.warning-with-link {
top: 120px;
}
}
}
.welcome-tabs {
display: none;
}
.header-text-title {
text-align: center;
}
.welcome-cards-container {
padding: 0;
}
&.without-content {
.header {
height: 100%;
}
}
#moderated-meetings {
display: none;
}
.welcome-footer-row-block {
display: block;
}
.welcome-badge {
margin-right: 16px;
}
.welcome-footer {
display: none;
}
}
}
.desktop-browser {
@media only screen and (max-width: $smallScreen) {
@include small-button-size();
}
@media only screen and (max-width: $verySmallScreen) {
@include very-small-button-size();
}
&.shift-right {
@media only screen and (max-width: $smallScreen + $sidebarWidth) {
@include small-button-size()
}
@media only screen and (max-width: $verySmallScreen + $sidebarWidth) {
@include very-small-button-size();
#videoResolutionLabel {
display: none;
}
.vertical-filmstrip .filmstrip {
display: none;
}
.chrome-extension-banner {
display: none;
}
}
}
}
@media (min-width: 480px) and (max-width: 580px) {
.shift-right .focus-lock > div > div {
@include full-size-modal-positioner();
}
.shift-right .focus-lock [role="dialog"] {
@include full-size-modal-dialog();
}
}
@media (min-width: 580px) and (max-width: 680px) {
.mobile-browser {
&.shift-right .focus-lock > div > div {
@include full-size-modal-positioner();
}
&.shift-right .focus-lock [role="dialog"] {
@include full-size-modal-dialog();
}
}
}

View File

@@ -14,12 +14,15 @@
text-overflow: ellipsis;
box-sizing: border-box;
white-space: nowrap;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
&.visible {
top: 0px;
}
&.gradient {
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
&-text {
vertical-align: middle;
}

View File

@@ -42,9 +42,11 @@
display: none;
}
&.shift-right {
margin-left: $sidebarWidth;
width: calc(100% - #{$sidebarWidth});
@media (min-width: 581px) {
&.shift-right {
margin-left: $sidebarWidth;
width: calc(100% - #{$sidebarWidth});
}
}
.toolbox-background {
@@ -88,31 +90,35 @@
margin: 0px 4px;
width: 38px;
height: 38px;
&:hover {
background-color: #daebfa;
border: 1px solid #daebfa;
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: #daebfa;
border: 1px solid #daebfa;
}
}
&.toggled {
background: #2a3a4b;
border: 1px solid #5e6d7a;
svg {
fill: #fff;
}
&:hover {
background-color: #5e6d7a;
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: #5e6d7a;
}
}
}
&.disabled, .disabled & {
cursor: initial;
color: #fff;
background-color: #a4b8d1;
}
svg {
fill: #5e6d7a;
}
@@ -124,9 +130,11 @@
border: 1px solid $hangupColor;
width: 40px;
height: 40px;
&:hover {
background-color: $hangupColor;
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: $hangupColor;
}
}
svg {
@@ -157,8 +165,9 @@
cursor: pointer;
display: flex;
font-size: 14px;
height: 22px;
height: 40px;
padding: 5px 12px;
box-sizing: border-box;
div {
display: flex;
@@ -166,16 +175,20 @@
align-items: center;
}
&:hover {
background-color: $overflowMenuItemHoverBG;
color: $overflowMenuItemHoverColor;
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: $overflowMenuItemHoverBG;
color: $overflowMenuItemHoverColor;
}
}
&.unclickable {
cursor: default;
}
&.unclickable:hover {
background: inherit;
@media (hover: hover) and (pointer: fine) {
&.unclickable:hover {
background: inherit;
}
}
&.disabled {
cursor: initial;
@@ -194,15 +207,17 @@
}
.overflow-menu-item-icon {
margin-right: 10px;
margin-right: 16px;
i {
display: inline;
font-size: 24px;
}
i:hover {
background-color: initial;
@media (hover: hover) and (pointer: fine) {
i:hover {
background-color: initial;
}
}
img {
@@ -212,6 +227,8 @@
svg {
fill: #B8C7E0 !important;
height: 20px;
width: 20px;
}
}
@@ -259,10 +276,16 @@
justify-content: center;
width: $newToolbarSize;
&:hover, &.toggled {
@media (hover: hover) and (pointer: fine) {
&:hover {
background: $newToolbarButtonHoverColor;
}
}
&.toggled {
background: $newToolbarButtonHoverColor;
}
&.disabled {
cursor: initial !important;
background-color: #a4b8d1 !important;

View File

@@ -12,7 +12,7 @@
1px 0px 1px rgba(0,0,0,0.3),
0px 0px 1px rgba(0,0,0,0.3);
transform: translateX(-50%);
z-index: $filmstripVideosZ + 1;
z-index: $subtitlesZ;
span {
background: black;

View File

@@ -114,18 +114,21 @@ $zindex1: 1;
$zindex2: 2;
$zindex3: 3;
$toolbarBackgroundZ: 4;
$filmstripVideosZ: 5;
$labelsZ: 5;
$filmstripVideosZ: 6;
$subtitlesZ: 7;
$popoverZ: 8;
$zindex10: 10;
$reloadZ: 20;
$poweredByZ: 100;
$ringingZ: 300;
$sideToolbarContainerZ: 300;
$toolbarZ: 350;
$drawerZ: 351;
$tooltipsZ: 401;
$dropdownMaskZ: 900;
$dropdownZ: 901;
$centeredVideoLabelZ: 1010;
$popoverZ: 1015;
$overlayZ: 1016;
@@ -161,71 +164,47 @@ $unsupportedDesktopBrowserTextFontSize: 21px;
/**
* The size of the default watermark.
*/
$watermarkWidth: 186px;
$watermarkHeight: 74px;
$watermarkWidth: 71px;
$watermarkHeight: 32px;
$welcomePageWatermarkWidth: 186px;
$welcomePageWatermarkHeight: 74px;
$welcomePageWatermarkWidth: 71px;
$welcomePageWatermarkHeight: 32px;
/**
* Welcome page variables.
*/
$welcomePageDescriptionColor: #fff;
$welcomePageFontFamily: inherit;
$welcomePageBackground: linear-gradient(-90deg, #1251AE 0%, #0074FF 50%, #1251AE 100%);
$welcomePageBackground: none;
$welcomePageTitleColor: #fff;
$welcomePageHeaderBackground: none;
$welcomePageHeaderBackgroundSmall: none;
$welcomePageHeaderBackgroundPosition: none;
$welcomePageHeaderBackground: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), url('../images/welcome-background.png');
$welcomePageHeaderBackgroundPosition: center;
$welcomePageHeaderBackgroundRepeat: none;
$welcomePageHeaderBackgroundSize: none;
$welcomePageHeaderBackgroundSize: cover;
$welcomePageHeaderPaddingBottom: 0px;
$welcomePageHeaderMinHeight: fit-content;
$welcomePageHeaderTitleMaxWidth: initial;
$welcomePageHeaderTextAlign: center;
$welcomePageHeaderTextMarginTop: 35px;
$welcomePageHeaderTextMarginBottom: 35px;
$welcomePageHeaderTextDisplay: flex;
$welcomePageHeaderTextWidth: 650px;
$welcomePageHeaderContainerDisplay: flex;
$welcomePageHeaderContainerMargin: 104px 32px 0 32px;
$welcomePageHeaderTextTitleMarginBottom: 16px;
$welcomePageHeaderTextTitleFontSize: 2.5rem;
$welcomePageHeaderTextTitleFontWeight: 500;
$welcomePageHeaderTextTitleLineHeight: 1.18;
$welcomePageHeaderTextTitleMarginBottom: 0;
$welcomePageHeaderTextTitleFontSize: 42px;
$welcomePageHeaderTextTitleFontWeight: normal;
$welcomePageHeaderTextTitleLineHeight: 50px;
$welcomePageHeaderTextTitleOpacity: 1;
$welcomePageHeaderTextDescriptionDisplay: inherit;
$welcomePageHeaderTextDescriptionFontSize: 1rem;
$welcomePageHeaderTextDescriptionFontWeight: 400;
$welcomePageHeaderTextDescriptionLineHeight: 24px;
$welcomePageHeaderTextDescriptionMarginBottom: 20px;
$welcomePageHeaderTextDescriptionAlignSelf: inherit;
$welcomePageEnterRoomDisplay: flex;
$welcomePageEnterRoomWidth: 680px;
$welcomePageEnterRoomPadding: 25px 30px;
$welcomePageEnterRoomBorderRadius: 0px;
$welcomePageEnterRoomInputContainerPadding: 0 8px 5px 0px;
$welcomePageEnterRoomInputContainerBorderWidth: 0px 0px 2px 0px;
$welcomePageEnterRoomInputContainerBorderStyle: solid;
$welcomePageEnterRoomInputContainerBorderImage: linear-gradient(to right, #dee1e6, #fff) 1;
$welcomePageEnterRoomTitleDisplay: inherit;
$welcomePageEnterRoomWidth: calc(100% - 32px);
$welcomePageEnterRoomPadding: 4px;
$welcomePageEnterRoomMargin: 0 auto;
$welcomePageTabContainerDisplay: flex;
$welcomePageTabContentDisplay: inherit;
$welcomePageTabButtonsDisplay: flex;
$welcomePageTabDisplay: block;
$welcomePageButtonWidth: 51px;
$welcomePageButtonMinWidth: inherit;
$welcomePageButtonFontSize: 14px;
$welcomePageButtonHeight: 35px;
$welcomePageButtonFontWeight: inherit;
$welcomePageButtonBorderRadius: 4px;
$welcomePageButtonLineHeight: 35px;
/**
* Deep-linking page variables.
*/

View File

@@ -63,7 +63,7 @@
}
// Override @atlaskit/InlineDialog container which is made with styled components
& > div > div:nth-child(2) > div > div {
& > div:nth-child(2) {
outline: none;
padding: 0;
}

View File

@@ -182,10 +182,12 @@
z-index: $zindex2;
}
&.shift-right {
&#largeVideoContainer {
margin-left: $sidebarWidth;
width: calc(100% - #{$sidebarWidth});
@media (min-width: 581px) {
&.shift-right {
&#largeVideoContainer {
margin-left: $sidebarWidth;
width: calc(100% - #{$sidebarWidth});
}
}
}
}
@@ -478,14 +480,6 @@
z-index: $reloadZ; /*The reload button should appear on top of the header!*/
}
.audiolevel {
display: inline-block;
position: absolute;
z-index: $zindex0;
border-radius:1px;
pointer-events: none;
}
#dominantSpeaker {
visibility: hidden;
width: 300px;

View File

@@ -5,6 +5,7 @@ body.welcome-page {
.welcome {
background-image: $welcomePageBackground;
background-color: #fff;
display: flex;
flex-direction: column;
font-family: $welcomePageFontFamily;
@@ -18,21 +19,15 @@ body.welcome-page {
background-repeat: $welcomePageHeaderBackgroundRepeat;
background-size: $welcomePageHeaderBackgroundSize;
padding-bottom: $welcomePageHeaderPaddingBottom;
align-items: center;
display: flex;
flex-direction: column;
min-height: $welcomePageHeaderMinHeight;
background-color: #131519;
height: 400px;
overflow: hidden;
position: relative;
text-align: center;
.header-text {
display: $welcomePageHeaderTextDisplay;
.header-container {
display: $welcomePageHeaderContainerDisplay;
flex-direction: column;
margin-top: $watermarkHeight + $welcomePageHeaderTextMarginTop;
margin-bottom: $welcomePageHeaderTextMarginBottom;
max-width: calc(100% - 40px);
width: $welcomePageHeaderTextWidth;
margin: $welcomePageHeaderContainerMargin;
z-index: $zindex2;
}
@@ -42,50 +37,52 @@ body.welcome-page {
font-weight: $welcomePageHeaderTextTitleFontWeight;
line-height: $welcomePageHeaderTextTitleLineHeight;
margin-bottom: $welcomePageHeaderTextTitleMarginBottom;
max-width: $welcomePageHeaderTitleMaxWidth;
opacity: $welcomePageHeaderTextTitleOpacity;
text-align: $welcomePageHeaderTextAlign;
}
.header-text-description {
display: $welcomePageHeaderTextDescriptionDisplay;
color: $welcomePageDescriptionColor;
font-size: $welcomePageHeaderTextDescriptionFontSize;
font-weight: $welcomePageHeaderTextDescriptionFontWeight;
line-height: $welcomePageHeaderTextDescriptionLineHeight;
margin-bottom: $welcomePageHeaderTextDescriptionMarginBottom;
align-self: $welcomePageHeaderTextDescriptionAlignSelf;
.header-text-subtitle {
color: #fff;
font-size: 20px;
font-weight: 600;
line-height: 26px;
margin: 16px 0 32px 0;
text-align: $welcomePageHeaderTextAlign;
}
#enter_room {
display: $welcomePageEnterRoomDisplay;
align-items: center;
max-width: calc(100% - 40px);
max-width: 480px;
width: $welcomePageEnterRoomWidth;
z-index: $zindex2;
background-color: #fff;
padding: $welcomePageEnterRoomPadding;
border-radius: $welcomePageEnterRoomBorderRadius;
border-radius: 4px;
margin: $welcomePageEnterRoomMargin;
.enter-room-input-container {
width: 100%;
padding: $welcomePageEnterRoomInputContainerPadding;
text-align: left;
color: #253858;
flex-grow: 1;
height: fit-content;
.enter-room-title {
display: $welcomePageEnterRoomTitleDisplay;
font-size: 18px;
font-weight: bold;
padding-bottom: 5px;
}
padding-right: 4px;
position: relative;
.enter-room-input {
border-width: $welcomePageEnterRoomInputContainerBorderWidth;
border-style: $welcomePageEnterRoomInputContainerBorderStyle;
border-image: $welcomePageEnterRoomInputContainerBorderImage;
border: 0;
background: #fff;
display: inline-block;
height: 50px;
width: 100%;
font-size: 14px;
padding-left: 10px;
&:focus {
outline: auto 2px #005fcc;
}
}
.insecure-room-name-warning {
@@ -93,7 +90,7 @@ body.welcome-page {
color: $defaultWarningColor;
display: flex;
flex-direction: row;
margin-top: 5px;
margin-top: 15px;
.jitsi-icon {
margin-right: 15px;
@@ -109,16 +106,28 @@ body.welcome-page {
}
}
.warning-without-link {
position: absolute;
top: 44px;
left: -10px;
}
.warning-with-link {
position: absolute;
top: 84px;
}
}
#moderated-meetings {
max-width: calc(100% - 40px);
padding: 16px 0 39px 0;
margin: $welcomePageEnterRoomMargin;
width: $welcomePageEnterRoomWidth;
p {
color: $welcomePageDescriptionColor;
text-align: left;
text-align: $welcomePageHeaderTextAlign;
a {
color: inherit;
@@ -126,76 +135,70 @@ body.welcome-page {
}
}
}
}
.tab-container {
font-size: 16px;
.tab-container {
font-size: 16px;
position: relative;
text-align: left;
display: $welcomePageTabContainerDisplay;
flex-direction: column;
.tab-content{
display: $welcomePageTabContentDisplay;
height: 250px;
margin: 5px 0px;
overflow: hidden;
flex-grow: 1;
position: relative;
text-align: left;
min-height: 354px;
width: 710px;
background: #75A7E7;
display: $welcomePageTabContainerDisplay;
flex-direction: column;
}
.tab-content{
display: $welcomePageTabContentDisplay;
margin: 5px 0px;
overflow: hidden;
.tab-buttons {
background-color: #c7ddff;
border-radius: 6px;
color: #0163FF;
font-size: 14px;
line-height: 18px;
margin: 4px;
display: $welcomePageTabButtonsDisplay;
.tab {
background-color: #c7ddff;
border-radius: 7px;
cursor: pointer;
display: $welcomePageTabDisplay;
flex-grow: 1;
position: relative;
margin: 2px;
padding: 7px 0;
text-align: center;
> * {
position: absolute;
&.selected {
background-color: #FFF;
}
}
.tab-buttons {
font-size: 18px;
color: #FFFFFF;
display: $welcomePageTabButtonsDisplay;
flex-grow: 0;
flex-direction: row;
min-height: 54px;
width: 100%;
.tab {
display: $welcomePageTabDisplay;
text-align: center;
background: rgba(9,30,66,0.37);
height: 55px;
line-height: 54px;
flex-grow: 1;
cursor: pointer;
&.selected, &:hover {
background: rgba(9,30,66,0.71);
}
&:last-child {
margin-left: 1px;
}
}
}
}
}
.welcome-page-button {
width: $welcomePageButtonWidth;
min-width: $welcomePageButtonMinWidth;
height: $welcomePageButtonHeight;
font-size: $welcomePageButtonFontSize;
font-weight: $welcomePageButtonFontWeight;
border: 0;
font-size: 14px;
background: #0074E0;
border-radius: $welcomePageButtonBorderRadius;
border-radius: 3px;
color: #FFFFFF;
text-align: center;
vertical-align: middle;
line-height: $welcomePageButtonLineHeight;
cursor: pointer;
padding: 16px 20px;
&:focus-within {
outline: auto 2px #022e61;
}
}
.welcome-page-settings {
background: rgba(255, 255, 255, 0.38);
border-radius: 3px;
color: $welcomePageDescriptionColor;
padding: 4px;
position: absolute;
top: 32px;
right: 32px;
@@ -217,4 +220,84 @@ body.welcome-page {
height: $welcomePageWatermarkHeight;
}
}
&.without-content {
.welcome-card {
min-width: 500px;
max-width: 580px;
}
}
.welcome-cards-container {
color:#131519;
padding-top: 40px;
}
.welcome-card-row {
display: flex;
justify-content: center;
padding: 0 32px;
}
.welcome-card-text {
padding: 32px;
}
.welcome-card {
width: 49%;
border-radius: 8px;
&--dark {
background: #444447;
color: #fff;
}
&--blue {
background: #D5E5FF;
}
&--grey {
background: #F2F3F4;
}
&--shadow {
box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.15);
}
}
.welcome-footer {
background: #131519;
color: #fff;
margin-top: 40px;
position: relative;
}
.welcome-footer-centered {
max-width: 688px;
margin: 0 auto;
}
.welcome-footer-padded {
padding: 0px 16px;
}
.welcome-footer-row-block {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #424447;
&:last-child {
border-bottom: none;
}
}
.welcome-footer--row-1 {
padding: 40px 0 24px 0;
}
.welcome-footer-row-1-text {
max-width: 200px;
margin-right: 16px;
}
}

View File

@@ -6,7 +6,6 @@
}
.horizontal-filmstrip .filmstrip {
position: absolute;
bottom: 0;
right: 0;
padding: 10px 5px;
@@ -67,20 +66,6 @@
}
}
/**
* Style the filmstrip videos in filmstrip-only mode.
*/
&__videos-filmstripOnly {
margin-top: auto;
margin-bottom: auto;
.filmstrip__videos {
&#filmstripLocalVideo {
bottom: 0px;
}
}
}
.remote-videos-container {
transition: opacity 1s;
}

View File

@@ -15,9 +15,8 @@
box-sizing: border-box;
display: flex;
flex-direction: column;
height: calc(100vh - 200px);
height: 100%;
width: 100vw;
margin: 100px 0px;
}
.filmstrip__videos .videocontainer {
@@ -43,17 +42,18 @@
height: 100%;
justify-content: center;
left: 0;
position: fixed;
position: absolute;
top: 0;
width: 100%;
z-index: $filmstripVideosZ;
&.shift-right {
margin-left: $sidebarWidth;
width: calc(100% - #{$sidebarWidth});
@media (min-width: 581px) {
&.shift-right {
margin-left: $sidebarWidth;
width: calc(100% - #{$sidebarWidth});
#filmstripRemoteVideos {
width: calc(100vw - #{$sidebarWidth});
#filmstripRemoteVideos {
width: calc(100vw - #{$sidebarWidth});
}
}
}
}
@@ -87,6 +87,7 @@
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
flex-shrink: 0;
margin-top: auto;
margin-bottom: auto;
justify-content: center;
@@ -95,12 +96,21 @@
border: 0;
box-sizing: border-box;
display: block;
margin: 5px;
margin: 2px;
}
video {
object-fit: contain;
}
/**
* Max-width corresponding to the ASPECT_RATIO_BREAKPOINT from features/filmstrip/constants.
*/
@media only screen and (max-width: 500px) {
video {
object-fit: cover;
}
}
}
.has-overflow#filmstripRemoteVideosContainer {
@@ -110,14 +120,4 @@
.has-overflow .videocontainer {
align-self: baseline;
}
/**
* Firefox flex acts a little differently. To make sure the bottom row of
* thumbnails is not overlapped by the horizontal toolbar, margin is added
* to the local thumbnail to keep it from the bottom of the screen. It is
* assumed the local thumbnail will always be on the bottom row.
*/
.has-overflow #localVideoContainer {
margin-bottom: 100px !important;
}
}

View File

@@ -22,11 +22,6 @@
display: none;
}
#remoteConnectionMessage,
.watermark {
z-index: $filmstripVideosZ + 1;
}
/**
* The follow styling uses !important to override inline styles set with
* javascript.

View File

@@ -145,26 +145,6 @@
}
}
/**
* Override other styles to support vertical filmstrip mode.
*/
.filmstrip-only .vertical-filmstrip {
.filmstrip {
flex-direction: row-reverse;
}
.filmstrip__videos-filmstripOnly {
margin-top: auto;
margin-bottom: auto;
height: 100%;
}
.filmstrip__videos {
&#filmstripLocalVideo {
bottom: 0px;
}
}
}
/**
* Workarounds for Edge and Firefox not handling scrolling properly with
* flex-direction: column-reverse. The remove videos in filmstrip should

View File

@@ -103,5 +103,6 @@ $flagsImagePath: "../images/";
@import 'e2ee';
@import 'responsive';
@import 'connection-status';
@import 'drawer';
/* Modules END */

View File

@@ -39,7 +39,7 @@
.device-selector-trigger-text {
overflow: hidden;
margin-left: 8px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;

View File

@@ -2,22 +2,6 @@
&-dialog {
display: flex;
flex-direction: column;
&-header {
display: flex;
justify-content: space-between;
margin: 16px 16px 24px;
width: calc(100% - 32px);
color: #fff;
font-weight: 600;
font-size: 24px;
line-height: 32px;
& > div > svg {
cursor: pointer;
fill: #A4B8D1;
}
}
}
&-copy {

View File

@@ -50,6 +50,12 @@
}
}
.dial-in-number {
display: flex;
justify-content: space-between;
padding-right: 8px;
}
.dial-in-numbers-list {
margin-top: 20px;
font-size: 12px;

View File

@@ -7,10 +7,6 @@
text-align: center;
z-index: $zindex2;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
&.elevated {
z-index: $filmstripVideosZ + 1;
}
}
&-header {
@@ -32,8 +28,10 @@
line-height: 24px;
cursor: pointer;
&:hover {
background: #278ADF;
@media (hover: hover) and (pointer: fine) {
&:hover {
background: #278ADF;
}
}
&-text {
@@ -47,22 +45,6 @@
font-size: 15px;
line-height: 24px;
&.header {
display: flex;
justify-content: space-between;
margin: 16px 16px 24px;
width: calc(100% - 32px);
color: #fff;
font-weight: 600;
font-size: 24px;
line-height: 32px;
& > div > svg {
cursor: pointer;
fill: #A4B8D1;
}
}
&.separator {
margin: 24px 0 24px -20px;
padding: 0 20px;
@@ -112,11 +94,11 @@
border-radius: 4px;
cursor: pointer;
}
&:hover > div:hover {
background-color: rgba(255, 255, 255, 0.2);
}
& > :not(:last-child) {
margin-right: 16px;
}
@@ -135,7 +117,6 @@
.dial-in-copy {
display: inline-block;
vertical-align: middle;
margin-left: 21px;
cursor: pointer;
}
}

View File

@@ -23,6 +23,10 @@
padding: 20px 0px 4px 0px;
}
input[type="checkbox"] + svg + span {
color: #9FB0CC;
}
.calendar-tab,
.more-tab,
.profile-edit {

View File

@@ -1,9 +1,4 @@
.video-quality-dialog {
.hide-warning {
height: 0;
visibility: hidden;
}
.video-quality-dialog-title {
margin-bottom: 10px;
}
@@ -109,30 +104,6 @@
word-spacing: unset;
}
}
&.video-not-supported {
.video-quality-dialog-labels {
color: gray;
}
.video-quality-dialog-slider {
@mixin sliderTrackDisabledStyles() {
background: rgba(14, 22, 36, 0.1);
}
&::-ms-track {
@include sliderTrackDisabledStyles();
}
&::-moz-range-track {
@include sliderTrackDisabledStyles();
}
&::-webkit-slider-runnable-track {
@include sliderTrackDisabledStyles();
}
}
}
}
.modal-dialog-form {
@@ -140,7 +111,3 @@
display: none;
}
}
#videoResolutionLabel {
z-index: $zindex3 + 1;
}

View File

@@ -8,16 +8,10 @@
position: fixed;
z-index: $overlayZ;
background: $defaultBackground;
&.filmstrip-only {
@include transparentBg($filmstripOnlyOverlayBg, 0.8);
}
}
&__container-light {
@include transparentBg($defaultBackground, 0.7);
&.filmstrip-only {
@include transparentBg($filmstripOnlyOverlayBg, 0.2);
}
}
&__content {
@@ -27,11 +21,6 @@
width: 56%;
left: 50%;
@include transform(translateX(-50%));
&.filmstrip-only {
left: 0px;
width: 100%;
@include transform(none);
}
&_bottom {
position: absolute;

View File

@@ -41,7 +41,6 @@ $overlayButtonBg: #0074E0;
* Color variables
**/
$defaultBackground: #474747;
$filmstripOnlyOverlayBg: #000;
$reloadProgressBarBg: #0074E0;
/**
@@ -59,10 +58,6 @@ $dialogErrorText: #344563;
**/
$inlayColorBg: lighten($defaultBackground, 20%);
$inlayBorderColor: lighten($baseLight, 10%);
$inlayIconBg: #000;
$inlayIconColor: #fff;
$inlayFilmstripOnlyColor: #474747;
$inlayFilmstripOnlyBg: #fff;
// Main controls
$placeHolderColor: #a7a7a7;

2
debian/control vendored
View File

@@ -33,7 +33,7 @@ Description: Configuration for web serving of Jitsi Meet
Package: jitsi-meet-prosody
Architecture: all
Depends: openssl, prosody | prosody-trunk | prosody-0.11
Depends: openssl, prosody | prosody-trunk | prosody-0.11, lua-sec
Replaces: jitsi-meet-tokens
Description: Prosody configuration for Jitsi Meet
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi

View File

@@ -60,15 +60,6 @@ case "$1" in
JICOFO_AUTH_PASSWORD="$RET"
fi
db_get jicofo/jicofosecret
if [ -z "$RET" ] ; then
# if secret is missing generate it, and store it
JICOFO_SECRET=`generateRandomPassword`
db_set jicofo/jicofosecret "$JICOFO_SECRET"
else
JICOFO_SECRET="$RET"
fi
JICOFO_AUTH_DOMAIN="auth.$JVB_HOSTNAME"
# detect dpkg-reconfigure, just delete old links
@@ -107,7 +98,6 @@ case "$1" in
mkdir -p /etc/prosody/conf.d/
cp /usr/share/jitsi-meet-prosody/prosody.cfg.lua-jvb.example $PROSODY_HOST_CONFIG
sed -i "s/jitmeet.example.com/$JVB_HOSTNAME/g" $PROSODY_HOST_CONFIG
sed -i "s/focusSecret/$JICOFO_SECRET/g" $PROSODY_HOST_CONFIG
sed -i "s/focusUser/$JICOFO_AUTH_USER/g" $PROSODY_HOST_CONFIG
sed -i "s/__turnSecret__/$TURN_SECRET/g" $PROSODY_HOST_CONFIG
if [ ! -f /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua ]; then
@@ -142,6 +132,28 @@ case "$1" in
echo -e " admins = { \"$JICOFO_AUTH_USER@auth.$JVB_HOSTNAME\", \"jvb@auth.$JVB_HOSTNAME\" }" >> $PROSODY_HOST_CONFIG
fi
# Convert the old focus component config to the new one.
# Old:
# Component "focus.jitmeet.example.com"
# component_secret = "focusSecret"
# New:
# Component "focus.jitmeet.example.com" "client_proxy"
# target_address = "focus@auth.jitmeet.example.com"
if grep -q "Component \"focus.$JVB_HOSTNAME\"" $PROSODY_HOST_CONFIG && ! grep "Component \"focus.$JVB_HOSTNAME\" \"client_proxy\"" $PROSODY_HOST_CONFIG ;then
sed -i "s/Component \"focus.$JVB_HOSTNAME\"/Component \"focus.$JVB_HOSTNAME\" \"client_proxy\"\n target_address = \"$JICOFO_AUTH_USER@auth.$JVB_HOSTNAME\"/g" $PROSODY_HOST_CONFIG
PROSODY_CONFIG_PRESENT="false"
fi
# Old versions of jitsi-meet-prosody come with the extra plugin path commented out (https://github.com/jitsi/jitsi-meet/commit/e11d4d3101e5228bf956a69a9e8da73d0aee7949)
# Make sure it is uncommented, as it contains required modules.
if grep -q -- '--plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }' $PROSODY_HOST_CONFIG ;then
sed -i 's#--plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }#plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }#g' $PROSODY_HOST_CONFIG
PROSODY_CONFIG_PRESENT="false"
fi
# Make sure the focus@auth user's roster includes the proxy component (this is idempotent)
prosodyctl mod_roster_command subscribe focus.$JVB_HOSTNAME $JICOFO_AUTH_USER@auth.$JVB_HOSTNAME
if [ ! -f /var/lib/prosody/$JVB_HOSTNAME.crt ]; then
# prosodyctl takes care for the permissions
# echo for using all default values

View File

@@ -45,8 +45,12 @@ case "$1" in
rm -rf /var/lib/prosody/$JICOFO_AUTH_DOMAIN.*
rm -rf /var/lib/prosody/$JVB_HOSTNAME.*
# clean created users
rm -rf /var/lib/prosody/`echo $JICOFO_AUTH_DOMAIN | sed -e "s/\./%2e/g"`
# clean created users, replace '.' with '%2e', replace '-' with '%2d'
rm -rf /var/lib/prosody/`echo $JICOFO_AUTH_DOMAIN | sed -e "s/\./%2e/g"| sed -e "s/-/%2d/g"`
# clean the prosody cert from the trust store
rm -rf /usr/local/share/ca-certificates/$JICOFO_AUTH_DOMAIN.*
update-ca-certificates -f
fi
# Clear the debconf variable

View File

@@ -24,11 +24,6 @@ Type: password
_Description: Jicofo user password:
The secret used to connect to xmpp server as jicofo user.
Template: jicofo/jicofosecret
Type: password
_Description: Jicofo Component secret:
The secret used to connect to xmpp server as component
Template: jitsi-meet-prosody/turn-secret
Type: string
_Description: The turn server secret

View File

@@ -36,26 +36,6 @@ case "$1" in
NGINX_CONFIG="/etc/nginx/sites-available/$JVB_HOSTNAME.conf"
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
NGINX_SITES_ENABLED="/etc/nginx/sites-enabled/"
NGINX_CONFIG_ENABLED="${NGINX_SITES_ENABLED}${JVB_HOSTNAME}.conf"
NGINX_MULTIPLEXING="true"
for site in ${NGINX_SITES_ENABLED}*; do
# if it is not a file continue
[ -f "${site}" ] || continue
# if it is our config skip
[ "${site}" != "${NGINX_CONFIG_ENABLED}" ] || continue
# check whether other enabled hosts has listen 443
if cat ${site} | grep -v "^[[:space:]]*#" | grep listen | grep -q "^.*[[:space:]:]443[;[:space:]].*" ; then
# nothing to do
echo "------------------------------------------------"
echo ""
echo "turnserver is listening on tcp 5349 as other nginx sites use port 443"
echo ""
echo "------------------------------------------------"
NGINX_MULTIPLEXING="false"
fi
done
# if there was a turn config backup it so we can configure
# we cannot recognize at the moment is this a user config or default config when installing coturn
if [[ -f $TURN_CONFIG ]] && ! grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
@@ -133,19 +113,9 @@ denied-peer-ip=240.0.0.0-255.255.255.255" >> $TURN_CONFIG
TURN_SECRET="$RET"
# no turn config exists, lt's copy template and fill it in
PUBLIC_IP=$(dig -4 +short myip.opendns.com a @resolver1.opendns.com) || true
if [ -z "$PUBLIC_IP" ] ; then
PUBLIC_IP="127.0.0.1"
echo "------------------------------------------------"
echo "Warning! Could not resolve your external ip address! Error:^"
echo "Your turn server will not work till you edit your $TURN_CONFIG config file."
echo "You need to set your external ip address in external-ip and restart coturn service."
echo "------------------------------------------------"
fi
cp /usr/share/jitsi-meet-turnserver/turnserver.conf $TURN_CONFIG
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
sed -i "s/__external_ip_address__/$PUBLIC_IP/g" $TURN_CONFIG
# SSL for nginx
db_get jitsi-meet/cert-choice
@@ -170,23 +140,14 @@ denied-peer-ip=240.0.0.0-255.255.255.255" >> $TURN_CONFIG
invoke-rc.d coturn restart || true
NGINX_STREAM_CONFIG="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
if [ $NGINX_MULTIPLEXING = "true" ] && [ ! -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then
ln -s /usr/share/jitsi-meet-turnserver/jitsi-meet.conf $NGINX_STREAM_CONFIG
sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG
sed -i "s/listen \[\:\:\]\:443 ssl/listen \[\:\:\]\:4444 ssl http2/g" $NGINX_CONFIG
invoke-rc.d nginx reload || true
else
PROSODY_HOST_CONFIG="/etc/prosody/conf.avail/$JVB_HOSTNAME.cfg.lua"
if [ -f $PROSODY_HOST_CONFIG ] ; then
# If we are not multiplexing we need to change the port in prosody config
sed -i 's/"443"/"5349"/g' $PROSODY_HOST_CONFIG
invoke-rc.d prosody restart || true
fi
fi
# Enable turn server in config.js
if [ -f $JITSI_MEET_CONFIG ] ; then
sed -i "s/\/\/ useStunTurn: true/useStunTurn: true/g" $JITSI_MEET_CONFIG
if [ -f $NGINX_STREAM_CONFIG ] ; then
echo "------------------------------------------------"
echo ""
echo "You have multiplexing enabled, it is recommended to disable it and migrate to using websockets for the bridge channel."
echo "The support for sctp data channels is deprecated and will be dropped at some point."
echo "How to do it at: https://jitsi.org/multiplexing-to-bridge-ws-howto"
echo ""
echo "------------------------------------------------"
fi
# and we're done with debconf

View File

@@ -24,7 +24,6 @@ set -e
case "$1" in
remove)
rm -rf /etc/nginx/modules-enabled/60-jitsi-meet.conf
if [ -x "/etc/init.d/nginx" ]; then
invoke-rc.d nginx reload || true
fi
@@ -33,7 +32,6 @@ case "$1" in
fi
;;
purge)
rm -rf /etc/nginx/modules-enabled/60-jitsi-meet.conf
rm -rf /etc/turnserver.conf
if [ -x "/etc/init.d/nginx" ]; then
invoke-rc.d nginx reload || true

View File

@@ -30,6 +30,7 @@ case "$1" in
db_set jitsi-videobridge/jvb-hostname "localhost"
db_input critical jitsi-videobridge/jvb-hostname || true
db_go
db_get jitsi-videobridge/jvb-hostname
fi
JVB_HOSTNAME="$RET"
@@ -44,8 +45,9 @@ case "$1" in
JVB_SERVE="false"
# this detect only old installations
RET=""
db_get jitsi-meet/jvb-serve || true
if [ -n "$RET" ] && [ "$RET" = "true" ] ; then
if [ "$RET" = "true" ] ; then
JVB_SERVE="true"
fi
@@ -67,23 +69,38 @@ case "$1" in
if [ "$APACHE_INSTALL_CHECK" = "installed" ] || [ "$APACHE_INSTALL_CHECK" = "unpacked" ] ; then
FORCE_APACHE="true"
fi
# In case user enforces apache and if apache is available, unset nginx.
RET=""
db_get jitsi-meet/enforce_apache || RET="false"
if [ "$RET" = "true" ] && [ "$FORCE_APACHE" = "true" ]; then
FORCE_NGINX="false"
fi
UPLOADED_CERT_CHOICE="I want to use my own certificate"
# if first time config ask for certs, or if we are reconfiguring
if [ -z "$JVB_HOSTNAME_OLD" ] || [ "$RECONFIGURING" = "true" ] ; then
RET=""
db_get jitsi-meet/cert-choice
CERT_CHOICE="$RET"
if [ "$CERT_CHOICE" = "$UPLOADED_CERT_CHOICE" ] ; then
db_set jitsi-meet/cert-path-key "/etc/ssl/$JVB_HOSTNAME.key"
db_input critical jitsi-meet/cert-path-key || true
db_go
RET=""
db_get jitsi-meet/cert-path-key
if [ -z "$RET" ] ; then
db_set jitsi-meet/cert-path-key "/etc/ssl/$JVB_HOSTNAME.key"
db_input critical jitsi-meet/cert-path-key || true
db_go
db_get jitsi-meet/cert-path-key
fi
CERT_KEY="$RET"
db_set jitsi-meet/cert-path-crt "/etc/ssl/$JVB_HOSTNAME.crt"
db_input critical jitsi-meet/cert-path-crt || true
db_go
RET=""
db_get jitsi-meet/cert-path-crt
if [ -z "$RET" ] ; then
db_set jitsi-meet/cert-path-crt "/etc/ssl/$JVB_HOSTNAME.crt"
db_input critical jitsi-meet/cert-path-crt || true
db_go
db_get jitsi-meet/cert-path-crt
fi
CERT_CRT="$RET"
else
# create self-signed certs
@@ -139,12 +156,15 @@ case "$1" in
# Removing this value will force nginx or apache to be locally configured
JVB_HOSTNAME_OLD=""
RET=""
db_get jitsi-meet/cert-choice
CERT_CHOICE="$RET"
# Fix certs on upgrade from jetty
if [ "$CERT_CHOICE" = "$UPLOADED_CERT_CHOICE" ] ; then
RET=""
db_get jitsi-meet/cert-path-key
CERT_KEY="$RET"
RET=""
db_get jitsi-meet/cert-path-crt
CERT_CRT="$RET"
else
@@ -198,7 +218,7 @@ case "$1" in
# apache2 config
if [ ! -f /etc/apache2/sites-available/$JVB_HOSTNAME.conf ] ; then
# when creating new config, make sure all needed modules are enabled
a2enmod rewrite ssl headers proxy_http include
a2enmod rewrite ssl headers proxy_http proxy_wstunnel include
cp /usr/share/jitsi-meet-web-config/jitsi-meet.example-apache /etc/apache2/sites-available/$JVB_HOSTNAME.conf
a2ensite $JVB_HOSTNAME.conf
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" /etc/apache2/sites-available/$JVB_HOSTNAME.conf

View File

@@ -13,3 +13,7 @@ lang /usr/share/jitsi-meet/
connection_optimization /usr/share/jitsi-meet/
resources/robots.txt /usr/share/jitsi-meet/
resources/*.sh /usr/share/jitsi-meet/scripts/
pwa-worker.js /usr/share/jitsi-meet/
manifest.json /usr/share/jitsi-meet/
resources/load-test/*.html /usr/share/jitsi-meet/load-test/
resources/load-test/libs /usr/share/jitsi-meet/load-test/

View File

@@ -3,12 +3,11 @@ plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
-- domain mapper options, must at least have domain base set to use the mapper
muc_mapper_domain_base = "jitmeet.example.com";
turncredentials_secret = "__turnSecret__";
turncredentials = {
{ type = "stun", host = "jitmeet.example.com", port = "3478" },
{ type = "turn", host = "jitmeet.example.com", port = "3478", transport = "udp" },
{ type = "turns", host = "jitmeet.example.com", port = "443", transport = "tcp" }
external_service_secret = "__turnSecret__";
external_services = {
{ type = "stun", host = "jitmeet.example.com", port = 3478 },
{ type = "turn", host = "jitmeet.example.com", port = 3478, transport = "udp", secret = true, ttl = 86400, algorithm = "turn" },
{ type = "turns", host = "jitmeet.example.com", port = 5349, transport = "tcp", secret = true, ttl = 86400, algorithm = "turn" }
};
cross_domain_bosh = false;
@@ -17,48 +16,48 @@ consider_bosh_secure = true;
-- https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.0g&guideline=5.4
ssl = {
protocol = "tlsv1_2+";
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"
protocol = "tlsv1_2+";
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"
}
VirtualHost "jitmeet.example.com"
-- enabled = false -- Remove this line to enable this host
authentication = "anonymous"
-- Properties below are modified by jitsi-meet-tokens package config
-- and authentication above is switched to "token"
--app_id="example_app_id"
--app_secret="example_app_secret"
-- Assign this host a certificate for TLS, otherwise it would use the one
-- set in the global section (if any).
-- Note that old-style SSL on port 5223 only supports one certificate, and will always
-- use the global one.
ssl = {
key = "/etc/prosody/certs/jitmeet.example.com.key";
certificate = "/etc/prosody/certs/jitmeet.example.com.crt";
}
speakerstats_component = "speakerstats.jitmeet.example.com"
conference_duration_component = "conferenceduration.jitmeet.example.com"
-- we need bosh
modules_enabled = {
"bosh";
"pubsub";
"ping"; -- Enable mod_ping
"speakerstats";
"turncredentials";
"conference_duration";
"muc_lobby_rooms";
}
c2s_require_encryption = false
lobby_muc = "lobby.jitmeet.example.com"
main_muc = "conference.jitmeet.example.com"
-- muc_lobby_whitelist = { "recorder.jitmeet.example.com" } -- Here we can whitelist jibri to enter lobby enabled rooms
-- enabled = false -- Remove this line to enable this host
authentication = "anonymous"
-- Properties below are modified by jitsi-meet-tokens package config
-- and authentication above is switched to "token"
--app_id="example_app_id"
--app_secret="example_app_secret"
-- Assign this host a certificate for TLS, otherwise it would use the one
-- set in the global section (if any).
-- Note that old-style SSL on port 5223 only supports one certificate, and will always
-- use the global one.
ssl = {
key = "/etc/prosody/certs/jitmeet.example.com.key";
certificate = "/etc/prosody/certs/jitmeet.example.com.crt";
}
speakerstats_component = "speakerstats.jitmeet.example.com"
conference_duration_component = "conferenceduration.jitmeet.example.com"
-- we need bosh
modules_enabled = {
"bosh";
"pubsub";
"ping"; -- Enable mod_ping
"speakerstats";
"external_services";
"conference_duration";
"muc_lobby_rooms";
}
c2s_require_encryption = false
lobby_muc = "lobby.jitmeet.example.com"
main_muc = "conference.jitmeet.example.com"
-- muc_lobby_whitelist = { "recorder.jitmeet.example.com" } -- Here we can whitelist jibri to enter lobby enabled rooms
Component "conference.jitmeet.example.com" "muc"
storage = "memory"
modules_enabled = {
"muc_meeting_id";
"muc_domain_mapper";
-- "token_verification";
--"token_verification";
}
admins = { "focusUser@auth.jitmeet.example.com" }
muc_room_locking = false
@@ -68,17 +67,18 @@ Component "conference.jitmeet.example.com" "muc"
Component "internal.auth.jitmeet.example.com" "muc"
storage = "memory"
modules_enabled = {
"ping";
"ping";
}
admins = { "focusUser@auth.jitmeet.example.com", "jvb@auth.jitmeet.example.com" }
muc_room_locking = false
muc_room_default_public_jids = true
VirtualHost "auth.jitmeet.example.com"
authentication = "internal_plain"
authentication = "internal_hashed"
Component "focus.jitmeet.example.com"
component_secret = "focusSecret"
-- Proxy to jicofo's user JID, so that it doesn't have to register as a component.
Component "focus.jitmeet.example.com" "client_proxy"
target_address = "focusUser@auth.jitmeet.example.com"
Component "speakerstats.jitmeet.example.com" "speakerstats_component"
muc_component = "conference.jitmeet.example.com"

View File

@@ -12,7 +12,6 @@ no-tcp-relay
no-tcp
listening-port=3478
tls-listening-port=5349
external-ip=__external_ip_address__
no-tlsv1
no-tlsv1_1
# https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.0g&guideline=5.4

View File

@@ -1,7 +1,11 @@
# this is jitsi-meet nginx module configuration
# this forward all http traffic to the nginx virtual host port
# and the rest to the turn server
#
# Multiplexing based on ALPN is DEPRECATED. ALPN does not play well with websockets on some browsers and reverse proxies.
# To migrate away from using it read: https://jitsi.org/multiplexing-to-bridge-ws-howto
# This file will be removed at some point and if deployment is still using it, will break.
#
stream {
upstream web {
server 127.0.0.1:4444;

View File

@@ -1,19 +1,23 @@
server_names_hash_bucket_size 64;
types {
# nginx's default mime.types doesn't include a mapping for wasm
application/wasm wasm;
}
server {
listen 80;
listen [::]:80;
server_name jitsi-meet.example.com;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/jitsi-meet;
default_type "text/plain";
root /usr/share/jitsi-meet;
}
location = /.well-known/acme-challenge/ {
return 404;
return 404;
}
location / {
return 301 https://$host$request_uri;
return 301 https://$host$request_uri;
}
}
server {
@@ -21,7 +25,7 @@ server {
listen [::]:443 ssl;
server_name jitsi-meet.example.com;
# Mozilla Guideline v5.4, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration
# Mozilla Guideline v5.4, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
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;
ssl_prefer_server_ciphers off;
@@ -58,7 +62,7 @@ server {
alias /usr/share/jitsi-meet/libs/external_api.min.js;
}
#ensure all static content can always be found first
# ensure all static content can always be found first
location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
{
add_header 'Access-Control-Allow-Origin' '*';
@@ -66,13 +70,13 @@ server {
# cache all versioned files
if ($arg_v) {
expires 1y;
expires 1y;
}
}
# BOSH
location = /http-bind {
proxy_pass http://localhost:5280/http-bind;
proxy_pass http://localhost:5280/http-bind;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
@@ -87,6 +91,24 @@ server {
tcp_nodelay on;
}
# colibri (JVB) websockets for jvb1
location ~ ^/colibri-ws/default-id/(.*) {
proxy_pass http://127.0.0.1:9090/colibri-ws/default-id/$1$is_args$args;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
tcp_nodelay on;
}
# load test minimal client, uncomment when used
#location ~ ^/_load-test/([^/?&:'"]+)$ {
# rewrite ^/_load-test/(.*)$ /load-test/index.html break;
#}
#location ~ ^/_load-test/libs/(.*)$ {
# add_header 'Access-Control-Allow-Origin' '*';
# alias /usr/share/jitsi-meet/load-test/libs/$1;
#}
location ~ ^/([^/?&:'"]+)$ {
try_files $uri @root_path;
}
@@ -97,13 +119,13 @@ server {
location ~ ^/([^/?&:'"]+)/config.js$
{
set $subdomain "$1.";
set $subdir "$1/";
set $subdomain "$1.";
set $subdir "$1/";
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
}
#Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
# Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
location ~ ^/([^/?&:'"]+)/(.*)$ {
set $subdomain "$1.";
set $subdir "$1/";

View File

@@ -8,50 +8,52 @@
</VirtualHost>
<VirtualHost *:443>
ServerName jitsi-meet.example.com
ServerName jitsi-meet.example.com
# enable HTTP/2, if available
Protocols h2 http/1.1
# enable HTTP/2, if available
Protocols h2 http/1.1
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/jitsi/meet/jitsi-meet.example.com.crt
SSLCertificateKeyFile /etc/jitsi/meet/jitsi-meet.example.com.key
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/jitsi/meet/jitsi-meet.example.com.crt
SSLCertificateKeyFile /etc/jitsi/meet/jitsi-meet.example.com.key
Header always set Strict-Transport-Security "max-age=63072000"
Header always set Strict-Transport-Security "max-age=63072000"
DocumentRoot "/usr/share/jitsi-meet"
<Directory "/usr/share/jitsi-meet">
Options Indexes MultiViews Includes FollowSymLinks
AddOutputFilter Includes html
AllowOverride All
Order allow,deny
Allow from all
</Directory>
DocumentRoot "/usr/share/jitsi-meet"
<Directory "/usr/share/jitsi-meet">
Options Indexes MultiViews Includes FollowSymLinks
AddOutputFilter Includes html
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorDocument 404 /static/404.html
ErrorDocument 404 /static/404.html
Alias "/config.js" "/etc/jitsi/meet/jitsi-meet.example.com-config.js"
<Location /config.js>
Require all granted
</Location>
Alias "/config.js" "/etc/jitsi/meet/jitsi-meet.example.com-config.js"
<Location /config.js>
Require all granted
</Location>
Alias "/external_api.js" "/usr/share/jitsi-meet/libs/external_api.min.js"
<Location /external_api.js>
Require all granted
</Location>
Alias "/external_api.js" "/usr/share/jitsi-meet/libs/external_api.min.js"
<Location /external_api.js>
Require all granted
</Location>
ProxyPreserveHost on
ProxyPass /http-bind http://localhost:5280/http-bind/
ProxyPassReverse /http-bind http://localhost:5280/http-bind/
ProxyPass /xmpp-websocket ws://localhost:5280/xmpp-websocket
ProxyPassReverse /xmpp-websocket ws://localhost:5280/xmpp-websocket
ProxyPassMatch ^/colibri-ws/default-id ws://localhost:9090
ProxyPreserveHost on
ProxyPass /http-bind http://localhost:5280/http-bind/
ProxyPassReverse /http-bind http://localhost:5280/http-bind/
RewriteEngine on
RewriteRule ^/([a-zA-Z0-9]+)$ /index.html
RewriteEngine on
RewriteRule ^/([a-zA-Z0-9]+)$ /index.html
</VirtualHost>
# Mozilla Guideline v5.4, Apache 2.4.41, OpenSSL 1.1.1d, intermediate configuration, no OCSP
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
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
SSLHonorCipherOrder off
SSLSessionTickets off
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
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
SSLHonorCipherOrder off
SSLSessionTickets off

View File

@@ -4,6 +4,5 @@ var config = {
muc: 'conference.jitsi.example.com', // FIXME: use XEP-0030
bridge: 'jitsi-videobridge.jitsi.example.com' // FIXME: use XEP-0030
},
useNicks: false,
bosh: '//jitsi.example.com/http-bind' // FIXME: use xep-0156 for that
};

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