Compare commits

...

35 Commits

Author SHA1 Message Date
Hayato Shimizu
5ce2bef556 fix: jicofo_lock is null when restored from storage (#13517)
* Fix jicofo_lock is null when restored from storage

* revert

---------

Co-authored-by: hshim432 <hshimizusv@gmail.com>
2023-07-07 07:52:22 -05:00
Bartosz Pawlak
472c8d7808 fix(lang) updated Polish translation 2023-07-07 11:42:37 +02:00
MrAndriy
a51b377d6b fix(lang, rn) add Ukrainian lang to builtinLanguages
Fixes: https://github.com/jitsi/jitsi-meet/issues/13401
2023-07-06 13:09:12 +02:00
Calin-Teodor
f5d764e3df feat(react-native-sdk): updated dependencies 2023-07-06 09:46:16 +03:00
Jaya Allamsetty
f71f6d9a0d chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1652.0.0+90da4884...v1654.0.0+782350e0
2023-07-05 11:56:52 -04:00
Calin-Teodor
78b8c811af deps(react-navigation): updated to latest 2023-07-05 15:55:31 +03:00
Calin-Teodor
10d8d71d8b deps(react-native-screens): updated to latest 2023-07-05 14:10:33 +03:00
Calinteodor
9e48943daf sdk(react-native-sdk): fixes (#13525)
* sdk(react-native-sdk): fix path, logs and dependency values.
2023-07-05 14:10:01 +03:00
Christoph Settgast
9f118c6b82 lang: update German translation 2023-07-04 22:12:37 +02:00
Robert Pintilii
2c8dedcb85 ref(scss) Variables cleanup (#13521)
Remove some unused variables
Replace variables that are only used once with their value
2023-07-04 12:34:41 +03:00
Calinteodor
f950dc90b9 sdk(react-native-sdk): added script that updates app dependencies (#13516)
* sdk(react-native-sdk): created script for missing dependencies
2023-07-04 11:09:58 +03:00
Saúl Ibarra Corretgé
92ca7a598a fix(jwt) fix not processing features if avatar, name, email are missing 2023-07-04 07:00:02 +02:00
Jaya Allamsetty
97f9d747c0 fix(config): Remove the deprecated configs. (#13500)
* fix(config): Remove the deprecated configs.
Add the new codec selection settings for desktop and mobile endpoints.

* fix(config): Use the new codec selection settings for RN.

* Address review comments.

* chore(deps) Update lib-jitsi-meet@latest.
https://github.com/jitsi/lib-jitsi-meet/compare/v1649.0.0+17ade96a...v1652.0.0+90da4884.
2023-07-03 18:25:44 -04:00
Hristo Terezov
159dd13c2d fix(chat-URLs): Use punycode only on host name.
This is workaround for PunycodeJS which truncates parts of the URL when
it contains '@'.
2023-07-03 11:16:27 -05:00
Saúl Ibarra Corretgé
98c6df0c10 deps(rn) update react-native-webrtc to 111.0.3
Fixes an issue where the transceiverf mid wasn't set.
2023-07-03 15:53:23 +02:00
Robert Pintilii
8acce9a2f5 fix(keyboard-shortcuts) Check modifier key (#13520) 2023-07-03 14:33:06 +03:00
Robert Pintilii
52fbd3aeb8 ref(toolbar) Convert to function component (#13511)
Extract keyboard shortcuts logic to custom hook
2023-07-03 12:58:58 +03:00
Saúl Ibarra Corretgé
e9b2d8ecdf deps(rn) update react-native-webrtc to 111.0.2
Fixes not receiving video in P2P mode when the mobile user starts with
video muted and is also the offerer.
2023-07-03 11:58:08 +02:00
Saúl Ibarra Corretgé
cdc4154cdf fix(android) remove no longer needed view clipping hack
This should no longer be necessary since we added it for Android 6
devices a long time ago but we no longer support those.

Fixes: https://github.com/jitsi/jitsi-meet/issues/13514
2023-07-03 11:57:50 +02:00
Calinteodor
16cacec43c sdk(react-native-sdk): moved some dependencies to peer dependencies (#13498)
* sdk(react-native-sdk): moved some dependencies to peer dependencies

https://github.com/react-native-community/cli/issues/870

https://github.com/callstack/react-native-builder-bob#how-do-i-add-a-react-native-library-containing-native-code-as-a-dependency-in-my-library
2023-06-30 16:12:00 +03:00
Robert Pintilii
877fbe63c1 fix(dialog) Fix close on backdrop (#13512) 2023-06-30 10:59:33 +03:00
Дамян Минков
322d846bd9 fix: Drop events if conn is closed while waiting for jicofo. 2023-06-29 11:31:31 -05:00
Gabriel Borlea
ca8c055a58 fix(shortcuts): reactions description translations (#13504)
* fix(shortscuts): reactions description translations

* fix lint
2023-06-29 15:58:46 +03:00
Robert Pintilii
2d8014775a ref(toolbar) Move getButtons to functions (#13502)
Move visible logic inside each button
Move click functionality inside each button
Extract getButtons function from Toolbox components to functions file
2023-06-29 14:59:12 +03:00
Saúl Ibarra Corretgé
699b797e0f feat(rn,settings) add field with SDK version
This helps us know it at a glance, from applications using it, without
having to look at any logs.
2023-06-29 11:30:45 +02:00
Saúl Ibarra Corretgé
a8e2fcdfea fix(ios) fix UUID comparison
Fixes: https://github.com/jitsi/jitsi-meet/issues/12716
2023-06-29 10:52:40 +02:00
Jaya Allamsetty
99016baa42 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1643.0.0+0748d89a...v1649.0.0+17ade96a
2023-06-28 12:27:11 -04:00
Hristo Terezov
6187bb928a fix(Popup): Invalid reference. 2023-06-28 09:13:24 -05:00
Hristo Terezov
fab8a98cf7 fix(iframe): Add allow screen-wake-lock. 2023-06-27 11:45:11 -05:00
Calinteodor
00092b79af sdk(react-native-sdk): react native sdk updates (#13482)
* sdk(react-native-sdk): minor updates
2023-06-27 15:38:12 +03:00
D1eter
ba26407469 fix: store only "clean" URLs in recent-list (#13489)
* store only "clean" URLs in recent-list

* remove spaces in parentheses
2023-06-26 08:30:17 -05:00
Mohammad Kazemi
63e40c9e03 lang: Farsi (Persian) translation (#13463)
* Translated using Weblate (Persian)

Currently translated at 4.0% (52 of 1272 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 7.8% (100 of 1272 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 32.0% (408 of 1272 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 51.0% (654 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 66.1% (848 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 67.2% (862 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 72.0% (924 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 75.6% (970 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (1282 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (1282 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (1288 of 1288 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/
2023-06-24 14:28:09 -05:00
Aaron van Meerten
cbac122525 feature: allowlist checking for token verification module (#13488) 2023-06-23 15:48:19 -04:00
damencho
9af56d52c2 fix: Adds one more check for iframes. 2023-06-23 11:05:37 -05:00
José Luís Andrade
2a9c40f0d2 lang: Update Portuguese translation (#13481) 2023-06-23 09:18:46 -05:00
87 changed files with 4341 additions and 4378 deletions

1
.gitignore vendored
View File

@@ -97,6 +97,7 @@ tsconfig.json
# React Native SDK
#
react-native-sdk/*.tgz
react-native-sdk/android/src
react-native-sdk/images
react-native-sdk/ios

View File

@@ -427,25 +427,9 @@ var config = {
// Specify the settings for video quality optimizations on the client.
// videoQuality: {
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
// disabledCodec: 'H264',
//
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
// // to take effect.
// preferredCodec: 'VP8',
//
// // Provides a way to enforce the preferred codec for the conference even when the conference has endpoints
// // that do not support the preferred codec. For example, older versions of Safari do not support VP9 yet.
// // This will result in Safari not being able to decode video from endpoints sending VP9 video.
// // When set to false, the conference falls back to VP8 whenever there is an endpoint that doesn't support the
// // preferred codec and goes back to the preferred codec when that endpoint leaves.
// enforcePreferredCodec: false,
// // Provides a way to set the codec preference on desktop based endpoints.
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264' ],
//
// // Provides a way to configure the maximum bitrates that will be enforced on the simulcast streams for
// // video tracks. The keys in the object represent the type of the stream (LD, SD or HD) and the values
@@ -485,6 +469,24 @@ var config = {
// 720: 'high',
// },
//
// // Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based endpoint
// mobileCodecPreferenceOrder: [ 'VP8', 'VP9', 'H264' ],
//
// // DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
// disabledCodec: 'H264',
//
// // DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
// // to take effect.
// preferredCodec: 'VP8',
//
// },
// Notification timeouts
@@ -935,12 +937,12 @@ var config = {
// If not set, the effective value is 'all'.
// iceTransportPolicy: 'all',
// Provides a way to set the video codec preference on the p2p connection. Acceptable
// codec values are 'VP8', 'VP9' and 'H264'.
// preferredCodec: 'H264',
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
// disabledCodec: '',
// Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based
// endpoints.
// mobileCodecPreferenceOrder: [ 'H264', 'VP8', 'VP9' ],
//
// Provides a way to set the codec preference on desktop based endpoints.
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264 ],
// How long we're going to wait, before going back to P2P after the 3rd
// participant has left the conference (to filter out page reload).
@@ -952,6 +954,15 @@ var config = {
// { urls: 'stun:jitsi-meet.example.com:3478' },
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' },
],
// DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// Provides a way to set the video codec preference on the p2p connection. Acceptable
// codec values are 'VP8', 'VP9' and 'H264'.
// preferredCodec: 'H264',
// DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
// disabledCodec: '',
},
analytics: {

View File

@@ -31,8 +31,8 @@ body {
font-size: 12px;
font-weight: 400;
overflow: hidden;
color: $defaultColor;
background: $defaultBackground;
color: #F1F1F1;
background: #040404; // should match DEFAULT_BACKGROUND from interface_config
}
/**
@@ -94,7 +94,7 @@ input[type='text'], input[type='password'], textarea {
button {
color: #FFF;
background-color: $buttonBackground;
background-color: #44A5FF;
border-radius: $borderRadius;
&.no-icon {
@@ -145,7 +145,7 @@ form {
font-size: 11pt;
color: rgba(255,255,255,.50);
text-decoration: none;
z-index: $poweredByZ;
z-index: 100;
}
.connected {

View File

@@ -5,7 +5,7 @@
position: relative;
transition: width .16s ease-in-out;
width: $sidebarWidth;
z-index: $sideToolbarContainerZ;
z-index: 300;
@media (max-width: 580px) {
height: 100vh;
@@ -253,7 +253,7 @@
.chatmessage {
&.localuser {
background-color: $chatLocalMessageBackgroundColor;
background-color: #484A4F;
border-radius: 6px 0px 6px 6px;
}
@@ -324,7 +324,7 @@
#smileysContainer {
background-color: $chatBackgroundColor;
border-top: 1px solid $chatInputSeparatorColor;
border-top: 1px solid #A4B8D1;
}
}
@@ -340,7 +340,7 @@
}
.smileyContainer:hover {
background-color: $newToolbarButtonToggleColor;
background-color: rgba(255, 255, 255, 0.15);
border-radius: 5px;
cursor: pointer;
}

View File

@@ -3,17 +3,17 @@
left: 0;
right: 0;
bottom: 0;
z-index: $drawerZ;
z-index: 351;
border-radius: 16px 16px 0 0;
&.notification-portal {
z-index: $dropdownZ;
z-index: 901;
}
}
.drawer-portal::after {
content: '';
background-color: $participantsPaneBgColor;
background-color: #141414;
margin-bottom: env(safe-area-inset-bottom, 0);
}
@@ -54,7 +54,7 @@
padding: 12px 16px;
align-items: center;
color: $overflowMenuItemColor;
color: #fff;
cursor: pointer;
display: flex;
font-size: 16px;

View File

@@ -3,20 +3,20 @@
@include border-radius(4px);
padding: 40px 38px 44px;
color: #fff;
background: $inlayColorBg;
background: lighten(#474747, 20%);
text-align: center;
&__title {
margin: 17px 0;
padding-bottom: 17px;
color: $popoverFontColor;
color: #ffffff;
font-size: 21px;
letter-spacing: 0.3px;
border-bottom: 1px solid $inlayBorderColor;
border-bottom: 1px solid lighten(#FFFFFF, 10%);
}
&__text {
color: $popoverFontColor;
color: #ffffff;
display: block;
margin-top: 22px;
font-size: 16px;

View File

@@ -1,5 +1,5 @@
.participants_pane {
background-color: $participantsPaneBgColor;
background-color: #141414;
flex-shrink: 0;
overflow: hidden;
position: relative;

View File

@@ -1,5 +1,5 @@
.popover {
z-index: $popoverZ;
z-index: 8;
.popover-content {
position: relative;

View File

@@ -2,7 +2,7 @@
.reactions-menu {
width: 280px;
background: $menuBG;
background: #242528;
box-shadow: 0px 3px 16px rgba(0, 0, 0, 0.6), 0px 0px 4px 1px rgba(0, 0, 0, 0.25);
border-radius: 6px;
padding: 16px;

View File

@@ -186,7 +186,7 @@
}
.google-error {
color: $errorColor;
color: #c61600;
}
.google-panel {

View File

@@ -5,7 +5,7 @@
font-size: 24px;
.thanks-msg {
border-bottom: 1px solid $selectBg;
border-bottom: 1px solid #FFFFFF;
padding-left: 30px;
padding-right: 30px;
p {
@@ -28,7 +28,7 @@
width: 120px;
height: 86px;
margin: 0 auto;
background: $happySoftwareBackground;
background: transparent;
}
}
}

View File

@@ -2,10 +2,10 @@
* Round badge.
*/
.badge-round {
background-color: $toolbarBadgeBackground;
background-color: #165ECC;
border-radius: 50%;
box-sizing: border-box;
color: $toolbarBadgeColor;
color: #FFFFFF;
// Do not inherit the font-family from the toolbar button, because it's an
// icon style.
font-family: $baseFontFamily;
@@ -192,7 +192,7 @@ div.hangup-menu-button {
background: none;
&:hover {
background: $newToolbarButtonHoverColor;
background: rgba(255, 255, 255, 0.2);
}
}

View File

@@ -13,7 +13,7 @@
1px 0px 1px rgba(0,0,0,0.3),
0px 0px 1px rgba(0,0,0,0.3);
transform: translateX(-50%);
z-index: $subtitlesZ;
z-index: 7;
&.lifted {
// Lift subtitle above toolbar+dominant speaker box.

View File

@@ -1,5 +1,3 @@
@import "themes/light";
/**
* Style variables
*/
@@ -10,83 +8,26 @@ $baseFontFamily: -apple-system, BlinkMacSystemFont, 'open_sanslight', 'Helvetica
*/
// Video layout.
$thumbnailVideoMargin: 2px;
$thumbnailsBorder: 2px;
$thumbnailVideoBorder: 2px;
$filmstripToggleButtonWidth: 17px;
/**
* Color variables.
*/
$defaultColor: #F1F1F1;
$defaultSideBarFontColor: #44A5FF;
$defaultSemiDarkColor: #ACACAC;
$defaultDarkColor: #2b3d5c;
$defaultWarningColor: rgb(215, 121, 118);
$participantsPaneBgColor: #141414;
/**
* Toolbar
*/
$newToolbarBackgroundColor: #131519;
$newToolbarButtonHoverColor: rgba(255, 255, 255, 0.2);
$newToolbarButtonToggleColor: rgba(255, 255, 255, 0.15);
$menuBG:#242528;
$newToolbarFontSize: 24px;
$newToolbarHangupFontSize: 32px;
$newToolbarSize: 48px;
$newToolbarSizeMobile: 60px;
$newToolbarSizeWithPadding: calc(#{$newToolbarSize} + 24px);
$toolbarTitleFontSize: 19px;
$overflowMenuItemColor: #fff;
/**
* Video layout
*/
$participantNameColor: #fff;
$audioLevelBg: #44A5FF;
$audioLevelShadow: rgba(9, 36, 77, 0.9);
$videoStateIndicatorColor: $defaultColor;
$videoStateIndicatorBackground: $toolbarBackground;
$videoStateIndicatorSize: 40px;
/**
* Feedback Modal
*/
$feedbackContentBg: #fff;
$feedbackInputBg: #fff;
$feedbackTextColor: #000;
$feedbackInputTextColor: #333;
$feedbackInputPlaceholderColor: #777;
/**
* Modals
*/
$modalButtonFontSize: 14px;
$modalMockAKInputBackground: #fafbfc;
$modalMockAKInputBorder: 1px solid #f4f5f7;
$modalTextColor: #333;
/**
* Chat
*/
$chatActionsSeparatorColor: rgb(173, 105, 112);
$chatBackgroundColor: #131519;
$chatInputSeparatorColor: #A4B8D1;
$chatLobbyActionsSeparatorColor: #6A50D3;
$chatLocalMessageBackgroundColor: #484A4F;
$chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
$chatRemoteMessageBackgroundColor: #242528;
$sidebarWidth: 315px;
/**
* Misc.
*/
$borderRadius: 4px;
$happySoftwareBackground: transparent;
$desktopAppDragBarHeight: 25px;
$scrollHeight: 7px;
/**
@@ -96,38 +37,11 @@ $zindex0: 0;
$zindex1: 1;
$zindex2: 2;
$zindex3: 3;
$subtitlesZ: 7;
$popoverZ: 8;
$reloadZ: 20;
$poweredByZ: 100;
$ringingZ: 300;
$sideToolbarContainerZ: 300;
$toolbarZ: 250;
$drawerZ: 351;
$dropdownZ: 901;
$overlayZ: 1016;
// Place filmstrip videos over toolbar in order
// to make connection info visible.
$filmstripVideosZ: $toolbarZ + 1;
/**
* Font Colors
*/
$defaultFontColor: #777;
$defaultLightFontColor: #F1F1F1;
$defaultDarkFontColor: #000;
/**
* Forms
*/
//inputs
$inputControlEmColor: #f29424;
//buttons
$linkFontColor: #489afe;
$linkHoverFontColor: #287ade;
$formPadding: 16px;
/**
* Unsupported browser
*/

View File

@@ -189,7 +189,7 @@
opacity: 0;
display: inline-block;
@include circle(5px);
background: $audioLevelShadow;
background: rgba(9, 36, 77, 0.9);
margin: 1px 0 1px 0;
transition: opacity .25s ease-in-out;
-moz-transition: opacity .25s ease-in-out;
@@ -205,7 +205,7 @@
border-radius: 50%;
-webkit-filter: blur(0.5px);
filter: blur(0.5px);
background: $audioLevelBg;
background: #44A5FF;
}
}
@@ -223,7 +223,7 @@
background-clip: padding-box;
-webkit-border-radius: 5px;
-webkit-background-clip: padding-box;
z-index: $reloadZ; /*The reload button should appear on top of the header!*/
z-index: 20; /*The reload button should appear on top of the header!*/
}
#dominantSpeaker {
@@ -365,7 +365,7 @@
}
.presence-label {
color: $participantNameColor;
color: #fff;
font-size: 12px;
font-weight: 100;
left: 0;

View File

@@ -63,7 +63,7 @@ body.welcome-page {
.insecure-room-name-warning {
align-items: center;
color: $defaultWarningColor;
color: rgb(215, 121, 118);
font-weight: 600;
display: flex;
flex-direction: row;
@@ -75,7 +75,7 @@ body.welcome-page {
margin-right: 15px;
svg {
fill: $defaultWarningColor;
fill: rgb(215, 121, 118);
& > *:first-child {
fill: none !important;

View File

@@ -19,7 +19,7 @@ input[type=range]:focus {
* Include the mixin for a range input style.
*/
@include slider {
background: $sliderTrackBackground;
background: #474747;
border: none;
border-radius: 3px;
cursor: pointer;
@@ -33,9 +33,9 @@ input[type=range]:focus {
@include slider-thumb {
-webkit-appearance: none;
background: white;
border: 1px solid $sliderThumbBackground;
border: 1px solid #3572b0;
border-radius: 50%;
box-shadow: 0px 0px 1px $sliderThumbBackground;
box-shadow: 0px 0px 1px #3572b0;
cursor: pointer;
height: 14px;
margin-top: -4px;

View File

@@ -5,7 +5,7 @@
width: auto;
&__title {
border-bottom: 1px solid $inlayBorderColor;
border-bottom: 1px solid lighten(#FFFFFF, 10%);
color: $unsupportedBrowserTitleColor;
font-weight: 400;
letter-spacing: 0.5px;

View File

@@ -2,9 +2,9 @@
display: inline-block;
position: relative;
background-size: contain;
border: $thumbnailVideoBorder solid transparent;
border: 2px solid transparent;
border-radius: $borderRadius;
margin: 0 $thumbnailVideoMargin;
margin: 0 2px;
&:hover {
cursor: hand;

View File

@@ -2,8 +2,8 @@
margin-top: 5px !important;
.input-control {
background: $modalMockAKInputBackground;
border: $modalMockAKInputBorder;
background: #fafbfc;
border: 1px solid #f4f5f7;
color: inherit;
}

View File

@@ -6,12 +6,12 @@
width: 100%;
height: 100%;
position: fixed;
z-index: $overlayZ;
background: $defaultBackground;
z-index: 1016;
background: #474747;
}
&__container-light {
@include transparentBg($defaultBackground, 0.7);
@include transparentBg(#474747, 0.7);
}
&__content {

View File

@@ -19,7 +19,7 @@
width: 180px;
.progress-indicator-fill {
background: $reloadProgressBarBg;
background: #0074E0;
height: 100%;
transition: width .5s;
}

View File

@@ -5,11 +5,11 @@
width: 100%;
height: 100%;
position: fixed;
z-index: $ringingZ;
z-index: 300;
@include transparentBg(#283447, 0.95);
&.solidBG {
background: $defaultBackground;
background: #040404;
}
&__content {

View File

@@ -1,77 +0,0 @@
/**
* Base
*/
$baseLight: #FFFFFF;
/**
* Controls
*/
$sliderTrackBackground: #474747;
$sliderThumbBackground: #3572b0;
/**
* Buttons
*/
$buttonBackground: #44A5FF;
$buttonHoverBackground: #2c4062;
$buttonBorder: transparent;
$buttonHoverBorder: transparent;
$buttonColor: #eceef1;
$buttonLightBackground: #f5f5f5;
$buttonLightHoverBackground: #e9e9e9;
$buttonLightBorder: #ccc;
$buttonLightHoverBorder: #999;
$buttonLinkBackground: transparent;
$buttonLinkColor: #0090e8;
$primaryButtonBackground: #3572b0;
$primaryButtonHoverBackground: #2a67a5;
$primaryButtonColor: $baseLight;
$primaryButtonFontWeight: 400;
$buttonShadowColor: #192d4f;
$overlayButtonBg: #0074E0;
/**
* Color variables
**/
$defaultBackground: #474747;
$reloadProgressBarBg: #0074E0;
/**
* Dialog colors
**/
$dialogErrorText: #344563;
/**
* Inlay colors
**/
$inlayColorBg: lighten($defaultBackground, 20%);
$inlayBorderColor: lighten($baseLight, 10%);
// Main controls
$placeHolderColor: #a7a7a7;
$readOnlyInputColor: #a7a7a7;
$defaultDarkSelectionColor: #ccc;
$buttonFontWeight: 400;
$labelFontWeight: 400;
$linkFontColor: #3572b0;
$linkHoverFontColor: darken(#3572b0, 10%);
$errorColor: #c61600;
// Popover colors
$popoverFontColor: #ffffff !important;
// Toolbar
$toolbarBackground: rgba(0, 0, 0, 0.5);
$toolbarBadgeBackground: #165ECC;
$toolbarBadgeColor: #FFFFFF;
/**
* Forms
*/
$selectBg: $baseLight;

View File

@@ -25,11 +25,11 @@
}
&__link {
color: $linkFontColor;
color: #489afe;
@include transition(color .1s ease-out);
&:hover {
color: $linkHoverFontColor;
color: #287ade;
cursor: pointer;
text-decoration: none;

View File

@@ -374,7 +374,7 @@ PODS:
- React-Core
- react-native-pager-view (5.4.9):
- React-Core
- react-native-safe-area-context (4.4.1):
- react-native-safe-area-context (4.6.4):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
@@ -390,7 +390,7 @@ PODS:
- react-native-video/Video (6.0.0-alpha.1):
- PromisesSwift
- React-Core
- react-native-webrtc (111.0.1):
- react-native-webrtc (111.0.3):
- JitsiWebRTC (~> 111.0.0)
- React-Core
- react-native-webview (11.15.1):
@@ -476,7 +476,7 @@ PODS:
- RNGoogleSignin (9.0.2):
- GoogleSignIn (~> 6.2)
- React-Core
- RNScreens (3.13.1):
- RNScreens (3.22.0):
- React-Core
- React-RCTImage
- RNSound (0.11.1):
@@ -751,11 +751,11 @@ SPEC CHECKSUMS:
react-native-netinfo: 27f287f2d191693f3b9d01a4273137fcf91c3b5d
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
react-native-pager-view: 3ee7d4c7697fb3ef788346e834a60cca97ed8540
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
react-native-safe-area-context: 68b07eabfb0d14547d36f6929c0e98d818064f02
react-native-slider: 6e9b86e76cce4b9e35b3403193a6432ed07e0c81
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
react-native-video: bb6f12a7198db53b261fefb5d609dc77417acc8b
react-native-webrtc: 2702afae1e59882b423e6077768ca0d1e6fc42ed
react-native-webrtc: 4d1669c2ed29767fe70b0169428b4466589ecf8b
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
React-perflogger: bc57c4a953c1ec913b0d984cf4f2b9842a12bde0
React-RCTActionSheet: 3efa3546119a1050f6c34a461b386dd9e36eaf0b
@@ -776,7 +776,7 @@ SPEC CHECKSUMS:
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
RNGoogleSignin: 22e468a9474dbcb8618d8847205ad4f0b2575d13
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
RNSVG: f3b60aeeaa81960e2e0536c3a9eef50b667ef3a9
RNWatch: dae6c858a2051dbdcfb00b9a86cf4d90400263b4

View File

@@ -197,7 +197,7 @@ static CXProviderConfiguration *_providerConfiguration = nil;
+ (BOOL)hasActiveCallForUUID:(nonnull NSString *)callUUID {
CXCall *activeCallForUUID = [[self.callController calls] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(CXCall *evaluatedObject, NSDictionary<NSString *,id> *bindings) {
return evaluatedObject.UUID.UUIDString == callUUID;
return [evaluatedObject.UUID.UUIDString isEqualToString:callUUID];
}]].firstObject;
if (!activeCallForUUID) {

View File

@@ -1,5 +1,8 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Konferenzlink: {{url}}"
},
"add": "Einladen",
"addContacts": "Laden Sie Ihre Kontakte ein",
"contacts": "Kontakte",
@@ -254,6 +257,8 @@
"WaitingForHostTitle": "Warten auf den Beginn der Konferenz …",
"Yes": "Ja",
"accessibilityLabel": {
"Cancel": "Abbrechen (Popup schließen)",
"Ok": "OK (Speichern und Popup schließen)",
"close": "Popup schließen",
"liveStreaming": "Livestream",
"sharingTabs": "Optionen zum Teilen"
@@ -459,6 +464,9 @@
"title": "Diese Konferenz einbetten"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "Ihre Auswahl: {{rating}}"
},
"average": "Durchschnittlich",
"bad": "Schlecht",
"detailsLabel": "Sagen Sie uns mehr dazu.",
@@ -1065,6 +1073,7 @@
"links": "Links",
"privacy": "Datenschutz",
"profileSection": "Profil",
"sdkVersion": "SDK-Version",
"serverURL": "Server-URL",
"showAdvanced": "Erweiterte Einstellungen anzeigen",
"startCarModeInLowBandwidthMode": "Automodus mit Datensparmodus starten",
@@ -1383,6 +1392,10 @@
"videomute": "Person hat die Kamera angehalten"
},
"virtualBackground": {
"accessibilityLabel": {
"currentBackground": "Aktueller Hintergrund: {{background}}",
"selectBackground": "Hintergrund auswählen"
},
"addBackground": "Hintergrund hinzufügen",
"apply": "Anwenden",
"backgroundEffectError": "Hintergrund konnte nicht aktiviert werden.",

File diff suppressed because it is too large Load Diff

View File

@@ -78,7 +78,6 @@
},
"carmode": {
"actions": {
"leaveMeeting": " Opuść spotkanie",
"selectSoundDevice": "Wybierz urządzenie dźwiękowe"
},
"labels": {
@@ -97,6 +96,7 @@
"messageAccessibleTitleMe": "mówię:",
"messageTo": "Prywatna wiadomość do {{recipient}}",
"messagebox": "Wpisz wiadomość",
"newMessages": "Nowe wiadomości",
"nickname": {
"popover": "Wybierz swój nick",
"title": "Wpisz swoją nazwę, aby użyć rozmowy",
@@ -107,12 +107,12 @@
"sendButton": "Wyślij",
"smileysPanel": "Panel emoji",
"tabs": {
"chat": "Chat",
"chat": "Czat",
"polls": "Ankiety"
},
"title": "Rozmowa",
"titleWithPolls": "Rozmowa",
"you": "Ty"
"title": "Czat",
"titleWithPolls": "Czat i Ankiety",
"you": "ja"
},
"chromeExtensionBanner": {
"buttonText": "Zainstaluj rozszerzenie Chrome",
@@ -137,7 +137,7 @@
"FETCH_SESSION_ID": "Uzyskiwanie id sesji...",
"GET_SESSION_ID_ERROR": "Nie można uzyskać id sesji. Błąd: {{code}}",
"GOT_SESSION_ID": "Uzyskiwanie id sesji... Gotowe",
"LOW_BANDWIDTH": "Wideo {{displayName}} zostało wyłączone w celu oszczędności zasobów"
"LOW_BANDWIDTH": "Wideo {{displayName}} zostało wyłączone w celu zaoszczędzenia przepustowości sieci"
},
"connectionindicator": {
"address": "Adres:",
@@ -147,6 +147,7 @@
"bridgeCount": "Liczba serwerów: ",
"codecs": "Kodeki (A/V): ",
"connectedTo": "Podłączone do:",
"e2eeVerified": "E2EE zweryfikowane:",
"framerate": "Klatek na sekundę:",
"less": "Pokaż mniej",
"localaddress": "Adres lokalny:",
@@ -155,6 +156,7 @@
"localport_plural": "Porty lokalne:",
"maxEnabledResolution": "wyślij maksymalną",
"more": "Pokaż więcej",
"no": "nie",
"packetloss": "Utrata pakietów:",
"participant_id": "ID uczestnika:",
"quality": {
@@ -173,7 +175,8 @@
"status": "Połączenie:",
"transport": "Transport:",
"transport_plural": "Transporty:",
"video_ssrc": "Video SSRC:"
"video_ssrc": "Video SSRC:",
"yes": "tak"
},
"dateUtils": {
"earlier": "Wcześniej",
@@ -183,13 +186,21 @@
"deepLinking": {
"appNotInstalled": "Potrzebujesz aplikacji mobilnej {{app}}, aby móc dołączyć do tego spotkania przez telefon.",
"description": "Nic się nie wydarzyło? Spróbowaliśmy uruchomić Twoje spotkanie w aplikacji stacjonarnej {{app}}. Spróbuj ponownie lub uruchom spotkanie w aplikacji webowej {{app}}.",
"descriptionNew": "Nic się nie stało? Próbowaliśmy uruchomić Twoje spotkanie w aplikacji stacjonarnej {{app}}. <br /><br /> Spróbuj ponownie lub uruchom spotkanie w aplikacji webowej.",
"descriptionWithoutWeb": "Nic się nie wydarzyło? Spróbowaliśmy uruchomić Twoje spotkanie w aplikacji stacjonarnej {{app}}.",
"downloadApp": "Pobierz aplikację",
"downloadMobileApp": "Pobierz ze sklepu App Store",
"ifDoNotHaveApp": "Jeśli nie masz jeszcze aplikacji:",
"ifHaveApp": "Jeśli już masz aplikację:",
"joinInApp": "Dołącz do spotkania używając aplikacji",
"joinInAppNew": "Dołącz w aplikacji",
"joinInBrowser": "Dołącz w przeglądarce",
"launchMeetingLabel": "Jak chcesz dołączyć do tego spotkania?",
"launchWebButton": "Uruchom przez przeglądarkę",
"noMobileApp": "Nie masz aplikacji?",
"termsAndConditions": "Kontynuując zgadzasz się na nasze <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>Zasady i Warunki.</a>",
"title": "Trwa uruchamianie Twojego spotkania w {{app}}...",
"titleNew": "Rozpoczynam spotkanie...",
"tryAgainButton": "Spróbuj ponownie w aplikacji stacjonarnej",
"unsupportedBrowser": "Wygląda na to, że używasz przeglądarki, której nie wspieramy."
},
@@ -202,6 +213,12 @@
"microphonePermission": "Błąd podczas otrzymywania uprawnień do mikrofonu"
},
"deviceSelection": {
"hid": {
"callControl": "Kontrola połączeń",
"connectedDevices": "Połączone urządzenia:",
"deleteDevice": "Usuń urządzenie",
"pairDevice": "Sparuj urządzenie"
},
"noPermission": "Nie przyznano uprawnienia",
"previewUnavailable": "Podgląd niedostępny",
"selectADevice": "Wybierz urządzenie",
@@ -225,7 +242,9 @@
"WaitingForHostTitle": "Oczekiwanie na gospodarza...",
"Yes": "Tak",
"accessibilityLabel": {
"liveStreaming": "Transmisja na żywo"
"close": "Zamknij okno dialogowe",
"liveStreaming": "Transmisja na żywo",
"sharingTabs": "Opcje udostępniania"
},
"add": "Dodaj",
"addMeetingNote": "Dodaj notatkę o tym spotkaniu",
@@ -245,7 +264,7 @@
"cameraUnsupportedResolutionError": "Twoja kamera nie obsługuje wymaganej rozdzielczości.",
"close": "Zamknij",
"conferenceDisconnectMsg": "Być może należy sprawdzić połączenie sieciowe. Ponowne połączenie za {{seconds}} sekund...",
"conferenceDisconnectTitle": "Zostałeś rozłączony.",
"conferenceDisconnectTitle": "Nastąpiło rozłączenie.",
"conferenceReloadMsg": "Staramy się to naprawić. Ponowne połączenie za {{seconds}} sekund...",
"conferenceReloadTitle": "Niestety, coś poszło nie tak.",
"confirm": "Potwierdź",
@@ -271,6 +290,7 @@
"gracefulShutdown": "Usługa aktualnie jest niedostępna. Prosze spróbować później.",
"grantModeratorDialog": "Czy na pewno chcesz przyznać temu uczestnikowi prawa moderatora?",
"grantModeratorTitle": "Przyznaj prawa moderatora",
"hide": "Ukryj",
"hideShareAudioHelper": "Nie pokazuj więcej",
"incorrectPassword": "Niepoprawna nazwa użytkownika lub hasło",
"incorrectRoomLockPassword": "Hasło nieprawidłowe",
@@ -301,8 +321,8 @@
"micPermissionDeniedError": "Nie udzieliłeś pozwolenia na użycie twojego mikrofonu. Nadal możesz uczestniczyc w konferencji ale inni nie będą cię słyszeli. Użyj przycisku kamera aby to naprawić.",
"micTimeoutError": "Nie udało się uruchomić źródła dźwięku. Przekroczono limit czasu",
"micUnknownError": "Z nieznanej przyczyny nie można użyć mikrofonu.",
"moderationAudioLabel": "Zezwalaj uczestnikom na wyłączanie wyciszenia",
"moderationVideoLabel": "Zezwalaj uczestnikom na rozpoczęcie wideo",
"moderationAudioLabel": "Zezwalaj uczestnikom na włączenie mikrofonów",
"moderationVideoLabel": "Zezwalaj uczestnikom na włączenie kamer",
"muteEveryoneDialog": "Uczestnicy mogą w dowolnym momencie wyłączyć wyciszenie.",
"muteEveryoneDialogModerationOn": "Uczestnicy mogą w każdej chwili wysłać prośbę o zabranie głosu.",
"muteEveryoneElseDialog": "Gdy wyciszysz wszystkich nie będziesz miał możliwości wyłączyć ich wyciszenia, ale oni będą mogli samodzielnie wyłączyć wyciszenie w dowolnym momencie.",
@@ -312,15 +332,15 @@
"muteEveryoneSelf": "siebie",
"muteEveryoneStartMuted": "Od tego momentu wszyscy są wyciszeni",
"muteEveryoneTitle": "Wyciszyć wszystkich?",
"muteEveryonesVideoDialog": "Uczestnicy mogą w każdej chwili włączyć swoje wideo.",
"muteEveryonesVideoDialogModerationOn": "Uczestnicy mogą w dowolnym momencie wysłać prośbę o włączenie ich wideo.",
"muteEveryonesVideoDialog": "Uczestnicy mogą w każdej chwili włączyć swoje kamery.",
"muteEveryonesVideoDialogModerationOn": "Uczestnicy mogą w dowolnym momencie wysłać prośbę o włączenie ich kamer.",
"muteEveryonesVideoDialogOk": "Wyłącz",
"muteEveryonesVideoTitle": "Wyłączyć kamery pozostałych uczestników?",
"muteParticipantBody": "Nie możesz wyłączyć ich wyciszenia, ale oni mogą samodzielnie wyłączyć wyciszenie w dowolnym momencie.",
"muteParticipantButton": "Wycisz",
"muteParticipantsVideoBody": "Nie będziesz mógł włączyć jego kamery ponownie, ale uczestnik samodzielnie może włączyć kamerę w dowolnym momencie.",
"muteParticipantsVideoBodyModerationOn": "Nie będziesz w stanie ponownie włączyć kamery i oni też nie.",
"muteParticipantsVideoButton": "Wyłącz kamerę",
"muteParticipantsVideoButton": "Wyłącz kamery",
"muteParticipantsVideoDialog": "Czy na pewno chcesz wyłączyć kamerę tego uczestnika? Nie będziesz mógł ponownie włączyć jego kamery, ale będzie on mógł samodzielnie włączyć kamerę w dowolnym momencie.",
"muteParticipantsVideoDialogModerationOn": "Czy na pewno chcesz wyłączyć kamerę tego uczestnika? Nie będziesz w stanie ponownie włączyć aparatu i oni też nie.",
"muteParticipantsVideoTitle": "Wyłączyć kamerę tego uczestnika?",
@@ -388,6 +408,7 @@
"shareYourScreenDisabled": "Udostępnianie ekranu wyłączone.",
"sharedVideoDialogError": "Błąd: nieprawidłowy adres URL",
"sharedVideoLinkPlaceholder": "Link do YouTube lub bezpośredni link do wideo",
"show": "Pokaż",
"start": "Rozpocznij ",
"startLiveStreaming": "Rozpocznij transmisję na żywo",
"startRecording": "Rozpocznij nagrywanie",
@@ -406,6 +427,10 @@
"user": "Użytkownik",
"userIdentifier": "Nazwa użytkownika",
"userPassword": "hasło użytkownika",
"verifyParticipantConfirm": "Pasują",
"verifyParticipantDismiss": "Nie pasują",
"verifyParticipantQuestion": "EKSPERYMENT: Zapytaj uczestnika {{participantName}}, czy widzi tę samą treść, w tej samej kolejności.",
"verifyParticipantTitle": "Weryfikacja użytkownika",
"videoLink": "Link do video",
"viewUpgradeOptions": "Pokaż opcje aktualizacji",
"viewUpgradeOptionsContent": "Musisz uaktualnić swój plan, aby korzystać z funkcji premium, takich jak nagrywanie, transkrypcja, przesyłanie strumieniowe RTMP i nie tylko.",
@@ -416,7 +441,7 @@
"title": "Udostępniony dokument"
},
"e2ee": {
"labelToolTip": "To połączenie audio i wideo jest szyfrowane"
"labelToolTip": "To połączenie audio i wideo jest szyfrowane end-to-end"
},
"embedMeeting": {
"title": "Osadź to spotkanie"
@@ -431,13 +456,15 @@
"veryBad": "Bardzo źle",
"veryGood": "Bardzo dobrze"
},
"filmstrip": {
"accessibilityLabel": {
"heading": "Miniatury wideo"
}
},
"giphy": {
"noResults": "Nie znaleziono wyników :(",
"search": "Szukaj GIPHY"
},
"helpView": {
"title": "Centrum pomocy"
},
"incomingCall": {
"answer": "Odbierz",
"audioCallTitle": "Przychodzące połączenie",
@@ -478,9 +505,11 @@
"noRoom": "Nie podano pokoju do wdzwonienia.",
"numbers": "Numery do wdzwonienia",
"password": "$t(lockRoomPasswordUppercase):",
"reachedLimit": "Osiągnąłeś limit swojego planu.",
"sip": "Adres SIP",
"title": "Udostępnij",
"tooltip": "Udostępnij odnośnik i informacje do wdzwonienia się na to spotkanie"
"tooltip": "Udostępnij odnośnik i informacje do wdzwonienia się na to spotkanie",
"upgradeOptions": "Sprawdź opcje aktualizacji na"
},
"inlineDialogFailure": {
"msg": "Nieco niedopisaliśmy.",
@@ -515,6 +544,10 @@
"toggleShortcuts": "Wyświetl lub ukryj skróty klawiaturowe",
"videoMute": "Uruchom lub zatrzymaj kamerę"
},
"largeVideo": {
"screenIsShared": "Udostępniasz swój ekran",
"showMeWhatImSharing": "Pokaż mi, co udostępniam"
},
"liveStreaming": {
"busy": "Pracujemy nad zwolnieniem zasobów transmisyjnych. Spróbuj ponownie za kilka minut.",
"busyTitle": "Wszyscy transmitujący są aktualnie zajęci",
@@ -555,7 +588,6 @@
"lobby": {
"admit": "Pozwól",
"admitAll": "Pozwól wszystkim",
"allow": "Zezwól",
"backToKnockModeButton": "Brak hasła, poproś o dołączenie",
"chat": "Chat",
"dialogTitle": "Lobby",
@@ -618,6 +650,7 @@
"no": "Nie",
"participant": "Uczestnik",
"participantStats": "Statystyki uczestników",
"selectTabTitle": "🎥 Wybierz tę zakładkę do nagrywania",
"sessionToken": "Token sesji",
"start": "Rozpocznij nagrywanie",
"stop": "Zatrzymaj nagrywanie",
@@ -640,8 +673,12 @@
"connectedOneMember": "{{name}} dołączył do spotkania",
"connectedThreePlusMembers": "{{name}} i {{count}} innych osób dołączyło do spotkania",
"connectedTwoMembers": "{{first}} i {{second}} dołączyli do spotkania",
"dataChannelClosed": "Pogorszona jakość wideo",
"dataChannelClosedDescription": "Kanał bridge został odłączony, przez co jakość wideo jest ograniczona do najniższego ustawienia.",
"disabledIframe": "Osadzanie jest przeznaczone wyłącznie do celów demonstracyjnych, więc to połączenie zostanie rozłączone za {{timeout}} minut.",
"disconnected": "Rozłączono",
"displayNotifications": "Wyświetlaj powiadomienia dla",
"dontRemindMe": "Nie przypominaj mi",
"focus": "Fokus konferencji",
"focusFail": "{{component}} jest niedostępny - ponowienie w ciągu {{ms}} sec",
"gifsMenu": "GIPHY",
@@ -650,6 +687,7 @@
"invitedOneMember": "{{name}} został zaproszony",
"invitedThreePlusMembers": "{{name}} i {{count}} innych osób zostało zaproszone",
"invitedTwoMembers": "{{first}} i {{second}} zostali zaproszeni",
"joinMeeting": "Dołącz",
"kickParticipant": "{{kicked}} został usunięty przez {{kicker}}",
"leftOneMember": "{{name}} opuścił spotkanie",
"leftThreePlusMembers": "{{name}} i wielu innych opuściło spotkanie",
@@ -700,7 +738,9 @@
"reactionSoundsForAll": "Wyłącz dźwięki dla wszystkich",
"screenShareNoAudio": "Opcja \"Udostępnij dźwięk\" nie została zaznaczona podczas wyboru okna.",
"screenShareNoAudioTitle": "Nie można udostępnić dźwięku",
"selfViewTitle": "Zawsze możesz odkryć własny podgląd w ustawieniach",
"screenSharingAudioOnlyDescription": "Pamiętaj, że udostępniając swój ekran, wpływasz na tryb \"Najlepsza wydajność\" i zużywasz więcej przepustowości.",
"screenSharingAudioOnlyTitle": "Tryb \"Najlepsza wydajność\"",
"selfViewTitle": "Zawsze możesz włączyć podgląd własnej kamery w ustawieniach",
"somebody": "Ktoś",
"startSilentDescription": "Ponownie dołącz do spotkania, aby włączyć dźwięk",
"startSilentTitle": "Dołączyłeś bez wyjścia dźwiękowego!",
@@ -736,7 +776,8 @@
"close": "Zamknij",
"headings": {
"lobby": "Lobby ({{count}})",
"participantsList": "Obecnych ({{count}})",
"participantsList": "Obecni uczestnicy ({{count}})",
"visitors": "Goście ({{count}})",
"waitingLobby": "Oczekujących ({{count}})"
},
"search": "Wyszukaj uczestników",
@@ -744,6 +785,7 @@
},
"passwordDigitsOnly": "Do {{number}} cyfr",
"passwordSetRemotely": "Ustawione przez innego uczestnika",
"pinParticipant": "{{participantName}} - Przypnij",
"pinnedParticipant": "Uczestnik jest przypięty",
"polls": {
"answer": {
@@ -828,9 +870,11 @@
"lookGood": "Wygląda na to, że Twój mikrofon działa poprawnie",
"or": "lub",
"premeeting": "Przed spotkaniem",
"proceedAnyway": "Kontynuuj mimo to",
"screenSharingError": "Błąd udostępniania ekranu:",
"showScreen": "Włącz ekran Przed spotkaniem",
"showScreen": "Tryb osobistej poczekalni przed spotkaniem",
"startWithPhone": "Uruchom przez telefon",
"unsafeRoomConsent": "Rozumiem ryzyko, chcę dołączyć do spotkania",
"videoOnlyError": "Błąd wideo:",
"videoTrackError": "Nie można utworzyć ścieżki wideo.",
"viewAllNumbers": "zobacz numery"
@@ -849,9 +893,6 @@
"rejected": "Odrzucony",
"ringing": "Dzwonek..."
},
"privacyView": {
"title": "Prywatność"
},
"profile": {
"avatar": "awatar",
"setDisplayNameLabel": "Podaj swoją wyświetlaną nazwę",
@@ -905,6 +946,7 @@
"localRecordingVideoWarning": "Aby nagrać film, musisz go mieć na początku nagrywania",
"localRecordingWarning": "Upewnij się, że wybrałeś bieżącą kartę, aby użyć odpowiedniego obrazu i dźwięku. Nagranie jest obecnie ograniczone do 1 GB, czyli około 100 minut.",
"loggedIn": "Zalogowano jako {{userName}}",
"noMicPermission": "Nie można utworzyć ścieżki mikrofonu. Zezwól na korzystanie z mikrofonu.",
"noStreams": "Nie wykryto strumienia audio lub wideo.",
"off": "Nagrywanie zatrzymane",
"offBy": "{{name}} zatrzymał nagrywanie",
@@ -934,10 +976,17 @@
"security": {
"about": "Możesz dodać $t(lockRoomPassword) do spotkania. Uczestnicy będą musieli wprowadzić $t(lockRoomPassword) przed dołączeniem do spotkania.",
"aboutReadOnly": "Uczestnicy posiadający uprawnienia do moderacji mogą ustawić $t(lockRoomPassword) do spotkania. Uczestnicy będą musieli wprowadzić $t(lockRoomPassword) zanim zostaną dołączeni do spotkania.",
"insecureRoomNameWarning": "Nazwa pokoju nie jest bezpieczna. Niepowołaniu uczestnicy mogą dołączyć do spotkania. Proszę rozważyć ustawienie hasła spotkania używając przycisku Opcje zabezpieczeń.",
"title": "Opcje zabezpieczeń"
"insecureRoomNameWarningNative": "Nazwa pokoju jest niebezpieczna. Niechciani uczestnicy mogą dołączyć do Twojego spotkania. {{recommendAction}} Dowiedz się więcej o zabezpieczeniu spotkania ",
"insecureRoomNameWarningWeb": "Nazwa pokoju jest niebezpieczna. Niechciani uczestnicy mogą dołączyć do Twojego spotkania. {{recommendAction}} Dowiedz się więcej o zabezpieczeniu spotkania <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">tutaj</a>.",
"title": "Opcje zabezpieczeń",
"unsafeRoomActions": {
"meeting": "Rozważ zabezpieczenie spotkania za pomocą przycisku bezpieczeństwa.",
"prejoin": "Rozważ użycie bardziej unikalnej nazwy spotkania.",
"welcome": "Rozważ użycie bardziej unikalnej nazwy spotkania lub wybierz jedną z sugestii."
}
},
"settings": {
"audio": "Audio",
"buttonLabel": "Ustawienia",
"calendar": {
"about": "{{appName}} integracji kalendarza służy do bezpiecznego dostępu do kalendarza, aby można było odczytywać nadchodzące wydarzenia.",
@@ -958,26 +1007,29 @@
"maxStageParticipants": "Maksymalna liczba uczestników, których można przypiąć do sceny głównej",
"microphones": "Mikrofony",
"moderator": "Moderacja",
"moderatorOptions": "Opcje moderatora",
"more": "Więcej",
"name": "Nazwa",
"noDevice": "Brak",
"notifications": "Powiadomienia",
"participantJoined": "Dołączył nowy uczestnik",
"participantKnocking": "Uczestnik wszedł do poczekalni",
"participantLeft": "Uczestnik opuścił spotkanie",
"playSounds": "Włącz dźwięki",
"playSounds": "Włącz powiadomienia dźwiękowe dla:",
"reactions": "Reakcje",
"sameAsSystem": "Jak system ({{label}})",
"selectAudioOutput": "Wyjście audio",
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
"selfView": "Własnego podgląd",
"sounds": "Dźwięki",
"shortcuts": "Skróty",
"speakers": "Głośniki",
"startAudioMuted": "Wycisz wszystkich dołączających",
"startReactionsMuted": "Wycisz dźwięki reakcji dla wszystkich",
"startVideoMuted": "Ukryj wszystkich dołączających",
"startVideoMuted": "Wyłącz kamery wszystkich dołączających",
"talkWhileMuted": "Jesteś wyciszony",
"title": "Ustawienia"
"title": "Ustawienia",
"video": "Wideo"
},
"settingsView": {
"advanced": "Zaawansowane",
@@ -994,6 +1046,7 @@
"displayName": "Wyświetlana nazwa",
"displayNamePlaceholderText": "Np. Jan Kowalski",
"email": "Email",
"emailPlaceholderText": "email@example.com",
"goTo": "Idź do",
"header": "Ustawienia",
"help": "Pomoc",
@@ -1002,6 +1055,7 @@
"profileSection": "Profil",
"serverURL": "Adres URL serwera",
"showAdvanced": "Pokaż ustawienia zawansowane",
"startCarModeInLowBandwidthMode": "Uruchom tryb samochodowy w trybie niskiej przepustowości",
"startWithAudioMuted": "Rozpocznij z wyciszonym dźwiękiem",
"startWithVideoMuted": "Rozpocznij z wyłączonym obrazem",
"terms": "Warunki",
@@ -1056,25 +1110,39 @@
"cc": "Przełączanie napisów",
"chat": "Przełączanie okna rozmowy",
"clap": "Klaskanie",
"closeChat": "Zamknij czat",
"closeMoreActions": "Zamknij rozszerzone menu opcji",
"closeParticipantsPane": "Zamknij okno uczestników",
"collapse": "Zwiń",
"document": "Przełączanie wspólnego dokumentu",
"documentClose": "Zamknij udostępniony dokument",
"documentOpen": "Otwórz udostępniony dokument",
"download": "Pobierz nasze aplikacje",
"embedMeeting": "Osadź spotkanie",
"endConference": "Zakończ spotkanie",
"enterFullScreen": "Wyświetl w trybie pełnego ekranu",
"enterTileView": "Wyświetl w trybie kafelkowym",
"exitFullScreen": "Zamknij tryb pełnego ekranu",
"exitTileView": "Zamknij tryb kafelkowy",
"expand": "Rozwiń",
"feedback": "Zostaw swoją opinię",
"fullScreen": "Przełączanie trybu pełnoekranowego",
"giphy": "Przełącz menu GIPHY",
"grantModerator": "Przyznaj prawa moderowania",
"hangup": "Zostaw rozmowę",
"heading": "Pasek narzędzi",
"help": "Pomoc",
"hideWhiteboard": "Ukryj tablicę",
"invite": "Zaproś uczestników",
"kick": "Usuń uczestnika",
"laugh": "Śmiech",
"leaveConference": "Opuść spotkanie",
"like": "Kciuk w górę",
"linkToSalesforce": "Link do Salesforce",
"lobbyButton": "Włącz/wyłącz tryb lobby",
"localRecording": "Przełączanie lokalnych urządzeń sterujących zapisem danych",
"lockRoom": "Przełączenie hasła spotkania",
"lowerHand": "Opuść rękę",
"moreActions": "Przełączanie menu więcej działań",
"moreActionsMenu": "Więcej działań w menu",
"moreOptions": "Pokaż więcej opcji",
@@ -1083,12 +1151,15 @@
"muteEveryoneElse": "Wycisz pozostałych",
"muteEveryoneElsesVideoStream": "Wyłącz kamery pozostałym",
"muteEveryonesVideoStream": "Wyłącz wszystkim kamery",
"muteGUMPending": "Podłączanie mikrofonu",
"noiseSuppression": "Tłumienie szumów",
"openChat": "Otwórz czat",
"participants": "Uczestnicy",
"pip": "Tryb przełączania obrazu-w-obrazie",
"privateMessage": "Wyślij wiadomość prywatną",
"profile": "Edytuj swój profil",
"raiseHand": "Przełączyć rękę w górę",
"reactions": "Reakcje",
"reactionsMenu": "Otwórz / Zamknij reakcje",
"recording": "Przełączanie nagrywania",
"remoteMute": "Wycisz uczestnika",
@@ -1102,14 +1173,20 @@
"sharedvideo": "Przełącz udostępnianie obrazu",
"shortcuts": "Przełączanie skrótów klawiszowych",
"show": "Pokaż na scenie",
"showWhiteboard": "Pokaż tablicę",
"silence": "Cisza",
"speakerStats": "Przełączanie statystyk dotyczących mówców",
"stopScreenSharing": "Zatrzymaj udostępnianie ekranu",
"stopSharedVideo": "Zatrzymaj wideo",
"surprised": "Zaskoczony",
"tileView": "Przełącz widok kafelkowy",
"toggleCamera": "Przełączanie kamery",
"toggleFilmstrip": "Przełącz filmstrip",
"unmute": "Wyłącz wyciszenie",
"videoblur": "Przełącz rozmazanie obrazu",
"videomute": "Przełączanie wyciszonego filmu wideo"
"videomute": "Przełączanie wyciszonego filmu wideo",
"videomuteGUMPending": "Podłączanie kamery",
"videounmute": "Uruchom kamerę"
},
"addPeople": "Dodaj ludzi do swojej rozmowy",
"audioOnlyOff": "Wyłącz tryb słabego łącza",
@@ -1122,6 +1199,7 @@
"chat": "Otwórz / Zamknij okno czatu",
"clap": "Klaskanie",
"closeChat": "Zamknij czat",
"closeParticipantsPane": "Zamknij okno uczestników",
"closeReactionsMenu": "Zamknij reakcje",
"disableNoiseSuppression": "Wyłącz tłumienie szumów",
"disableReactionSounds": "Wyłącz dźwięki reakcji dla tego spotkania",
@@ -1130,6 +1208,8 @@
"download": "Pobierz nasze aplikacje",
"e2ee": "Szyfrowanie End-to-End",
"embedMeeting": "Osadź spotkanie",
"enableNoiseSuppression": "Włącz tłumienie szumów",
"endConference": "Zakończ spotkanie",
"enterFullScreen": "Wyświetl na pełnym ekranie",
"enterTileView": "Wyświetl widok kafelkowy",
"exitFullScreen": "Zamknij pełny ekran",
@@ -1138,10 +1218,12 @@
"giphy": "Przełącz menu GIPHY",
"hangup": "Opuść spotkanie",
"help": "Pomoc",
"hideWhiteboard": "Ukryj tablicę",
"invite": "Zaproś uczestników",
"joinBreakoutRoom": "Dołącz do pokoju podgrupy",
"laugh": "Śmiech",
"leaveBreakoutRoom": "Opuść pokój spotkań",
"leaveConference": "Opuść spotkanie",
"like": "Kciuk w górę",
"linkToSalesforce": "Link do Salesforce",
"lobbyButtonDisable": "Wyłącz tryb lobby",
@@ -1154,6 +1236,7 @@
"mute": "Włącz / Wyłącz mikrofon",
"muteEveryone": "Wycisz wszystkich",
"muteEveryonesVideo": "Wyłącz wszystkim kamery",
"muteGUMPending": "Podłączanie mikrofonu",
"noAudioSignalDesc": "Jeżeli celowo nie wyciszyłeś mikrofonu w ustawieniach systemowych spróbuj innego urządzenia.",
"noAudioSignalDescSuggestion": "Jeżeli celowo nie wyciszyłeś mikrofonu w ustawieniach systemowych spróbuj sugerowanego urządzenia.",
"noAudioSignalDialInDesc": "Możesz się również wdzwonić korzystając z numerów:",
@@ -1176,12 +1259,14 @@
"reactionLike": "Wyślij kciuk w górę",
"reactionSilence": "Wyślij cisza",
"reactionSurprised": "Wyślij zaskoczony",
"reactions": "Reakcje",
"security": "Opcje zabezpieczeń",
"selectBackground": "Wybierz tło",
"shareRoom": "Zaproś kogoś",
"shareaudio": "Udostępnij audio",
"sharedvideo": "Udostępnij wideo",
"shortcuts": "Wyświetl skróty",
"showWhiteboard": "Pokaż tablicę",
"silence": "Cisza",
"speakerStats": "Statystyki mówców",
"startScreenSharing": "Zacznij współdzielenie ekranu",
@@ -1192,10 +1277,13 @@
"stopSubtitles": "Zatrzymaj napisy",
"surprised": "Zaskoczony",
"talkWhileMutedPopup": "Próbujesz mówić? Jesteś wyciszony.",
"tileViewToggle": "Przełączanie kafelkowego widoku",
"tileViewToggle": "Przełączanie widoku kafelkowego",
"toggleCamera": "Przełączanie kamery",
"unmute": "Wyłącz wyciszenie",
"videoSettings": "Ustawienia video",
"videomute": "Włącz / Wyłącz kamerę"
"videomute": "Włącz / Wyłącz kamerę",
"videomuteGUMPending": "Podłączanie kamery",
"videounmute": "Uruchom kamerę"
},
"transcribing": {
"ccButtonTooltip": "Uruchom / Zatrzymaj napisy",
@@ -1205,10 +1293,15 @@
"labelToolTip": "Spotkanie jest transkrybowane",
"off": "Transkrypcja została zatrzymana",
"pending": "Przygotowanie do transkrypcji spotkania...",
"sourceLanguageDesc": "Obecnie język spotkania jest ustawiony na <b>{{sourceLanguage}}</b>. <br/> Możesz to zmienić ",
"sourceLanguageHere": "tutaj",
"start": "Rozpocznij wyświetlanie napisów",
"stop": "Zatrzymaj wyświetlanie napisów",
"subtitles": "Napisy",
"subtitlesOff": "Wyłączone",
"tr": "TR"
},
"unpinParticipant": "{{participantName}} - Odepnij",
"userMedia": {
"androidGrantPermissions": "Wybierz <b><i>Pozwól</i></b>, gdy przeglądarka zapyta o pozwolenie.",
"chromeGrantPermissions": "Wybierz <b><i>Pozwól</i></b>, gdy przeglądarka zapyta o pozwolenie.",
@@ -1247,9 +1340,11 @@
"ldTooltip": "Podgląd obrazu w niskiej rozdzielczości",
"lowDefinition": "Niska rozdzielczość",
"performanceSettings": "Ustawienia wydajności",
"recording": "Trwa nagrywanie",
"sd": "SD",
"sdTooltip": "Podgląd obrazu w standardowej rozdzielczości",
"standardDefinition": "Standardowa rozdzielczość"
"standardDefinition": "Standardowa rozdzielczość",
"streaming": "Trwa transmisja"
},
"videothumbnail": {
"connectionInfo": "Informacje o połączeniu",
@@ -1261,6 +1356,7 @@
"grantModerator": "Przyznaj prawa moderatora",
"hideSelfView": "Ukryj widok własnego podglądu",
"kick": "Wyrzuć",
"mirrorVideo": "Lustrzane odbicie",
"moderator": "Moderator",
"mute": "Uczestnik ma wyciszone audio",
"muted": "Wyciszony",
@@ -1270,6 +1366,7 @@
"show": "Pokaż na scenie",
"showSelfView": "Pokaż własny widok",
"unpinFromStage": "Odepnij",
"verify": "Zweryfikuj uczestnika",
"videoMuted": "Kamera wyłączona",
"videomute": "Uczestnik zatrzymał kamerę"
},
@@ -1297,6 +1394,14 @@
"webAssemblyWarning": "WebAssembly nie jest obsługiwany",
"webAssemblyWarningDescription": "WebAssembly wyłączony lub nieobsługiwany przez tę przeglądarkę"
},
"visitors": {
"chatIndicator": "(visitor)",
"labelTooltip": "Liczba odwiedzających: {{count}}",
"notification": {
"description": "Aby wziąć udział, podnieś rękę",
"title": "Jesteś gościem na spotkaniu"
}
},
"volumeSlider": "Kontrola głośności",
"welcomepage": {
"accessibilityLabel": {
@@ -1329,6 +1434,7 @@
"microsoftLogo": "Logo Microsoftu",
"policyLogo": "Logo polityki"
},
"meetingsAccessibilityLabel": "Spotkania",
"mobileDownLoadLinkAndroid": "Pobierz appkę dla systemu Android",
"mobileDownLoadLinkFDroid": "Pobierz appkę dla systemu F-Droid",
"mobileDownLoadLinkIos": "Pobierz appkę dla systemu iOS",
@@ -1337,6 +1443,7 @@
"recentList": "Niedawno",
"recentListDelete": "Usuń",
"recentListEmpty": "Twoja ostatnia lista jest obecnie pusta. Rozmawiaj ze swoim zespołem, a wszystkie ostatnie spotkania znajdziesz tutaj.",
"recentMeetings": "Twoje ostatnie spotkania",
"reducedUIText": "Witamy w {{app}}!",
"roomNameAllowedChars": "Nazwa spotkania nie powinna zawierać znaków: ?, &, :, ', \", %, #.",
"roomname": "Podaj nazwę sali konferencyjnej",
@@ -1345,6 +1452,12 @@
"settings": "Ustawienia",
"startMeeting": "Rozpocznij spotkanie",
"terms": "Warunki korzystania",
"title": "Bezpieczna, w pełni funkcjonalna i całkowicie bezpłatna wideokonferencja"
"title": "Bezpieczna, w pełni funkcjonalna i całkowicie bezpłatna wideokonferencja",
"upcomingMeetings": "Twoje nadchodzące spotkania"
},
"whiteboard": {
"accessibilityLabel": {
"heading": "Tablica"
}
}
}

View File

@@ -1,5 +1,8 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Link da reunião: {{url}}"
},
"add": "Convidar",
"addContacts": "Convidar os seus contactos",
"contacts": "contactos",
@@ -39,6 +42,18 @@
"audioOnly": {
"audioOnly": "Largura de banda baixa"
},
"bandwidthSettings": {
"assumedBandwidthBps": "p. ex. 10000000 para 10 Mbps",
"assumedBandwidthBpsWarning": "Valores mais elevados podem causar problemas na rede.",
"customValue": "valor personalizado",
"customValueEffect": "para definir o valor actual de bps",
"leaveEmpty": "deixar em branco",
"leaveEmptyEffect": "para permitir a realização de estimativas",
"possibleValues": "Valores possíveis",
"setAssumedBandwidthBps": "Largura de banda presumida (bps)",
"title": "Definições de largura de banda",
"zeroEffect": "para desligar o vídeo"
},
"breakoutRooms": {
"actions": {
"add": "Adicionar salas simultâneas",
@@ -242,6 +257,8 @@
"WaitingForHostTitle": "À espera do anfitrião ...",
"Yes": "Sim",
"accessibilityLabel": {
"Cancel": "Cancelar (sair da caixa de diálogo)",
"Ok": "OK (guardar e sair da caixa de diálogo)",
"close": "Fechar caixa de diálogo",
"liveStreaming": "Transmissão em direto",
"sharingTabs": "Opções de partilha"
@@ -447,6 +464,9 @@
"title": "Incorporar esta reunião"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "A sua escolha: {{rating}}"
},
"average": "Média",
"bad": "Má",
"detailsLabel": "Conte-nos mais sobre isso.",
@@ -1151,6 +1171,7 @@
"muteEveryoneElse": "Silenciar todos os outros",
"muteEveryoneElsesVideo": "Parar o vídeo de todos os outros",
"muteEveryonesVideo": "Parar o vídeo de todos",
"muteGUMPending": "A ligar o seu microfone",
"noiseSuppression": "Supressão de ruído",
"openChat": "Abrir chat",
"participants": "Abrir painel de participantes",
@@ -1184,6 +1205,7 @@
"unmute": "Ligar microfone",
"videoblur": "Mudar o desfoque de vídeo",
"videomute": "Parar câmara",
"videomuteGUMPending": "A ligar a sua câmara",
"videounmute": "Iniciar câmara"
},
"addPeople": "Adicione pessoas à sua chamada",
@@ -1234,6 +1256,7 @@
"mute": "Desligar microfone",
"muteEveryone": "Silenciar todos",
"muteEveryonesVideo": "Desativar a câmara de todos",
"muteGUMPending": "A ligar o seu microfone",
"noAudioSignalDesc": "Se não o silenciou propositadamente a partir de configurações do sistema ou hardware, considere mudar de dispositivo.",
"noAudioSignalDescSuggestion": "Se não o silenciou propositadamente a partir das configurações do sistema ou hardware, considere mudar para o dispositivo sugerido.",
"noAudioSignalDialInDesc": "Também pode marcar usando:",
@@ -1279,6 +1302,7 @@
"unmute": "Ligar microfone",
"videoSettings": "Definições de vídeo",
"videomute": "Parar câmara",
"videomuteGUMPending": "A ligar a sua câmara",
"videounmute": "Iniciar câmara"
},
"transcribing": {
@@ -1325,7 +1349,7 @@
"audioOnly": "AUD",
"audioOnlyExpanded": "Está em modo de baixa largura de banda. Neste modo, receberá apenas partilha de áudio e ecrã.",
"bestPerformance": "Melhor desempenho",
"callQuality": "Qualidade de vídeo",
"callQuality": "Qualidade de vídeo (0 para o melhor desempenho, 3 para a melhor qualidade)",
"hd": "HD",
"hdTooltip": "Ver vídeo em alta definição",
"highDefinition": "Alta definição (HD)",
@@ -1367,6 +1391,10 @@
"videomute": "Participante parou a câmara"
},
"virtualBackground": {
"accessibilityLabel": {
"currentBackground": "Atual imagem de fundo: {{background}}",
"selectBackground": "Selecionar uma imagem de fundo"
},
"addBackground": "Adicionar imagem de fundo",
"apply": "Aplicar",
"backgroundEffectError": "Falha ao aplicar efeito de fundo.",

View File

@@ -1073,13 +1073,14 @@
"links": "Links",
"privacy": "Privacy",
"profileSection": "Profile",
"sdkVersion": "SDK version",
"serverURL": "Server URL",
"showAdvanced": "Show advanced settings",
"startCarModeInLowBandwidthMode": "Start car mode in low bandwidth mode",
"startWithAudioMuted": "Start with audio muted",
"startWithVideoMuted": "Start with video muted",
"terms": "Terms",
"version": "Version"
"version": "App version"
},
"share": {
"dialInfoText": "\n\n=====\n\nJust want to dial in on your phone?\n\n{{defaultDialInNumber}}Click this link to see the dial in phone numbers for this meeting\n{{dialInfoPageUrl}}",

View File

@@ -396,7 +396,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
const frameName = `jitsiConferenceFrame${id}`;
this._frame = document.createElement('iframe');
this._frame.allow = 'camera; microphone; display-capture; autoplay; clipboard-write; hid';
this._frame.allow = 'camera; microphone; display-capture; autoplay; clipboard-write; hid; screen-wake-lock';
this._frame.name = frameName;
this._frame.id = frameName;
this._setSize(height, width);

252
package-lock.json generated
View File

@@ -31,11 +31,11 @@
"@react-native-community/netinfo": "7.1.7",
"@react-native-community/slider": "4.1.12",
"@react-native-google-signin/google-signin": "9.0.2",
"@react-navigation/bottom-tabs": "6.5.3",
"@react-navigation/elements": "1.3.13",
"@react-navigation/material-top-tabs": "6.5.2",
"@react-navigation/native": "6.1.2",
"@react-navigation/stack": "6.3.11",
"@react-navigation/bottom-tabs": "6.5.8",
"@react-navigation/elements": "1.3.18",
"@react-navigation/material-top-tabs": "6.6.3",
"@react-navigation/native": "6.1.7",
"@react-navigation/stack": "6.3.17",
"@svgr/webpack": "6.3.1",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
@@ -60,14 +60,14 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
"punycode": "2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
@@ -89,8 +89,8 @@
"react-native-pager-view": "5.4.9",
"react-native-paper": "5.1.2",
"react-native-performance": "2.1.0",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.13.1",
"react-native-safe-area-context": "4.6.4",
"react-native-screens": "3.22.0",
"react-native-sound": "0.11.1",
"react-native-splash-screen": "3.3.0",
"react-native-svg": "12.4.3",
@@ -99,7 +99,7 @@
"react-native-url-polyfill": "1.3.0",
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
"react-native-watch-connectivity": "1.0.11",
"react-native-webrtc": "111.0.1",
"react-native-webrtc": "111.0.3",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
@@ -4704,11 +4704,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"node_modules/@react-navigation/bottom-tabs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.3.tgz",
"integrity": "sha512-ZA2Ko9fNwNaaSNn7738KpEk8Doi+yjRfTg8Wb/WvduIaK/28qNLAYWBCUEVjBC55y/9zJOzwc4R8Av2J2MG/4g==",
"version": "6.5.8",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz",
"integrity": "sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg==",
"dependencies": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -4749,11 +4749,11 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-navigation/core": {
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
"integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"version": "6.4.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.9.tgz",
"integrity": "sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g==",
"dependencies": {
"@react-navigation/routers": "^6.1.6",
"@react-navigation/routers": "^6.1.9",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.23",
"query-string": "^7.1.3",
@@ -4770,9 +4770,9 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/@react-navigation/elements": {
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
"integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA==",
"version": "1.3.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q==",
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
@@ -4781,9 +4781,9 @@
}
},
"node_modules/@react-navigation/material-top-tabs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.5.2.tgz",
"integrity": "sha512-i/R3bEXVE5pygWP0dOMdFNOVzrQyHXL0lbqLfQx5HZXwbvCrpUBFqOED3bWLBrBOUhHQSXfYgTuteAfIF5hzzg==",
"version": "6.6.3",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.6.3.tgz",
"integrity": "sha512-7rbBUUvVSKD8jV/a7iV2BTSQ83G7W8grGSwBNojdeXdeZpsUa+wmmKnPtBFhdPv7DDQp7nzAYRx6RCOPtjZSCw==",
"dependencies": {
"color": "^4.2.3",
"warn-once": "^0.1.0"
@@ -4825,11 +4825,11 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-navigation/native": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
"integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.7.tgz",
"integrity": "sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw==",
"dependencies": {
"@react-navigation/core": "^6.4.6",
"@react-navigation/core": "^6.4.9",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
@@ -4840,19 +4840,19 @@
}
},
"node_modules/@react-navigation/routers": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz",
"integrity": "sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==",
"version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
"integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==",
"dependencies": {
"nanoid": "^3.1.23"
}
},
"node_modules/@react-navigation/stack": {
"version": "6.3.11",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
"integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"version": "6.3.17",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.17.tgz",
"integrity": "sha512-8/8ZvJROK3fp6PRmQ9MrXd9epBowA8NkfCaWW/N9H5arqwNX9lTXAkmcjicRhjpX+UNlMBR9dTLkWvPRe2vY9A==",
"dependencies": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -6681,14 +6681,6 @@
"node": ">=0.4.0"
}
},
"node_modules/adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
"engines": {
"node": ">=6.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -7793,6 +7785,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"optional": true,
"engines": {
"node": ">=10"
}
@@ -10541,6 +10534,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
@@ -12768,8 +12762,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"integrity": "sha512-HtLhGkrSHEztTcMZ1iJmG7a5Bj8KvsT8bGL/h3G+4kro5JRp/E40XJPPWiaGT0e9av4RQZa4u1giSgF/50ssoQ==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"integrity": "sha512-uGRFpvKj6FSDhVHWvMerNwzaLflUrHQLXiP7Py0ITqV5Ix0d+hTFw9+OgI/JXzdBM3SLOP3GVNQLQfNR45oveA==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -13894,6 +13888,7 @@
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -13905,6 +13900,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"optional": true,
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@@ -14013,9 +14009,15 @@
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -15403,9 +15405,9 @@
}
},
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
"engines": {
"node": ">=6"
}
@@ -15863,18 +15865,18 @@
}
},
"node_modules/react-native-safe-area-context": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz",
"integrity": "sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA==",
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.6.4.tgz",
"integrity": "sha512-UWYsokTLZmj8g0cluzoUeGUjQrCTW4slKr2xKmuwQCurAuvSJq/QvfhCrqyea++XrXo46+1Q3wSoP50YXG24jA==",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-screens": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.13.1.tgz",
"integrity": "sha512-xcrnuUs0qUrGpc2gOTDY4VgHHADQwp80mwR1prU/Q0JqbZN5W3koLhuOsT6FkSRKjR5t40l+4LcjhHdpqRB2HA==",
"version": "3.22.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.22.0.tgz",
"integrity": "sha512-csLypBSXIt/egh37YJmokETptZJCtZdoZBsZNLR9n31GesDyVogprT+MM22dEPDuxPxt/mFWq+lSpVwk7khuTw==",
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -16027,15 +16029,13 @@
}
},
"node_modules/react-native-webrtc": {
"version": "111.0.1",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.1.tgz",
"integrity": "sha512-yMRmLFtKRDXaK5b/s92+ArsMElEEjZnGW2cE+GqTHxLka0Kj0qq/sgNS2sMTuJuZRhW4oT6ryMLwTYzIrGM1lQ==",
"version": "111.0.3",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.3.tgz",
"integrity": "sha512-flharkWM5QTSlik+ppK5tf5W86IeabHnrMI7bKkhUJJyibDDMz6X3ReH3dtHWFbiRjDGLktZ4FGwqOCGhL68DA==",
"dependencies": {
"adm-zip": "0.5.9",
"base64-js": "1.5.1",
"debug": "4.3.4",
"event-target-shim": "6.0.2",
"tar": "6.1.11"
"event-target-shim": "6.0.2"
},
"peerDependencies": {
"react-native": ">=0.60.0"
@@ -17962,6 +17962,7 @@
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"optional": true,
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -17978,6 +17979,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
@@ -18798,9 +18800,12 @@
}
},
"node_modules/use-latest-callback": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.5.tgz",
"integrity": "sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ=="
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz",
"integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg==",
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/use-sidecar": {
"version": "1.1.2",
@@ -19809,7 +19814,8 @@
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
},
"node_modules/yaml": {
"version": "1.10.2",
@@ -23148,11 +23154,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"@react-navigation/bottom-tabs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.3.tgz",
"integrity": "sha512-ZA2Ko9fNwNaaSNn7738KpEk8Doi+yjRfTg8Wb/WvduIaK/28qNLAYWBCUEVjBC55y/9zJOzwc4R8Av2J2MG/4g==",
"version": "6.5.8",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz",
"integrity": "sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg==",
"requires": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -23182,11 +23188,11 @@
}
},
"@react-navigation/core": {
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
"integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"version": "6.4.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.9.tgz",
"integrity": "sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g==",
"requires": {
"@react-navigation/routers": "^6.1.6",
"@react-navigation/routers": "^6.1.9",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.23",
"query-string": "^7.1.3",
@@ -23202,14 +23208,14 @@
}
},
"@react-navigation/elements": {
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
"integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA=="
"version": "1.3.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q=="
},
"@react-navigation/material-top-tabs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.5.2.tgz",
"integrity": "sha512-i/R3bEXVE5pygWP0dOMdFNOVzrQyHXL0lbqLfQx5HZXwbvCrpUBFqOED3bWLBrBOUhHQSXfYgTuteAfIF5hzzg==",
"version": "6.6.3",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.6.3.tgz",
"integrity": "sha512-7rbBUUvVSKD8jV/a7iV2BTSQ83G7W8grGSwBNojdeXdeZpsUa+wmmKnPtBFhdPv7DDQp7nzAYRx6RCOPtjZSCw==",
"requires": {
"color": "^4.2.3",
"warn-once": "^0.1.0"
@@ -23240,30 +23246,30 @@
}
},
"@react-navigation/native": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
"integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.7.tgz",
"integrity": "sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw==",
"requires": {
"@react-navigation/core": "^6.4.6",
"@react-navigation/core": "^6.4.9",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
}
},
"@react-navigation/routers": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz",
"integrity": "sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==",
"version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
"integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==",
"requires": {
"nanoid": "^3.1.23"
}
},
"@react-navigation/stack": {
"version": "6.3.11",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
"integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"version": "6.3.17",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.17.tgz",
"integrity": "sha512-8/8ZvJROK3fp6PRmQ9MrXd9epBowA8NkfCaWW/N9H5arqwNX9lTXAkmcjicRhjpX+UNlMBR9dTLkWvPRe2vY9A==",
"requires": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -24658,11 +24664,6 @@
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true
},
"adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg=="
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -25510,7 +25511,8 @@
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"optional": true
},
"chrome-trace-event": {
"version": "1.0.3",
@@ -27612,6 +27614,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"optional": true,
"requires": {
"minipass": "^3.0.0"
}
@@ -29266,8 +29269,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"integrity": "sha512-HtLhGkrSHEztTcMZ1iJmG7a5Bj8KvsT8bGL/h3G+4kro5JRp/E40XJPPWiaGT0e9av4RQZa4u1giSgF/50ssoQ==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"integrity": "sha512-uGRFpvKj6FSDhVHWvMerNwzaLflUrHQLXiP7Py0ITqV5Ix0d+hTFw9+OgI/JXzdBM3SLOP3GVNQLQfNR45oveA==",
"requires": {
"@jitsi/js-utils": "2.0.0",
"@jitsi/logger": "2.0.0",
@@ -30167,6 +30170,7 @@
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
"optional": true,
"requires": {
"yallist": "^4.0.0"
}
@@ -30175,6 +30179,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"optional": true,
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@@ -30263,9 +30268,9 @@
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
},
"nanomatch": {
"version": "1.2.13",
@@ -31286,9 +31291,9 @@
}
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
},
"qs": {
"version": "6.9.7",
@@ -31609,14 +31614,14 @@
"integrity": "sha512-Q3dFPN7whBCY7X8nvQe7TBw4F5g1PyB78KwyKDXpJENcDrBodlFtj9/c5T2ZkRwAPb+bxr39b+lq9FyT6WQWtg=="
},
"react-native-safe-area-context": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz",
"integrity": "sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA=="
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.6.4.tgz",
"integrity": "sha512-UWYsokTLZmj8g0cluzoUeGUjQrCTW4slKr2xKmuwQCurAuvSJq/QvfhCrqyea++XrXo46+1Q3wSoP50YXG24jA=="
},
"react-native-screens": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.13.1.tgz",
"integrity": "sha512-xcrnuUs0qUrGpc2gOTDY4VgHHADQwp80mwR1prU/Q0JqbZN5W3koLhuOsT6FkSRKjR5t40l+4LcjhHdpqRB2HA==",
"version": "3.22.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.22.0.tgz",
"integrity": "sha512-csLypBSXIt/egh37YJmokETptZJCtZdoZBsZNLR9n31GesDyVogprT+MM22dEPDuxPxt/mFWq+lSpVwk7khuTw==",
"requires": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -31725,15 +31730,13 @@
}
},
"react-native-webrtc": {
"version": "111.0.1",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.1.tgz",
"integrity": "sha512-yMRmLFtKRDXaK5b/s92+ArsMElEEjZnGW2cE+GqTHxLka0Kj0qq/sgNS2sMTuJuZRhW4oT6ryMLwTYzIrGM1lQ==",
"version": "111.0.3",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.3.tgz",
"integrity": "sha512-flharkWM5QTSlik+ppK5tf5W86IeabHnrMI7bKkhUJJyibDDMz6X3ReH3dtHWFbiRjDGLktZ4FGwqOCGhL68DA==",
"requires": {
"adm-zip": "0.5.9",
"base64-js": "1.5.1",
"debug": "4.3.4",
"event-target-shim": "6.0.2",
"tar": "6.1.11"
"event-target-shim": "6.0.2"
},
"dependencies": {
"base64-js": {
@@ -33172,6 +33175,7 @@
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"optional": true,
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -33184,7 +33188,8 @@
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"optional": true
}
}
},
@@ -33774,9 +33779,9 @@
}
},
"use-latest-callback": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.5.tgz",
"integrity": "sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ=="
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz",
"integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg=="
},
"use-sidecar": {
"version": "1.1.2",
@@ -34497,7 +34502,8 @@
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
},
"yaml": {
"version": "1.10.2",

View File

@@ -36,11 +36,11 @@
"@react-native-community/netinfo": "7.1.7",
"@react-native-community/slider": "4.1.12",
"@react-native-google-signin/google-signin": "9.0.2",
"@react-navigation/bottom-tabs": "6.5.3",
"@react-navigation/elements": "1.3.13",
"@react-navigation/material-top-tabs": "6.5.2",
"@react-navigation/native": "6.1.2",
"@react-navigation/stack": "6.3.11",
"@react-navigation/bottom-tabs": "6.5.8",
"@react-navigation/elements": "1.3.18",
"@react-navigation/material-top-tabs": "6.6.3",
"@react-navigation/native": "6.1.7",
"@react-navigation/stack": "6.3.17",
"@svgr/webpack": "6.3.1",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
@@ -65,14 +65,14 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
"punycode": "2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
@@ -94,8 +94,8 @@
"react-native-pager-view": "5.4.9",
"react-native-paper": "5.1.2",
"react-native-performance": "2.1.0",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.13.1",
"react-native-safe-area-context": "4.6.4",
"react-native-screens": "3.22.0",
"react-native-sound": "0.11.1",
"react-native-splash-screen": "3.3.0",
"react-native-svg": "12.4.3",
@@ -104,7 +104,7 @@
"react-native-url-polyfill": "1.3.0",
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
"react-native-watch-connectivity": "1.0.11",
"react-native-webrtc": "111.0.1",
"react-native-webrtc": "111.0.3",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",

View File

@@ -1,3 +1,2 @@
package-lock=true
; FIXME Set legacy-peer-deps=false when we upgrade RN.
legacy-peer-deps=true

View File

@@ -1,7 +0,0 @@
module.exports = {
androidSourcePath: '../android/sdk/src/main/java/org/jitsi/meet/sdk',
androidTargetPath: './android/src/main/java/org/jitsi/meet/sdk',
iosSrcPath: '../ios/sdk/src',
iosDestPath: './ios/src'
};

View File

@@ -1,8 +0,0 @@
/**
* Converts the meetingOptions domain and roomName to a URL that can be passed to the App component.
* @param {*} domain domain address from props.
* @param {*} roomName room name from props.
*/
export function convertPropsToURL(domain, roomName) {
return `${domain}/${roomName}`;
}

View File

@@ -4,18 +4,17 @@ import 'react-native-gesture-handler';
// Apply all necessary polyfills as early as possible
// to make sure anything imported henceforth sees them.
import 'react-native-get-random-values';
import '../react/features/mobile/polyfills';
import './react/features/mobile/polyfills';
// @ts-ignore
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { View } from 'react-native';
import { convertPropsToURL } from '../functions';
import { appNavigate } from '../react/features/app/actions.native';
import { App } from '../react/features/app/components/App.native';
import { setAudioMuted, setVideoMuted } from '../react/features/base/media/actions';
import { appNavigate } from './react/features/app/actions.native';
import { App } from './react/features/app/components/App.native';
import { setAudioMuted, setVideoMuted } from './react/features/base/media/actions';
// @ts-ignore
import JitsiThemePaperProvider from '../react/features/base/ui/components/JitsiThemeProvider';
import JitsiThemePaperProvider from './react/features/base/ui/components/JitsiThemeProvider.native';
interface IAppProps {
@@ -40,7 +39,7 @@ interface IAppProps {
/**
* Main React Native SDK component that displays a Jitsi Meet conference and gets all required params as props
*/
const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref) => {
export const JitsiMeeting = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref) => {
const [ appProps, setAppProps ] = useState({});
const app = useRef(null);
@@ -65,7 +64,7 @@ const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref)
useEffect(
() => {
const url = convertPropsToURL(meetingOptions.domain, meetingOptions.roomName);
const url = `${meetingOptions.domain}/${meetingOptions.roomName}`;
setAppProps({
'url': {
@@ -95,5 +94,3 @@ const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref)
</View>
);
});
export default JitsiMeet;

View File

@@ -3,7 +3,7 @@ require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = package['name']
s.name = 'jitsi-meet-rnsdk'
s.version = package['version']
s.summary = package['description']
s.description = package['description']

File diff suppressed because it is too large Load Diff

View File

@@ -2,51 +2,50 @@
"name": "@jitsi/react-native-sdk",
"version": "0.1.0",
"description": "React Native SDK for Jitsi Meet.",
"main": "index.js",
"main": "index.tsx",
"license": "Apache-2.0",
"author": "",
"homepage": "https://jitsi.org",
"repository": {
"type": "git",
"url": "git://github.com/jitsi/jitsi-meet.git"
"url": "git+https://github.com/jitsi/jitsi-meet.git"
},
"dependencies": {
"@amplitude/react-native": "2.7.0",
"@giphy/react-components": "6.8.1",
"@giphy/react-native-sdk": "2.3.0",
"@hapi/bourne": "2.0.0",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.0",
"@jitsi/rtcstats": "9.5.1",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
"@react-navigation/bottom-tabs": "6.5.3",
"@react-navigation/elements": "1.3.13",
"@react-navigation/material-top-tabs": "6.5.2",
"@react-navigation/native": "6.1.2",
"@react-navigation/stack": "6.3.11",
"@react-navigation/bottom-tabs": "6.5.8",
"@react-navigation/elements": "1.3.18",
"@react-navigation/material-top-tabs": "6.6.3",
"@react-navigation/native": "6.1.7",
"@react-navigation/stack": "6.3.17",
"@xmldom/xmldom": "0.8.7",
"base64-js": "1.3.1",
"grapheme-splitter": "1.0.4",
"i18n-iso-countries": "6.8.0",
"i18next": "17.0.6",
"i18next-browser-languagedetector": "3.0.1",
"i18next-xhr-backend": "3.0.0",
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1652.0.0+90da4884/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
"punycode": "2.3.0",
"react-emoji-render": "1.2.4",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native-callstats": "3.73.7",
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
"react-native-svg-transformer": "1.0.0",
"react-native-tab-view": "3.1.1",
"react-native-url-polyfill": "1.3.0",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
"react-window": "1.8.6",
"react-youtube": "10.1.0",
"redux": "4.0.4",
"redux-thunk": "2.4.1",
"unorm": "1.6.0",
@@ -55,40 +54,36 @@
"zxcvbn": "4.4.2"
},
"peerDependencies": {
"@react-native-async-storage/async-storage": "1.17.3",
"@amplitude/react-native": "2.7.0",
"@giphy/react-native-sdk": "2.3.0",
"@react-native-async-storage/async-storage": "1.18.2",
"@react-native-community/clipboard": "1.5.1",
"@react-native-community/netinfo": "7.1.7",
"@react-native-community/slider": "4.1.12",
"@react-native-google-signin/google-signin": "7.0.4",
"@react-native-masked-view/masked-view": "0.2.6",
"react-native": "*",
"react": "*",
"react-dom": "*",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-callstats": "3.73.7",
"react-native-collapsible": "1.6.0",
"react-native-default-preference": "1.4.4",
"react-native-device-info": "8.4.8",
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
"react-native-get-random-values": "1.7.2",
"react-native-gesture-handler": "2.9.0",
"react-native-immersive": "2.0.0",
"react-native-keep-awake": "4.0.0",
"react-native-pager-view": "5.4.9",
"react-native-paper": "4.11.1",
"react-native-performance": "2.1.0",
"react-native-orientation-locker": "1.5.0",
"react-native-orientation-locker": "https://git@github.com/wonday/react-native-orientation-locker#f483520ea6b64b97002374a9e9f053a5299a062a",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.22.0",
"react-native-sound": "0.11.1",
"react-native-splash-screen": "3.3.0",
"react-native-svg": "12.4.3",
"react-native-svg-transformer": "1.0.0",
"react-native-tab-view": "3.1.1",
"react-native-url-polyfill": "1.3.0",
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
"react-native-watch-connectivity": "1.0.11",
"react-native-webrtc": "111.0.0",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1"
"react-native-webrtc": "111.0.1",
"react-native-webview": "11.15.1"
},
"overrides": {
"strophe.js@1.5.0": {
@@ -96,6 +91,7 @@
}
},
"scripts": {
"postinstall": "node sdk_instructions.js",
"prepare": "node prepare_sdk.js"
},
"bugs": {

View File

@@ -3,14 +3,13 @@ const path = require('path');
const packageJSON = require('../package.json');
const {
androidSourcePath,
androidTargetPath,
iosDestPath,
iosSrcPath
} = require('./constants.ts');
const SDKPackageJSON = require('./package.json');
const androidSourcePath = '../android/sdk/src/main/java/org/jitsi/meet/sdk';
const androidTargetPath = './android/src/main/java/org/jitsi/meet/sdk';
const iosSrcPath = '../ios/sdk/src';
const iosDestPath = './ios/src';
/**
* Copies a specified file in a way that recursive copy is possible.

2
react-native-sdk/sdk_instructions.js vendored Normal file
View File

@@ -0,0 +1,2 @@
console.log('Run node node_modules/@jitsi/react-native-sdk/update_dependencies.js '
+ 'script to update the necessary dependencies');

58
react-native-sdk/update_dependencies.js vendored Normal file
View File

@@ -0,0 +1,58 @@
/* eslint-disable guard-for-in */
/* global __dirname */
const fs = require('fs');
const path = require('path');
const pathToPackageJSON = path.resolve(__dirname, '../../../package.json');
const packageJSON = require(pathToPackageJSON);
const RNSDKpackageJSON = require(path.resolve(__dirname, './package.json'));
/**
* Updates dependencies from the app package.json with the peer dependencies of the RNSDK package.json.
*/
function updateDependencies() {
let updated = false;
for (const key in RNSDKpackageJSON.peerDependencies) {
if (!packageJSON.dependencies.hasOwnProperty(key)) {
packageJSON.dependencies[key] = RNSDKpackageJSON.peerDependencies[key];
updated = true;
}
}
if (!updated) {
return;
}
console.log(`
=========================
The following dependencies were added to your package.json:
\n
${Object.keys(packageJSON.dependencies)}
\n
Make sure you run npm install
If you are building for ios run cd ios && pod install to link them.
=========================
`);
packageJSON.dependencies = Object.keys(packageJSON.dependencies)
.sort()
.reduce((item, itemKey) => {
item[itemKey] = packageJSON.dependencies[itemKey];
return item;
}, {});
const data = JSON.stringify(packageJSON, null, 2);
fs.writeFileSync(pathToPackageJSON, data);
console.log(
'All needed dependencies have been updated. \nPlease run npm install.'
);
}
updateDependencies();

View File

@@ -441,10 +441,10 @@ export interface IConfig {
opusMaxAverageBitrate?: number;
p2p?: {
backToP2PDelay?: number;
disabledCodec?: string;
codecPreferenceOrder?: Array<string>;
enabled?: boolean;
iceTransportPolicy?: string;
preferredCodec?: string;
mobileCodecPreferenceOrder?: Array<string>;
stunServers?: Array<{ urls: string; }>;
};
participantsPane?: {
@@ -545,8 +545,7 @@ export interface IConfig {
useHostPageLocalStorage?: boolean;
useTurnUdp?: boolean;
videoQuality?: {
disabledCodec?: string;
enforcePreferredCodec?: boolean;
codecPreferenceOrder?: Array<string>;
maxBitratesVideo?: {
[key: string]: {
high?: number;
@@ -557,8 +556,8 @@ export interface IConfig {
minHeightForQualityLvl?: {
[key: number]: string;
};
mobileCodecPreferenceOrder?: Array<string>;
persist?: boolean;
preferredCodec?: string;
};
webhookProxyUrl?: string;
webrtcIceTcpDisable?: boolean;

View File

@@ -195,7 +195,6 @@ export default [
'p2p',
'participantsPane',
'pcStatsInterval',
'preferredCodec',
'prejoinConfig',
'prejoinPageEnabled',
'recordingService',

View File

@@ -43,18 +43,6 @@ const INITIAL_NON_RN_STATE: IConfig = {
* @type {Object}
*/
const INITIAL_RN_STATE: IConfig = {
// FIXME: Mobile codecs should probably be configurable separately, rather
// FIXME: than requiring this override here...
p2p: {
disabledCodec: 'vp9',
preferredCodec: 'h264'
},
videoQuality: {
disabledCodec: 'vp9',
preferredCodec: 'vp8'
}
};
/**

View File

@@ -192,7 +192,7 @@ export const brandedDialog = {
*/
ColorSchemeRegistry.register('Dialog', {
button: {
backgroundColor: schemeColor('buttonBackground'),
backgroundColor: '#44A5FF',
flex: 1,
padding: BoxModel.padding * 1.5
},

View File

@@ -160,6 +160,11 @@ const _LANGUAGES = {
main: require('../../../../lang/main-tr')
},
// Ukrainian
'uk': {
main: require('../../../../lang/main-uk')
},
// Vietnamese
'vi': {
main: require('../../../../lang/main-vi')

View File

@@ -54,8 +54,7 @@ function _overwriteLocalParticipant(
{ avatarURL?: string; email?: string; features?: any; id?: string; name?: string; }) {
let localParticipant;
if ((avatarURL || email || name)
&& (localParticipant = getLocalParticipant(getState))) {
if ((avatarURL || email || name || features) && (localParticipant = getLocalParticipant(getState))) {
const newProperties: IParticipant = {
id: localParticipant.id,
local: true

View File

@@ -282,7 +282,7 @@ class Popover extends Component<IProps, IState> {
// Use the `enabled` prop instead of conditionally rendering ReactFocusOn
// to prevent UI stutter on dialog appearance. It seems the focus guards generated annoy
// our DialogPortal positioning calculations.
enabled = { this.state.enableFocusLock }
enabled = { Boolean(this._contextMenuRef) && this.state.enableFocusLock }
returnFocus = {
// If we return the focus to an element outside the viewport the page will scroll to
@@ -294,7 +294,7 @@ class Popover extends Component<IProps, IState> {
// large video.
isElementInTheViewport
}
shards = { [ this._contextMenuRef ] }>
shards = { this._contextMenuRef && [ this._contextMenuRef ] }>
{this._renderContent()}
</FocusOn>
</DialogPortal>
@@ -325,7 +325,9 @@ class Popover extends Component<IProps, IState> {
* @returns {void}
*/
_setContextMenuRef(elem: HTMLElement) {
this._contextMenuRef = elem;
if (!elem || document.body.contains(elem)) {
this._contextMenuRef = elem;
}
}
/**

View File

@@ -1,9 +1,9 @@
import punycode from 'punycode';
import React, { Component } from 'react';
import ReactLinkify from 'react-linkify';
import { Text } from 'react-native';
import { StyleType } from '../../../styles/functions.any';
import { formatURLText } from '../../functions';
import Link from './Link';
@@ -72,7 +72,7 @@ export default class Linkify extends Component<IProps> {
key = { key }
style = { this.props.linkStyle }
url = { decoratedHref }>
{ punycode.toASCII(decoratedText) }
{ formatURLText(decoratedText) }
</Link>
);
}

View File

@@ -1,7 +1,8 @@
import punycode from 'punycode';
import React, { Component, ReactNode } from 'react';
import ReactLinkify from 'react-linkify';
import { formatURLText } from '../../functions';
interface IProps {
/**
@@ -43,7 +44,7 @@ export default class Linkify extends Component<IProps> {
key = { key }
rel = 'noopener noreferrer'
target = '_blank'>
{ punycode.toASCII(decoratedText) }
{ formatURLText(decoratedText) }
</a>
);
}

View File

@@ -1,3 +1,5 @@
import punycode from 'punycode';
/**
* Returns the field value in a platform generic way.
*
@@ -7,3 +9,41 @@
export function getFieldValue(fieldParameter: { target: { value: string; }; } | string) {
return typeof fieldParameter === 'string' ? fieldParameter : fieldParameter?.target?.value;
}
/**
* Formats the URL text for react-linkify.
*
* @param {string} text - The URL text.
* @returns {string} - The formatted text.
*/
export function formatURLText(text = '') {
let result;
// In order to prevent homograph attacks we need to use punycode. Reference
// https://github.com/tasti/react-linkify/issues/84. In the same time it seems PunycodeJS will treat the URL
// as an email when there is '@' and will erase parts of it. This is problematic if there is a URL like
// https://example.com/@test@@@123/test@test, punycode will truncate this to https://example.com/@test which
// is security issue because parts of the URL are actually missing from the text that we display. That's why
// we use punycode on valid URLs(that don't have '@' as part of the host) only for the host part of the URL.
try {
const url = new URL(text);
const { host } = url;
if (host) {
url.host = punycode.toASCII(host);
result = url.toString();
}
} catch (e) {
// Not a valid URL
}
if (!result) {
// This will be the case for invalid URLs or URLs without a host (emails for example). In this case beacuse
// of the issue with PunycodeJS that truncates parts of the text when there is '@' we split the text by '@'
// and use punycode for every separate part to prevent homograph attacks.
result = text.split('@').map(punycode.toASCII)
.join('@');
}
return result;
}

View File

@@ -1,7 +1,3 @@
import Platform from '../react/Platform';
import { ColorPalette } from './components/styles/ColorPalette';
declare type StyleSheet = {
[key: string]: string | number | { [key: string]: string | number; };
};
@@ -121,28 +117,6 @@ export function createStyleSheet(
return combinedStyles;
}
/**
* Works around a bug in react-native or react-native-webrtc on Android which
* causes Views overlaying RTCView to be clipped. Even though we (may) display
* multiple RTCViews, it is enough to apply the fix only to a View with a
* bounding rectangle containing all RTCviews and their overlaying Views.
*
* @param {StyleSheet} styles - An object which represents a stylesheet.
* @public
* @returns {StyleSheet}
*/
export function fixAndroidViewClipping<T extends StyleSheet>(styles: T): T {
if (Platform.OS === 'android') {
// @ts-ignore
styles.borderColor = ColorPalette.appBackground;
// @ts-ignore
styles.borderWidth = 1;
}
return styles;
}
/**
* Returns an rgba format of the provided color if it's in hex or rgb format.
*

View File

@@ -180,11 +180,10 @@ const BaseDialog = ({
return (
<div className = { cx(classes.container, isUnmounting && 'unmount') }>
<div
className = { classes.backdrop }
onClick = { onBackdropClick } />
<div className = { classes.backdrop } />
<FocusOn
className = { classes.focusLock }
onClickOutside = { onBackdropClick }
returnFocus = {
// If we return the focus to an element outside the viewport the page will scroll to

View File

@@ -1,10 +1,14 @@
import React from 'react';
import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconMessage } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { closeOverflowMenuIfOpen } from '../../../toolbox/actions.web';
import { toggleChat } from '../../actions.web';
import ChatCounter from './ChatCounter';
@@ -59,6 +63,24 @@ class ChatButton extends AbstractButton<IProps> {
</div>
);
}
/**
* Handles clicking the button, and toggles the chat.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch } = this.props;
sendAnalytics(createToolbarEvent(
'toggle.chat',
{
enable: !this.props._chatOpen
}));
dispatch(closeOverflowMenuIfOpen());
dispatch(toggleChat());
}
}
/**

View File

@@ -1,4 +1,3 @@
import { fixAndroidViewClipping } from '../../../base/styles/functions.native';
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
export const INSECURE_ROOM_NAME_LABEL_COLOR = BaseTheme.palette.actionDanger;
@@ -38,11 +37,11 @@ export default {
/**
* {@code Conference} Style.
*/
conference: fixAndroidViewClipping({
conference: {
alignSelf: 'stretch',
backgroundColor: BaseTheme.palette.uiBackground,
flex: 1
}),
},
displayNameContainer: {
margin: 10

View File

@@ -176,7 +176,7 @@ function _conferenceJoined({ dispatch, getState }: IStore) {
function _checkIframe(state: IReduxState, dispatch: IStore['dispatch']) {
let allowIframe = false;
if (document.referrer === '') {
if (document.referrer === '' && browser.isElectron()) {
// no iframe
allowIframe = true;
} else {

View File

@@ -2,10 +2,13 @@ import { connect } from 'react-redux';
import { createToolbarEvent } from '../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../analytics/functions';
import { IReduxState } from '../../app/types';
import { openDialog } from '../../base/dialog/actions';
import { isMobileBrowser } from '../../base/environment/utils';
import { translate } from '../../base/i18n/functions';
import { IconCode } from '../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../base/toolbox/components/AbstractButton';
import { isVpaasMeeting } from '../../jaas/functions';
import EmbedMeetingDialog from './EmbedMeetingDialog';
@@ -32,4 +35,16 @@ class EmbedMeetingButton extends AbstractButton<AbstractButtonProps> {
}
}
export default translate(connect()(EmbedMeetingButton));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: !isVpaasMeeting(state) && !isMobileBrowser()
};
};
export default translate(connect(mapStateToProps)(EmbedMeetingButton));

View File

@@ -45,8 +45,11 @@ class FeedbackButton extends AbstractButton<IProps> {
}
const mapStateToProps = (state: IReduxState) => {
const { callStatsID } = state['features/base/config'];
return {
_conference: state['features/base/conference'].conference
_conference: state['features/base/conference'].conference,
visible: Boolean(callStatsID)
};
};

View File

@@ -2,11 +2,14 @@ import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n/functions';
import { IconShortcuts } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { openSettingsDialog } from '../../../settings/actions';
import { SETTINGS_TABS } from '../../../settings/constants';
import { areKeyboardShortcutsEnabled } from '../../functions';
/**
* Implementation of a button for opening keyboard shortcuts dialog.
@@ -31,4 +34,16 @@ class KeyboardShortcutsButton extends AbstractButton<AbstractButtonProps> {
}
}
export default translate(connect()(KeyboardShortcutsButton));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: !isMobileBrowser() && areKeyboardShortcutsEnabled(state)
};
};
export default translate(connect(mapStateToProps)(KeyboardShortcutsButton));

View File

@@ -33,7 +33,7 @@ export const getPriorityFocusedElement = (): HTMLElement | null =>
*/
export const getKeyboardKey = (e: KeyboardEvent): string => {
// @ts-ignore
const { altKey, code, key, shiftKey, type, which } = e;
const { altKey, code, key, shiftKey, type, which, ctrlKey } = e;
// If alt is pressed a different char can be returned so this takes
// the char from the code. It also prefixes with a colon to differentiate
@@ -50,6 +50,10 @@ export const getKeyboardKey = (e: KeyboardEvent): string => {
// keyboard key. To be safe, when a key is "Unidentified" it must be
// further analyzed by jitsi to a key using e.which.
if (typeof key === 'string' && key !== 'Unidentified') {
if (ctrlKey) {
return `-${key}`;
}
return key;
}

View File

@@ -5,6 +5,10 @@ import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconUsers } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import {
close as closeParticipantsPane,
open as openParticipantsPane
} from '../../../participants-pane/actions.web';
import ParticipantsCounter from './ParticipantsCounter';
@@ -41,6 +45,22 @@ class ParticipantsPaneButton extends AbstractButton<IProps> {
return this.props._isOpen;
}
/**
* Handles clicking the button, and toggles the participants pane.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch, _isOpen } = this.props;
if (_isOpen) {
dispatch(closeParticipantsPane());
} else {
dispatch(openParticipantsPane());
}
}
/**
* Overrides AbstractButton's {@link Component#render()}.
*

View File

@@ -1,8 +1,11 @@
import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconRaiseHand } from '../../../base/icons/svg';
import { raiseHand } from '../../../base/participants/actions';
import { getLocalParticipant, hasRaisedHand } from '../../../base/participants/functions';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
@@ -40,6 +43,22 @@ class RaiseHandButton extends AbstractButton<IProps> {
_isToggled() {
return this.props.raisedHand;
}
/**
* Handles clicking the button, and toggles the raise hand.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch, raisedHand } = this.props;
sendAnalytics(createToolbarEvent(
'raise.hand',
{ enable: !raisedHand }));
dispatch(raiseHand(!raisedHand));
}
}

View File

@@ -0,0 +1,26 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { IReduxState } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { isReactionsButtonEnabled, isReactionsEnabled } from '../../functions.web';
import RaiseHandButton from './RaiseHandButton';
import ReactionsMenuButton from './ReactionsMenuButton';
const RaiseHandContainerButton = (props: AbstractButtonProps) => {
const reactionsButtonEnabled = useSelector(isReactionsButtonEnabled);
const reactionsEnabled = useSelector(isReactionsEnabled);
const isNarrowLayout = useSelector((state: IReduxState) => state['features/base/responsive-ui'].isNarrowLayout);
const showReactionsAsPartOfRaiseHand
= !reactionsButtonEnabled && reactionsEnabled && !isNarrowLayout && !isMobileBrowser();
return showReactionsAsPartOfRaiseHand
? <ReactionsMenuButton
{ ...props }
showRaiseHand = { true } />
: <RaiseHandButton { ...props } />;
};
export default RaiseHandContainerButton;

View File

@@ -1,11 +1,15 @@
import React, { ReactElement, useCallback } from 'react';
import React, { ReactElement, useCallback, useMemo } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { connect, useSelector } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState, IStore } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n/functions';
import { IconArrowUp, IconFaceSmile } from '../../../base/icons/svg';
import { raiseHand } from '../../../base/participants/actions';
import { getLocalParticipant, hasRaisedHand } from '../../../base/participants/functions';
import AbstractButton, { type IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import ToolboxButtonWithPopup from '../../../base/toolbox/components/web/ToolboxButtonWithPopup';
import { toggleReactionsMenuVisibility } from '../../actions.web';
@@ -30,6 +34,11 @@ interface IProps extends WithTranslation {
*/
_reactionsButtonEnabled: boolean;
/**
* Whether or not the reactions are enabled.
*/
_reactionsEnabled: boolean;
/**
* The button's key.
*/
@@ -40,11 +49,6 @@ interface IProps extends WithTranslation {
*/
dispatch: IStore['dispatch'];
/**
* Click handler for raise hand functionality.
*/
handleClick: Function;
/**
* Whether or not it's narrow mode or mobile browser.
*/
@@ -65,6 +69,11 @@ interface IProps extends WithTranslation {
* The array of reactions to be displayed.
*/
reactionsQueue: Array<IReactionEmojiProps>;
/**
* Whether or not to show the raise hand button.
*/
showRaiseHand?: boolean;
}
@@ -88,14 +97,15 @@ const ReactionsButton = translate(connect()(ReactionsButtonImpl));
*/
function ReactionsMenuButton({
_reactionsButtonEnabled,
_reactionsEnabled,
_isMobile,
buttonKey,
dispatch,
handleClick,
isOpen,
isNarrow,
notifyMode,
reactionsQueue,
showRaiseHand,
t
}: IProps) {
const toggleReactionsMenu = useCallback(() => {
@@ -110,26 +120,27 @@ function ReactionsMenuButton({
isOpen && toggleReactionsMenu();
}, [ isOpen, toggleReactionsMenu ]);
const localParticipant = useSelector(getLocalParticipant);
const raisedHand = useMemo(() => hasRaisedHand(localParticipant), [ localParticipant ]);
const handleClick = useCallback(() => {
sendAnalytics(createToolbarEvent(
'raise.hand',
{ enable: !raisedHand }));
dispatch(raiseHand(!raisedHand));
}, [ raisedHand ]);
if (!showRaiseHand && (!_reactionsButtonEnabled || !_reactionsEnabled)) {
return null;
}
const reactionsMenu = (<div className = 'reactions-menu-container'>
<ReactionsMenu parent = { IReactionsMenuParent.Button } />
</div>);
let content: ReactElement | null = null;
if (_reactionsButtonEnabled) {
content = (
<ToolboxButtonWithPopup
ariaLabel = { t('toolbar.accessibilityLabel.reactionsMenu') }
onPopoverClose = { closeReactionsMenu }
onPopoverOpen = { openReactionsMenu }
popoverContent = { reactionsMenu }
trigger = { _isMobile ? 'click' : undefined }
visible = { isOpen }>
<ReactionsButton
buttonKey = { buttonKey }
notifyMode = { notifyMode } />
</ToolboxButtonWithPopup>);
} else {
if (showRaiseHand) {
content = isNarrow
? (
<RaiseHandButton
@@ -150,6 +161,19 @@ function ReactionsMenuButton({
handleClick = { handleClick }
notifyMode = { notifyMode } />
</ToolboxButtonWithPopup>);
} else {
content = (
<ToolboxButtonWithPopup
ariaLabel = { t('toolbar.accessibilityLabel.reactionsMenu') }
onPopoverClose = { closeReactionsMenu }
onPopoverOpen = { openReactionsMenu }
popoverContent = { reactionsMenu }
trigger = { _isMobile ? 'click' : undefined }
visible = { isOpen }>
<ReactionsButton
buttonKey = { buttonKey }
notifyMode = { notifyMode } />
</ToolboxButtonWithPopup>);
}
return (

View File

@@ -82,7 +82,7 @@ function _deleteRecentListEntry(
* @returns {Object}
*/
function _storeCurrentConference(state: IRecentListState, { locationURL }: { locationURL: { href: string; }; }) {
const conference = locationURL.href;
const conference = getURLWithoutParamsNormalized(new URL(locationURL.href));
// If the current conference is already in the list, we remove it to re-add
// it to the top.

View File

@@ -3,10 +3,11 @@ import { connect } from 'react-redux';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconVolumeOff, IconVolumeUp } from '../../../base/icons/svg';
import JitsiMeetJS from '../../../base/lib-jitsi-meet';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { setOverflowMenuVisible } from '../../../toolbox/actions.web';
import { startAudioScreenShareFlow } from '../../actions.web';
import { isAudioOnlySharing } from '../../functions';
import { isAudioOnlySharing, isScreenAudioSupported } from '../../functions';
interface IProps extends AbstractButtonProps {
@@ -62,7 +63,8 @@ class ShareAudioButton extends AbstractButton<IProps> {
function _mapStateToProps(state: IReduxState) {
return {
_isAudioOnlySharing: Boolean(isAudioOnlySharing(state))
_isAudioOnlySharing: Boolean(isAudioOnlySharing(state)),
visible: JitsiMeetJS.isDesktopSharingEnabled() && isScreenAudioSupported()
};
}

View File

@@ -385,6 +385,14 @@ class SettingsView extends Component<IProps, IState> {
{`${AppInfo.version} build ${AppInfo.buildNumber}`}
</Text>
</FormRow>
{/* @ts-ignore */}
<Divider style = { styles.fieldSeparator } />
<FormRow
label = 'settingsView.sdkVersion'>
<Text style = { styles.text }>
{AppInfo.sdkVersion}
</Text>
</FormRow>
</FormSection>
<FormSection
label = 'settingsView.advanced'>

View File

@@ -2,8 +2,10 @@ import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { openDialog } from '../../../base/dialog/actions';
import { translate } from '../../../base/i18n/functions';
import { isSpeakerStatsDisabled } from '../../functions';
import AbstractSpeakerStatsButton from '../AbstractSpeakerStatsButton';
import SpeakerStats from './SpeakerStats';
@@ -28,4 +30,16 @@ class SpeakerStatsButton extends AbstractSpeakerStatsButton {
}
}
export default translate(connect()(SpeakerStatsButton));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: !isSpeakerStatsDisabled(state)
};
};
export default translate(connect(mapStateToProps)(SpeakerStatsButton));

View File

@@ -264,3 +264,17 @@ export function setToolboxTimeout(handler: Function, timeoutMS: number) {
});
};
}
/**
* Closes the overflow menu if opened.
*
* @private
* @returns {void}
*/
export function closeOverflowMenuIfOpen() {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const { overflowMenuVisible } = getState()['features/toolbox'];
overflowMenuVisible && dispatch(setOverflowMenuVisible(false));
};
}

View File

@@ -79,7 +79,7 @@ function DialogPortal({ children, className, style, getRef, setSize, targetSelec
getRef(portalTarget);
portalTarget.style.zIndex = `${ZINDEX_DIALOG_PORTAL}`;
}
}, [ portalTarget ]);
}, [ portalTarget, getRef ]);
useEffect(() => {
const size = {

View File

@@ -1,9 +1,13 @@
import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { isIosMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n/functions';
import { IconEnterFullscreen, IconExitFullscreen } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { closeOverflowMenuIfOpen, setFullScreen } from '../../actions.web';
interface IProps extends AbstractButtonProps {
@@ -36,6 +40,25 @@ class FullscreenButton extends AbstractButton<IProps> {
_isToggled() {
return this.props._fullScreen;
}
/**
* Handles clicking the button, and toggles fullscreen.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch, _fullScreen } = this.props;
sendAnalytics(createToolbarEvent(
'toggle.fullscreen',
{
enable: !_fullScreen
}));
dispatch(closeOverflowMenuIfOpen());
dispatch(setFullScreen(!_fullScreen));
}
}
/**
@@ -46,7 +69,8 @@ class FullscreenButton extends AbstractButton<IProps> {
*/
const mapStateToProps = (state: IReduxState) => {
return {
_fullScreen: state['features/toolbox'].fullScreen
_fullScreen: state['features/toolbox'].fullScreen,
visible: !isIosMobileBrowser()
};
};

View File

@@ -2,11 +2,13 @@ import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { openDialog } from '../../../base/dialog/actions';
import { translate } from '../../../base/i18n/functions';
import { IconCloudUpload } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import SalesforceLinkDialog from '../../../salesforce/components/web/SalesforceLinkDialog';
import { isSalesforceEnabled } from '../../../salesforce/functions';
/**
* Implementation of a button for opening the Salesforce link dialog.
@@ -31,4 +33,16 @@ class LinkToSalesforce extends AbstractButton<AbstractButtonProps> {
}
}
export default translate(connect()(LinkToSalesforce));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: isSalesforceEnabled(state)
};
};
export default translate(connect(mapStateToProps)(LinkToSalesforce));

View File

@@ -103,13 +103,14 @@ class ProfileButton extends AbstractButton<IProps> {
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
const { defaultLocalDisplayName } = state['features/base/config'];
const { defaultLocalDisplayName, disableProfile } = state['features/base/config'];
return {
_defaultLocalDisplayName: defaultLocalDisplayName ?? '',
_localParticipant: getLocalParticipant(state),
_unclickable: !interfaceConfig.SETTINGS_SECTIONS.includes('profile'),
customClass: 'profile-button-avatar'
customClass: 'profile-button-avatar',
visible: !disableProfile
};
};

View File

@@ -1,11 +1,15 @@
import { connect } from 'react-redux';
import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconScreenshare, IconStopScreenshare } from '../../../base/icons/svg';
import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { startScreenShareFlow } from '../../../screen-share/actions.web';
import { isScreenVideoShared } from '../../../screen-share/functions';
import { closeOverflowMenuIfOpen } from '../../actions.web';
import { isDesktopShareButtonDisabled } from '../../functions';
interface IProps extends AbstractButtonProps {
@@ -72,6 +76,23 @@ class ShareDesktopButton extends AbstractButton<IProps> {
_isDisabled() {
return !this.props._desktopSharingEnabled;
}
/**
* Handles clicking the button, and toggles the chat.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch, _screensharing } = this.props;
sendAnalytics(createToolbarEvent(
'toggle.screen.sharing',
{ enable: !_screensharing }));
dispatch(closeOverflowMenuIfOpen());
dispatch(startScreenShareFlow(!_screensharing));
}
}
/**
@@ -88,7 +109,8 @@ const mapStateToProps = (state: IReduxState) => {
return {
_desktopSharingEnabled: desktopSharingEnabled,
_screensharing: isScreenVideoShared(state)
_screensharing: isScreenVideoShared(state),
visible: JitsiMeetJS.isDesktopSharingEnabled()
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,43 @@ import { hasAvailableDevices } from '../base/devices/functions';
import { MEET_FEATURES } from '../base/jwt/constants';
import { isJwtFeatureEnabled } from '../base/jwt/functions';
import { IGUMPendingState } from '../base/media/types';
import ChatButton from '../chat/components/web/ChatButton';
import EmbedMeetingButton from '../embed-meeting/components/EmbedMeetingButton';
import SharedDocumentButton from '../etherpad/components/SharedDocumentButton.web';
import FeedbackButton from '../feedback/components/FeedbackButton.web';
import InviteButton from '../invite/components/add-people-dialog/web/InviteButton';
import KeyboardShortcutsButton from '../keyboard-shortcuts/components/web/KeyboardShortcutsButton';
import NoiseSuppressionButton from '../noise-suppression/components/NoiseSuppressionButton';
import ParticipantsPaneButton from '../participants-pane/components/web/ParticipantsPaneButton';
import RaiseHandContainerButton from '../reactions/components/web/RaiseHandContainerButtons';
import ReactionsMenuButton from '../reactions/components/web/ReactionsMenuButton';
import LiveStreamButton from '../recording/components/LiveStream/web/LiveStreamButton';
import RecordButton from '../recording/components/Recording/web/RecordButton';
import ShareAudioButton from '../screen-share/components/web/ShareAudioButton';
import { isScreenMediaShared } from '../screen-share/functions';
import SecurityDialogButton from '../security/components/security-dialog/web/SecurityDialogButton';
import SettingsButton from '../settings/components/web/SettingsButton';
import SharedVideoButton from '../shared-video/components/web/SharedVideoButton';
import SpeakerStatsButton from '../speaker-stats/components/web/SpeakerStatsButton';
import ClosedCaptionButton from '../subtitles/components/web/ClosedCaptionButton';
import TileViewButton from '../video-layout/components/TileViewButton';
import VideoQualityButton from '../video-quality/components/VideoQualityButton.web';
import VideoBackgroundButton from '../virtual-background/components/VideoBackgroundButton';
import WhiteboardButton from '../whiteboard/components/web/WhiteboardButton';
import { isWhiteboardVisible } from '../whiteboard/functions';
import DownloadButton from './components/DownloadButton';
import HelpButton from './components/HelpButton';
import AudioSettingsButton from './components/web/AudioSettingsButton';
import CustomOptionButton from './components/web/CustomOptionButton';
import FullscreenButton from './components/web/FullscreenButton';
import LinkToSalesforceButton from './components/web/LinkToSalesforceButton';
import ProfileButton from './components/web/ProfileButton';
import ShareDesktopButton from './components/web/ShareDesktopButton';
import ToggleCameraButton from './components/web/ToggleCameraButton';
import VideoSettingsButton from './components/web/VideoSettingsButton';
import { TOOLBAR_TIMEOUT } from './constants';
import { IToolboxButton } from './types';
export * from './functions.any';
@@ -158,3 +191,255 @@ export function getToolbarTimeout(state: IReduxState) {
return toolbarConfig?.timeout || TOOLBAR_TIMEOUT;
}
/**
* Returns all buttons that could be rendered.
*
* @param {Object} _customToolbarButtons - An array containing custom buttons objects.
* @returns {Object} The button maps mainMenuButtons and overflowMenuButtons.
*/
export function getAllToolboxButtons(_customToolbarButtons?: {
icon: string;
id: string;
text: string;
}[]): { [key: string]: IToolboxButton; } {
const microphone = {
key: 'microphone',
Content: AudioSettingsButton,
group: 0
};
const camera = {
key: 'camera',
Content: VideoSettingsButton,
group: 0
};
const profile = {
key: 'profile',
Content: ProfileButton,
group: 1
};
const chat = {
key: 'chat',
Content: ChatButton,
group: 2
};
const desktop = {
key: 'desktop',
Content: ShareDesktopButton,
group: 2
};
// In Narrow layout and mobile web we are using drawer for popups and that is why it is better to include
// all forms of reactions in the overflow menu. Otherwise the toolbox will be hidden and the reactions popup
// misaligned.
const raisehand = {
key: 'raisehand',
Content: RaiseHandContainerButton,
group: 2
};
const reactions = {
key: 'reactions',
Content: ReactionsMenuButton,
group: 2
};
const participants = {
key: 'participants-pane',
Content: ParticipantsPaneButton,
group: 2
};
const invite = {
key: 'invite',
Content: InviteButton,
group: 2
};
const tileview = {
key: 'tileview',
Content: TileViewButton,
group: 2
};
const toggleCamera = {
key: 'toggle-camera',
Content: ToggleCameraButton,
group: 2
};
const videoQuality = {
key: 'videoquality',
Content: VideoQualityButton,
group: 2
};
const fullscreen = {
key: 'fullscreen',
Content: FullscreenButton,
group: 2
};
const security = {
key: 'security',
alias: 'info',
Content: SecurityDialogButton,
group: 2
};
const cc = {
key: 'closedcaptions',
Content: ClosedCaptionButton,
group: 2
};
const recording = {
key: 'recording',
Content: RecordButton,
group: 2
};
const livestreaming = {
key: 'livestreaming',
Content: LiveStreamButton,
group: 2
};
const linkToSalesforce = {
key: 'linktosalesforce',
Content: LinkToSalesforceButton,
group: 2
};
const shareVideo = {
key: 'sharedvideo',
Content: SharedVideoButton,
group: 3
};
const shareAudio = {
key: 'shareaudio',
Content: ShareAudioButton,
group: 3
};
const noiseSuppression = {
key: 'noisesuppression',
Content: NoiseSuppressionButton,
group: 3
};
const whiteboard = {
key: 'whiteboard',
Content: WhiteboardButton,
group: 3
};
const etherpad = {
key: 'etherpad',
Content: SharedDocumentButton,
group: 3
};
const virtualBackground = {
key: 'select-background',
Content: VideoBackgroundButton,
group: 3
};
const speakerStats = {
key: 'stats',
Content: SpeakerStatsButton,
group: 3
};
const settings = {
key: 'settings',
Content: SettingsButton,
group: 4
};
const shortcuts = {
key: 'shortcuts',
Content: KeyboardShortcutsButton,
group: 4
};
const embed = {
key: 'embedmeeting',
Content: EmbedMeetingButton,
group: 4
};
const feedback = {
key: 'feedback',
Content: FeedbackButton,
group: 4
};
const download = {
key: 'download',
Content: DownloadButton,
group: 4
};
const help = {
key: 'help',
Content: HelpButton,
group: 4
};
const customButtons = _customToolbarButtons?.reduce((prev, { icon, id, text }) => {
return {
...prev,
[id]: {
key: id,
Content: CustomOptionButton,
group: 4,
icon,
text
}
};
}, {});
return {
microphone,
camera,
profile,
desktop,
chat,
raisehand,
reactions,
participants,
invite,
tileview,
toggleCamera,
videoQuality,
fullscreen,
security,
cc,
recording,
livestreaming,
linkToSalesforce,
shareVideo,
shareAudio,
noiseSuppression,
whiteboard,
etherpad,
virtualBackground,
speakerStats,
settings,
shortcuts,
embed,
feedback,
download,
help,
...customButtons
};
}

View File

@@ -0,0 +1,310 @@
import { useEffect } from 'react';
import { batch, useDispatch, useSelector } from 'react-redux';
import { ACTION_SHORTCUT_TRIGGERED, createShortcutEvent } from '../analytics/AnalyticsEvents';
import { sendAnalytics } from '../analytics/functions';
import { IReduxState } from '../app/types';
import { getToolbarButtons, isToolbarButtonEnabled } from '../base/config/functions.web';
import { toggleDialog } from '../base/dialog/actions';
import JitsiMeetJS from '../base/lib-jitsi-meet';
import { raiseHand } from '../base/participants/actions';
import { getLocalParticipant, hasRaisedHand } from '../base/participants/functions';
import { toggleChat } from '../chat/actions.web';
import { setGifMenuVisibility } from '../gifs/actions';
import { isGifEnabled } from '../gifs/function.any';
import { registerShortcut, unregisterShortcut } from '../keyboard-shortcuts/actions.any';
import {
close as closeParticipantsPane,
open as openParticipantsPane
} from '../participants-pane/actions.web';
import { getParticipantsPaneOpen } from '../participants-pane/functions';
import { addReactionToBuffer } from '../reactions/actions.any';
import { toggleReactionsMenuVisibility } from '../reactions/actions.web';
import { REACTIONS } from '../reactions/constants';
import { isReactionsEnabled } from '../reactions/functions.any';
import { startScreenShareFlow } from '../screen-share/actions.web';
import { isScreenVideoShared } from '../screen-share/functions';
import SpeakerStats from '../speaker-stats/components/web/SpeakerStats';
import { isSpeakerStatsDisabled } from '../speaker-stats/functions';
import { toggleTileView } from '../video-layout/actions.any';
import { shouldDisplayTileView } from '../video-layout/functions.any';
import VideoQualityDialog from '../video-quality/components/VideoQualityDialog.web';
import { setFullScreen } from './actions.web';
import { isDesktopShareButtonDisabled } from './functions.web';
export const useKeyboardShortcuts = (toolbarButtons: Array<string>) => {
const dispatch = useDispatch();
const _isSpeakerStatsDisabled = useSelector(isSpeakerStatsDisabled);
const _toolbarButtons = useSelector((state: IReduxState) => toolbarButtons || getToolbarButtons(state));
const chatOpen = useSelector((state: IReduxState) => state['features/chat'].isOpen);
const desktopSharingButtonDisabled = useSelector(isDesktopShareButtonDisabled);
const desktopSharingEnabled = JitsiMeetJS.isDesktopSharingEnabled();
const fullScreen = useSelector((state: IReduxState) => state['features/toolbox'].fullScreen);
const gifsEnabled = useSelector(isGifEnabled);
const localParticipant = useSelector(getLocalParticipant);
const participantsPaneOpen = useSelector(getParticipantsPaneOpen);
const raisedHand = hasRaisedHand(localParticipant);
const reactionsEnabled = useSelector(isReactionsEnabled);
const screenSharing = useSelector(isScreenVideoShared);
const tileViewEnabled = useSelector(shouldDisplayTileView);
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling the display of chat.
*
* @private
* @returns {void}
*/
function onToggleChat() {
sendAnalytics(createShortcutEvent(
'toggle.chat',
ACTION_SHORTCUT_TRIGGERED,
{
enable: !chatOpen
}));
// Checks if there was any text selected by the user.
// Used for when we press simultaneously keys for copying
// text messages from the chat board
if (window.getSelection()?.toString() !== '') {
return false;
}
dispatch(toggleChat());
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling the display of the participants pane.
*
* @private
* @returns {void}
*/
function onToggleParticipantsPane() {
sendAnalytics(createShortcutEvent(
'toggle.participants-pane',
ACTION_SHORTCUT_TRIGGERED,
{
enable: !participantsPaneOpen
}));
if (participantsPaneOpen) {
dispatch(closeParticipantsPane());
} else {
dispatch(openParticipantsPane());
}
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling the display of Video Quality.
*
* @private
* @returns {void}
*/
function onToggleVideoQuality() {
sendAnalytics(createShortcutEvent('video.quality'));
dispatch(toggleDialog(VideoQualityDialog));
}
/**
* Dispatches an action for toggling the tile view.
*
* @private
* @returns {void}
*/
function onToggleTileView() {
sendAnalytics(createShortcutEvent(
'toggle.tileview',
ACTION_SHORTCUT_TRIGGERED,
{
enable: !tileViewEnabled
}));
dispatch(toggleTileView());
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling full screen mode.
*
* @private
* @returns {void}
*/
function onToggleFullScreen() {
sendAnalytics(createShortcutEvent(
'toggle.fullscreen',
ACTION_SHORTCUT_TRIGGERED,
{
enable: !fullScreen
}));
dispatch(setFullScreen(!fullScreen));
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling raise hand.
*
* @private
* @returns {void}
*/
function onToggleRaiseHand() {
sendAnalytics(createShortcutEvent(
'toggle.raise.hand',
ACTION_SHORTCUT_TRIGGERED,
{ enable: !raisedHand }));
dispatch(raiseHand(!raisedHand));
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling screensharing.
*
* @private
* @returns {void}
*/
function onToggleScreenshare() {
// Ignore the shortcut if the button is disabled.
if (desktopSharingButtonDisabled) {
return;
}
sendAnalytics(createShortcutEvent(
'toggle.screen.sharing',
ACTION_SHORTCUT_TRIGGERED,
{
enable: !screenSharing
}));
if (desktopSharingEnabled && !desktopSharingButtonDisabled) {
dispatch(startScreenShareFlow(!screenSharing));
}
}
/**
* Creates an analytics keyboard shortcut event and dispatches an action for
* toggling speaker stats.
*
* @private
* @returns {void}
*/
function onSpeakerStats() {
sendAnalytics(createShortcutEvent(
'speaker.stats'
));
dispatch(toggleDialog(SpeakerStats, {
conference: APP.conference
}));
}
useEffect(() => {
const KEYBOARD_SHORTCUTS = [
isToolbarButtonEnabled('videoquality', _toolbarButtons) && {
character: 'A',
exec: onToggleVideoQuality,
helpDescription: 'toolbar.callQuality'
},
isToolbarButtonEnabled('chat', _toolbarButtons) && {
character: 'C',
exec: onToggleChat,
helpDescription: 'keyboardShortcuts.toggleChat'
},
isToolbarButtonEnabled('desktop', _toolbarButtons) && {
character: 'D',
exec: onToggleScreenshare,
helpDescription: 'keyboardShortcuts.toggleScreensharing'
},
isToolbarButtonEnabled('participants-pane', _toolbarButtons) && {
character: 'P',
exec: onToggleParticipantsPane,
helpDescription: 'keyboardShortcuts.toggleParticipantsPane'
},
isToolbarButtonEnabled('raisehand', _toolbarButtons) && {
character: 'R',
exec: onToggleRaiseHand,
helpDescription: 'keyboardShortcuts.raiseHand'
},
isToolbarButtonEnabled('fullscreen', _toolbarButtons) && {
character: 'S',
exec: onToggleFullScreen,
helpDescription: 'keyboardShortcuts.fullScreen'
},
isToolbarButtonEnabled('tileview', _toolbarButtons) && {
character: 'W',
exec: onToggleTileView,
helpDescription: 'toolbar.tileViewToggle'
},
!_isSpeakerStatsDisabled && isToolbarButtonEnabled('stats', _toolbarButtons) && {
character: 'T',
exec: onSpeakerStats,
helpDescription: 'keyboardShortcuts.showSpeakerStats'
}
];
KEYBOARD_SHORTCUTS.forEach(shortcut => {
if (typeof shortcut === 'object') {
dispatch(registerShortcut({
character: shortcut.character,
handler: shortcut.exec,
helpDescription: shortcut.helpDescription
}));
}
});
if (reactionsEnabled) {
const REACTION_SHORTCUTS = Object.keys(REACTIONS).map(key => {
const onShortcutSendReaction = () => {
dispatch(addReactionToBuffer(key));
sendAnalytics(createShortcutEvent(
`reaction.${key}`
));
};
return {
character: REACTIONS[key].shortcutChar,
exec: onShortcutSendReaction,
helpDescription: `toolbar.reaction${key.charAt(0).toUpperCase()}${key.slice(1)}`,
altKey: true
};
});
REACTION_SHORTCUTS.forEach(shortcut => {
dispatch(registerShortcut({
alt: shortcut.altKey,
character: shortcut.character,
handler: shortcut.exec,
helpDescription: shortcut.helpDescription
}));
});
if (gifsEnabled) {
const onGifShortcut = () => {
batch(() => {
dispatch(toggleReactionsMenuVisibility());
dispatch(setGifMenuVisibility(true));
});
};
dispatch(registerShortcut({
character: 'G',
handler: onGifShortcut,
helpDescription: 'keyboardShortcuts.giphyMenu'
}));
}
}
return () => {
[ 'A', 'C', 'D', 'P', 'R', 'S', 'W', 'T', 'G' ].forEach(letter =>
dispatch(unregisterShortcut(letter)));
if (reactionsEnabled) {
Object.keys(REACTIONS).map(key => REACTIONS[key].shortcutChar)
.forEach(letter =>
dispatch(unregisterShortcut(letter, true)));
}
};
}, []);
};

View File

@@ -0,0 +1,8 @@
import { ComponentType } from 'react';
export interface IToolboxButton {
Content: ComponentType<any>;
alias?: string;
group: number;
key: string;
}

View File

@@ -1,7 +1,14 @@
import { connect } from 'react-redux';
import { createToolbarEvent } from '../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../analytics/functions';
import { openDialog } from '../../base/dialog/actions';
import { translate } from '../../base/i18n/functions';
import { IconPerformance } from '../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../base/toolbox/components/AbstractButton';
import VideoQualityDialog from './VideoQualityDialog.web';
/**
* The type of the React {@code Component} props of
* {@link VideoQualityButton}.
@@ -32,6 +39,20 @@ class VideoQualityButton extends AbstractButton<IProps> {
label = 'videoStatus.performanceSettings';
tooltip = 'videoStatus.performanceSettings';
icon = IconPerformance;
/**
* Handles clicking the button, and opens the video quality dialog.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch } = this.props;
sendAnalytics(createToolbarEvent('video.quality'));
dispatch(openDialog(VideoQualityDialog));
}
}
export default translate(VideoQualityButton);
export default connect()(translate(VideoQualityButton));

View File

@@ -1,9 +1,11 @@
import { connect } from 'react-redux';
import { IReduxState } from '../../app/types';
import { getMultipleVideoSendingSupportFeatureFlag } from '../../base/config/functions.any';
import { translate } from '../../base/i18n/functions';
import { IconImage } from '../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../base/toolbox/components/AbstractButton';
import { isScreenVideoShared } from '../../screen-share/functions';
import { openSettingsDialog } from '../../settings/actions';
import { SETTINGS_TABS } from '../../settings/constants';
import { checkBlurSupport } from '../functions';
@@ -67,7 +69,7 @@ function _mapStateToProps(state: IReduxState) {
return {
_isBackgroundEnabled: Boolean(state['features/virtual-background'].backgroundEffectEnabled),
visible: checkBlurSupport()
visible: checkBlurSupport() && getMultipleVideoSendingSupportFeatureFlag(state) && !isScreenVideoShared(state)
};
}

View File

@@ -6,7 +6,7 @@ import { IconWhiteboard, IconWhiteboardHide } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { setOverflowMenuVisible } from '../../../toolbox/actions.web';
import { setWhiteboardOpen } from '../../actions';
import { isWhiteboardVisible } from '../../functions';
import { isWhiteboardButtonVisible, isWhiteboardVisible } from '../../functions';
interface IProps extends AbstractButtonProps {
@@ -63,7 +63,8 @@ class WhiteboardButton extends AbstractButton<IProps> {
*/
function _mapStateToProps(state: IReduxState) {
return {
_toggled: isWhiteboardVisible(state)
_toggled: isWhiteboardVisible(state),
visible: isWhiteboardButtonVisible(state)
};
}

View File

@@ -81,7 +81,7 @@ module:hook('muc-occupant-pre-join', function (event)
local room, stanza = event.room, event.stanza;
-- we skip processing only if jicofo_lock is set to false
if room.jicofo_lock == false or is_healthcheck_room(stanza.attr.from) then
if room._data.jicofo_lock == false or is_healthcheck_room(stanza.attr.from) then
return;
end
@@ -89,7 +89,7 @@ module:hook('muc-occupant-pre-join', function (event)
if ends_with(occupant.nick, '/focus') then
module:fire_event('jicofo-unlock-room', { room = room; });
else
room.jicofo_lock = true;
room._data.jicofo_lock = true;
if not room.pre_join_queue then
room.pre_join_queue = queue.new(QUEUE_MAX_SIZE);
end
@@ -108,15 +108,18 @@ end, 8); -- just after the rate limit
function handle_jicofo_unlock(event)
local room = event.room;
room.jicofo_lock = false;
room._data.jicofo_lock = false;
if not room.pre_join_queue then
return;
end
-- and now let's handle all pre_join_queue events
for _, ev in room.pre_join_queue:items() do
module:log('debug', 'Occupant processed from queue %s', ev.occupant.nick);
room:handle_normal_presence(ev.origin, ev.stanza);
-- if the connection was closed while waiting in the queue, ignore
if ev.origin.conn then
module:log('debug', 'Occupant processed from queue %s', ev.occupant.nick);
room:handle_normal_presence(ev.origin, ev.stanza);
end
end
room.pre_join_queue = nil;
end

View File

@@ -5,6 +5,8 @@ local log = module._log;
local host = module.host;
local st = require "util.stanza";
local um_is_admin = require "core.usermanager".is_admin;
local jid_split = require 'util.jid'.split;
local jid_bare = require 'util.jid'.bare;
local function is_admin(jid)
@@ -39,8 +41,11 @@ module:log("debug",
-- option to disable room modification (sending muc config form) for guest that do not provide token
local require_token_for_moderation;
-- option to allow domains to skip token verification
local allowlist;
local function load_config()
require_token_for_moderation = module:get_option_boolean("token_verification_require_token_for_moderation");
allowlist = module:get_option_set('token_verification_allowlist', {});
end
load_config();
@@ -57,6 +62,17 @@ local function verify_user(session, stanza)
return true;
end
-- token not required for users matching allow list
local user_bare_jid = jid_bare(user_jid);
local _, user_domain = jid_split(user_jid);
-- allowlist for participants
if allowlist:contains(user_domain) or allowlist:contains(user_bare_jid) then
module:log("debug", "Token not required from user in allow list: %s", user_jid);
return true;
end
module:log("debug",
"Will verify token for user: %s, room: %s ", user_jid, stanza.attr.to);
if not token_util:verify_room(session, stanza.attr.to) then