Compare commits

...

133 Commits

Author SHA1 Message Date
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
225 changed files with 5469 additions and 3824 deletions

6
.gitignore vendored
View File

@@ -85,3 +85,9 @@ ios/app/dropbox.key
ios/app/GoogleService-Info.plist
.vscode
# TWA
twa/*.apk
twa/*.aab
twa/assetlinks.json

View File

@@ -5,7 +5,7 @@ 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
NODE_SASS = ./node_modules/.bin/sass
NPM = npm
OUTPUT_DIR = .
STYLES_BUNDLE = css/all.bundle.css

View File

@@ -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
@@ -74,7 +78,7 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
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'
@@ -82,6 +86,7 @@ dependencies {
// Firebase
// - Crashlytics
// - Dynamic Links
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'
}

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

@@ -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;
@@ -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);

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.
@@ -9,18 +10,44 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.android.tools.build:gradle:4.0.2'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
}
}
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
}
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
@@ -135,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=20.5.0
sdkVersion=2.11.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'
@@ -35,10 +33,6 @@ android {
}
}
}
packagingOptions {
pickFirst '**/libc++_shared.so'
}
}
dependencies {
@@ -50,11 +44,8 @@ dependencies {
//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'
@@ -80,6 +71,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 +145,7 @@ android.libraryVariants.all { def variant ->
mergeResourcesTask.dependsOn(currentBundleTask)
mergeAssetsTask.doLast {
def assetsDir = mergeAssetsTask.outputDir
def assetsDir = mergeAssetsTask.outputDir.get()
// Bundle sounds
//
@@ -187,7 +179,7 @@ android.libraryVariants.all { def variant ->
if (currentBundleTask.enabled) {
copy {
from(resourcesDir)
into(mergeResourcesTask.outputDir)
into(mergeResourcesTask.outputDir.get())
}
}
}
@@ -227,14 +219,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,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

@@ -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),
@@ -216,8 +217,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

@@ -21,6 +21,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'

12
app.js
View File

@@ -6,6 +6,13 @@ 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';
@@ -15,7 +22,10 @@ import translation from './modules/translation/translation';
// Initialize Olm as early as possible.
if (window.Olm) {
window.Olm.init();
window.Olm.init().catch(e => {
console.error('Failed to initialize Olm, E2EE will be disabled', e);
delete window.Olm;
});
}
window.APP = {

View File

@@ -24,7 +24,6 @@ import {
reloadWithStoredParams
} from './react/features/app/actions';
import {
AVATAR_ID_COMMAND,
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
authStatusChanged,
@@ -66,6 +65,8 @@ import {
JitsiTrackEvents
} from './react/features/base/lib-jitsi-meet';
import {
getStartWithAudioMuted,
getStartWithVideoMuted,
isVideoMutedByUser,
MEDIA_TYPE,
setAudioAvailable,
@@ -97,17 +98,15 @@ 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 {
@@ -123,7 +122,6 @@ import {
isPrejoinPageVisible,
makePrecallTest
} from './react/features/prejoin';
import { createRnnoiseProcessorPromise } from './react/features/rnnoise';
import { toggleScreenshotCaptureEffect } from './react/features/screenshot-capture';
import { setSharedVideoStatus } from './react/features/shared-video';
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
@@ -172,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,
@@ -736,10 +733,10 @@ 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())
};
@@ -814,7 +811,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);
},
@@ -1221,19 +1218,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
}));
downloadJSON(logs, filename);
},
/**
@@ -1329,53 +1315,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());
},
/**
@@ -2196,16 +2136,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));
@@ -2674,6 +2604,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,
@@ -3095,7 +3039,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);
},

View File

@@ -14,9 +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',
@@ -67,6 +64,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
@@ -321,10 +323,6 @@ var config = {
// 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,
// 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)
@@ -335,6 +333,7 @@ var config = {
// 'datachannel'), undefined (treat it as 'datachannel') and false (don't
// open any channel).
// openBridgeChannel: true,
openBridgeChannel: 'websocket',
// UI
@@ -439,9 +438,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: [
@@ -635,8 +631,6 @@ var config = {
// List of undocumented settings used in jitsi-meet
/**
_immediateReloadThreshold
autoRecord
autoRecordToken
debug
debugAudioLevels
deploymentInfo

View File

@@ -33,6 +33,14 @@ body {
}
}
/**
* 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;
}
/**
* AtlasKit sets a default margin on the rendered modals, so
* when the shift-right class is set when the chat opens, we

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

@@ -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

@@ -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 {

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

@@ -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

@@ -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

@@ -13,3 +13,5 @@ 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/

View File

@@ -8,7 +8,7 @@ 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" }
{ type = "turns", host = "jitmeet.example.com", port = "5349", transport = "tcp" }
};
cross_domain_bosh = false;

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

@@ -87,6 +87,15 @@ 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;
}
location ~ ^/([^/?&:'"]+)$ {
try_files $uri @root_path;
}

View File

@@ -1,5 +1,5 @@
// flow-typed signature: d2ddacbbca9700881249a9435381e689
// flow-typed version: c6154227d1/react-redux_v7.x.x/flow_>=v0.89.x <=v0.103.x
// flow-typed signature: 8da1e134b3de1d6f6bf9ba1cc7e2dc7e
// flow-typed version: 387a235736/react-redux_v7.x.x/flow_>=v0.104.x
/**
The order of type arguments for connect() is as follows:
@@ -219,6 +219,7 @@ declare module "react-redux" {
declare export class Provider<Store> extends React$Component<{
store: Store,
children?: React$Node,
...
}> {}
declare export function createProvider(
@@ -237,6 +238,7 @@ declare module "react-redux" {
shouldHandleStateChanges?: boolean,
storeKey?: string,
forwardRef?: boolean,
...
};
declare type SelectorFactoryOptions<Com> = {
@@ -249,6 +251,7 @@ declare module "react-redux" {
displayName: string,
wrappedComponentName: string,
WrappedComponent: Com,
...
};
declare type MapStateToPropsEx<S: Object, SP: Object, RSP: Object> = (
@@ -275,12 +278,14 @@ declare module "react-redux" {
OP: Object,
CP: Object,
EFO: Object,
ST: { [_: $Keys<Com>]: any },
ST: { [_: $Keys<Com>]: any, ... },
>(
selectorFactory: SelectorFactory<Com, D, S, OP, EFO, CP>,
connectAdvancedOptions: ?(ConnectAdvancedOptions & EFO),
): (component: Com) => React$ComponentType<OP> & $Shape<ST>;
declare export function batch(() => void): void
declare export default {
Provider: typeof Provider,
createProvider: typeof createProvider,
@@ -289,5 +294,7 @@ declare module "react-redux" {
useDispatch: typeof useDispatch,
useSelector: typeof useSelector,
useStore: typeof useStore,
batch: typeof batch,
...
};
}

View File

@@ -4,11 +4,18 @@
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#2A3A4B">
<!--#include virtual="base.html" -->
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
<link rel="stylesheet" href="css/all.css">
<link rel="manifest" id="manifest-placeholder">
<script>
// Dynamically generate the manifest location URL. It must be served from the document origin, and we may have
// the base pointing to the CDN. This way we can generate a full URL which will bypass the base.
document.querySelector('#manifest-placeholder').setAttribute('href', window.location.origin + '/manifest.json');
document.addEventListener('DOMContentLoaded', () => {
if (!JitsiMeetJS.app) {
return;
@@ -17,7 +24,21 @@
JitsiMeetJS.app.renderEntryPoint({
Component: JitsiMeetJS.app.entryPoints.APP
})
})
const isElectron = navigator.userAgent.includes('Electron');
const shouldRegisterWorker = !isElectron && 'serviceWorker' in navigator;
if (shouldRegisterWorker) {
navigator.serviceWorker
.register(window.location.origin + '/pwa-worker.js')
.then(reg => {
console.log('Service worker registered.', reg);
})
.catch(err => {
console.log(err);
});
}
});
</script>
<script>
// IE11 and earlier can be identified via their user agent and be
@@ -164,6 +185,9 @@
<!--#include virtual="static/settingsToolbarAdditionalContent.html" -->
</head>
<body>
<noscript>
<div>JavaScript is disabled. </br>For this site to work you have to enable JavaScript.</div>
</noscript>
<!--#include virtual="body.html" -->
<div id="react"></div>
</body>

View File

@@ -5,8 +5,9 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ
target 'jitsi-meet' do
project 'app/app.xcodeproj'
pod 'Firebase/Crashlytics', '~> 6.24.0'
pod 'Firebase/DynamicLinks', '~> 6.24.0'
pod 'Firebase/Analytics', '~> 6.33.0'
pod 'Firebase/Crashlytics', '~> 6.33.0'
pod 'Firebase/DynamicLinks', '~> 6.33.0'
end
target 'JitsiMeet' do
@@ -65,6 +66,7 @@ target 'JitsiMeet' do
pod 'RNSVG', :path => '../node_modules/react-native-svg'
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
pod 'RNDefaultPreference', :path => '../node_modules/react-native-default-preference'
pod 'react-native-splash-screen', :path => '../node_modules/react-native-splash-screen'
# Native pod dependencies
#

View File

@@ -12,50 +12,57 @@ PODS:
- CocoaLumberjack/Core (= 3.5.3)
- CocoaLumberjack/Core (3.5.3)
- DoubleConversion (1.1.6)
- FBLazyVector (0.61.5-jitsi.1)
- FBReactNativeSpec (0.61.5-jitsi.1):
- FBLazyVector (0.61.5-jitsi.2)
- FBReactNativeSpec (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- RCTRequired (= 0.61.5-jitsi.1)
- RCTTypeSafety (= 0.61.5-jitsi.1)
- React-Core (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- Firebase/CoreOnly (6.24.0):
- FirebaseCore (= 6.7.0)
- Firebase/Crashlytics (6.24.0):
- RCTRequired (= 0.61.5-jitsi.2)
- RCTTypeSafety (= 0.61.5-jitsi.2)
- React-Core (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
- Firebase/Analytics (6.33.0):
- Firebase/Core
- Firebase/Core (6.33.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 4.1.0)
- Firebase/DynamicLinks (6.24.0):
- FirebaseAnalytics (= 6.8.3)
- Firebase/CoreOnly (6.33.0):
- FirebaseCore (= 6.10.3)
- Firebase/Crashlytics (6.33.0):
- Firebase/CoreOnly
- FirebaseDynamicLinks (~> 4.0.8)
- FirebaseAnalyticsInterop (1.5.0)
- FirebaseCore (6.7.0):
- FirebaseCoreDiagnostics (~> 1.3)
- FirebaseCoreDiagnosticsInterop (~> 1.2)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Logger (~> 6.5)
- FirebaseCoreDiagnostics (1.3.0):
- FirebaseCoreDiagnosticsInterop (~> 1.2)
- GoogleDataTransportCCTSupport (~> 3.1)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Logger (~> 6.5)
- nanopb (~> 1.30905.0)
- FirebaseCoreDiagnosticsInterop (1.2.0)
- FirebaseCrashlytics (4.1.1):
- FirebaseAnalyticsInterop (~> 1.2)
- FirebaseCore (~> 6.6)
- FirebaseInstallations (~> 1.1)
- GoogleDataTransport (~> 6.1)
- GoogleDataTransportCCTSupport (~> 3.1)
- nanopb (~> 1.30905.0)
- FirebaseCrashlytics (~> 4.6.1)
- Firebase/DynamicLinks (6.33.0):
- Firebase/CoreOnly
- FirebaseDynamicLinks (~> 4.3.1)
- FirebaseAnalytics (6.8.3):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleAppMeasurement (= 6.8.3)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/MethodSwizzler (~> 6.7)
- GoogleUtilities/Network (~> 6.7)
- "GoogleUtilities/NSData+zlib (~> 6.7)"
- nanopb (~> 1.30906.0)
- FirebaseCore (6.10.3):
- FirebaseCoreDiagnostics (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- FirebaseCoreDiagnostics (1.7.0):
- GoogleDataTransport (~> 7.4)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- nanopb (~> 1.30906.0)
- FirebaseCrashlytics (4.6.1):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleDataTransport (~> 7.2)
- nanopb (~> 1.30906.0)
- PromisesObjC (~> 1.2)
- FirebaseDynamicLinks (4.0.8):
- FirebaseAnalyticsInterop (~> 1.3)
- FirebaseCore (~> 6.2)
- FirebaseInstallations (1.2.0):
- FirebaseCore (~> 6.6)
- GoogleUtilities/Environment (~> 6.6)
- GoogleUtilities/UserDefaults (~> 6.6)
- FirebaseDynamicLinks (4.3.1):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (1.7.0):
- FirebaseCore (~> 6.10)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- PromisesObjC (~> 1.2)
- Folly (2018.10.22.00):
- boost-for-react-native
@@ -67,19 +74,36 @@ PODS:
- DoubleConversion
- glog
- glog (0.3.5)
- GoogleDataTransport (6.1.0)
- GoogleDataTransportCCTSupport (3.1.0):
- GoogleDataTransport (~> 6.1)
- nanopb (~> 1.30905.0)
- GoogleAppMeasurement (6.8.3):
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/MethodSwizzler (~> 6.7)
- GoogleUtilities/Network (~> 6.7)
- "GoogleUtilities/NSData+zlib (~> 6.7)"
- nanopb (~> 1.30906.0)
- GoogleDataTransport (7.4.0):
- nanopb (~> 1.30906.0)
- GoogleSignIn (5.0.1):
- AppAuth (~> 1.2)
- GTMAppAuth (~> 1.0)
- GTMSessionFetcher/Core (~> 1.1)
- GoogleUtilities/Environment (6.6.0):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.6.0):
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/UserDefaults (6.6.0):
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (6.7.2):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/MethodSwizzler (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/Network (6.7.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (6.7.2)"
- GoogleUtilities/Reachability (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger
- GTMAppAuth (1.0.0):
- AppAuth/Core (~> 1.0)
@@ -89,176 +113,176 @@ PODS:
- GTMSessionFetcher/Core (1.2.2)
- GTMSessionFetcher/Full (1.2.2):
- GTMSessionFetcher/Core (= 1.2.2)
- nanopb (1.30905.0):
- nanopb/decode (= 1.30905.0)
- nanopb/encode (= 1.30905.0)
- nanopb/decode (1.30905.0)
- nanopb/encode (1.30905.0)
- nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0)
- nanopb/decode (1.30906.0)
- nanopb/encode (1.30906.0)
- ObjectiveDropboxOfficial (3.9.4)
- PromisesObjC (1.2.8)
- RCTRequired (0.61.5-jitsi.1)
- RCTTypeSafety (0.61.5-jitsi.1):
- FBLazyVector (= 0.61.5-jitsi.1)
- PromisesObjC (1.2.10)
- RCTRequired (0.61.5-jitsi.2)
- RCTTypeSafety (0.61.5-jitsi.2):
- FBLazyVector (= 0.61.5-jitsi.2)
- Folly (= 2018.10.22.00)
- RCTRequired (= 0.61.5-jitsi.1)
- React-Core (= 0.61.5-jitsi.1)
- React (0.61.5-jitsi.1):
- React-Core (= 0.61.5-jitsi.1)
- React-Core/DevSupport (= 0.61.5-jitsi.1)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.1)
- React-RCTActionSheet (= 0.61.5-jitsi.1)
- React-RCTAnimation (= 0.61.5-jitsi.1)
- React-RCTBlob (= 0.61.5-jitsi.1)
- React-RCTImage (= 0.61.5-jitsi.1)
- React-RCTLinking (= 0.61.5-jitsi.1)
- React-RCTNetwork (= 0.61.5-jitsi.1)
- React-RCTSettings (= 0.61.5-jitsi.1)
- React-RCTText (= 0.61.5-jitsi.1)
- React-RCTVibration (= 0.61.5-jitsi.1)
- React-Core (0.61.5-jitsi.1):
- RCTRequired (= 0.61.5-jitsi.2)
- React-Core (= 0.61.5-jitsi.2)
- React (0.61.5-jitsi.2):
- React-Core (= 0.61.5-jitsi.2)
- React-Core/DevSupport (= 0.61.5-jitsi.2)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.2)
- React-RCTActionSheet (= 0.61.5-jitsi.2)
- React-RCTAnimation (= 0.61.5-jitsi.2)
- React-RCTBlob (= 0.61.5-jitsi.2)
- React-RCTImage (= 0.61.5-jitsi.2)
- React-RCTLinking (= 0.61.5-jitsi.2)
- React-RCTNetwork (= 0.61.5-jitsi.2)
- React-RCTSettings (= 0.61.5-jitsi.2)
- React-RCTText (= 0.61.5-jitsi.2)
- React-RCTVibration (= 0.61.5-jitsi.2)
- React-Core (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-Core/Default (= 0.61.5-jitsi.2)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/CoreModulesHeaders (0.61.5-jitsi.1):
- React-Core/CoreModulesHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/Default (0.61.5-jitsi.1):
- React-Core/Default (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/DevSupport (0.61.5-jitsi.1):
- React-Core/DevSupport (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default (= 0.61.5-jitsi.1)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-jsinspector (= 0.61.5-jitsi.1)
- React-Core/Default (= 0.61.5-jitsi.2)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.2)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- React-jsinspector (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTActionSheetHeaders (0.61.5-jitsi.1):
- React-Core/RCTActionSheetHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTAnimationHeaders (0.61.5-jitsi.1):
- React-Core/RCTAnimationHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTBlobHeaders (0.61.5-jitsi.1):
- React-Core/RCTBlobHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTImageHeaders (0.61.5-jitsi.1):
- React-Core/RCTImageHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTLinkingHeaders (0.61.5-jitsi.1):
- React-Core/RCTLinkingHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTNetworkHeaders (0.61.5-jitsi.1):
- React-Core/RCTNetworkHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTSettingsHeaders (0.61.5-jitsi.1):
- React-Core/RCTSettingsHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTTextHeaders (0.61.5-jitsi.1):
- React-Core/RCTTextHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTVibrationHeaders (0.61.5-jitsi.1):
- React-Core/RCTVibrationHeaders (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-Core/RCTWebSocket (0.61.5-jitsi.1):
- React-Core/RCTWebSocket (0.61.5-jitsi.2):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-Core/Default (= 0.61.5-jitsi.2)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsiexecutor (= 0.61.5-jitsi.2)
- Yoga
- React-CoreModules (0.61.5-jitsi.1):
- FBReactNativeSpec (= 0.61.5-jitsi.1)
- React-CoreModules (0.61.5-jitsi.2):
- FBReactNativeSpec (= 0.61.5-jitsi.2)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.61.5-jitsi.1)
- React-Core/CoreModulesHeaders (= 0.61.5-jitsi.1)
- React-RCTImage (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- React-cxxreact (0.61.5-jitsi.1):
- RCTTypeSafety (= 0.61.5-jitsi.2)
- React-Core/CoreModulesHeaders (= 0.61.5-jitsi.2)
- React-RCTImage (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
- React-cxxreact (0.61.5-jitsi.2):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-jsinspector (= 0.61.5-jitsi.1)
- React-jsi (0.61.5-jitsi.1):
- React-jsinspector (= 0.61.5-jitsi.2)
- React-jsi (0.61.5-jitsi.2):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-jsi/Default (= 0.61.5-jitsi.1)
- React-jsi/Default (0.61.5-jitsi.1):
- React-jsi/Default (= 0.61.5-jitsi.2)
- React-jsi/Default (0.61.5-jitsi.2):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-jsiexecutor (0.61.5-jitsi.1):
- React-jsiexecutor (0.61.5-jitsi.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsinspector (0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-jsinspector (0.61.5-jitsi.2)
- react-native-background-timer (2.4.0):
- React
- react-native-calendar-events (2.0.0):
@@ -267,64 +291,66 @@ PODS:
- React
- react-native-netinfo (4.1.5):
- React
- react-native-splash-screen (3.2.0):
- React
- react-native-webrtc (1.84.0):
- React
- react-native-webview (7.4.1):
- react-native-webview (10.9.0):
- React
- React-RCTActionSheet (0.61.5-jitsi.1):
- React-Core/RCTActionSheetHeaders (= 0.61.5-jitsi.1)
- React-RCTAnimation (0.61.5-jitsi.1):
- React-Core/RCTAnimationHeaders (= 0.61.5-jitsi.1)
- React-RCTBlob (0.61.5-jitsi.1):
- React-Core/RCTBlobHeaders (= 0.61.5-jitsi.1)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-RCTNetwork (= 0.61.5-jitsi.1)
- React-RCTImage (0.61.5-jitsi.1):
- React-Core/RCTImageHeaders (= 0.61.5-jitsi.1)
- React-RCTNetwork (= 0.61.5-jitsi.1)
- React-RCTLinking (0.61.5-jitsi.1):
- React-Core/RCTLinkingHeaders (= 0.61.5-jitsi.1)
- React-RCTNetwork (0.61.5-jitsi.1):
- React-Core/RCTNetworkHeaders (= 0.61.5-jitsi.1)
- React-RCTSettings (0.61.5-jitsi.1):
- React-Core/RCTSettingsHeaders (= 0.61.5-jitsi.1)
- React-RCTText (0.61.5-jitsi.1):
- React-Core/RCTTextHeaders (= 0.61.5-jitsi.1)
- React-RCTVibration (0.61.5-jitsi.1):
- React-Core/RCTVibrationHeaders (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (0.61.5-jitsi.1):
- React-RCTActionSheet (0.61.5-jitsi.2):
- React-Core/RCTActionSheetHeaders (= 0.61.5-jitsi.2)
- React-RCTAnimation (0.61.5-jitsi.2):
- React-Core/RCTAnimationHeaders (= 0.61.5-jitsi.2)
- React-RCTBlob (0.61.5-jitsi.2):
- React-Core/RCTBlobHeaders (= 0.61.5-jitsi.2)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- React-RCTNetwork (= 0.61.5-jitsi.2)
- React-RCTImage (0.61.5-jitsi.2):
- React-Core/RCTImageHeaders (= 0.61.5-jitsi.2)
- React-RCTNetwork (= 0.61.5-jitsi.2)
- React-RCTLinking (0.61.5-jitsi.2):
- React-Core/RCTLinkingHeaders (= 0.61.5-jitsi.2)
- React-RCTNetwork (0.61.5-jitsi.2):
- React-Core/RCTNetworkHeaders (= 0.61.5-jitsi.2)
- React-RCTSettings (0.61.5-jitsi.2):
- React-Core/RCTSettingsHeaders (= 0.61.5-jitsi.2)
- React-RCTText (0.61.5-jitsi.2):
- React-Core/RCTTextHeaders (= 0.61.5-jitsi.2)
- React-RCTVibration (0.61.5-jitsi.2):
- React-Core/RCTVibrationHeaders (= 0.61.5-jitsi.2)
- ReactCommon/jscallinvoker (0.61.5-jitsi.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-cxxreact (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule (0.61.5-jitsi.1):
- React-cxxreact (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule (0.61.5-jitsi.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/samples (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (0.61.5-jitsi.1):
- React-Core (= 0.61.5-jitsi.2)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/samples (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/core (0.61.5-jitsi.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/samples (0.61.5-jitsi.1):
- React-Core (= 0.61.5-jitsi.2)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/samples (0.61.5-jitsi.2):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- React-Core (= 0.61.5-jitsi.2)
- React-cxxreact (= 0.61.5-jitsi.2)
- React-jsi (= 0.61.5-jitsi.2)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.2)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.2)
- RNCAsyncStorage (1.3.4):
- React
- RNDefaultPreference (1.4.2):
@@ -337,7 +363,7 @@ PODS:
- RNSound/Core (= 0.11.0)
- RNSound/Core (0.11.0):
- React
- RNSVG (9.7.1):
- RNSVG (10.1.0):
- React
- RNWatch (0.4.3):
- React
@@ -350,8 +376,9 @@ DEPENDENCIES:
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector/`)
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec/`)
- Firebase/Crashlytics (~> 6.24.0)
- Firebase/DynamicLinks (~> 6.24.0)
- Firebase/Analytics (~> 6.33.0)
- Firebase/Crashlytics (~> 6.33.0)
- Firebase/DynamicLinks (~> 6.33.0)
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- ObjectiveDropboxOfficial (~> 3.9.4)
@@ -370,6 +397,7 @@ DEPENDENCIES:
- react-native-calendar-events (from `../node_modules/react-native-calendar-events`)
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
@@ -397,15 +425,14 @@ SPEC REPOS:
- boost-for-react-native
- CocoaLumberjack
- Firebase
- FirebaseAnalyticsInterop
- FirebaseAnalytics
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseCoreDiagnosticsInterop
- FirebaseCrashlytics
- FirebaseDynamicLinks
- FirebaseInstallations
- GoogleAppMeasurement
- GoogleDataTransport
- GoogleDataTransportCCTSupport
- GoogleSignIn
- GoogleUtilities
- GTMAppAuth
@@ -453,6 +480,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-keep-awake"
react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo"
react-native-splash-screen:
:path: "../node_modules/react-native-splash-screen"
react-native-webrtc:
:path: "../node_modules/react-native-webrtc"
react-native-webview:
@@ -499,60 +528,60 @@ SPEC CHECKSUMS:
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
CocoaLumberjack: 2f44e60eb91c176d471fdba43b9e3eae6a721947
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
FBLazyVector: 4a5251159a3ed05dc11cc8b74cf937869935814b
FBReactNativeSpec: 6fa602a20993212cc9877a81838578ffb0008bc9
Firebase: b28e55c60efd98963cd9011fe2fac5a10c2ba124
FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae
FirebaseCore: e610482f64097b0e9f056cd97bc6b33dfabcbb6a
FirebaseCoreDiagnostics: 4a773a47bd83bbd5a9b1ccf1ce7caa8b2d535e67
FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
FirebaseCrashlytics: a87cce5746d3335995bd18b1b60d073cd05a6920
FirebaseDynamicLinks: 417dc6dbb6013233c77558290d73296f429656a6
FirebaseInstallations: 2119fb3e46b0a88bfdbf12562f855ee3252462fa
FBLazyVector: ca7f56c8ff6cd8590f7a673d7903b06019805581
FBReactNativeSpec: 8136c3cf27de2bb310a69cffbb423c5643f5c1c4
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
FirebaseCrashlytics: 5777d3462fb8c3ab9e80a2473bd7d667a2e8411c
FirebaseDynamicLinks: 6eac37d86910382eafb6315d952cc44c9e176094
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
GoogleDataTransport: f6f8eba931df03ebd2232ff4645aa85f8f47b5ab
GoogleDataTransportCCTSupport: d70a561f7d236af529fee598835caad5e25f6d3d
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
GoogleDataTransport: b7f406340a291370045a270c599e53c6fa6ec20f
GoogleSignIn: 3a51b9bb8e48b635fd7f4272cee06ca260345b86
GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
GTMAppAuth: 4deac854479704f348309e7b66189e604cf5e01e
GTMSessionFetcher: 61bb0f61a4cb560030f1222021178008a5727a23
nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
ObjectiveDropboxOfficial: a5afefc83f6467c42c45f2253f583f2ad1ffc701
PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6
RCTRequired: f63dd90a89a60602acdd44c42e5d2645ca60ab79
RCTTypeSafety: 24a3c6d55684046ed550b1d0ef083a9bf71c8bd4
React: 71c5a51135f291c3b32c0b558e167b858ae50e84
React-Core: e82c03ff91062abf963f35bf99a357154e570285
React-CoreModules: e236aeecd18cec37743c8c50562431db5302f668
React-cxxreact: 526ec106aa1bf2b3f6aab2a7d528d1d23d5f59c2
React-jsi: 4f35c1a2273d193a80c1c3831c808413840c260c
React-jsiexecutor: de1c37cf59ae9adcbf2be82eea0e090dc3f3205e
React-jsinspector: b76c4e84a7833bb4c90549d59ed53ec299ff912b
PromisesObjC: b14b1c6b68e306650688599de8a45e49fae81151
RCTRequired: a686731276578c125dff205f08b6ec9cee6ede32
RCTTypeSafety: 88e5500e801c00d16a3d1895e3470d13beed6584
React: 8b2bcf6a93846e47a7a365a54ec6edeb78b37701
React-Core: 3fbdbc87c18c4742b735ff9a0c02fa38c87e0fba
React-CoreModules: f6f8a8212aec52a21251c0af58bdb037b57c70b3
React-cxxreact: c6ad34143db06a5c3cb0e8e169c775475287ac9c
React-jsi: ddb471a56185e4007835a1bba0882ecb5ce3dc0e
React-jsiexecutor: 67106691c60030ec888d7cbbc4f48a3168e27a02
React-jsinspector: 92ceee6c66dc19886289b52436ade7e020b89602
react-native-background-timer: e0384ea2fa5a98f67f84f9c4dc274260ddd674ed
react-native-calendar-events: 1442fad71a00388f933cfa25512588fec300fcf8
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
react-native-netinfo: 8d8db463bcc5db66a8ac5c48a7d86beb3b92f61a
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
react-native-webrtc: 9268ae9a2bc9730796b0968d012327e92c392adf
react-native-webview: 4dbc1d2a4a6b9c5e9e723c62651917aa2b5e579e
React-RCTActionSheet: b72ddbfbe15b44ce691d128e4b582f4bb9abb540
React-RCTAnimation: cfaefba5024499d336b76ab850e6bd33b232b5e3
React-RCTBlob: c427e643bef82999deeab97489ba43298ecfbe24
React-RCTImage: 79934bc96f3349da6a75b1d61cad594a932e4097
React-RCTLinking: 12b153399567c30efac0b32bb00f9c064587dc26
React-RCTNetwork: 603ad75778a54521b7797fd07c67dff562317526
React-RCTSettings: 8d45fcf14513582539ea1ddea69391207de7f046
React-RCTText: b4c29897c3df0c9f112e29aa3167fa6caf40b690
React-RCTVibration: a1bcfcdc0b5a73a1b0829a34cee22bd0e95bacba
ReactCommon: 675681aba4fecff5acbc0e440530cc422103c610
react-native-webview: 6ee7868ca8eba635dbf7963986d1ab7959da0391
React-RCTActionSheet: bcbc311dc3b47bc8efb2737ff0940239a45789a9
React-RCTAnimation: 65f61080ce632f6dea23d52e354ffac9948396c6
React-RCTBlob: 70d88f7b68b5c44953cdb286ac2e36a7a509a97e
React-RCTImage: e0d25b620e42de91ed791ef129e2d3a0df1eb5ab
React-RCTLinking: bc2287cfd9e56403ecea5dafdbdac8c57fa1ac36
React-RCTNetwork: cd8ae8fc787c02ed5152fe9cbf7521ee70c1bce7
React-RCTSettings: f6667271ccd8876a934134b73002b5a2714e1525
React-RCTText: 4f1b99f228278d2a5e9008eced8dc9c974c4a270
React-RCTVibration: c1041024893fdfdb8371e7c720c437751b711676
ReactCommon: 18014e1d98dbeb9141e935cfe35fc93bd511ffb6
RNCAsyncStorage: 8e31405a9f12fbf42c2bb330e4560bfd79c18323
RNDefaultPreference: 56a405ce61033ac77b95004dccd7ac54c2eb50d1
RNGoogleSignin: 39336070b35fc4cea6a98cf111e00480317be0ae
RNSound: c980916b596cc15c8dcd2f6ecd3b13c4881dbe20
RNSVG: aac12785382e8fd4f28d072fe640612e34914631
RNSVG: 069864be08c9fe065a2cf7e63656a34c78653c99
RNWatch: a5320c959c75e72845c07985f3e935e58998f1d3
Yoga: 7b4209fda2441f99d54dd6cf4c82b094409bb68f
Yoga: 96b469c5e81ff51b917b92e8c3390642d4ded30c
PODFILE CHECKSUM: 7255ec38ea51a8bc10a7a582248b4eb4bbbff80c
PODFILE CHECKSUM: f2400f8e5a52c4d91697cbacba6956569efc5ab8
COCOAPODS: 1.9.3

View File

@@ -53,6 +53,9 @@
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:![jitsiMeet isCrashReportingDisabled]];
}
ViewController *rootController = (ViewController *)self.window.rootViewController;
[jitsiMeet showSplashScreen:rootController.view];
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
return YES;

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>20.4.0</string>
<string>20.5.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
@@ -66,10 +66,10 @@
<string>See your scheduled meetings in the app.</string>
<key>NSCameraUsageDescription</key>
<string>Participate in meetings with video.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSMicrophoneUsageDescription</key>
<string>Participate in meetings with voice.</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Local network is used for establishing Peer-to-Peer connections.</string>
<key>NSUserActivityTypes</key>
<array>
<string>org.jitsi.JitsiMeet.ios.conference</string>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>20.4.0</string>
<string>20.5.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>UISupportedInterfaceOrientations</key>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>20.4.0</string>
<string>20.5.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CLKComplicationPrincipalClass</key>

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.10.0</string>
<string>2.11.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>

View File

@@ -67,4 +67,6 @@
- (BOOL)isCrashReportingDisabled;
- (void)showSplashScreen:(UIView * _Nonnull) rootView;
@end

View File

@@ -22,6 +22,7 @@
#import "JitsiMeetView+Private.h"
#import "RCTBridgeWrapper.h"
#import "ReactUtils.h"
#import "RNSplashScreen.h"
#import <RNGoogleSignin/RNGoogleSignin.h>
#import <WebRTC/RTCLogging.h>
@@ -183,6 +184,10 @@
return nil;
}
- (void)showSplashScreen:(UIView*)rootView {
[RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView];
}
#pragma mark - Property getter / setters
- (NSArray<NSString *> *)universalLinkDomains {

View File

@@ -20,6 +20,7 @@
"ru": "Russisch",
"sk": "Slowakisch",
"sl": "Slowenisch",
"sr": "Serbish",
"sv": "Schwedisch",
"tr": "Türkisch",
"vi": "Vietnamesisch",

View File

@@ -20,6 +20,7 @@
"ru": "Russian",
"sk": "",
"sl": "Slovenian",
"sr": "Serbian",
"sv": "Swedish",
"tr": "Turkish",
"vi": "Vietnamese",

View File

@@ -20,6 +20,7 @@
"ru": "Ruski",
"sk": "Slovački",
"sl": "Slovenski",
"sr": "Srpski",
"sv": "Švedski",
"tr": "Turski",
"vi": "Vijetnamski",

View File

@@ -24,6 +24,7 @@
"pl": "Польский",
"ptBR": "Португальский (Бразилия)",
"ru": "Русский",
"sr": "Сербский",
"sv": "Шведский",
"tr": "Турецкий",
"vi": "Вьетнамский",

View File

@@ -1,34 +1,39 @@
{
"en": "",
"af": "",
"bg": "",
"ca": "",
"cs": "",
"da": "",
"de": "",
"el": "",
"enGB": "",
"eo": "",
"es": "",
"esUS": "",
"et": "",
"fi": "",
"fr": "",
"frCA": "",
"hr": "",
"hu": "",
"hy": "",
"it": "",
"ja": "",
"ko": "",
"nl": "",
"oc": "",
"pl": "",
"ptBR": "",
"ru": "",
"sv": "",
"tr": "",
"vi": "",
"zhCN": "",
"zhTW": ""
"en": "Енглески",
"af": "Африкански",
"az": "Азербејџански",
"bg": "Бугарски",
"cs": "Чешки",
"de": "Њемачки",
"el": "Грчки",
"eo": "Есперанто",
"es": "Шпански",
"fr": "Француски",
"hy": "Јерменски",
"it": "Италијански",
"ja": "Јапански",
"ko": "Корејски",
"nb": "Норвешки Бокал",
"oc": "Окцитански",
"pl": "Пољски",
"ptBR": "Португалски (Бразил)",
"ru": "Руски",
"sk": "Словачки",
"sl": "Словенски",
"sr": "Српски",
"sv": "Шведски",
"tr": "Турски",
"vi": "Вијетнамски",
"zhCN": "Кинески (Кина)",
"zhTW": "Кинески (Тајван)",
"nl": "Холандски",
"hu": "Мађарски",
"hr": "Хрватски",
"frCA": "Француски (Канада)",
"fi": "Фински",
"et": "Естонски",
"esUS": "Шпански (Латинска Америка)",
"enGB": "Енглески (Велика Британија)",
"da": "Дански",
"ca": "Каталонски"
}

View File

@@ -37,6 +37,7 @@
"sc": "Sardinian",
"sk": "Slovak",
"sl": "Slovenian",
"sr": "Serbian",
"sv": "Swedish",
"th": "Thailand",
"tr": "Turkish",

View File

@@ -234,7 +234,7 @@
"micPermissionDeniedError": "Die Berechtigung zur Verwendung des Mikrofons wurde nicht erteilt. Sie können trotzdem an der Konferenz teilnehmen, aber die anderen Teilnehmer können Sie nicht hören. Verwenden Sie die Kamera-Schaltfläche in der Adressleiste, um die Berechtigungen zu erteilen.",
"micUnknownError": "Das Mikrofon kann aus einem unbekannten Grund nicht verwendet werden.",
"muteEveryoneElseDialog": "Einmal stummgeschaltet, können Sie deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
"muteEveryoneElseTitle": "Alle außer {{whom}} stummschaten?",
"muteEveryoneElseTitle": "Alle außer {{whom}} stummschalten?",
"muteEveryoneDialog": "Wollen Sie wirklich alle stummschalten? Sie können deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
"muteEveryoneTitle": "Alle stummschalten?",
"muteEveryoneSelf": "sich selbst",

View File

@@ -139,6 +139,9 @@
"description": "Rien ne s'est passé ? Nous avons essayé de lancer votre réunion dans l'application de bureau {{app}}. Essayez à nouveau ou lancez-la dans l'application web {{app}}.",
"descriptionWithoutWeb": "Rien ne s'est passé ? Nous avons essayé de démarrer votre réunion dans l'application bureau {{app}}.",
"downloadApp": "Télécharger l'application",
"ifDoNotHaveApp": "Si vous n'avez pas encore l'application:",
"ifHaveApp": "Si vous avez déjà installé l'application:",
"joinInApp": "Rejoindre la réunion en utilisant l'application",
"launchWebButton": "Lancer dans le navigateur",
"openApp": "Continuer vers l'application",
"title": "Lancement de votre réunion dans {{app}} en cours...",

View File

@@ -212,7 +212,7 @@
"kickParticipantButton": "Verwijderen",
"kickParticipantDialog": "Weet u zeker dat u deze deelnemer wilt verwijderen?",
"kickParticipantTitle": "Deze deelnemer verwijderen?",
"kickTitle": "Oei! {{ParticipantDisplayName}} heeft u uit de vergadering verwijderd",
"kickTitle": "Oei! {{participantDisplayName}} heeft u uit de vergadering verwijderd",
"liveStreaming": "Livestreamen",
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Niet mogelijk tijdens opnemen",
"liveStreamingDisabledForGuestTooltip": "Gasten kunnen geen livestream starten.",

View File

@@ -1,62 +1,77 @@
{
"addPeople": {
"add": "Pozvať",
"addContacts": "Pozvať kontakty",
"copyInvite": "Skopírovať pozvánku",
"copyLink": "Skopírovať odkaz na konferenciu",
"copyStream": "Skopírovať odkaz na živé vysielanie",
"countryNotSupported": "Zatiaľ nepodporujeme túto krajinu.",
"countryReminder": "Medzinárodný hovor? Prosím skontrolujte, či telefónne číslo začína smerovým číslo krajiny.",
"disabled": "Nemôžete pozvať ďalších účastníkov.",
"defaultEmail": "Predvolený email",
"disabled": "Nemôžete pozvať ďalších ľudí.",
"failedToAdd": "Nepodarilo sa pridať účastníka.",
"footerText": "Odchádzajúce hovory sú zablokované.",
"loading": "Hľadanie účastníkov a telefónnych čísiel",
"googleEmail": "Google email",
"inviteMoreHeader": "Ste sám v tejto konferencii",
"inviteMoreMailSubject": "Pozvánka do konferencie {{appName}}",
"inviteMorePrompt": "Pozvať ľudí",
"linkCopied": "Odkaz skopírovaný do schránky",
"loading": "Hľadanie ľudí a telefónnych čísiel",
"loadingNumber": "Kontrola telefónneho čísla",
"loadingPeople": "Hľadanie účastníkov na pozvanie",
"loadingPeople": "Hľadanie ľudí na pozvanie",
"noResults": "Žiadne výsledky hľadania",
"noValidNumbers": "Prosím zadajte telefónne číslo",
"outlookEmail": "Outlook email",
"searchNumbers": "Zadajte telefónne čísla",
"searchPeople": "Hľadanie účastníkov",
"searchPeopleAndNumbers": "Hľadanie účastníkov alebo pridávanie telefónny čísel",
"searchPeople": "Hľadanie ľudí",
"searchPeopleAndNumbers": "Hľadať ľudí alebo pridať ich telefónne čísla",
"shareInvite": "Zdieľať pozvánku do konferencie",
"shareLink": "Zdieľať odkaz na pozvanie",
"shareStream": "Zdieľať odkaz na živé vysielanie",
"telephone": "Telefón: {{number}}",
"title": "Pozvať účastníkov do tejto konferencie"
"title": "Pozvať ľudí do tejto konferencie",
"yahooEmail": "Yahoo email"
},
"audioDevices": {
"bluetooth": "Bluetooth",
"headphones": "Sluchátka",
"headphones": "Slúchadlá",
"phone": "Telefón",
"speaker": "Rečník",
"speaker": "Reproduktor",
"none": "Žiadne zvukové zariadenia"
},
"audioOnly": {
"audioOnly": "Iba zvuk"
},
"calendarSync": {
"addMeetingURL": "Pridať odkaz na stretnutie",
"addMeetingURL": "Pridať odkaz na konferenciu",
"confirmAddLink": "Chcete pridal Jitsi odkaz do tejto udalosti?",
"error": {
"appConfiguration": "Integrácia s kalendárom nie je správne nastavená.",
"generic": "Stala sa chyba. Skontrolujte si nastavenia kalendáru a skúste aktualizovať kalendár. ",
"notSignedIn": "Stala sa chyba počas autentifikácie pre zobrazovanie kaledárových udalosti. Skontrolujte si nastavenia kalendáru a skúste sa znovu prihlásiť."
"generic": "Stala sa chyba. Skontrolujte nastavenia kalendára a skúste obnoviť kalendár.",
"notSignedIn": "Stala sa chyba počas autentifikácie pre zobrazenie kaledárových udalosti. Skontrolujte nastavenia kalendára a skúste sa znovu prihlásiť."
},
"join": "Zúčastniť sa",
"joinTooltip": "Zúčastniť sa stretnutia",
"nextMeeting": "nasledujúce stretnutie",
"noEvents": "Niesú naplánované žiadne ďalšie udalosti.",
"ongoingMeeting": "prebiehajúce stretnutie",
"joinTooltip": "Zúčastniť sa konferencie",
"nextMeeting": "nasledujúca konferencia",
"noEvents": "Nie sú naplánované žiadne ďalšie udalosti.",
"ongoingMeeting": "prebiehajúca konferencia",
"permissionButton": "Otvoriť nastavenia",
"permissionMessage": "Aplikácia potrebuje kalendárové oprávnenie pre zobranie termínov a stretnutí ",
"refresh": "Aktualizovať kalendár",
"permissionMessage": "Aplikácia potrebuje kalendárové oprávnenie pre zobranie termínov a stretnutí.",
"refresh": "Obnoviť kalendár",
"today": "Dnes"
},
"chat": {
"error": "Chyba: vaša správa \"{{originalText}}\" nebola poslaná. Dôvod: {{error}}",
"fieldPlaceHolder": "Zadajte sem vašu správu",
"messagebox": "Napíšte správu",
"messageTo": "Správa pre {{recipient}}",
"noMessagesMessage": "V tejto konferencií ešte nie je žiadna správa. Začnite tu vašu diskusiu!",
"messageTo": "Súkromná správa pre {{recipient}}",
"noMessagesMessage": "V tejto konferencii ešte nie je žiadna správa. Začnite tu vašu diskusiu!",
"nickname": {
"popover": "Zvoľte meno",
"title": "Zadajte sem vašu prezývku"
"title": "Zadajte vašu prezývku"
},
"privateNotice": "Súkromná správa pre {{recipient}}",
"title": "Písanie",
"title": "Chat",
"you": "Vy"
},
"chromeExtensionBanner": {
@@ -65,54 +80,54 @@
"dontShowAgain": "Upozornenie viac nezobrazovať"
},
"connectingOverlay": {
"joiningRoom": "Vytvára sa spojenie do vašej konferencie"
"joiningRoom": "Pripájanie do konferencie..."
},
"connection": {
"ATTACHED": "Priložený",
"AUTHENTICATING": "Overujem",
"AUTHENTICATING": "Overovanie",
"AUTHFAIL": "Overenie zlyhalo",
"CONNECTED": "Pripojený",
"CONNECTING": "Pripájam",
"CONNECTING": "Pripájanie",
"CONNFAIL": "Spojenie zlyhalo",
"DISCONNECTED": "Odpojený",
"DISCONNECTING": "Odpájam",
"DISCONNECTING": "Odpájanie",
"ERROR": "Chyba",
"RECONNECTING": "Chyba siete. Skúšam sa znova pripojiť ...",
"FETCH_SESSION_ID": "Získavanie session-id...",
"GET_SESSION_ID_ERROR": "Chyba pri získavaní session-id: {{code}}",
"GOT_SESSION_ID": "Získavanie session-id... Hotovo",
"LOW_BANDWIDTH": "Video pre {{displayName}} bolo vypnuté, aby sa ušetrila prenosová kapacita"
},
"connectionindicator": {
"address": "Adresa:",
"bandwidth": "Predpokladaný dat. tok:",
"bitrate": "Prenos. rýchlosť",
"bridgeCount": "Počet serverov:",
"bandwidth": "Dátový tok:",
"bitrate": "Prenos. rýchlosť:",
"bridgeCount": "Počet serverov: ",
"connectedTo": "Spojenie s:",
"e2e_rtt": "E2E RTT:",
"framerate": "Rýchlosť snímkovania:",
"less": "Zobraz menej",
"localaddress_0": "Lokálna adresa:",
"localaddress_1": "Lokálne adresy:",
"localaddress_2": "",
"localport_0": "Lokálny port:",
"localport_1": "Lokálne porty:",
"localport_2": "",
"more": "Zobraz viac",
"packetloss": "Strata packetov:",
"less": "Zobraz menej",
"localaddress": "Lokálna adresa:",
"localaddress_plural": "Lokálne adresy:",
"localport": "Lokálny port:",
"localport_plural": "Lokálne porty:",
"maxEnabledResolution": "send max",
"more": "Zobraziť viac",
"packetloss": "Strata paketov:",
"quality": {
"good": "Dobré",
"inactive": "Neaktívne",
"lost": "Stratené",
"nonoptimal": "Nie je optimálne",
"nonoptimal": "Neoptimálne",
"poor": "Slabé"
},
"remoteaddress_0": "Vzdialená adresa:",
"remoteaddress_1": "Vzdialené adresy:",
"remoteaddress_2": "",
"remoteport_0": "Vzdialený port:",
"remoteport_1": "Vzdialené porty:",
"remoteport_2": "",
"remoteaddress": "Vzdialená adresa:",
"remoteaddress_plural": "Vzdialené adresy:",
"remoteport": "Vzdialený port:",
"remoteport_plural": "Vzdialené porty:",
"resolution": "Rozlíšenie:",
"status": "Spojenie:",
"transport": "Prenos:"
"transport": "Prenos:",
"transport_plural": "Prenosy:"
},
"dateUtils": {
"earlier": "Skôr",
@@ -121,16 +136,18 @@
},
"deepLinking": {
"appNotInstalled": "Potrebujete aplikáciu {{app}}, aby ste sa mohli pripojiť do tejto konferencie na vašom telefóne.",
"description": "Nič sa nestalo? Snažili sme sa otvoriť konferenciu v {{app}}. Skúste to znovu, alebo sa pripojte na konferenciu v {{app}} cez Web.",
"descriptionWithoutWeb": "Nič sa nestalo? Snažili sme sa spustiť váš rozhovor v desktopovej aplikácií {{app}}.",
"description": "Nič sa nestalo? Snažili sme sa otvoriť konferenciu v {{app}}. Skúste to znovu, alebo sa pripojte na konferenciu v {{app}} cez web.",
"descriptionWithoutWeb": "Nič sa nestalo? Snažili sme sa spustiť konferenciu v desktopovej aplikácií {{app}}.",
"downloadApp": "Stiahnutie aplikácie",
"ifDoNotHaveApp": "Ak nemáte aplikáciu:",
"ifHaveApp": "Ak máte aplikáciu:",
"joinInApp": "Vstúpiť do konferencie cez aplikáciu",
"launchWebButton": "Otvoriť na webe",
"openApp": "Pokračovať na aplikáciu",
"title": "Konferencia sa otvára v {{app}}...",
"tryAgainButton": "Skúsiť znova s natívnou aplikáciou"
},
"defaultLink": "napr. {{url}}",
"defaultNickname": "napr. Jane Pink",
"defaultNickname": "napr. Ján Kováč",
"deviceError": {
"cameraError": "Chyba pri prístupe ku kamere",
"cameraPermission": "Aplikácia nemá oprávnenie pristupovať ku kamere",
@@ -140,79 +157,84 @@
"deviceSelection": {
"noPermission": "Oprávnenie nie je poskytnuté",
"previewUnavailable": "Náhľad nie je dostupný",
"selectADevice": "Vyberte zvukové zariadenie",
"selectADevice": "Vybrať zariadenie",
"testAudio": "Vyskúšať zvuk"
},
"dialog": {
"accessibilityLabel": {
"liveStreaming": "Živé vysielanie"
},
"add": "Pridať",
"allow": "Povoliť",
"alreadySharedVideoMsg": "Iný účastník už poskytuje video. Pri tejto konferencií môže poskytovať súčasne iba jeden účastník.",
"alreadySharedVideoTitle": "Naraz sa dá poskytovať iba jedno video",
"alreadySharedVideoMsg": "Iný účastník už zdieľa video. Pri tejto konferencií môže zdieľať video iba jeden účastník.",
"alreadySharedVideoTitle": "Je možné zdieľať iba jedno video",
"applicationWindow": "Okno aplikácie",
"Back": "Späť",
"cameraConstraintFailedError": "Vaša kamera nespĺňa potrebné požiadavky.",
"cameraNotFoundError": "Kamera nebola nájdená.",
"cameraNotSendingData": "Kamera nie je dostupná. Skontrolujte či iná aplikácia používa kameru, vyberte inú kameru v nastaveniach ale znovu spustite aplikáciu.",
"cameraNotSendingData": "Kamera nie je dostupná. Skontrolujte či iná aplikácia používa kameru, vyberte inú kameru v nastaveniach alebo znovu spustite aplikáciu.",
"cameraNotSendingDataTitle": "Prístup na kameru nie je možný.",
"cameraPermissionDeniedError": "Nebolo udelené oprávnenie používať kameru. Napriek tomu sa môže zúčastniť na konferencií, ale ostatný účastníci vás nebudu vidieť. Pre pridelenie oprávnenia môžete použiť ikonu kamery na adresnej lište.",
"cameraPermissionDeniedError": "Nebolo udelené oprávnenie používať kameru. Napriek tomu sa môže zúčastniť na konferencií, ale ostatní účastníci vás nebudu vidieť. Pre pridelenie oprávnenia môžete použiť ikonu kamery na adresnej lište.",
"cameraUnknownError": "Z neznámeho dôvodu sa kamera nedá použiť.",
"cameraUnsupportedResolutionError": "Táto kamera nepodporuje požadované rozlíšenie.",
"cameraUnsupportedResolutionError": "Kamera nepodporuje požadované rozlíšenie.",
"Cancel": "Zrušiť",
"close": "Zatvoriť",
"conferenceDisconnectMsg": "Skontrolujte prípadne vaše sieťové pripojenie. Pripájam znovu o {{seconds}} sekúnd...",
"conferenceDisconnectTitle": "Vaše spojenie bolo prerušené.",
"conferenceReloadMsg": "Snažíme sa to napraviť. Pripájam znovu o {{seconds}} sekund...",
"conferenceReloadTitle": "Žiaľ niečo sa nepodarilo.",
"conferenceReloadTitle": "Spojenie sa prerušilo.",
"confirm": "Potvrdiť",
"confirmNo": "Nie",
"confirmYes": "Áno",
"connectError": "Oops! Niečo je zle a nemôžem sa pripojiť do konferencie.",
"connectErrorWithMsg": "Oops! Niečo je zle a nemôžem sa pripojiť do konferencie. Správa: {{msg}}",
"connectError": "Niečo je zle a nemôžem sa pripojiť do konferencie.",
"connectErrorWithMsg": "Niečo je zle a nemôžem sa pripojiť do konferencie. Správa: {{msg}}",
"connecting": "Pripájam",
"contactSupport": "Spojiť sa s podporou",
"copy": "Kopírovať",
"dismiss": "Zavrieť",
"displayNameRequired": "Ahoj! Ako sa voláš?",
"done": "Hotovo",
"e2eeDescription": "Koncové šifrovanie (End-to-End Encryption, E2EE) je momentálne EXPERIMENTÁLNE. Zapnutie koncového šifrovania znemožní použitie serverových služieb ako: nahrávanie, živé vysielanie a účasť cez telefón. Do konferencie je možné vstúpiť len s prehliadačom, ktorý podporuje vložiteľné prúdy (insertable streams).",
"e2eeLabel": "E2EE kľúč",
"e2eeNoKey": "žiadny",
"e2eeToggleSet": "Nastaviť kľúč",
"e2eeSet": "Nastaviť",
"e2eeWarning": "VAROVANIE: NIektorí účastníci nemajú podporu pre koncové šifrovanie. Ak ho zapnete, nebudú Vás vidieť ani počuť.",
"enterDisplayName": "Prosím zadajte sem vaše meno",
"error": "Chyba",
"externalInstallationMsg": "Zlyhanie pri inštalácií rozšírenia pre zdieľanie prac. plochy",
"externalInstallationTitle": "Potrebné rozšírenie:",
"goToStore": "",
"gracefulShutdown": "Naša služba je momentálne vypnutá pre údržbu. Skúste to neskor.",
"gracefulShutdown": "Služba je momentálne vypnutá pre údržbu. Skúste to neskor.",
"grantModeratorDialog": "Chcete naozaj tohoto účastníka urobiť moderatorom?",
"grantModeratorTitle": "Urobiť moderatorom",
"IamHost": "Ja som hostiteľ",
"incorrectRoomLockPassword": "Nesprávne heslo",
"incorrectPassword": "Používateľské meno alebo heslo je nesprávne",
"inlineInstallationMsg": "Musí byť nainštalované rozšírenie pre zdieľanie pracovnej prochy.",
"inlineInstallExtension": "Teraz inštalovať",
"internalError": "Ups! Niečo nefunguje. Vyskytla sa nasledujúca chyba: {{error}}",
"internalErrorTitle": "Interná chyba",
"kickMessage": "Pre podrobnosti sa môžete spojiť s {{participantDisplayName}}.",
"kickParticipantButton": "Odstrániť",
"kickParticipantDialog": "Skutočne chcete odstrániť tohto účastnika?",
"kickParticipantTitle": "Odstrániť účastníka?",
"kickTitle": "Ouch! {{participantDisplayName}} vás odstránil zo stretnutia.",
"kickTitle": "{{participantDisplayName}} vás odstránil z konferencie.",
"liveStreaming": "Živé vysielanie",
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Nie je možné keď je aktívne nahrávanie",
"liveStreamingDisabledForGuestTooltip": "Hostia nemôžu začať živé vysielanie.",
"liveStreamingDisabledTooltip": "Štartovanie živého vysielania je vypnuté.",
"liveStreamingDisabledTooltip": "Spustenie živého vysielania je zakázané.",
"lockMessage": "Zlyhanie pri pokuse o zabezpečenie konferencie.",
"lockRoom": "Pridať stretnutie $t(lockRoomPasswordUppercase)",
"lockRoom": "Pridať $t(lockRoomPassword)",
"lockTitle": "Zabezpečenie zlyhalo",
"logoutQuestion": "Ste si istý, že sa chcete odhlásiť a skončiť konferenciu?",
"logoutTitle": "Odhlásiť",
"maxUsersLimitReached": "Bol dosiahnutý maximálny počet účastníkov. Konferencia je plná. Spojte sa prosím s organizátorom stretnutia, alebo to skúste neskôr.",
"maxUsersLimitReached": "Bol dosiahnutý maximálny počet účastníkov. Konferencia je plná. Spojte sa prosím s organizátorom konferencie, alebo to skúste neskôr.",
"maxUsersLimitReachedTitle": "Dosiahnutý maximálny počet účastníkov",
"micConstraintFailedError": "Váš mikrofón nespĺňa potrebné požiadavky.",
"micNotFoundError": "Mikrofón nebol nájdený.",
"micNotSendingData": "Choďte do nastavení vašeho počítača, aby ste odblokovali stlmenie vášho mikrofónu a upravte jeho úroveň.",
"micNotSendingDataTitle": "Mikrofón je stlmený vašimi systémovými nastaveniami.",
"micPermissionDeniedError": "Nebolo udelené oprávnenie používať mikrofón. Napriek tomu sa môže zúčastniť na konferencií, ale ostatný účastníci vás nebudú počuť. Pre pridelenie oprávnenia môžete použiť ikonu kamery na adresnej lište.",
"micPermissionDeniedError": "Nebolo udelené oprávnenie používať mikrofón. Napriek tomu sa môže zúčastniť na konferencií, ale ostatní účastníci vás nebudú počuť. Pre pridelenie oprávnenia môžete použiť ikonu kamery na adresnej lište.",
"micUnknownError": "Mikrofón sa nedá použiť z neznámeho dôvodu.",
"muteEveryoneElseDialog": "Keď všetkým vypnete mikrofón, nedokážete spať zapnuť mikrofóny. Účastníci si ale môžu zapnúť mikrofóny sami.",
"muteEveryoneElseDialog": "Keď všetkým vypnete mikrofóny, nedokážete ich späť zapnúť. Účastníci si ale môžu zapnúť mikrofóny sami.",
"muteEveryoneElseTitle": "Vypnúť mikrofón všetkým okrem {{whom}}?",
"muteEveryoneDialog": "Chcete naozaj všetkým vypnúť mikrofón. Keď všetkým vypnete mikrofón, nedokážete spať zapnúť mikrofóny. Účastníci si ale môžu zapnúť mikrofóny sami.",
"muteEveryoneDialog": "Chcete naozaj všetkým vypnúť mikrofón. Keď všetkým vypnete mikrofóny, nedokážete ich späť zapnúť. Účastníci si ale môžu zapnúť mikrofóny sami.",
"muteEveryoneTitle": "Všetkým vypnúť mikrofón?",
"muteEveryoneSelf": "seba samého",
"muteEveryoneStartMuted": "Všetci odteraz začínajú s vypnutým mikrofónom",
@@ -222,33 +244,34 @@
"muteParticipantTitle": "Vypnúť účastníkovi mikrofón?",
"Ok": "Ok",
"passwordLabel": "$t(lockRoomPasswordUppercase)",
"passwordNotSupported": "Nastavovanie $t(lockRoomPassword) nie je podporované.",
"passwordNotSupported": "$t(lockRoomPasswordUppercase) nie je podporované.",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) nie je podporované",
"passwordRequired": "$t(lockRoomPasswordUppercase) je potrebné",
"popupError": "Váš prehliadať blokuje vyskakovacie okná tejto stránky. Prosím aktivujte vyskakovacie okná v bezpečnostných nastaveniach vašeho prehliadača a skúste znovu.",
"passwordRequired": "Prihlásenie",
"popupError": "Váš prehliadač blokuje vyskakovacie okná tejto stránky. Prosím aktivujte vyskakovacie okná v bezpečnostných nastaveniach vašeho prehliadača a skúste znovu.",
"popupErrorTitle": "Vyskakovacie okná sú zablokované",
"readMore": "viac",
"recording": "Nahrávanie",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Nie je možné keď je aktívny živý prenos",
"recordingDisabledForGuestTooltip": "Hostia nemôžu začať nahrávanie.",
"recordingDisabledTooltip": "Štartovanie nahrávania je vypnuté.",
"rejoinNow": "Teraz sa znovu pridať.",
"recordingDisabledTooltip": "Spustenie nahrávania je zakázané.",
"rejoinNow": "Pripojiť hneď",
"remoteControlAllowedMessage": "{{user}} prijal požiadavku o vzdialené ovládanie.",
"remoteControlDeniedMessage": "{{user}} odmietol prijal požiadavku o vzdialené ovládanie.",
"remoteControlDeniedMessage": "{{user}} odmietol požiadavku o vzdialené ovládanie.",
"remoteControlErrorMessage": "Stala sa chyba počas žiadania o vzdialené ovládanie od {{user}}",
"remoteControlRequestMessage": "Povolíte {{user}} ovládať vášu pracovnú plochu?",
"remoteControlShareScreenWarning": "Pozor, keď povolíte požiadavku budete zdielať vašu obrazovku!",
"remoteControlStopMessage": "Vzdialené ovládanie bolo ukončené.",
"remoteControlTitle": "Vzdialené ovládanie",
"Remove": "Odstrániť",
"removePassword": "$t(lockRoomPassword) odstránené",
"removeSharedVideoMsg": "Ste si istý že chcete odstrániť zdielané video?",
"removeSharedVideoTitle": "Odstrániť zdielané video",
"removePassword": "$t(lockRoomPasswordUppercase) odstránené",
"removeSharedVideoMsg": "Naozaj chcete odstrániť zdieľané video?",
"removeSharedVideoTitle": "Odstrániť zdieľané video",
"reservationError": "Systémová chyba rezervácie",
"reservationErrorMsg": "Chyba: {{code}}, správa: {{msg}}",
"retry": "Skúsiť znovu",
"screenSharingFailedToInstall": "Ups! Nepodarilo sa nainštalovať rozšírenie pre zdieľanie obrazovky.",
"screenSharingFailedToInstallTitle": "Chyba v inštalácii rozšírenie pre zdieľanie obrazovky",
"screenSharingFirefoxPermissionDeniedError": "Niečo sa nepodarilo pri pokuse o zdielanie obrazovky. Skontrolujte prosím či ste dali oprávnenie v prehliadači.",
"screenSharingFirefoxPermissionDeniedTitle": "Nepodarilo sa zdielať obrazovku",
"screenSharingAudio": "Zdieľať zvuk",
"screenSharingFailed": "Nie je možné spustiť zdieľanie obrazovky!",
"screenSharingFailedTitle": "Zdieľanie obrazovky zlyhalo!",
"screenSharingPermissionDeniedError": "Ups! Niečo sa nepodarilo pri žiadaní o oprávnenie zdielať obrazovku. Prosím aktualizovať a skúsiť znovu.",
"sendPrivateMessage": "Dostali ste súkromnú správu. Chceli ste na ňu odpovedať súkromne, alebo chcete poslať správu skupine?",
"sendPrivateMessageCancel": "Poslať skupine",
@@ -258,26 +281,26 @@
"sessTerminated": "Volanie ukončené",
"Share": "Zdieľať",
"shareVideoLinkError": "Prosím, zadajte správny Youtube odkaz.",
"shareVideoTitle": "Zdielať video",
"shareVideoTitle": "Zdieľať video",
"shareYourScreen": "Zdielať obrazovku",
"shareYourScreenDisabled": "Zdieľanie obrazovky vypnuté.",
"shareYourScreenDisabledForGuest": "Hostia nemôžu zdielať obrazovku.",
"startLiveStreaming": "Spustiť priamy prenos",
"startLiveStreaming": "Spustiť živý prenos",
"startRecording": "Začať záznam",
"startRemoteControlErrorMessage": "Chyba pri pokuse o začatie vzdialeného riadenia!",
"stopLiveStreaming": "Prerušiť priamy prenos",
"startRemoteControlErrorMessage": "Chyba pri pokuse o začatie vzdialeného ovládania!",
"stopLiveStreaming": "Zastaviť živý prenos",
"stopRecording": "Zastaviť záznam",
"stopRecordingWarning": "Chcete zastaviť záznam?",
"stopStreamingWarning": "Chcete prerušiť priamy prenos",
"streamKey": "Klúč živého vysielania",
"stopStreamingWarning": "Chcete zastaviť priamy prenos?",
"streamKey": "Kľúč živého vysielania",
"Submit": "OK",
"thankYou": "Ďakujeme vám za používanie {{appName}}!",
"thankYou": "Ďakujeme za používanie {{appName}}!",
"token": "token",
"tokenAuthFailed": "Prepáčte, nie ste oprávnený zúčastniť tejto sa konferencie.",
"tokenAuthFailedTitle": "Overenie zlyhalo",
"transcribing": "",
"unlockRoom": "Odstrániť stretnutie $t(lockRoomPassword)",
"userPassword": "užívateľské heslo",
"unlockRoom": "Odstrániť $t(lockRoomPassword)",
"userPassword": "heslo",
"WaitForHostMsg": "Konferencia <b>{{room}}</b> sa ešte nezačala. Autorizujte sa prosím ak ste hostiteľ. V opačnom prípade čakajte na hostiteľa.",
"WaitForHostMsgWOk": "Konferencia <b>{{room}}</b> sa ešte nezačala. Ak ste hostiteľ autorizujte sa stlačením Ok. V opačnom prípade čakajte na hostiteľa.",
"WaitingForHost": "Čakám na hostiteľa ...",
@@ -288,7 +311,10 @@
"statusMessage": "je teraz {{status}}"
},
"documentSharing": {
"title": "Zdielaný dokument"
"title": "Zdieľaný dokument"
},
"e2ee": {
"labelToolTip": "Zvuková a obrazová komunikácia je koncovo šifrovaná"
},
"feedback": {
"average": "Priemerný",
@@ -308,8 +334,8 @@
},
"info": {
"accessibilityLabel": "Zobraziť informácie",
"addPassword": "$t(lockRoomPassword) pridať",
"cancelPassword": "$t(lockRoomPassword) zmazať",
"addPassword": "Nastaviť $t(lockRoomPassword)",
"cancelPassword": "Zrušiť $t(lockRoomPassword)",
"conferenceURL": "Odkaz:",
"country": "Krajina",
"dialANumber": "Aby ste sa zúčastnili stretnutia, zavolajte jedno z týchto čísel a zadajte pin.",
@@ -322,9 +348,9 @@
"inviteLiveStream": "Kliknite túto linku {{url}}, pre zobrazenie živého vysielania z tohto stretnutia.",
"invitePhone": "Keď sa chcete pripojiť cez telefón, klikni na: {{number}},,{{conferenceID}}#\n",
"invitePhoneAlternatives": "Hľadáte iné pripojovacie číslo? Pripojovacie čísla pre konferenciu: {{{url}}\n\n\n\nTaktiež pokiaľ sa telefonicky pripájate cez konferenčný celomiestnostný telefón pripojte sa bez prenosu zvuku {{silentUrl}}",
"inviteURLFirstPartGeneral": "Ste pozývaný pripojiť sa na stretnutie.",
"inviteURLFirstPartPersonal": "{{name}} vás pozýva na stretnutie.",
"inviteURLSecondPart": "\n Zúčastniť sa stretnutia:\n{{url}}\n",
"inviteURLFirstPartGeneral": "Ste pozvaný do konferencie.",
"inviteURLFirstPartPersonal": "{{name}} vás pozýva do konferencie.\n",
"inviteURLSecondPart": "\nVstúpiť do konferencie:\n{{url}}\n",
"liveStreamURL": "Živý prenos:",
"moreNumbers": "Ďalšie telefónne čísla",
"noNumbers": "Žiadne pripojovacie telefónne čísla.",
@@ -368,6 +394,8 @@
"videoQuality": "Nastavenie kvality volania"
},
"liveStreaming": {
"limitNotificationDescriptionWeb": "Živé vysielanie je obmedzené na {{limit}} minút. Pre neobmedzené vysielanie skúste <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"limitNotificationDescriptionNative": "Živé vysielanie je obmedzené na {{limit}} minút. Pre neobmedzené vysielanie skúste {{app}}.",
"busy": "Chystajú sa zdroje pre vysielanie. Skúste znova za pár minút.",
"busyTitle": "Všetky vysielacie inštancie sú obsadené",
"changeSignIn": "Prepnúť konto",
@@ -375,19 +403,19 @@
"chooseCTA": "Vyberte vysielaciu možnosť. Ste prihlásený ako {{email}}",
"enterStreamKey": "Zadajte meno/heslo pre YouTube vysielanie.",
"error": "Živé vysielanie zlyhalo. Prosím skúste to znovu.",
"errorAPI": "Došlo chybe pri prístupe k vašemu YouTube vysielaniu. Prosím skúste sa znovu prihlásiť.",
"errorAPI": "Došlo k chybe pri prístupe k vašemu YouTube vysielaniu. Prosím skúste sa znovu prihlásiť.",
"errorLiveStreamNotEnabled": "Živé vysielanie pre {{email}} nie je aktivované. Aktivujte živé vysielanie, alebo sa prihláste pomocou konta s aktivovaným živým vysielaním.",
"expandedOff": "Živé vysielanie bolo zastavené",
"expandedOn": "Stretnutie je momentálne vysielané na YouTube.",
"expandedPending": "Spúšťa živé vysielanie...",
"failedToStart": "Nepodarilo sa naštartovať živé vysielanie",
"failedToStart": "Nepodarilo sa spustiť živé vysielanie",
"getStreamKeyManually": "Nepodarilo sa získať žiadne živé vysielania. Skúste získať kľúč pre živé vysielanie z YouTube.",
"invalidStreamKey": "Kľúč pre živé vysielanie je nesprávny.",
"off": "Živé vysielanie ukončené",
"offBy": "{{name}} ukončil živé vysielanie",
"on": "Živé vysielanie",
"onBy": "{{name}} začal živé vysielanie",
"pending": "Štartuje sa živé vysielanie...",
"pending": "Spúšťa sa živé vysielanie...",
"serviceName": "Služba pre živé vysielanie",
"signedInAs": "Ste prihlásený ako:",
"signIn": "Prihlásiť sa pomocou Google",
@@ -395,7 +423,9 @@
"signOut": "Odhlásiť",
"start": "Začať živé vysielanie",
"streamIdHelp": "Čo je to?",
"unavailableTitle": "Živé vysielanie nie je k dispozícií"
"unavailableTitle": "Živé vysielanie nie je k dispozícií",
"youtubeTerms": "Podmienky poskytovania služby YouTube",
"googlePrivacyPolicy": "Pravidlá ochrany súkromia Google"
},
"localRecording": {
"clientState": {
@@ -403,19 +433,19 @@
"on": "Zapnutý",
"unknown": "Neznámy"
},
"dialogTitle": "Lokálne ovládacie prvky nahrávania",
"dialogTitle": "Ovládacie prvky lokálneho nahrávania",
"duration": "Dĺžka",
"durationNA": "neznáma",
"encoding": "Kódovanie",
"label": "",
"labelToolTip": "Lokálny nahrávanie je aktivovaný",
"labelToolTip": "Lokálne nahrávanie je aktivovaný",
"localRecording": "Lokálne nahrávanie",
"me": "Ja",
"messages": {
"engaged": "Lokálne nahrávanie je spustené",
"finished": "Nahrávanie sedenia {{token}} je ukončené. Prosím pošlite nahratý súbor moderátorovi.",
"finishedModerator": "Nahrávanie sedenia {{token}} je ukončené. Bola uložená nahrávka lokálnej stopy. Poproste ostatných účastníkov, aby vám poslali ich nahrávky.",
"notModerator": "Nieste moderátor. Nemôže začať, alebo skončiť lokálne nahrávanie."
"notModerator": "Nie ste moderátor. Nemôže začať, alebo skončiť lokálne nahrávanie."
},
"moderator": "Moderátor",
"no": "Nie",
@@ -438,17 +468,17 @@
"focusFail": "{{component}} je nedostupný - skúste znova za {{ms}} sek",
"grantedTo": "Práva moderátora boli udelené {{to}}!",
"invitedOneMember": "{{displayName}} bol pozvaný",
"invitedThreePlusMembers": "{{name}} a {{count}} ďalší boli pozvaný",
"invitedTwoMembers": "{{first}} a {{second}} boli pozvaný",
"kickParticipant": "Pre ďalšie podrobnosti sa môže obrátiť na {{participantDisplayName}}",
"invitedThreePlusMembers": "{{name}} a {{count}} ďalší boli pozvaní",
"invitedTwoMembers": "{{first}} a {{second}} boli pozvaní",
"kickParticipant": "{{kicked}} bol odstránený účastníkom {{kicker}}",
"me": "Ja",
"moderator": "Boli vám udelené práva moderátora!",
"muted": "Začali ste rozhovor s vypnutým mikrofónom.",
"mutedTitle": "Boli ste stíšený!",
"mutedRemotelyTitle": "{{participantDisplayName}} vás stíšil",
"mutedRemotelyTitle": "{{participantDisplayName}} vám vypol mikrofón",
"mutedRemotelyDescription": "Kedykoľvek môžete stíšenie zrušiť, keď ste prichystaný rozprávať. Keď skončite môžete sa znova stíšiť, aby ste znížili hluk na stretnutí.",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) bolo odstránené iným účastníkom",
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) bolo nastavené iným účastníkom",
"passwordRemovedRemotely": "Iný účastník odstránil $t(lockRoomPassword)",
"passwordSetRemotely": "Iný účastník nastavil $t(lockRoomPassword)",
"raisedHand": "{{name}} chce hovoriť",
"somebody": "Niekto",
"startSilentTitle": "Pripojili ste sa bez zvukového výstupu!",
@@ -458,11 +488,49 @@
"unmute": "Zapnúť mikrofón",
"newDeviceCameraTitle": "Bola zistená nová kamera",
"newDeviceAudioTitle": "Bolo zistené nové audio zariadenie",
"newDeviceAction": "Použiť"
"newDeviceAction": "Použiť",
"OldElectronAPPTitle": "Bezpečnostná hrozba!",
"oldElectronClientDescription1": "Používate starú verziu klienta Jitsi Meet, ktorá má známe zraniteľnosti. Aktualizujte na ",
"oldElectronClientDescription2": "najnovšiu verziu",
"oldElectronClientDescription3": " teraz!"
},
"passwordSetRemotely": "nastavené iným účastníkom",
"passwordDigitsOnly": "až {{number}} číslic",
"poweredby": "založené na",
"prejoin": {
"audioAndVideoError": "Chyba zvuku a videa:",
"audioOnlyError": "Chyba zvuku:",
"audioTrackError": "Nemôžem vytvoriť zvukovú stopu.",
"callMe": "Zavolať mi",
"callMeAtNumber": "Zavolajte mi na toto číslo:",
"configuringDevices": "Konfigurácia zariedení...",
"connectedWithAudioQ": "Ste pripojení so zvukom?",
"copyAndShare": "Kopírovať a zdieľať odkaz",
"dialInMeeting": "Volanie dnu do konferencie",
"dialInPin": "Volajte dnu do konferencie a zadajte PIN kód:",
"dialing": "Vytáčanie",
"doNotShow": "Viac nezobrazovať",
"errorDialOut": "Nemôžem volať von",
"errorDialOutDisconnected": "Nemôžem volať von. Odpojené",
"errorDialOutFailed": "Nemôžem volať von. Volanie zlyhalo",
"errorDialOutStatus": "Chyba pri získavaní stavu volania",
"errorStatusCode": "Chyba volania von, kód: {{status}}",
"errorValidation": "Overenie čísla zlyhalo",
"iWantToDialIn": "Chcem volať dnu",
"joinAudioByPhone": "Vstúpiť so zvukom cez telefón",
"joinMeeting": "Vstúpiť do konferencie",
"joinWithoutAudio": "Vstúpiť bez zvuku",
"initiated": "Hovor začatý",
"linkCopied": "Odkaz skopírovaný do schránky",
"lookGood": "Váš mikrofón funguje správne",
"or": "alebo",
"calling": "Volanie",
"startWithPhone": "Začať so zvukom cez telefón",
"screenSharingError": "Chyba pri zdieľaní obrazovky:",
"videoOnlyError": "Chyba videa:",
"videoTrackError": "Nemôžem vytvoriť video stopu.",
"viewAllNumbers": "zobraziť všetky čísla"
},
"presenceStatus": {
"busy": "Obsadený",
"calling": "Je volaný",
@@ -485,6 +553,8 @@
},
"raisedHand": "Chcel by som hovoriť",
"recording": {
"limitNotificationDescriptionWeb": "Nahrávanie je obmedzené na {{limit}} minút. Pre neobmedzené nahrávanie skúste <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"limitNotificationDescriptionNative": "Nahrávanie je obmedzené na {{limit}} minút. Pre neobmedzené nahrávanie skúste <3>{{app}}</3>.",
"authDropboxText": "Nahrať na Dropbox",
"availableSpace": "Dostupná kapacita {{spaceLeft}} MB (ca. {{duration}} minút nahrávania)",
"beta": "BETA",
@@ -514,6 +584,12 @@
"sectionList": {
"pullToRefresh": "Potiahnuť pre aktualizáciu"
},
"security": {
"about": "Môžete nastaviť $t(lockRoomPassword) pre konferenciu. Účastníci budú musieť zadať $t(lockRoomPassword), aby mohli vstúpiť.",
"aboutReadOnly": "Moderátor može nastaviť $t(lockRoomPassword) pre konferenciu. Účastníci budú musieť zadať $t(lockRoomPassword), aby mohli vstúpiť.",
"insecureRoomNameWarning": "Názov konferencie nie je bezpečný. Môžu do nej vstúpiť neželaní účastníci. Zvážte zabezpečenie konferencie tlačidlom.",
"securityOptions": "Nastavenie zabezpečenia"
},
"settings": {
"calendar": {
"about": "Používa sa kalendárová integrácia {{appName}} pre zabezpečený prístup ku vašemu kalendáru.",
@@ -526,6 +602,7 @@
"followMe": "Všetci sledujú mňa",
"language": "Jazyk",
"loggedIn": "Prihlásený ako {{name}}",
"microphones": "Mikrofóny",
"moderator": "Moderátor",
"more": "Viac",
"name": "Meno",
@@ -533,6 +610,7 @@
"selectAudioOutput": "Zvukový výstup",
"selectCamera": "Kamera",
"selectMic": "Mikrofón",
"speakers": "Reproduktory",
"startAudioMuted": "Pri pripojení všetkým stlmiť zvuk",
"startVideoMuted": "Pri pripojení všetkým vypnúť video",
"title": "Nastavenia"
@@ -540,12 +618,15 @@
"settingsView": {
"advanced": "Rozšírené",
"alertOk": "OK",
"alertCancel": "Zrušiť",
"alertTitle": "Upozornenie",
"alertURLText": "Zadaná serverový URL je neplatná",
"alertURLText": "Zadaná serverová URL je neplatná",
"buildInfoSection": "informácie o kompilácií",
"conferenceSection": "Konferencia",
"disableCallIntegration": "Deaktivovať integráciu s natívnymi volaniami",
"disableP2P": "Deaktivovať mód s koncovými zariadeniami",
"disableCrashReporting": "Vypnúť oznamovanie pádov",
"disableCrashReportingWarning": "Naozak chcete vypnúť oznamovanie pádov? Nastavenie bude aktívne po reštartovaní aplikácie.",
"displayName": "Ukázať",
"email": "E-mail",
"header": "Nastavenia",
@@ -562,10 +643,10 @@
},
"speaker": "Rečník",
"speakerStats": {
"hours": "",
"minutes": "",
"hours": "{{count}}h",
"minutes": "{{count}}m",
"name": "Meno",
"seconds": "",
"seconds": "{{count}}s",
"speakerStats": "Štatistiky rečníka",
"speakerTime": "Čas rečníka"
},
@@ -576,7 +657,7 @@
"suspendedoverlay": {
"rejoinKeyTitle": "Znovu pripojiť",
"text": "Stlačte tlačidlo <i>Znovu pripojiť</i> na opätovné spojenie.",
"title": "Konferencia sa prerušila lebo váš počítač bol uspaní."
"title": "Konferencia sa prerušila lebo váš počítač bol uspaný."
},
"toolbar": {
"accessibilityLabel": {
@@ -587,14 +668,17 @@
"chat": "Zapnúť/vypnúť textovú diskusiu",
"document": "Zatvoriť zdielaný dokument",
"download": "Stiahnuť našu aplikáciu",
"e2ee": "Koncové šifrovanie",
"feedback": "Zanechať spätnú väzbu",
"fullScreen": "Zapnúť/vypnúť zobrazenie na celú obrazovku",
"grantModerator": "Urobiť moderátorom",
"hangup": "Ukončiť volanie",
"help": "Pomoc",
"invite": "Pozvať účastníka",
"kick": "Odstrániť účastníka",
"lobbyButton": "Zapnúť/vypnúť čakáreň",
"localRecording": "Zapnúť/vypnúť ovládanie lokálneho nahrávania",
"lockRoom": "Zapnúť/vypnúť heslo pre stretnutie",
"lockRoom": "Zapnúť/vypnúť heslo",
"moreActions": "Menu „Ďalšie akcie“ zapnúť/vypnúť",
"moreActionsMenu": "Menu „Ďalšie akcie“",
"moreOptions": "Zobraz viac možností",
@@ -606,6 +690,7 @@
"raiseHand": "„Ohlásiť sa“ zapnúť/vypnúť",
"recording": "Nahrávanie zapnúť/vypnúť",
"remoteMute": "Účastníka stlmiť",
"security": "Nastavenie zabezpečenia",
"Settings": "Nastavenia zapnúť/vypnúť",
"sharedvideo": "Zdieľanie YouTube videa zapnúť/vypnúť",
"shareRoom": "Pozvať osobu",
@@ -615,6 +700,7 @@
"speakerStats": "Štatistiky rečníka zobraziť/skryť",
"tileView": "Prepnúť dlaždicové zobrazenie",
"toggleCamera": "Zmeniť kameru",
"toggleFilmstrip": "Zapnúť/vypnúť video náhľady",
"videomute": "„Video odpojiť“ zapnúť/vypnúť",
"videoblur": "Rozmazanie pozadia zapnúť/vypnúť"
},
@@ -622,21 +708,24 @@
"audioOnlyOff": "Mód „Iba zvuk“ deaktivovať",
"audioOnlyOn": "Mód „Iba zvuk“ aktivovať",
"audioRoute": "Vybrať zvukové zariadenie",
"authenticate": "Overiť",
"authenticate": "Autentifikácia",
"callQuality": "Spravovať kvalitu videa",
"chat": "Otvoriť / Zatvoriť chat",
"closeChat": "Chat zatvoriť",
"documentClose": "Zdielaný dokument zatvoriť",
"documentOpen": "Zdielaný dokument otvoriť",
"documentClose": "Zatvoriť zdieľaný dokument",
"documentOpen": "Otvoriť zdieľaný dokument",
"download": "Stiahnuť našu aplikáciu",
"e2ee": "Koncové šifrovanie",
"enterFullScreen": "Zobraziť na celú obrazovku",
"enterTileView": "Kachličkové zobrazenie",
"enterTileView": "Dlaždicové zobrazenie",
"exitFullScreen": "Opustiť celú obrazovku",
"exitTileView": "Kachličkové zobrazenie vypnúť",
"exitTileView": "Zrušiť dlaždicové zobrazenie",
"feedback": "Nechať spätnú väzbu",
"hangup": "Odísť",
"help": "Pomoc",
"invite": "Pozvať účastníkov",
"invite": "Pozvať ľudí",
"lobbyButtonDisable": "Vypnúť čakáreň",
"lobbyButtonEnable": "Zapnúť čakáreň",
"login": "Prihlásiť",
"logout": "Odhlásiť",
"lowerYourHand": "Dať dole ruku",
@@ -645,10 +734,10 @@
"mute": "Vypnúť / Zapnúť mikrofón",
"muteEveryone": "Všetkých stlmiť",
"noAudioSignalTitle": "Neprichádza žiaden vstup z vašeho mikrofónu!",
"noAudioSignalDesc": "Pokiaľ ste zámerne nestlmili váš mikrofón v systémových nastavenia alebo hardvery, pouvažujte nad prepnutím zariadenia.",
"noAudioSignalDescSuggestion": "Pokiaľ ste zámerne nestlmili váš mikrofón v systémových nastavenia alebo hardvery, pouvažujte nad prepnutím na odporúčané zariadenie.",
"noAudioSignalDesc": "Pokiaľ ste zámerne nestlmili váš mikrofón v systémových nastaveniach alebo hardvéri, pouvažujte nad prepnutím zariadenia.",
"noAudioSignalDescSuggestion": "Pokiaľ ste zámerne nestlmili váš mikrofón v systémových nastaveniach alebo hardvéri, pouvažujte nad prepnutím na odporúčané zariadenie.",
"noAudioSignalDialInDesc": "Môže zavolať pomocou:",
"noAudioSignalDialInLinkDesc" : "Pripojovacie telefónne čísla",
"noAudioSignalDialInLinkDesc": "Pripojovacie telefónne čísla",
"noisyAudioInputTitle": "Váš mikrofón vyzerá byť zašumený!",
"noisyAudioInputDesc": "Vyzerá, že váš mikrofón je zašumený, skúste ho vypnuť, alebo zmeňte zariadenie.",
"openChat": "Otvoriť chat",
@@ -657,6 +746,7 @@
"profile": "Úprava profilu",
"raiseHand": "Prihlásiť / Odhlásiť sa o slovo",
"raiseYourHand": "Prihlásiť sa o slovo",
"security": "Nastavenie zabezpečenia",
"Settings": "Nastavenia",
"sharedvideo": "Zdielať YouTube video",
"shareRoom": "Pozvať niekoho",
@@ -684,7 +774,7 @@
"pending": "Pripravuje sa prepisovanie stretnutia...",
"start": "Začni zobrazovať titulky",
"stop": "Skonči zobrazovať titulky",
"tr": ""
"tr": "TR"
},
"userMedia": {
"androidGrantPermissions": "Vyberte <b><i>Povoliť</i></b> keď sa prehliadač bude pýtať na povolenie.",
@@ -699,14 +789,14 @@
"safariGrantPermissions": "Vyberte <b><i>OK</i></b> keď sa prehliadač bude pýtať na povolenie."
},
"videoSIPGW": {
"busy": "",
"busyTitle": "",
"errorAlreadyInvited": "",
"errorInvite": "",
"errorInviteFailed": "",
"errorInviteFailedTitle": "",
"errorInviteTitle": "",
"pending": ""
"busy": "Všetky zdroje sú obsadené, skúste znovu o pár minút.",
"busyTitle": "Služba je obsadená",
"errorAlreadyInvited": "{{displayName}} už bol pozvaný",
"errorInvite": "Konferencia sa ešte nezačala, skúste neskôr.",
"errorInviteFailed": "Skúste znovu neskôr.",
"errorInviteFailedTitle": "Pozývanie {{displayName}} zlyhalo",
"errorInviteTitle": "Chyba pozývania",
"pending": "{{displayName}} bol pozvaný"
},
"videoStatus": {
"audioOnly": "AUD",
@@ -728,8 +818,10 @@
},
"videothumbnail": {
"domute": "Vypnúť mikrofón",
"domuteOthers": "Vypnúť mikrofóny ostatným",
"flip": "Prevrátiť",
"kick": "Vyhodiť",
"grantModerator": "Urobiť moderátorom",
"kick": "Odstrániť",
"moderator": "Moderátor",
"mute": "Účastník s vypnutým mikrofónom",
"muted": "Vypnutý mikrofón",
@@ -751,20 +843,62 @@
"connectCalendarButton": "Pripojte váš kalendár",
"connectCalendarText": "",
"enterRoomTitle": "Začať nové stretnutie",
"roomNameAllowedChars": "Meno stretnutia by nemalo obsahovať žiaden z týchto znakov: ?, &, :, ', \", %, #.",
"getHelp": "Získať pomoc",
"go": "Začať",
"goSmall": "Začať",
"join": "Pripojiť",
"info": "Info",
"join": "Pripojiť",
"moderatedMessage": "Alebo si <a href=\"{{url}}\" rel=\"noopener noreferrer\" target=\"_blank\">rezervujte vopred URL</a> pre konferenciu, kde budete jediný moderátor.",
"privacy": "Súkromie",
"recentList": "Posledné",
"recentListDelete": "Vymazať",
"recentListEmpty": "Váš zoznam posledných hovorov je prázdny. Spojte sa s kolegami z Vášho tímu a potom tu nájdete všetky vaše stretnutia.",
"reducedUIText": "Vítajte v {{app}}!",
"reducedUIText": "Vitajte v {{app}}!",
"roomNameAllowedChars": "Názov miestnosti by nemal obsahovať žiaden z týchto znakov: ?, &, :, ', \", %, #.",
"roomname": "Zadajte názov miestnosti",
"roomnameHint": "Zadajte názov alebo URL odkaz miestnosti ku ktorej sa chcete pripojiť. Pokial ste miestnosť vytvorili, uistite sa, že ostatný účastníci schôdzky zadajú rovnaké meno ako vy.",
"roomnameHint": "Zadajte názov alebo URL odkaz miestnosti ku ktorej sa chcete pripojiť. Názov si môžete vymyslieť - dajte ho vedieť ostatným účastníkom konferencie, ktorí ho sem zadajú.",
"sendFeedback": "Odoslať spätnú väzbu",
"terms": "Podmienky používania",
"title": "Zabezpečené, plnohodnotné a úplne bezplatné videokonferencie"
},
"lonelyMeetingExperience": {
"button": "Pozvať ďalších",
"youAreAlone": "Ste sám v tejto konferencii"
},
"helpView": {
"header": "Centrum pomoci"
},
"lobby": {
"knockingParticipantList": "Zoznam čakajúcich účastníkov",
"allow": "Povoliť",
"backToKnockModeButton": "Žiadne heslo, požiadať o vstup",
"dialogTitle": "Čakáreň",
"disableDialogContent": "Čakáreň je zapnutá. Táto funkcia zabezpečuje, že do konferencie nemôžu vstúpiť neželaní účastníci. Chcete ju vypnúť?",
"disableDialogSubmit": "Vypnúť",
"emailField": "Zadajte vašu e-mailovú adresu",
"enableDialogPasswordField": "Nastaviť heslo (voliteľné)",
"enableDialogSubmit": "Zapnúť",
"enableDialogText": "Čakáreň umožňuje zabezpečiť konferenciu tým, že účastníci môžu do konferencie vstúpiť len po schválení moderátorom.",
"enterPasswordButton": "Zadať heslo do konferencie",
"enterPasswordTitle": "Zadajte heslo pre vstup do konferencie",
"invalidPassword": "Nesprávne heslo",
"joiningMessage": "Vstúpite do konferencie, keď niekto schváli vašu žiadosť",
"joinWithPasswordMessage": "Vstupujem s heslom...",
"joinRejectedMessage": "Vaša žiadosť bola zamietnutá moderátorom.",
"joinTitle": "Vstup do konferencie",
"joiningTitle": "Žiadam o vstup do konferencie...",
"joiningWithPasswordTitle": "Vstupujem s heslom...",
"knockButton": "Požiadať o vstup",
"knockTitle": "Niekto žiada o vstup do konferencie",
"nameField": "Zadajte vaše meno",
"notificationLobbyAccessDenied": "Žiadosť {{targetParticipantName}} o vstup bola zamietnutá účastníkom {{originParticipantName}}",
"notificationLobbyAccessGranted": "Žiadosť {{targetParticipantName}} o vstup bola povolená účastníkom {{originParticipantName}}",
"notificationLobbyDisabled": "Účastník {{originParticipantName}} vypol čakáreň",
"notificationLobbyEnabled": "Účastník {{originParticipantName}} zapol čakáreň",
"notificationTitle": "Čakáreň",
"passwordField": "Zadajte heslo do konferencie",
"passwordJoinButton": "Vstúpiť",
"reject": "Odmietnuť",
"toggleLabel": "Zapnúť čakáreň"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -579,7 +579,7 @@
},
"security": {
"about": "Toplantınıza bir şifre ekleyebilirsiniz. Katılımcıların toplantıya katılmasına izin verilmeden önce şifreyi girmeleri gerekecektir.",
"about": "Toplantınıza bir parola ekleyebilirsiniz. Katılımcıların toplantıya katılmasına izin verilmeden önce parolayı girmeleri gerekecektir.",
"insecureRoomNameWarning": "Toplantı odası güvenli değil. Konferansınıza istenmeyen katılımcılar katılabilir.",
"securityOptions": "Güvenlik Seçenekleri"
},
@@ -819,7 +819,7 @@
"join": "Katılmak için dokunun",
"roomname": "Oda adı girin"
},
"appDescription": "Durma ve tüm ekiple görüntülü sohbet et. Hatta tanıdığın herkesi davet et. {{app}} tüm gün, her gün ücretsiz olarak kullanabileceğiniz, hesap gerektirmeden kullanbilieceğiniz tamamen şifrelenmiş, % 100 özgür bir video konferans çözümüdür.",
"appDescription": "Durma ve tüm ekiple görüntülü sohbet et. Hatta tanıdığın herkesi davet et. {{app}} tüm gün, her gün ücretsiz olarak ve hesap gerektirmeden kullanabileceğiniz tamamen şifrelenmiş, % 100 özgür bir video konferans çözümüdür.",
"audioVideoSwitch": {
"audio": "Ses",
"video": "Görüntü"
@@ -865,27 +865,27 @@
"lobby": {
"allow": "İzin ver",
"backToKnockModeButton": "Şifre yok, bunun yerine katılmayı isteyin",
"backToKnockModeButton": "Parola yok, bunun yerine katılmayı isteyin",
"dialogTitle": "Lobi modu",
"disableDialogContent": "Lobi modu şu anda etkin. Bu özellik, istenmeyen katılımcıların toplantınıza katılamamasını sağlar. Devre dışı bırakmak istiyor musunuz?",
"disableDialogSubmit": "Devre Dışı",
"emailField": "E-posta adresinizi giriniz",
"enableDialogPasswordField": "Şifre belirleyin (isteğe bağlı)",
"enableDialogPasswordField": "Parola belirleyin (isteğe bağlı)",
"enableDialogSubmit": "Etkin",
"enableDialogText": "Lobi modu, toplantınızı yalnızca kişilerin bir moderatör tarafından resmi olarak onaylandıktan sonra girmelerine izin vererek korumanıza izin verir.",
"enterPasswordButton": "Toplantı şifresini girin",
"enterPasswordTitle": "Toplantıya katılmak için şifre girin",
"invalidPassword": "Geçersiz şifre",
"enterPasswordButton": "Toplantı parolasını girin",
"enterPasswordTitle": "Toplantıya katılmak için parola girin",
"invalidPassword": "Geçersiz parola",
"joiningMessage": "Birisi isteğinizi kabul eder etmez toplantıya katılacaksınız",
"joinWithPasswordMessage": "Şifre ile katılmaya çalışıyorsunuz lütfen bekleyin...",
"joinWithPasswordMessage": "Parola ile katılmaya çalışıyorsunuz lütfen bekleyin...",
"joinRejectedMessage": "Katılma isteğiniz bir moderatör tarafından reddedildi.",
"joinTitle": "Toplantıya katıl",
"joiningTitle": "Toplantıya katılma isteniyor...",
"joiningWithPasswordTitle": "Şifre ile katılıyor...",
"joiningWithPasswordTitle": "Parola ile katılıyor...",
"knockButton": "Katılmak için sor",
"knockTitle": "Birisi toplantıya katılmak istiyor",
"nameField": "Adınızı giriniz",
"passwordField": "Toplantı şifresini giriniz",
"passwordField": "Toplantı parolasını giriniz",
"passwordJoinButton": "Katıl",
"reject": "Reddet",
"toggleLabel": "Lobiyi etkinleştir"

View File

@@ -99,6 +99,7 @@
},
"connectionindicator": {
"address": "Address:",
"audio_ssrc": "Audio SSRC:",
"bandwidth": "Estimated bandwidth:",
"bitrate": "Bitrate:",
"bridgeCount": "Server count: ",
@@ -126,9 +127,12 @@
"remoteport": "Remote port:",
"remoteport_plural": "Remote ports:",
"resolution": "Resolution:",
"savelogs": "Save logs",
"participant_id": "Participant id:",
"status": "Connection:",
"transport": "Transport:",
"transport_plural": "Transports:"
"transport_plural": "Transports:",
"video_ssrc": "Video SSRC:"
},
"dateUtils": {
"earlier": "Earlier",
@@ -362,7 +366,7 @@
"password": "$t(lockRoomPasswordUppercase):",
"title": "Share",
"tooltip": "Share link and dial-in info for this meeting",
"label": "Meeting info"
"label": "Dial-in info"
},
"inviteDialog": {
"alertText": "Failed to invite some participants.",
@@ -532,7 +536,7 @@
"dialInMeeting": "Dial into the meeting",
"dialInPin": "Dial into the meeting and enter PIN code:",
"dialing": "Dialing",
"doNotShow": "Don't show this again",
"doNotShow": "Don't show this screen again",
"errorDialOut": "Could not dial out",
"errorDialOutDisconnected": "Could not dial out. Disconnected",
"errorDialOutFailed": "Could not dial out. Call failed",
@@ -872,12 +876,12 @@
"getHelp": "Get help",
"go": "GO",
"goSmall": "GO",
"info": "Info",
"info": "Dial-in info",
"join": "CREATE / JOIN",
"moderatedMessage": "Or <a href=\"{{url}}\" rel=\"noopener noreferrer\" target=\"_blank\">book a meeting URL</a> in advance where you are the only moderator.",
"privacy": "Privacy",
"recentList": "Recent",
"recentListDelete": "Delete",
"recentListDelete": "Delete entry",
"recentListEmpty": "Your recent list is currently empty. Chat with your team and you will find all your recent meetings here.",
"reducedUIText": "Welcome to {{app}}!",
"roomNameAllowedChars": "Meeting name should not contain any of these characters: ?, &, :, ', \", %, #.",

36
manifest.json Normal file
View File

@@ -0,0 +1,36 @@
{
"android_package_name": "org.jitsi.meet",
"prefer_related_applications": true,
"related_applications": [
{
"id": "org.jitsi.meet",
"platform": "chromeos_play"
}
],
"short_name": "Jitsi Meet",
"name": "Jitsi Meet",
"icons": [
{
"src": "static/pwa/icons/icon192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "static/pwa/icons/icon512.png",
"type": "image/png",
"sizes": "512x512"
},
{
"src": "static/pwa/icons/iconMask.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"start_url": "/",
"background_color": "#17A0DB",
"display": "standalone",
"scope": "/",
"theme_color": "#17A0DB"
}

View File

@@ -15,13 +15,18 @@ import {
} from '../../react/features/base/conference';
import { parseJWTFromURLParams } from '../../react/features/base/jwt';
import { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
import { pinParticipant } from '../../react/features/base/participants';
import {
processExternalDeviceRequest
} from '../../react/features/device-selection/functions';
import { isEnabled as isDropboxEnabled } from '../../react/features/dropbox';
import { toggleE2EE } from '../../react/features/e2ee/actions';
import { invite } from '../../react/features/invite';
import { selectParticipantInLargeVideo } from '../../react/features/large-video/actions';
import {
captureLargeVideoScreenshot,
resizeLargeVideo,
selectParticipantInLargeVideo
} from '../../react/features/large-video/actions';
import { toggleLobbyMode } from '../../react/features/lobby/actions.web';
import { RECORDING_TYPES } from '../../react/features/recording/constants';
import { getActiveSession } from '../../react/features/recording/functions';
@@ -116,9 +121,19 @@ function initCommands() {
));
}
},
'pin-participant': id => {
logger.debug('Pin participant command received');
sendAnalytics(createApiEvent('participant.pinned'));
APP.store.dispatch(pinParticipant(id));
},
'proxy-connection-event': event => {
APP.conference.onProxyConnectionEvent(event);
},
'resize-large-video': (width, height) => {
logger.debug('Resize large video command received');
sendAnalytics(createApiEvent('largevideo.resized'));
APP.store.dispatch(resizeLargeVideo(width, height));
},
'send-tones': (options = {}) => {
const { duration, tones, pause } = options;
@@ -208,7 +223,8 @@ function initCommands() {
},
/**
* Starts a file recording or streaming depending on the passed on params.
* Starts a file recording or streaming session depending on the passed on params.
* For RTMP streams, `rtmpStreamKey` must be passed on. `rtmpBroadcastID` is optional.
* For youtube streams, `youtubeStreamKey` must be passed on. `youtubeBroadcastID` is optional.
* For dropbox recording, recording `mode` should be `file` and a dropbox oauth2 token must be provided.
* For file recording, recording `mode` should be `file` and optionally `shouldShare` could be passed on.
@@ -216,13 +232,23 @@ function initCommands() {
*
* @param { string } arg.mode - Recording mode, either `file` or `stream`.
* @param { string } arg.dropboxToken - Dropbox oauth2 token.
* @param { string } arg.rtmpStreamKey - The RTMP stream key.
* @param { string } arg.rtmpBroadcastID - The RTMP braodcast ID.
* @param { boolean } arg.shouldShare - Whether the recording should be shared with the participants or not.
* Only applies to certain jitsi meet deploys.
* @param { string } arg.youtubeStreamKey - The youtube stream key.
* @param { string } arg.youtubeBroadcastID - The youtube broacast ID.
* @returns {void}
*/
'start-recording': ({ mode, dropboxToken, shouldShare, youtubeStreamKey, youtubeBroadcastID }) => {
'start-recording': ({
mode,
dropboxToken,
shouldShare,
rtmpStreamKey,
rtmpBroadcastID,
youtubeStreamKey,
youtubeBroadcastID
}) => {
const state = APP.store.getState();
const conference = getCurrentConference(state);
@@ -238,8 +264,8 @@ function initCommands() {
return;
}
if (mode === JitsiRecordingConstants.mode.STREAM && !youtubeStreamKey) {
logger.error('Failed starting recording: missing youtube stream key');
if (mode === JitsiRecordingConstants.mode.STREAM && !(youtubeStreamKey || rtmpStreamKey)) {
logger.error('Failed starting recording: missing youtube or RTMP stream key');
return;
}
@@ -271,9 +297,9 @@ function initCommands() {
}
} else if (mode === JitsiRecordingConstants.mode.STREAM) {
recordingConfig = {
broadcastId: youtubeBroadcastID,
broadcastId: youtubeBroadcastID || rtmpBroadcastID,
mode: JitsiRecordingConstants.mode.STREAM,
streamId: youtubeStreamKey
streamId: youtubeStreamKey || rtmpStreamKey
};
} else {
logger.error('Invalid recording mode provided');
@@ -334,6 +360,21 @@ function initCommands() {
const { name } = request;
switch (name) {
case 'capture-largevideo-screenshot' :
APP.store.dispatch(captureLargeVideoScreenshot())
.then(dataURL => {
let error;
if (!dataURL) {
error = new Error('No large video found!');
}
callback({
error,
dataURL
});
});
break;
case 'invite': {
const { invitees } = request;
@@ -996,6 +1037,19 @@ class API {
});
}
/**
* Notify external application (if API is enabled) that the localStorage has changed.
*
* @param {string} localStorageContent - The new localStorageContent.
* @returns {void}
*/
notifyLocalStorageChanged(localStorageContent: string) {
this._sendEvent({
name: 'local-storage-changed',
localStorageContent
});
}
/**
* Disposes the allocated resources.
*

View File

@@ -1,3 +1,4 @@
import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';
import EventEmitter from 'events';
import { urlObjectToString } from '../../../react/features/base/util/uri';
@@ -35,6 +36,8 @@ const commands = {
hangup: 'video-hangup',
muteEveryone: 'mute-everyone',
password: 'password',
pinParticipant: 'pin-participant',
resizeLargeVideo: 'resize-large-video',
sendEndpointTextMessage: 'send-endpoint-text-message',
sendTones: 'send-tones',
setLargeVideoParticipant: 'set-large-video-participant',
@@ -266,6 +269,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
userInfo,
e2eeKey
} = parseArguments(args);
const localStorageContent = jitsiLocalStorage.getItem('jitsiLocalStorage');
this._parentNode = parentNode;
this._url = generateURL(domain, {
@@ -275,7 +279,10 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
noSSL,
roomName,
devices,
userInfo
userInfo,
appData: {
localStorageContent
}
});
this._createIFrame(height, width, onload);
this._transport = new Transport({
@@ -437,10 +444,12 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
const parsedWidth = parseSizeParam(width);
if (parsedHeight !== undefined) {
this._height = height;
this._frame.style.height = parsedHeight;
}
if (parsedWidth !== undefined) {
this._width = width;
this._frame.style.width = parsedWidth;
}
}
@@ -522,6 +531,11 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
case 'video-quality-changed':
this._videoQuality = data.videoQuality;
break;
case 'local-storage-changed':
jitsiLocalStorage.setItem('jitsiLocalStorage', data.localStorageContent);
// Since this is internal event we don't need to emit it to the consumer of the API.
return true;
}
const eventName = events[name];
@@ -633,6 +647,18 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
}
}
/**
* Captures the screenshot of the large video.
*
* @returns {Promise<string>} - Resolves with a base64 encoded image data of the screenshot
* if large video is detected, an error otherwise.
*/
captureLargeVideoScreenshot() {
return this._transport.sendRequest({
name: 'capture-largevideo-screenshot'
});
}
/**
* Removes the listeners and removes the Jitsi Meet frame.
*
@@ -904,6 +930,17 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
});
}
/**
* Pins a participant's video on to the stage view.
*
* @param {string} participantId - Participant id (JID) of the participant
* that needs to be pinned on the stage view.
* @returns {void}
*/
pinParticipant(participantId) {
this.executeCommand('pinParticipant', participantId);
}
/**
* Removes event listener.
*
@@ -930,6 +967,19 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
eventList.forEach(event => this.removeEventListener(event));
}
/**
* Resizes the large video container as per the dimensions provided.
*
* @param {number} width - Width that needs to be applied on the large video container.
* @param {number} height - Height that needs to be applied on the large video container.
* @returns {void}
*/
resizeLargeVideo(width, height) {
if (width <= this._width && height <= this._height) {
this.executeCommand('resizeLargeVideo', width, height);
}
}
/**
* Passes an event along to the local conference participant to establish
* or update a direct peer connection. This is currently used for developing
@@ -997,6 +1047,39 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
return setVideoInputDevice(this._transport, label, deviceId);
}
/**
* Starts a file recording or streaming session depending on the passed on params.
* For RTMP streams, `rtmpStreamKey` must be passed on. `rtmpBroadcastID` is optional.
* For youtube streams, `youtubeStreamKey` must be passed on. `youtubeBroadcastID` is optional.
* For dropbox recording, recording `mode` should be `file` and a dropbox oauth2 token must be provided.
* For file recording, recording `mode` should be `file` and optionally `shouldShare` could be passed on.
* No other params should be passed.
*
* @param {Object} options - An object with config options to pass along.
* @param { string } options.mode - Recording mode, either `file` or `stream`.
* @param { string } options.dropboxToken - Dropbox oauth2 token.
* @param { boolean } options.shouldShare - Whether the recording should be shared with the participants or not.
* Only applies to certain jitsi meet deploys.
* @param { string } options.rtmpStreamKey - The RTMP stream key.
* @param { string } options.rtmpBroadcastID - The RTMP broacast ID.
* @param { string } options.youtubeStreamKey - The youtube stream key.
* @param { string } options.youtubeBroadcastID - The youtube broacast ID.
* @returns {void}
*/
startRecording(options) {
this.executeCommand('startRecording', options);
}
/**
* Stops a recording or streaming session that is in progress.
*
* @param {string} mode - `file` or `stream`.
* @returns {void}
*/
stopRecording(mode) {
this.executeCommand('startRecording', mode);
}
/**
* Returns the configuration for electron for the windows that are open
* from Jitsi Meet.

View File

@@ -356,8 +356,8 @@ UI.askForNickname = function() {
/**
* Sets muted audio state for participant
*/
UI.setAudioMuted = function(id, muted) {
VideoLayout.onAudioMute(id, muted);
UI.setAudioMuted = function(id) {
// FIXME: Maybe this can be removed!
if (APP.conference.isLocalId(id)) {
APP.conference.updateAudioIconEnabled();
}
@@ -366,8 +366,8 @@ UI.setAudioMuted = function(id, muted) {
/**
* Sets muted video state for participant
*/
UI.setVideoMuted = function(id, muted) {
VideoLayout.onVideoMute(id, muted);
UI.setVideoMuted = function(id) {
VideoLayout.onVideoMute(id);
if (APP.conference.isLocalId(id)) {
APP.conference.updateVideoIconEnabled();
}

View File

@@ -26,7 +26,6 @@ export default class SharedVideoThumb extends SmallVideo {
this.$container = $(this.container);
this._setThumbnailSize();
this.bindHoverHandler();
this.isVideoMuted = true;
this.updateDisplayName();
this.container.onclick = this._onContainerClick;
}

View File

@@ -5,13 +5,6 @@
*/
const UIUtil = {
/**
* Returns the available video width.
*/
getAvailableVideoWidth() {
return window.innerWidth;
},
/**
* Escapes the given text.
*/

View File

@@ -15,13 +15,12 @@ import { VIDEO_TYPE } from '../../../react/features/base/media';
import { CHAT_SIZE } from '../../../react/features/chat';
import {
updateKnownLargeVideoResolution
} from '../../../react/features/large-video';
} from '../../../react/features/large-video/actions';
import { PresenceLabel } from '../../../react/features/presence-status';
/* eslint-enable no-unused-vars */
import UIEvents from '../../../service/UI/UIEvents';
import { createDeferred } from '../../util/helpers';
import AudioLevels from '../audio_levels/AudioLevels';
import UIUtil from '../util/UIUtil';
import { VideoContainer, VIDEO_CONTAINER_TYPE } from './VideoContainer';
@@ -68,7 +67,30 @@ export default class LargeVideoManager {
// use the same video container to handle desktop tracks
this.addContainer(DESKTOP_CONTAINER_TYPE, this.videoContainer);
/**
* The preferred width passed as an argument to {@link updateContainerSize}.
*
* @type {number|undefined}
*/
this.preferredWidth = undefined;
/**
* The preferred height passed as an argument to {@link updateContainerSize}.
*
* @type {number|undefined}
*/
this.preferredHeight = undefined;
/**
* The calculated width that will be used for the large video.
* @type {number}
*/
this.width = 0;
/**
* The calculated height that will be used for the large video.
* @type {number}
*/
this.height = 0;
/**
@@ -323,8 +345,15 @@ export default class LargeVideoManager {
/**
* Update container size.
*/
updateContainerSize() {
let widthToUse = UIUtil.getAvailableVideoWidth();
updateContainerSize(width, height) {
if (typeof width === 'number') {
this.preferredWidth = width;
}
if (typeof height === 'number') {
this.preferredHeight = height;
}
let widthToUse = this.preferredWidth || window.innerWidth;
const { isOpen } = APP.store.getState()['features/chat'];
if (isOpen) {
@@ -336,7 +365,7 @@ export default class LargeVideoManager {
}
this.width = widthToUse;
this.height = window.innerHeight;
this.height = this.preferredHeight || window.innerHeight;
}
/**

View File

@@ -63,6 +63,7 @@ export default class LocalVideo extends SmallVideo {
this.addAudioLevelIndicator();
this.updateIndicators();
this.updateStatusBar();
this.container.onclick = this._onContainerClick;
}

View File

@@ -12,10 +12,13 @@ import { i18next } from '../../../react/features/base/i18n';
import {
JitsiParticipantConnectionStatus
} from '../../../react/features/base/lib-jitsi-meet';
import { MEDIA_TYPE } from '../../../react/features/base/media';
import {
getParticipantById,
getPinnedParticipant,
pinParticipant
} from '../../../react/features/base/participants';
import { isRemoteTrackMuted } from '../../../react/features/base/tracks';
import { PresenceLabel } from '../../../react/features/presence-status';
import {
REMOTE_CONTROL_MENU_STATES,
@@ -86,7 +89,6 @@ export default class RemoteVideo extends SmallVideo {
this.bindHoverHandler();
this.flipX = false;
this.isLocal = false;
this.popupMenuIsHovered = false;
this._isRemoteControlSessionActive = false;
/**
@@ -137,17 +139,6 @@ export default class RemoteVideo extends SmallVideo {
return this.container;
}
/**
* Checks whether current video is considered hovered. Currently it is hovered
* if the mouse is over the video, or if the connection indicator or the popup
* menu is shown(hovered).
* @private
* NOTE: extends SmallVideo's method
*/
_isHovered() {
return super._isHovered() || this.popupMenuIsHovered;
}
/**
* Generates the popup menu content.
*
@@ -207,7 +198,6 @@ export default class RemoteVideo extends SmallVideo {
<AtlasKitThemeProvider mode = 'dark'>
<RemoteVideoMenuTriggerButton
initialVolumeValue = { initialVolumeValue }
isAudioMuted = { this.isAudioMuted }
menuPosition = { remoteMenuPosition }
onMenuDisplay
= {this._onRemoteVideoMenuDisplay.bind(this)}
@@ -311,22 +301,16 @@ export default class RemoteVideo extends SmallVideo {
/**
* Updates the remote video menu.
*
* @param isMuted the new muted state to update to
*/
updateRemoteVideoMenu(isMuted) {
if (typeof isMuted !== 'undefined') {
this.isAudioMuted = isMuted;
}
updateRemoteVideoMenu() {
this._generatePopupContent();
}
/**
* @inheritDoc
* @override
* Video muted status changed handler.
*/
setVideoMutedView(isMuted) {
super.setVideoMutedView(isMuted);
onVideoMute() {
super.updateView();
// Update 'mutedWhileDisconnected' flag
this._figureOutMutedWhileDisconnected();
@@ -340,10 +324,12 @@ export default class RemoteVideo extends SmallVideo {
*/
_figureOutMutedWhileDisconnected() {
const isActive = this.isConnectionActive();
const isVideoMuted
= isRemoteTrackMuted(APP.store.getState()['features/base/tracks'], MEDIA_TYPE.VIDEO, this.id);
if (!isActive && this.isVideoMuted) {
if (!isActive && isVideoMuted) {
this.mutedWhileDisconnected = true;
} else if (isActive && !this.isVideoMuted) {
} else if (isActive && !isVideoMuted) {
this.mutedWhileDisconnected = false;
}
}
@@ -373,7 +359,6 @@ export default class RemoteVideo extends SmallVideo {
if (stream === this.videoStream) {
this.videoStream = null;
this.videoType = undefined;
}
this.updateView();
@@ -484,7 +469,6 @@ export default class RemoteVideo extends SmallVideo {
if (isVideo) {
this.videoStream = stream;
this.videoType = stream.videoType;
} else {
this.audioStream = stream;
}

View File

@@ -11,11 +11,15 @@ import { Provider } from 'react-redux';
import { AudioLevelIndicator } from '../../../react/features/audio-level-indicator';
import { Avatar as AvatarDisplay } from '../../../react/features/base/avatar';
import { i18next } from '../../../react/features/base/i18n';
import { MEDIA_TYPE } from '../../../react/features/base/media';
import {
getLocalParticipant,
getParticipantById,
getParticipantCount,
getPinnedParticipant,
pinParticipant
} from '../../../react/features/base/participants';
import { isLocalTrackMuted, isRemoteTrackMuted } from '../../../react/features/base/tracks';
import { ConnectionIndicator } from '../../../react/features/connection-indicator';
import { DisplayName } from '../../../react/features/display-name';
import {
@@ -81,8 +85,6 @@ export default class SmallVideo {
* Constructor.
*/
constructor(VideoLayout) {
this.isAudioMuted = false;
this.isVideoMuted = false;
this.isScreenSharing = false;
this.videoStream = null;
this.audioStream = null;
@@ -100,15 +102,6 @@ export default class SmallVideo {
*/
this._connectionStatus = null;
/**
* Whether or not the ConnectionIndicator's popover is hovered. Modifies
* how the video overlays display based on hover state.
*
* @private
* @type {boolean}
*/
this._popoverIsHovered = false;
/**
* Whether or not the connection indicator should be displayed.
*
@@ -134,7 +127,6 @@ export default class SmallVideo {
this._showRaisedHand = false;
// Bind event handlers so they are only bound once for every instance.
this._onPopoverHover = this._onPopoverHover.bind(this);
this.updateView = this.updateView.bind(this);
this._onContainerClick = this._onContainerClick.bind(this);
@@ -225,17 +217,6 @@ export default class SmallVideo {
this.updateIndicators();
}
/**
* Shows / hides the audio muted indicator over small videos.
*
* @param {boolean} isMuted indicates if the muted element should be shown
* or hidden
*/
showAudioIndicator(isMuted) {
this.isAudioMuted = isMuted;
this.updateStatusBar();
}
/**
* Shows / hides the screen-share indicator over small videos.
*
@@ -243,20 +224,11 @@ export default class SmallVideo {
* or hidden
*/
setScreenSharing(isScreenSharing) {
this.isScreenSharing = isScreenSharing;
this.updateView();
this.updateStatusBar();
}
if (isScreenSharing === this.isScreenSharing) {
return;
}
/**
* Shows video muted indicator over small videos and disables/enables avatar
* if video muted.
*
* @param {boolean} isMuted indicates if we should set the view to muted view
* or not
*/
setVideoMutedView(isMuted) {
this.isVideoMuted = isMuted;
this.isScreenSharing = isScreenSharing;
this.updateView();
this.updateStatusBar();
}
@@ -278,9 +250,7 @@ export default class SmallVideo {
<Provider store = { APP.store }>
<I18nextProvider i18n = { i18next }>
<StatusIndicators
showAudioMutedIndicator = { this.isAudioMuted }
showScreenShareIndicator = { this.isScreenSharing }
showVideoMutedIndicator = { this.isVideoMuted }
participantID = { this.id } />
</I18nextProvider>
</Provider>,
@@ -455,7 +425,18 @@ export default class SmallVideo {
* or <tt>false</tt> otherwise.
*/
isVideoPlayable() {
return this.videoStream && !this.isVideoMuted && !APP.conference.isAudioOnly();
const state = APP.store.getState();
const tracks = state['features/base/tracks'];
const participant = this.id ? getParticipantById(state, this.id) : getLocalParticipant(state);
let isVideoMuted = true;
if (participant?.local) {
isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);
} else if (!participant?.isFakeParticipant) { // remote participants excluding shared video
isVideoMuted = isRemoteTrackMuted(tracks, MEDIA_TYPE.VIDEO, this.id);
}
return this.videoStream && !isVideoMuted && !APP.conference.isAudioOnly();
}
/**
@@ -496,7 +477,6 @@ export default class SmallVideo {
mutedWhileDisconnected: this.mutedWhileDisconnected,
canPlayEventReceived: this._canPlayEventReceived,
videoStream: Boolean(this.videoStream),
isVideoMuted: this.isVideoMuted,
isScreenSharing: this.isScreenSharing,
videoStreamMuted: this.videoStream ? this.videoStream.isMuted() : 'no stream'
};
@@ -509,7 +489,7 @@ export default class SmallVideo {
* @private
*/
_isHovered() {
return this.videoIsHovered || this._popoverIsHovered;
return this.videoIsHovered;
}
/**
@@ -832,19 +812,6 @@ export default class SmallVideo {
}
}
/**
* Updates the current state of the connection indicator popover being hovered.
* If hovered, display the small video as if it is hovered.
*
* @param {boolean} popoverIsHovered - Whether or not the mouse cursor is
* currently over the connection indicator popover.
* @returns {void}
*/
_onPopoverHover(popoverIsHovered) {
this._popoverIsHovered = popoverIsHovered;
this.updateView();
}
/**
* Sets the size of the thumbnail.
*/

View File

@@ -52,7 +52,7 @@ function onLocalFlipXChanged(val) {
*/
function getAllThumbnails() {
return [
localVideoThumbnail,
...localVideoThumbnail ? [ localVideoThumbnail ] : [],
...Object.values(remoteVideos)
];
}
@@ -173,10 +173,8 @@ const VideoLayout = {
remoteVideo.addRemoteStreamElement(stream);
// Make sure track's muted state is reflected
if (stream.getType() === 'audio') {
this.onAudioMute(id, stream.isMuted());
} else {
this.onVideoMute(id, stream.isMuted());
if (stream.getType() !== 'audio') {
this.onVideoMute(id);
remoteVideo.setScreenSharing(stream.videoType === 'desktop');
}
},
@@ -210,7 +208,7 @@ const VideoLayout = {
if (mediaType === 'audio') {
APP.UI.setAudioMuted(participantId, true);
} else if (mediaType === 'video') {
APP.UI.setVideoMuted(participantId, true);
APP.UI.setVideoMuted(participantId);
} else {
logger.error(`Unsupported media type: ${mediaType}`);
}
@@ -329,35 +327,17 @@ const VideoLayout = {
this._updateLargeVideoIfDisplayed(resourceJid, true);
},
/**
* On audio muted event.
*/
onAudioMute(id, isMuted) {
if (APP.conference.isLocalId(id)) {
localVideoThumbnail.showAudioIndicator(isMuted);
} else {
const remoteVideo = remoteVideos[id];
if (!remoteVideo) {
return;
}
remoteVideo.showAudioIndicator(isMuted);
remoteVideo.updateRemoteVideoMenu();
}
},
/**
* On video muted event.
*/
onVideoMute(id, value) {
onVideoMute(id) {
if (APP.conference.isLocalId(id)) {
localVideoThumbnail && localVideoThumbnail.setVideoMutedView(value);
localVideoThumbnail && localVideoThumbnail.updateView();
} else {
const remoteVideo = remoteVideos[id];
if (remoteVideo) {
remoteVideo.setVideoMutedView(value);
remoteVideo.onVideoMute();
}
}
@@ -489,7 +469,7 @@ const VideoLayout = {
onVideoTypeChanged(id, newVideoType) {
const remoteVideo = remoteVideos[id];
if (!remoteVideo || remoteVideo.videoType === newVideoType) {
if (!remoteVideo) {
return;
}

View File

@@ -209,7 +209,7 @@ export default {
})
.catch(err => {
audioTrackError = err;
showError && APP.store.disptach(notifyMicError(err));
showError && APP.store.dispatch(notifyMicError(err));
return [];
}));

2182
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@
"@atlaskit/theme": "7.0.2",
"@atlaskit/toggle": "5.0.14",
"@atlaskit/tooltip": "12.1.13",
"@jitsi/js-utils": "1.0.1",
"@jitsi/js-utils": "1.0.2",
"@microsoft/microsoft-graph-client": "1.1.0",
"@react-native-community/async-storage": "1.3.4",
"@react-native-community/google-signin": "3.0.1",
@@ -40,11 +40,11 @@
"@svgr/webpack": "4.3.2",
"@tensorflow-models/body-pix": "2.0.4",
"@tensorflow/tfjs": "1.5.1",
"@webcomponents/url": "0.7.1",
"amplitude-js": "7.1.1",
"base64-js": "1.3.1",
"bc-css-flags": "3.0.0",
"dropbox": "4.0.9",
"focus-visible": "5.1.0",
"i18n-iso-countries": "3.7.8",
"i18next": "17.0.6",
"i18next-browser-languagedetector": "3.0.1",
@@ -56,21 +56,22 @@
"jquery-i18next": "1.2.1",
"js-md5": "0.6.1",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#43e7c853b834dc7ced0f81ee5f4b130444d85e95",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#3bfdb98e3b4db12ba28d88aa8710afc4d1b458b2",
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
"lodash": "4.17.19",
"moment": "2.19.4",
"moment-duration-format": "2.2.2",
"olm": "https://packages.matrix.org/npm/olm/olm-3.1.4.tgz",
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
"pixelmatch": "5.1.0",
"punycode": "2.1.1",
"react": "16.9",
"react-dom": "16.9",
"react-emoji-render": "1.2.4",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "github:jitsi/react-native#efd2aff5661d75a230e36406b698cfe0ee545be2",
"react-native": "github:jitsi/react-native#891986ec5ecaef65d1c8a7fe472f86cf84fe7551",
"react-native-background-timer": "2.4.0",
"react-native-calendar-events": "github:jitsi/react-native-calendar-events#928a80e2ffef0d7e84936d7e7e0acc4f53ee8470",
"react-native-calendar-events": "github:jitsi/react-native-calendar-events#df48ecdc4e1e90c5352f803ddbab1fa7269b74a7",
"react-native-callstats": "3.61.0",
"react-native-collapsible": "1.5.1",
"react-native-default-preference": "1.4.2",
@@ -78,12 +79,13 @@
"react-native-keep-awake": "4.0.0",
"react-native-linear-gradient": "2.5.6",
"react-native-sound": "github:jitsi/react-native-sound#3fe5480fce935e888d5089d94a191c7c7e3aa190",
"react-native-svg": "9.7.1",
"react-native-svg-transformer": "0.13.0",
"react-native-swipeout": "2.3.6",
"react-native-splash-screen": "3.2.0",
"react-native-svg": "10.1.0",
"react-native-svg-transformer": "0.14.3",
"react-native-url-polyfill": "1.2.0",
"react-native-watch-connectivity": "0.4.3",
"react-native-webrtc": "1.84.0",
"react-native-webview": "7.4.1",
"react-native-webview": "10.9.0",
"react-native-youtube-iframe": "1.2.3",
"react-redux": "7.1.0",
"react-textarea-autosize": "7.1.0",
@@ -92,6 +94,7 @@
"redux-thunk": "2.2.0",
"rnnoise-wasm": "github:jitsi/rnnoise-wasm.git#566a16885897704d6e6d67a1d5ac5d39781db2af",
"rtcstats": "github:jitsi/rtcstats#v6.2.0",
"stackblur-canvas": "2.3.0",
"styled-components": "3.4.9",
"util": "0.12.1",
"uuid": "3.1.0",
@@ -128,7 +131,7 @@
"imports-loader": "0.7.1",
"jetifier": "1.6.4",
"metro-react-native-babel-preset": "0.56.0",
"node-sass": "4.14.1",
"sass": "1.26.8",
"string-replace-loader": "2.1.1",
"style-loader": "0.19.0",
"unorm": "1.6.0",

88
pwa-worker.js Normal file
View File

@@ -0,0 +1,88 @@
/*
Copyright 2015, 2019, 2020 Google LLC. All Rights Reserved.
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.
*/
const CACHE_NAME = 'offline';
// Customize this with a different URL if needed.
const OFFLINE_URL = 'static/offline.html';
self.addEventListener('install', event => {
event.waitUntil(
(async () => {
const cache = await caches.open(CACHE_NAME);
// Setting {cache: 'reload'} in the new request will ensure that the
// response isn't fulfilled from the HTTP cache; i.e., it will be from
// the network.
await cache.add(new Request(OFFLINE_URL, { cache: 'reload' }));
})()
);
// Force the waiting service worker to become the active service worker.
self.skipWaiting();
});
self.addEventListener('activate', event => {
event.waitUntil(
(async () => {
// Enable navigation preload if it's supported.
// See https://developers.google.com/web/updates/2017/02/navigation-preload
if ('navigationPreload' in self.registration) {
await self.registration.navigationPreload.enable();
}
})()
);
// Tell the active service worker to take control of the page immediately.
self.clients.claim();
});
self.addEventListener('fetch', event => {
// We only want to call event.respondWith() if this is a navigation request
// for an HTML page.
if (event.request.mode === 'navigate') {
event.respondWith((async () => {
try {
// First, try to use the navigation preload response if it's supported.
const preloadResponse = await event.preloadResponse;
if (preloadResponse) {
return preloadResponse;
}
// Always try the network first.
const networkResponse = await fetch(event.request);
return networkResponse;
} catch (error) {
// catch is only triggered if an exception is thrown, which is likely
// due to a network error.
// If fetch() returns a valid HTTP response with a response code in
// the 4xx or 5xx range, the catch() will NOT be called.
console.log('Fetch failed; returning offline page instead.', error);
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(OFFLINE_URL);
return cachedResponse;
}
})());
}
// If our if() condition is false, then this fetch handler won't intercept the
// request. If there are any other fetch handlers registered, they will get a
// chance to call event.respondWith(). If no fetch handlers call
// event.respondWith(), the request will be handled by the browser as if there
// were no service worker involvement.
});

View File

@@ -57,12 +57,15 @@ export function resetAnalytics() {
* @param {Store} store - The redux store in which the specified {@code action} is being dispatched.
* @returns {Promise} Resolves with the handlers that have been successfully loaded.
*/
export function createHandlers({ getState }: { getState: Function }) {
export async function createHandlers({ getState }: { getState: Function }) {
getJitsiMeetGlobalNS().analyticsHandlers = [];
window.analyticsHandlers = []; // Legacy support.
if (!isAnalyticsEnabled(getState)) {
return Promise.resolve([]);
// Avoid all analytics processing if there are no handlers, since no event would be sent.
analytics.dispose();
return [];
}
const state = getState();
@@ -100,43 +103,47 @@ export function createHandlers({ getState }: { getState: Function }) {
};
const handlers = [];
try {
const amplitude = new AmplitudeHandler(handlerConstructorOptions);
if (amplitudeAPPKey) {
try {
const amplitude = new AmplitudeHandler(handlerConstructorOptions);
analytics.amplitudeIdentityProps = amplitude.getIdentityProps();
analytics.amplitudeIdentityProps = amplitude.getIdentityProps();
handlers.push(amplitude);
// eslint-disable-next-line no-empty
} catch (e) {}
handlers.push(amplitude);
} catch (e) {
logger.error('Failed to initialize Amplitude handler', e);
}
}
try {
const matomo = new MatomoHandler(handlerConstructorOptions);
if (matomoEndpoint && matomoSiteID) {
try {
const matomo = new MatomoHandler(handlerConstructorOptions);
handlers.push(matomo);
// eslint-disable-next-line no-empty
} catch (e) {}
handlers.push(matomo);
} catch (e) {
logger.error('Failed to initialize Matomo handler', e);
}
}
return (
_loadHandlers(scriptURLs, handlerConstructorOptions)
.then(externalHandlers => {
handlers.push(...externalHandlers);
if (handlers.length === 0) {
// Throwing an error in order to dispose the analytics in the catch clause due to the lack of any
// analytics handlers.
throw new Error('No analytics handlers created!');
}
if (Array.isArray(scriptURLs) && scriptURLs.length > 0) {
let externalHandlers;
return handlers;
})
.catch(e => {
analytics.dispose();
if (handlers.length !== 0) {
logger.error(e);
}
try {
externalHandlers = await _loadHandlers(scriptURLs, handlerConstructorOptions);
handlers.push(...externalHandlers);
} catch (e) {
logger.error('Failed to initialize external analytics handlers', e);
}
}
return [];
}));
// Avoid all analytics processing if there are no handlers, since no event would be sent.
if (handlers.length === 0) {
analytics.dispose();
}
logger.info(`Initialized ${handlers.length} analytics handlers`);
return handlers;
}
/**
@@ -228,7 +235,7 @@ function _inIframe() {
}
/**
* Tries to load the scripts for the analytics handlers and creates them.
* Tries to load the scripts for the external analytics handlers and creates them.
*
* @param {Array} scriptURLs - The array of script urls to load.
* @param {Object} handlerConstructorOptions - The default options to pass when creating handlers.
@@ -279,7 +286,7 @@ function _loadHandlers(scriptURLs = [], handlerConstructorOptions) {
logger.warn(`Error creating analytics handler: ${error}`);
}
}
logger.debug(`Loaded ${handlers.length} analytics handlers`);
logger.debug(`Loaded ${handlers.length} external analytics handlers`);
return handlers;
});

View File

@@ -72,6 +72,11 @@ export default class AmplitudeHandler extends AbstractHandler {
* @returns {Object}
*/
getIdentityProps() {
// TODO: Remove when web and native Aplitude implementations are unified.
if (navigator.product === 'ReactNative') {
return {};
}
return {
sessionId: amplitude.getInstance(this._amplitudeOptions).getSessionId(),
deviceId: amplitude.getInstance(this._amplitudeOptions).options.deviceId,

View File

@@ -16,7 +16,7 @@ import { connect, disconnect, setLocationURL } from '../base/connection';
import { loadConfig } from '../base/lib-jitsi-meet';
import { MEDIA_TYPE } from '../base/media';
import { toState } from '../base/redux';
import { createDesiredLocalTracks, isLocalVideoTrackMuted, isLocalTrackMuted } from '../base/tracks';
import { createDesiredLocalTracks, isLocalCameraTrackMuted, isLocalTrackMuted } from '../base/tracks';
import {
addHashParamsToURL,
getBackendSafeRoomName,
@@ -232,7 +232,7 @@ export function reloadNow() {
function addTrackStateToURL(url, stateful) {
const state = toState(stateful);
const tracks = state['features/base/tracks'];
const isVideoMuted = isLocalVideoTrackMuted(tracks);
const isVideoMuted = isLocalCameraTrackMuted(tracks);
const isAudioMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
return addHashParamsToURL(new URL(url), { // use new URL object in order to not pollute the passed parameter.
@@ -294,6 +294,8 @@ export function maybeRedirectToWelcomePage(options: Object = {}) {
if (enableClosePage) {
if (isVpaasMeeting(getState())) {
redirectToStaticPage('/');
return;
}
const { isGuest, jwt } = getState()['features/base/jwt'];

View File

@@ -1,6 +1,7 @@
// @flow
import React from 'react';
import SplashScreen from 'react-native-splash-screen';
import { setColorScheme } from '../../base/color-scheme';
import { DialogContainer } from '../../base/dialog';
@@ -84,6 +85,8 @@ export class App extends AbstractApp {
componentDidMount() {
super.componentDidMount();
SplashScreen.hide();
this._init.then(() => {
const { dispatch, getState } = this.state.store;

View File

@@ -24,6 +24,7 @@ import '../base/sounds/reducer';
import '../base/testing/reducer';
import '../base/tracks/reducer';
import '../base/user-interaction/reducer';
import '../billing-counter/reducer';
import '../blur/reducer';
import '../calendar-sync/reducer';
import '../chat/reducer';

View File

@@ -37,6 +37,11 @@ export type Props = {
*/
displayName?: string,
/**
* Whether or not to update the background color of the avatar
*/
dynamicColor?: Boolean,
/**
* ID of the element, if any.
*/
@@ -78,6 +83,15 @@ export const DEFAULT_SIZE = 65;
* Implements a class to render avatars in the app.
*/
class Avatar<P: Props> extends PureComponent<P, State> {
/**
* Default values for {@code Avatar} component's properties.
*
* @static
*/
static defaultProps = {
dynamicColor: true
};
/**
* Instantiates a new {@code Component}.
*
@@ -123,6 +137,7 @@ class Avatar<P: Props> extends PureComponent<P, State> {
_loadableAvatarUrl,
className,
colorBase,
dynamicColor,
id,
size,
status,
@@ -156,7 +171,10 @@ class Avatar<P: Props> extends PureComponent<P, State> {
const initials = getInitials(_initialsBase);
if (initials) {
avatarProps.color = getAvatarColor(colorBase || _initialsBase);
if (dynamicColor) {
avatarProps.color = getAvatarColor(colorBase || _initialsBase);
}
avatarProps.initials = initials;
}

View File

@@ -52,7 +52,6 @@ import {
SET_START_MUTED_POLICY
} from './actionTypes';
import {
AVATAR_ID_COMMAND,
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
JITSI_CONFERENCE_URL_KEY
@@ -198,13 +197,6 @@ function _addConferenceListeners(conference, dispatch) {
botType
})));
conference.addCommandListener(
AVATAR_ID_COMMAND,
(data, id) => dispatch(participantUpdated({
conference,
id,
avatarID: data.value
})));
conference.addCommandListener(
AVATAR_URL_COMMAND,
(data, id) => dispatch(participantUpdated({

View File

@@ -1,10 +1,3 @@
/**
* The command type for updating a participant's avatar ID.
*
* @type {string}
*/
export const AVATAR_ID_COMMAND = 'avatar-id';
/**
* The command type for updating a participant's avatar URL.
*

View File

@@ -14,7 +14,6 @@ import { toState } from '../redux';
import { safeDecodeURIComponent } from '../util';
import {
AVATAR_ID_COMMAND,
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
JITSI_CONFERENCE_URL_KEY
@@ -316,16 +315,12 @@ export function sendLocalParticipant(
setDisplayName: Function,
setLocalParticipantProperty: Function }) {
const {
avatarID,
avatarURL,
email,
features,
name
} = getLocalParticipant(stateful);
avatarID && conference.sendCommand(AVATAR_ID_COMMAND, {
value: avatarID
});
avatarURL && conference.sendCommand(AVATAR_URL_COMMAND, {
value: avatarURL
});

View File

@@ -3,7 +3,7 @@ import extraConfigWhitelist from './extraConfigWhitelist';
/**
* The config keys to whitelist, the keys that can be overridden.
* Currently we can only whitelist the first part of the properties, like
* 'p2p.useStunTurn' and 'p2p.enabled' we whitelist all p2p options.
* 'p2p.enabled' we whitelist all p2p options.
* The whitelist is used only for config.js.
*
* @type Array
@@ -15,8 +15,6 @@ export default [
'abTesting',
'analytics.disabled',
'audioLevelsInterval',
'autoRecord',
'autoRecordToken',
'apiLogLevels',
'avgRtpStatsN',
@@ -151,7 +149,6 @@ export default [
'stereo',
'subject',
'testing',
'useStunTurn',
'useTurnUdp',
'videoQuality.persist',
'webrtcIceTcpDisable',

View File

@@ -172,9 +172,7 @@ ColorSchemeRegistry.register('BottomSheet', {
},
expandIcon: {
color: schemeColor('icon'),
fontSize: 48,
opacity: 0.8
color: schemeColor('icon')
},
/**

View File

@@ -49,6 +49,12 @@ export const INVITE_ENABLED = 'invite.enabled';
*/
export const IOS_RECORDING_ENABLED = 'ios.recording.enabled';
/**
* Flag indicating if kickout is enabled.
* Default: enabled (true).
*/
export const KICK_OUT_ENABLED = 'kick-out.enabled';
/**
* Flag indicating if live-streaming should be enabled.
* Default: auto-detected.

View File

@@ -0,0 +1,3 @@
<svg width="10" height="7" viewBox="0 0 10 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.41115 6.05746C8.71903 6.39955 9.24594 6.42729 9.58803 6.1194C9.93012 5.81152 9.95786 5.28461 9.64997 4.94252L5.72917 0.562752C5.39813 0.194935 4.82138 0.194935 4.49034 0.562752L0.63061 4.94252C0.322728 5.28461 0.35046 5.81152 0.692552 6.1194C1.03464 6.42729 1.56155 6.39955 1.86943 6.05746L5.10975 2.36593L8.41115 6.05746Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 492 B

View File

@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="24"
height="24"
viewBox="0 0 24 24">
<path
d="m 5.6875,10.59375 h 12.625 c 0.779062,0 1.40625,0.627187 1.40625,1.40625 0,0.779062 -0.627188,1.40625 -1.40625,1.40625 H 5.6875 c -0.7790625,0 -1.40625,-0.627188 -1.40625,-1.40625 0,-0.779063 0.6271875,-1.40625 1.40625,-1.40625 z"
id="rect3711" />
width="128"
height="32"
viewBox="0 0 128 32">
<path
d="m 19.431133,13.973662 h 90.198887 c 4.85877,0 4.20737,0.903746 4.20737,2.026338 0,1.122591 0.33306,2.026338 -4.52571,2.026338 H 19.218901 c -4.858774,0 -4.844061,-0.903747 -4.844061,-2.026338 0,-1.122592 0.197519,-2.026338 5.056293,-2.026338 z" />
</svg>

Before

Width:  |  Height:  |  Size: 474 B

After

Width:  |  Height:  |  Size: 424 B

View File

@@ -5,6 +5,7 @@ export { default as IconAddPeople } from './link.svg';
export { default as IconArrowBack } from './arrow_back.svg';
export { default as IconArrowDown } from './arrow_down.svg';
export { default as IconArrowDownSmall } from './arrow-down-small.svg';
export { default as IconArrowUp } from './arrow_up.svg';
export { default as IconArrowLeft } from './arrow-left.svg';
export { default as IconAudioOnly } from './visibility.svg';
export { default as IconAudioOnlyOff } from './visibility-off.svg';
@@ -90,6 +91,7 @@ export { default as IconShareVideo } from './shared-video.svg';
export { default as IconSwitchCamera } from './switch-camera.svg';
export { default as IconTileView } from './tiles-many.svg';
export { default as IconToggleRecording } from './camera-take-picture.svg';
export { default as IconTrash } from './trash.svg';
export { default as IconVideoQualityAudioOnly } from './AUD.svg';
export { default as IconVideoQualityHD } from './HD.svg';
export { default as IconVideoQualityLD } from './LD.svg';

View File

@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="trash-alt" class="svg-inline--fa fa-trash-alt fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"></path></svg>

After

Width:  |  Height:  |  Size: 577 B

View File

@@ -0,0 +1,5 @@
// @flow
import { getLogger } from '../logging/functions';
export default getLogger('features/base/jitsi-local-storage');

View File

@@ -0,0 +1,45 @@
// @flow
import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';
import { parseURLParams } from '../util/parseURLParams';
import logger from './logger';
declare var APP: Object;
/**
* Handles changes of the fake local storage.
*
* @returns {void}
*/
function onFakeLocalStorageChanged() {
APP.API.notifyLocalStorageChanged(jitsiLocalStorage.serialize());
}
/**
* Performs initial setup of the jitsiLocalStorage.
*
* @returns {void}
*/
function setupJitsiLocalStorage() {
if (jitsiLocalStorage.isLocalStorageDisabled()) {
const urlParams = parseURLParams(window.location);
try {
const localStorageContent = JSON.parse(urlParams['appData.localStorageContent']);
if (typeof localStorageContent === 'object') {
Object.keys(localStorageContent).forEach(key => {
jitsiLocalStorage.setItem(key, localStorageContent[key]);
});
}
} catch (error) {
logger.error('Can\'t parse localStorageContent.', error);
}
jitsiLocalStorage.on('changed', onFakeLocalStorageChanged);
}
}
setupJitsiLocalStorage();

View File

@@ -4,7 +4,6 @@ import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
import { SCREEN_SHARE_PARTICIPANTS_UPDATED, SET_TILE_VIEW } from '../../video-layout/actionTypes';
import { shouldDisplayTileView } from '../../video-layout/functions';
import { SET_AUDIO_ONLY } from '../audio-only/actionTypes';
import { CONFERENCE_JOINED } from '../conference/actionTypes';
import {
@@ -81,12 +80,14 @@ function _updateLastN({ getState }) {
if (typeof appState !== 'undefined' && appState !== 'active') {
lastN = 0;
} else if (audioOnly) {
const { screenShares } = state['features/video-layout'];
const tileViewEnabled = shouldDisplayTileView(state);
const { screenShares, tileViewEnabled } = state['features/video-layout'];
const largeVideoParticipantId = state['features/large-video'].participantId;
const largeVideoParticipant
= largeVideoParticipantId ? getParticipantById(state, largeVideoParticipantId) : undefined;
// Use tileViewEnabled state from redux here instead of determining if client should be in tile
// view since we make an exception only for screenshare when in audio-only mode. If the user unpins
// the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned.
if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) {
lastN = (screenShares || []).includes(largeVideoParticipantId) ? 1 : 0;
} else {

View File

@@ -1,5 +1,6 @@
/* @flow */
import { jitsiLocalStorage } from '@jitsi/js-utils';
import type { Dispatch } from 'redux';
import { isOnline } from '../net-info/selectors';
@@ -51,7 +52,8 @@ export function initLib() {
try {
JitsiMeetJS.init({
enableAnalyticsLogging: isAnalyticsEnabled(getState),
...config
...config,
externalStorage: jitsiLocalStorage.isLocalStorageDisabled() ? jitsiLocalStorage : undefined
});
JitsiMeetJS.setNetworkInfo({
isOnline: isOnline(state)

View File

@@ -18,7 +18,7 @@ const { JavaScriptSandbox } = NativeModules;
*/
export async function loadConfig(url: string): Promise<Object> {
try {
const configTxt = await loadScript(url, 2.5 * 1000 /* Timeout in ms */, true /* skipeval */);
const configTxt = await loadScript(url, 10 * 1000 /* Timeout in ms */, true /* skipeval */);
const configJson = await JavaScriptSandbox.evaluate(`${configTxt}\nJSON.stringify(config);`);
const config = JSON.parse(configJson);

View File

@@ -104,8 +104,10 @@ function _setErrorHandlers() {
// eslint-disable-next-line max-params
window.onerror = (message, source, lineno, colno, error) => {
JitsiMeetJS.getGlobalOnErrorHandler(
message, source, lineno, colno, error);
const errMsg = message || (error && error.message);
const stack = error && error.stack;
JitsiMeetJS.getGlobalOnErrorHandler(errMsg, source, lineno, colno, stack);
if (oldOnErrorHandler) {
oldOnErrorHandler(message, source, lineno, colno, error);
@@ -115,8 +117,14 @@ function _setErrorHandlers() {
const oldOnUnhandledRejection = window.onunhandledrejection;
window.onunhandledrejection = function(event) {
JitsiMeetJS.getGlobalOnErrorHandler(
null, null, null, null, event.reason);
let message = event.reason;
let stack = 'n/a';
if (event.reason instanceof Error) {
({ message, stack } = event.reason);
}
JitsiMeetJS.getGlobalOnErrorHandler(message, null, null, null, stack);
if (oldOnUnhandledRejection) {
oldOnUnhandledRejection(event);

View File

@@ -1,9 +1,30 @@
/* @flow */
import { toState } from '../redux';
import { getPropertyValue } from '../settings';
import { VIDEO_MUTISM_AUTHORITY } from './constants';
// XXX The configurations/preferences/settings startWithAudioMuted and startWithVideoMuted were introduced for
// conferences/meetings. So it makes sense for these to not be considered outside of conferences/meetings
// (e.g. WelcomePage). Later on, though, we introduced a "Video <-> Voice" toggle on the WelcomePage which utilizes
// startAudioOnly outside of conferences/meetings so that particular configuration/preference/setting employs slightly
// exclusive logic.
const START_WITH_AUDIO_VIDEO_MUTED_SOURCES = {
// We have startWithAudioMuted and startWithVideoMuted here:
config: true,
settings: true,
// XXX We've already overwritten base/config with urlParams. However,
// settings are more important than the server-side config.
// Consequently, we need to read from urlParams anyway:
urlParams: true,
// We don't have startWithAudioMuted and startWithVideoMuted here:
jwt: false
};
/**
* Determines whether audio is currently muted.
*
@@ -47,6 +68,26 @@ function _isVideoMutedByAuthority(
return Boolean(muted & videoMutismAuthority);
}
/**
* Computes the startWithAudioMuted by retrieving its values from config, URL and settings.
*
* @param {Object|Function} stateful - The redux state object or {@code getState} function.
* @returns {boolean} - The computed startWithAudioMuted value that will be used.
*/
export function getStartWithAudioMuted(stateful: Object | Function) {
return Boolean(getPropertyValue(stateful, 'startWithAudioMuted', START_WITH_AUDIO_VIDEO_MUTED_SOURCES));
}
/**
* Computes the startWithAudioMuted by retrieving its values from config, URL and settings.
*
* @param {Object|Function} stateful - The redux state object or {@code getState} function.
* @returns {boolean} - The computed startWithAudioMuted value that will be used.
*/
export function getStartWithVideoMuted(stateful: Object | Function) {
return Boolean(getPropertyValue(stateful, 'startWithVideoMuted', START_WITH_AUDIO_VIDEO_MUTED_SOURCES));
}
/**
* Determines whether video is currently muted by the user authority.
*

View File

@@ -21,6 +21,7 @@ import {
MEDIA_TYPE,
VIDEO_MUTISM_AUTHORITY
} from './constants';
import { getStartWithAudioMuted, getStartWithVideoMuted } from './functions';
import logger from './logger';
import {
_AUDIO_INITIAL_MEDIA_STATE,
@@ -133,37 +134,8 @@ function _setRoom({ dispatch, getState }, next, action) {
const state = getState();
const { room } = action;
const roomIsValid = isRoomValid(room);
// XXX The configurations/preferences/settings startWithAudioMuted,
// startWithVideoMuted, and startAudioOnly were introduced for
// conferences/meetings. So it makes sense for these to not be considered
// outside of conferences/meetings (e.g. WelcomePage). Later on, though, we
// introduced a "Video <-> Voice" toggle on the WelcomePage which utilizes
// startAudioOnly outside of conferences/meetings so that particular
// configuration/preference/setting employs slightly exclusive logic.
const mutedSources = {
// We have startWithAudioMuted and startWithVideoMuted here:
config: true,
settings: true,
// XXX We've already overwritten base/config with urlParams. However,
// settings are more important than the server-side config.
// Consequently, we need to read from urlParams anyway:
urlParams: true,
// We don't have startWithAudioMuted and startWithVideoMuted here:
jwt: false
};
const audioMuted
= roomIsValid
? Boolean(
getPropertyValue(state, 'startWithAudioMuted', mutedSources))
: _AUDIO_INITIAL_MEDIA_STATE.muted;
const videoMuted
= roomIsValid
? Boolean(
getPropertyValue(state, 'startWithVideoMuted', mutedSources))
: _VIDEO_INITIAL_MEDIA_STATE.muted;
const audioMuted = roomIsValid ? getStartWithAudioMuted(state) : _AUDIO_INITIAL_MEDIA_STATE.muted;
const videoMuted = roomIsValid ? getStartWithVideoMuted(state) : _VIDEO_INITIAL_MEDIA_STATE.muted;
sendAnalytics(
createStartMutedConfigurationEvent('local', audioMuted, videoMuted));

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