Compare commits

..

14 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
c32c2e0a1e fix(jwt) fix not processing features if avatar, name, email are missing 2023-07-07 13:15:51 -05:00
Jaya Allamsetty
7da59ff5d7 chore(deps): Update lib-jitsi-meet.
Fixes blurry screenshare - d949c0efe5
2023-07-07 11:28:48 -04:00
Hristo Terezov
4e4c530b44 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-05 09:39:59 -05:00
Hristo Terezov
3e5b643f34 fix(iframe): Add allow screen-wake-lock. 2023-06-27 12:02:12 -05:00
damencho
8ca7795b3a fix: Adds one more check for iframes. 2023-06-23 11:19:24 -05:00
Jaya Allamsetty
67d8fd96dc fix(lastn) Update lastN on virtual screenshare updates.
Fixes https://github.com/jitsi/jitsi-meet/issues/13448.
2023-06-21 12:41:41 -04:00
Hristo Terezov
b9d07df24c fix(screenLock): Improve.
- Add debug logs.
 - Re-request wake lock if it is released by the OS because of page
visibility.
2023-06-20 15:40:04 -05:00
Horatiu Muresan
b02d290b89 fix(prejoin) Check for valid url for prejoin (#13468)
- `getPropertyValue` calls `parseUrlParam` with the connection URL from store, which is not yet defined
2023-06-19 15:55:26 +03:00
Eze Posada
44f2bf1395 fix(lang) update Spanish translation 2023-06-19 09:12:48 +02:00
Jaya Allamsetty
049c0c0e79 Update LJM - fix(log) Add debug logs for track mute state changes in presence. 2023-06-16 14:24:20 -04:00
Saúl Ibarra Corretgé
d0fe1e1d06 fix(password) use the numeric input mode when only digits are required
Fixes: https://github.com/jitsi/brave-tracker/issues/101
2023-06-16 16:04:31 +02:00
Robert Pintilii
0cf8a56de0 fix(transcriptions) Open correct settings tab (#13460) 2023-06-15 09:50:48 -05:00
Hristo Terezov
a01bae8fc1 fix(horizontal-filmstrip): JS error.
Fixes the following JS error which prevents the whole page from
rendering:
TypeError: Cannot read properties of null (reading 'offsetHeight')
2023-06-14 18:32:26 -05:00
Horatiu Muresan
ebf1bb708c fix(notif-sounds) Set correct audio output device for notifs (#13436) 2023-06-14 19:27:59 +03:00
188 changed files with 3348 additions and 10934 deletions

13
.gitignore vendored
View File

@@ -94,16 +94,3 @@ twa/*.aab
twa/assetlinks.json
tsconfig.json
# React Native SDK
#
react-native-sdk/*.tgz
react-native-sdk/android/src
react-native-sdk/images
react-native-sdk/ios
react-native-sdk/lang
react-native-sdk/modules
react-native-sdk/node_modules
react-native-sdk/react
react-native-sdk/service
react-native-sdk/sounds

View File

@@ -2029,10 +2029,7 @@ export default {
room.on(
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED,
(...args) => {
APP.store.dispatch(nonParticipantMessageReceived(...args));
APP.API.notifyNonParticipantMessageReceived(...args);
});
(...args) => APP.store.dispatch(nonParticipantMessageReceived(...args)));
room.on(
JitsiConferenceEvents.LOCK_STATE_CHANGED,

View File

@@ -74,9 +74,6 @@ var config = {
//
testing: {
// Allows the setting of a custom bandwidth value from the UI.
// assumeBandwidth: true,
// Disables the End to End Encryption feature. Useful for debugging
// issues related to insertable streams.
// disableE2EE: false,
@@ -427,9 +424,25 @@ 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 the codec preference on desktop based endpoints.
// codecPreferenceOrder: [ 'VP9', 'VP8', '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 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
@@ -469,24 +482,6 @@ 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
@@ -937,12 +932,12 @@ var config = {
// If not set, the effective value is 'all'.
// iceTransportPolicy: 'all',
// 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 ],
// 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: '',
// 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).
@@ -954,15 +949,6 @@ 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: {
@@ -1079,12 +1065,7 @@ var config = {
// },
// e2ee: {
// labels: {
// description: '',
// label: '',
// tooltip: '',
// warning: '',
// },
// labels,
// externallyManagedKey: false,
// },
@@ -1394,6 +1375,7 @@ var config = {
dialOutRegionUrl
disableRemoteControl
displayJids
e2eeLabels
firefox_fake_device
googleApiApplicationClientID
iAmRecorder

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
.reactions-menu {
width: 280px;
background: #242528;
background: $menuBG;
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: #c61600;
color: $errorColor;
}
.google-panel {

View File

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

View File

@@ -2,10 +2,10 @@
* Round badge.
*/
.badge-round {
background-color: #165ECC;
background-color: $toolbarBadgeBackground;
border-radius: 50%;
box-sizing: border-box;
color: #FFFFFF;
color: $toolbarBadgeColor;
// 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: rgba(255, 255, 255, 0.2);
background: $newToolbarButtonHoverColor;
}
}

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: 7;
z-index: $subtitlesZ;
&.lifted {
// Lift subtitle above toolbar+dominant speaker box.

View File

@@ -41,36 +41,3 @@
display: -webkit-flex !important;
display: flex !important;
}
/**
* resets default button styles,
* mostly intended to be used on interactive elements that
* differ from their default styles (e.g. <a>) or have custom styles
*/
.invisible-button {
background: none;
border: none;
color: inherit;
cursor: pointer;
padding: 0;
}
/**
* style an element the same as an <a>
* useful on some cases where we visually have a link but it's actually a <button>
*/
.as-link {
@extend .invisible-button;
display: inline;
color: #44A5FF;
text-decoration: none;
font-weight: bold;
&:focus,
&:hover,
&:active {
text-decoration: underline;
}
}

View File

@@ -1,3 +1,5 @@
@import "themes/light";
/**
* Style variables
*/
@@ -8,26 +10,83 @@ $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;
/**
@@ -37,11 +96,38 @@ $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: rgba(9, 36, 77, 0.9);
background: $audioLevelShadow;
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: #44A5FF;
background: $audioLevelBg;
}
}
@@ -223,7 +223,7 @@
background-clip: padding-box;
-webkit-border-radius: 5px;
-webkit-background-clip: padding-box;
z-index: 20; /*The reload button should appear on top of the header!*/
z-index: $reloadZ; /*The reload button should appear on top of the header!*/
}
#dominantSpeaker {
@@ -365,7 +365,7 @@
}
.presence-label {
color: #fff;
color: $participantNameColor;
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: rgb(215, 121, 118);
color: $defaultWarningColor;
font-weight: 600;
display: flex;
flex-direction: row;
@@ -75,7 +75,7 @@ body.welcome-page {
margin-right: 15px;
svg {
fill: rgb(215, 121, 118);
fill: $defaultWarningColor;
& > *: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: #474747;
background: $sliderTrackBackground;
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 #3572b0;
border: 1px solid $sliderThumbBackground;
border-radius: 50%;
box-shadow: 0px 0px 1px #3572b0;
box-shadow: 0px 0px 1px $sliderThumbBackground;
cursor: pointer;
height: 14px;
margin-top: -4px;

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,7 @@
&-actions {
margin-top: 10px;
button {
a {
cursor: pointer;
text-decoration: none;
font-size: 14px;

View File

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

View File

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

View File

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

77
css/themes/_light.scss Normal file
View File

@@ -0,0 +1,77 @@
/**
* 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: #489afe;
color: $linkFontColor;
@include transition(color .1s ease-out);
&:hover {
color: #287ade;
color: $linkHoverFontColor;
cursor: pointer;
text-decoration: none;

View File

@@ -1,23 +0,0 @@
/**
* @type { import("@inlang/core/config").DefineConfig }
*/
export async function defineConfig(env) {
const { default: i18nextPlugin } = await env.$import(
'https://cdn.jsdelivr.net/npm/@inlang/plugin-i18next@2/dist/index.js'
);
const { default: standardLintRules } = await env.$import(
'https://cdn.jsdelivr.net/npm/@inlang/plugin-standard-lint-rules@3/dist/index.js'
);
return {
referenceLanguage: 'main',
plugins: [
i18nextPlugin({
pathPattern: 'lang/{language}.json',
ignore: [ 'languages.json', 'translation-languages.json' ]
}),
standardLintRules()
]
};
}

View File

@@ -374,7 +374,7 @@ PODS:
- React-Core
- react-native-pager-view (5.4.9):
- React-Core
- react-native-safe-area-context (4.6.4):
- react-native-safe-area-context (4.4.1):
- 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.3):
- react-native-webrtc (111.0.1):
- 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.22.0):
- RNScreens (3.13.1):
- 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: 68b07eabfb0d14547d36f6929c0e98d818064f02
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
react-native-slider: 6e9b86e76cce4b9e35b3403193a6432ed07e0c81
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
react-native-video: bb6f12a7198db53b261fefb5d609dc77417acc8b
react-native-webrtc: 4d1669c2ed29767fe70b0169428b4466589ecf8b
react-native-webrtc: 2702afae1e59882b423e6077768ca0d1e6fc42ed
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
React-perflogger: bc57c4a953c1ec913b0d984cf4f2b9842a12bde0
React-RCTActionSheet: 3efa3546119a1050f6c34a461b386dd9e36eaf0b
@@ -776,7 +776,7 @@ SPEC CHECKSUMS:
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
RNGoogleSignin: 22e468a9474dbcb8618d8847205ad4f0b2575d13
RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
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 isEqualToString:callUUID];
return evaluatedObject.UUID.UUIDString == callUUID;
}]].firstObject;
if (!activeCallForUUID) {

View File

@@ -1,8 +1,5 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Konferenzlink: {{url}}"
},
"add": "Einladen",
"addContacts": "Laden Sie Ihre Kontakte ein",
"contacts": "Kontakte",
@@ -42,18 +39,6 @@
"audioOnly": {
"audioOnly": "Geringe Bandbreite"
},
"bandwidthSettings": {
"assumedBandwidthBps": "z.B. 10000000 für 10 Mbps",
"assumedBandwidthBpsWarning": "Höhere Werte können zu Netzwerk-Problemen führen.",
"customValue": "spezifischer Wert",
"customValueEffect": "setzt den Wert in bps",
"leaveEmpty": "leer lassen",
"leaveEmptyEffect": "aktiviert die automatische Abschätzung",
"possibleValues": "Mögliche Werte",
"setAssumedBandwidthBps": "Angenommene Bandbreite (bps)",
"title": "Einstellungen Bandbreite",
"zeroEffect": "schaltet Video aus"
},
"breakoutRooms": {
"actions": {
"add": "Breakout-Raum hinzufügen",
@@ -171,7 +156,6 @@
"localport_plural": "Lokale Ports:",
"maxEnabledResolution": "max. senden",
"more": "Mehr anzeigen",
"no": "Nein",
"packetloss": "Paketverlust:",
"participant_id": "Personen-ID:",
"quality": {
@@ -190,8 +174,7 @@
"status": "Verbindung:",
"transport": "Protokoll:",
"transport_plural": "Protokolle:",
"video_ssrc": "Video-SSRC:",
"yes": "Ja"
"video_ssrc": "Video-SSRC:"
},
"dateUtils": {
"earlier": "Früher",
@@ -257,8 +240,6 @@
"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"
@@ -464,9 +445,6 @@
"title": "Diese Konferenz einbetten"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "Ihre Auswahl: {{rating}}"
},
"average": "Durchschnittlich",
"bad": "Schlecht",
"detailsLabel": "Sagen Sie uns mehr dazu.",
@@ -695,7 +673,6 @@
"connectedTwoMembers": "{{first}} und {{second}} nehmen am Meeting teil",
"dataChannelClosed": "Schlechte Videoqualität",
"dataChannelClosedDescription": "Die Steuerungsverbindung (Bridge Channel) wurde unterbrochen, daher ist die Videoqulität auf die schlechteste Stufe limitiert.",
"disabledIframe": "Die Einbettung ist nur für Demo-Zwecke vorgesehen. Diese Konferenz wird in {{timeout}} Minuten beendet.",
"disconnected": "getrennt",
"displayNotifications": "Benachrichtigungen anzeigen für",
"dontRemindMe": "Nicht erinnern",
@@ -890,11 +867,9 @@
"lookGood": "Ihr Mikrofon scheint zu funktionieren.",
"or": "oder",
"premeeting": "Vorschau",
"proceedAnyway": "Trotzdem fortsetzen",
"screenSharingError": "Fehler bei Bildschirmfreigabe:",
"showScreen": "Konferenzvorschau aktivieren",
"startWithPhone": "Mit Telefonaudio starten",
"unsafeRoomConsent": "Ich verstehe das Risiko und möchte der Konferenz beitreten",
"videoOnlyError": "Videofehler:",
"videoTrackError": "Videotrack konnte nicht erstellt werden.",
"viewAllNumbers": "alle Nummern anzeigen"
@@ -996,14 +971,8 @@
"security": {
"about": "Sie können Ihre Konferenz mit einem Passwort sichern. Teilnehmer müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"aboutReadOnly": "Mit Moderationsrechten kann die Konferenz mit einem Passwort gesichert werden. Personen müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"insecureRoomNameWarningNative": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten. {{recommendAction}} Lernen Sie mehr über die Absicherung Ihrer Konferenz ",
"insecureRoomNameWarningWeb": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten {{recommendAction}} Lernen Sie <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">hier</a> mehr über die Absicherung Ihrer Konferenz.",
"title": "Sicherheitsoptionen",
"unsafeRoomActions": {
"meeting": "Erwägen Sie die Absicherung Ihrer Konferenz über den Sicherheits-Button.",
"prejoin": "Erwägen Sie einen einzigartigeren Raumnamen zu wählen.",
"welcome": "Erwägen Sie einen einzigartigeren Raumnamen zu wählen oder wählen Sie einen der Vorschläge."
}
"insecureRoomNameWarning": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten",
"title": "Sicherheitsoptionen"
},
"settings": {
"audio": "Audio",
@@ -1073,7 +1042,6 @@
"links": "Links",
"privacy": "Datenschutz",
"profileSection": "Profil",
"sdkVersion": "SDK-Version",
"serverURL": "Server-URL",
"showAdvanced": "Erweiterte Einstellungen anzeigen",
"startCarModeInLowBandwidthMode": "Automodus mit Datensparmodus starten",
@@ -1172,7 +1140,6 @@
"muteEveryoneElse": "Alle anderen stummschalten",
"muteEveryoneElsesVideoStream": "Alle anderen Kameras ausschalten",
"muteEveryonesVideoStream": "Alle Kameras ausschalten",
"muteGUMPending": "Verbinde Ihr Mikrofon",
"noiseSuppression": "Rauschunterdrückung",
"openChat": "Chat öffnen",
"participants": "Anwesende",
@@ -1180,7 +1147,6 @@
"privateMessage": "Private Nachricht senden",
"profile": "Profil bearbeiten",
"raiseHand": "Hand heben",
"reactions": "Interaktionen",
"reactionsMenu": "Interaktionsmenü öffnen / schließen",
"recording": "Aufzeichnung ein-/ausschalten",
"remoteMute": "Personen stummschalten",
@@ -1206,7 +1172,6 @@
"unmute": "Stummschaltung aufheben",
"videoblur": "Unscharfer Hintergrund ein-/ausschalten",
"videomute": "„Video stummschalten“ ein-/ausschalten",
"videomuteGUMPending": "Verbinde Ihre Kamera",
"videounmute": "Kamera einschalten"
},
"addPeople": "Personen zur Konferenz hinzufügen",
@@ -1257,7 +1222,6 @@
"mute": "Stummschalten",
"muteEveryone": "Alle stummschalten",
"muteEveryonesVideo": "Alle Kameras ausschalten",
"muteGUMPending": "Verbinde Ihre Kamera",
"noAudioSignalDesc": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stumm geschaltet haben, sollten Sie einen Wechsel des Geräts in Erwägung ziehen.",
"noAudioSignalDescSuggestion": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stummgeschaltet haben, sollten Sie einen Wechsel auf das vorgeschlagene Gerät in Erwägung ziehen.",
"noAudioSignalDialInDesc": "Sie können sich auch über die Einwahlnummer einwählen:",
@@ -1280,7 +1244,6 @@
"reactionLike": "Daumen hoch senden",
"reactionSilence": "Stille senden",
"reactionSurprised": "Überrascht senden",
"reactions": "Interaktionen",
"security": "Sicherheitsoptionen",
"selectBackground": "Hintergrund auswählen",
"shareRoom": "Person einladen",
@@ -1303,7 +1266,6 @@
"unmute": "Stummschaltung aufheben",
"videoSettings": "Kameraeinstellungen",
"videomute": "Kamera stoppen",
"videomuteGUMPending": "Verbinde Ihre Kamera",
"videounmute": "Kamera einschalten"
},
"transcribing": {
@@ -1392,10 +1354,6 @@
"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.",
@@ -1419,14 +1377,7 @@
"webAssemblyWarning": "WebAssembly wird nicht unterstützt",
"webAssemblyWarningDescription": "WebAssembly ist deaktiviert oder wird in diesem Browser nicht unterstützt"
},
"visitors": {
"chatIndicator": "(Gast)",
"labelTooltip": "Anzahl Gäste: {{count}}",
"notification": {
"description": "Bitte melden Sie sich um teilzunehmen",
"title": "Sie sind Gast in der Konferenz"
}
},
"visitorsLabel": "Anzahl Gäste: {{count}}",
"volumeSlider": "Lautstärkeregler",
"welcomepage": {
"accessibilityLabel": {

File diff suppressed because it is too large Load Diff

View File

@@ -78,6 +78,7 @@
},
"carmode": {
"actions": {
"leaveMeeting": " Opuść spotkanie",
"selectSoundDevice": "Wybierz urządzenie dźwiękowe"
},
"labels": {
@@ -96,7 +97,6 @@
"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": "Czat",
"chat": "Chat",
"polls": "Ankiety"
},
"title": "Czat",
"titleWithPolls": "Czat i Ankiety",
"you": "ja"
"title": "Rozmowa",
"titleWithPolls": "Rozmowa",
"you": "Ty"
},
"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 zaoszczędzenia przepustowości sieci"
"LOW_BANDWIDTH": "Wideo {{displayName}} zostało wyłączone w celu oszczędności zasobów"
},
"connectionindicator": {
"address": "Adres:",
@@ -147,7 +147,6 @@
"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:",
@@ -156,7 +155,6 @@
"localport_plural": "Porty lokalne:",
"maxEnabledResolution": "wyślij maksymalną",
"more": "Pokaż więcej",
"no": "nie",
"packetloss": "Utrata pakietów:",
"participant_id": "ID uczestnika:",
"quality": {
@@ -175,8 +173,7 @@
"status": "Połączenie:",
"transport": "Transport:",
"transport_plural": "Transporty:",
"video_ssrc": "Video SSRC:",
"yes": "tak"
"video_ssrc": "Video SSRC:"
},
"dateUtils": {
"earlier": "Wcześniej",
@@ -186,21 +183,13 @@
"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."
},
@@ -213,12 +202,6 @@
"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",
@@ -242,9 +225,7 @@
"WaitingForHostTitle": "Oczekiwanie na gospodarza...",
"Yes": "Tak",
"accessibilityLabel": {
"close": "Zamknij okno dialogowe",
"liveStreaming": "Transmisja na żywo",
"sharingTabs": "Opcje udostępniania"
"liveStreaming": "Transmisja na żywo"
},
"add": "Dodaj",
"addMeetingNote": "Dodaj notatkę o tym spotkaniu",
@@ -264,7 +245,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": "Nastąpiło rozłączenie.",
"conferenceDisconnectTitle": "Zostałeś rozłączony.",
"conferenceReloadMsg": "Staramy się to naprawić. Ponowne połączenie za {{seconds}} sekund...",
"conferenceReloadTitle": "Niestety, coś poszło nie tak.",
"confirm": "Potwierdź",
@@ -290,7 +271,6 @@
"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",
@@ -321,8 +301,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 włączenie mikrofonów",
"moderationVideoLabel": "Zezwalaj uczestnikom na włączenie kamer",
"moderationAudioLabel": "Zezwalaj uczestnikom na wyłączanie wyciszenia",
"moderationVideoLabel": "Zezwalaj uczestnikom na rozpoczęcie wideo",
"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.",
@@ -332,15 +312,15 @@
"muteEveryoneSelf": "siebie",
"muteEveryoneStartMuted": "Od tego momentu wszyscy są wyciszeni",
"muteEveryoneTitle": "Wyciszyć wszystkich?",
"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.",
"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.",
"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 kamery",
"muteParticipantsVideoButton": "Wyłącz kamerę",
"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?",
@@ -408,7 +388,6 @@
"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",
@@ -427,10 +406,6 @@
"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.",
@@ -441,7 +416,7 @@
"title": "Udostępniony dokument"
},
"e2ee": {
"labelToolTip": "To połączenie audio i wideo jest szyfrowane end-to-end"
"labelToolTip": "To połączenie audio i wideo jest szyfrowane"
},
"embedMeeting": {
"title": "Osadź to spotkanie"
@@ -456,15 +431,13 @@
"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",
@@ -505,11 +478,9 @@
"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",
"upgradeOptions": "Sprawdź opcje aktualizacji na"
"tooltip": "Udostępnij odnośnik i informacje do wdzwonienia się na to spotkanie"
},
"inlineDialogFailure": {
"msg": "Nieco niedopisaliśmy.",
@@ -544,10 +515,6 @@
"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",
@@ -588,6 +555,7 @@
"lobby": {
"admit": "Pozwól",
"admitAll": "Pozwól wszystkim",
"allow": "Zezwól",
"backToKnockModeButton": "Brak hasła, poproś o dołączenie",
"chat": "Chat",
"dialogTitle": "Lobby",
@@ -650,7 +618,6 @@
"no": "Nie",
"participant": "Uczestnik",
"participantStats": "Statystyki uczestników",
"selectTabTitle": "🎥 Wybierz tę zakładkę do nagrywania",
"sessionToken": "Token sesji",
"start": "Rozpocznij nagrywanie",
"stop": "Zatrzymaj nagrywanie",
@@ -673,12 +640,8 @@
"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",
@@ -687,7 +650,6 @@
"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",
@@ -738,9 +700,7 @@
"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",
"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",
"selfViewTitle": "Zawsze możesz odkryć własny podgląd 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!",
@@ -776,8 +736,7 @@
"close": "Zamknij",
"headings": {
"lobby": "Lobby ({{count}})",
"participantsList": "Obecni uczestnicy ({{count}})",
"visitors": "Goście ({{count}})",
"participantsList": "Obecnych ({{count}})",
"waitingLobby": "Oczekujących ({{count}})"
},
"search": "Wyszukaj uczestników",
@@ -785,7 +744,6 @@
},
"passwordDigitsOnly": "Do {{number}} cyfr",
"passwordSetRemotely": "Ustawione przez innego uczestnika",
"pinParticipant": "{{participantName}} - Przypnij",
"pinnedParticipant": "Uczestnik jest przypięty",
"polls": {
"answer": {
@@ -870,11 +828,9 @@
"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": "Tryb osobistej poczekalni przed spotkaniem",
"showScreen": "Włącz ekran 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"
@@ -893,6 +849,9 @@
"rejected": "Odrzucony",
"ringing": "Dzwonek..."
},
"privacyView": {
"title": "Prywatność"
},
"profile": {
"avatar": "awatar",
"setDisplayNameLabel": "Podaj swoją wyświetlaną nazwę",
@@ -946,7 +905,6 @@
"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",
@@ -976,17 +934,10 @@
"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.",
"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."
}
"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ń"
},
"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.",
@@ -1007,29 +958,26 @@
"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 powiadomienia dźwiękowe dla:",
"playSounds": "Włącz dźwięki",
"reactions": "Reakcje",
"sameAsSystem": "Jak system ({{label}})",
"selectAudioOutput": "Wyjście audio",
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
"selfView": "Własnego podgląd",
"shortcuts": "Skróty",
"sounds": "Dźwięki",
"speakers": "Głośniki",
"startAudioMuted": "Wycisz wszystkich dołączających",
"startReactionsMuted": "Wycisz dźwięki reakcji dla wszystkich",
"startVideoMuted": "Wyłącz kamery wszystkich dołączających",
"startVideoMuted": "Ukryj wszystkich dołączających",
"talkWhileMuted": "Jesteś wyciszony",
"title": "Ustawienia",
"video": "Wideo"
"title": "Ustawienia"
},
"settingsView": {
"advanced": "Zaawansowane",
@@ -1046,7 +994,6 @@
"displayName": "Wyświetlana nazwa",
"displayNamePlaceholderText": "Np. Jan Kowalski",
"email": "Email",
"emailPlaceholderText": "email@example.com",
"goTo": "Idź do",
"header": "Ustawienia",
"help": "Pomoc",
@@ -1055,7 +1002,6 @@
"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",
@@ -1110,39 +1056,25 @@
"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",
@@ -1151,15 +1083,12 @@
"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",
@@ -1173,20 +1102,14 @@
"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",
"videomuteGUMPending": "Podłączanie kamery",
"videounmute": "Uruchom kamerę"
"videomute": "Przełączanie wyciszonego filmu wideo"
},
"addPeople": "Dodaj ludzi do swojej rozmowy",
"audioOnlyOff": "Wyłącz tryb słabego łącza",
@@ -1199,7 +1122,6 @@
"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",
@@ -1208,8 +1130,6 @@
"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",
@@ -1218,12 +1138,10 @@
"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",
@@ -1236,7 +1154,6 @@
"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:",
@@ -1259,14 +1176,12 @@
"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",
@@ -1277,13 +1192,10 @@
"stopSubtitles": "Zatrzymaj napisy",
"surprised": "Zaskoczony",
"talkWhileMutedPopup": "Próbujesz mówić? Jesteś wyciszony.",
"tileViewToggle": "Przełączanie widoku kafelkowego",
"tileViewToggle": "Przełączanie kafelkowego widoku",
"toggleCamera": "Przełączanie kamery",
"unmute": "Wyłącz wyciszenie",
"videoSettings": "Ustawienia video",
"videomute": "Włącz / Wyłącz kamerę",
"videomuteGUMPending": "Podłączanie kamery",
"videounmute": "Uruchom kamerę"
"videomute": "Włącz / Wyłącz kamerę"
},
"transcribing": {
"ccButtonTooltip": "Uruchom / Zatrzymaj napisy",
@@ -1293,15 +1205,10 @@
"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.",
@@ -1340,11 +1247,9 @@
"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ść",
"streaming": "Trwa transmisja"
"standardDefinition": "Standardowa rozdzielczość"
},
"videothumbnail": {
"connectionInfo": "Informacje o połączeniu",
@@ -1356,7 +1261,6 @@
"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",
@@ -1366,7 +1270,6 @@
"show": "Pokaż na scenie",
"showSelfView": "Pokaż własny widok",
"unpinFromStage": "Odepnij",
"verify": "Zweryfikuj uczestnika",
"videoMuted": "Kamera wyłączona",
"videomute": "Uczestnik zatrzymał kamerę"
},
@@ -1394,14 +1297,6 @@
"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": {
@@ -1434,7 +1329,6 @@
"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",
@@ -1443,7 +1337,6 @@
"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",
@@ -1452,12 +1345,6 @@
"settings": "Ustawienia",
"startMeeting": "Rozpocznij spotkanie",
"terms": "Warunki korzystania",
"title": "Bezpieczna, w pełni funkcjonalna i całkowicie bezpłatna wideokonferencja",
"upcomingMeetings": "Twoje nadchodzące spotkania"
},
"whiteboard": {
"accessibilityLabel": {
"heading": "Tablica"
}
"title": "Bezpieczna, w pełni funkcjonalna i całkowicie bezpłatna wideokonferencja"
}
}

View File

@@ -1,8 +1,5 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Link da reunião: {{url}}"
},
"add": "Convidar",
"addContacts": "Convidar os seus contactos",
"contacts": "contactos",
@@ -42,18 +39,6 @@
"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",
@@ -257,8 +242,6 @@
"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"
@@ -464,9 +447,6 @@
"title": "Incorporar esta reunião"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "A sua escolha: {{rating}}"
},
"average": "Média",
"bad": "Má",
"detailsLabel": "Conte-nos mais sobre isso.",
@@ -1171,7 +1151,6 @@
"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",
@@ -1205,7 +1184,6 @@
"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",
@@ -1256,7 +1234,6 @@
"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:",
@@ -1302,7 +1279,6 @@
"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": {
@@ -1349,7 +1325,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 (0 para o melhor desempenho, 3 para a melhor qualidade)",
"callQuality": "Qualidade de vídeo",
"hd": "HD",
"hdTooltip": "Ver vídeo em alta definição",
"highDefinition": "Alta definição (HD)",
@@ -1391,10 +1367,6 @@
"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

@@ -1,8 +1,5 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Meeting link: {{url}}"
},
"add": "Invite",
"addContacts": "Invite your contacts",
"contacts": "contacts",
@@ -42,18 +39,6 @@
"audioOnly": {
"audioOnly": "Low bandwidth"
},
"bandwidthSettings": {
"assumedBandwidthBps": "e.g. 10000000 for 10 Mbps",
"assumedBandwidthBpsWarning": "Higher values might cause network issues.",
"customValue": "custom value",
"customValueEffect": "to set the actual bps value",
"leaveEmpty": "leave empty",
"leaveEmptyEffect": "to allow estimations to take place",
"possibleValues": "Possible values",
"setAssumedBandwidthBps": "Assumed bandwidth (bps)",
"title": "Bandwidth settings",
"zeroEffect": "to disable video"
},
"breakoutRooms": {
"actions": {
"add": "Add breakout room",
@@ -257,8 +242,6 @@
"WaitingForHostTitle": "Waiting for the host ...",
"Yes": "Yes",
"accessibilityLabel": {
"Cancel": "Cancel (leave dialog)",
"Ok": "OK (save and leave dialog)",
"close": "Close dialog",
"liveStreaming": "Live Stream",
"sharingTabs": "Sharing options"
@@ -464,9 +447,6 @@
"title": "Embed this meeting"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "Your choice: {{rating}}"
},
"average": "Average",
"bad": "Bad",
"detailsLabel": "Tell us more about it.",
@@ -1073,14 +1053,13 @@
"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": "App version"
"version": "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}}",
@@ -1350,7 +1329,7 @@
"audioOnly": "AUD",
"audioOnlyExpanded": "You are in low bandwidth mode. In this mode you will receive only audio and screen sharing.",
"bestPerformance": "Best performance",
"callQuality": "Video Quality (0 for best performance, 3 for highest quality)",
"callQuality": "Video Quality",
"hd": "HD",
"hdTooltip": "Viewing high definition video",
"highDefinition": "High definition",
@@ -1392,10 +1371,6 @@
"videomute": "Participant has stopped the camera"
},
"virtualBackground": {
"accessibilityLabel": {
"currentBackground": "Current background: {{background}}",
"selectBackground": "Select a background"
},
"addBackground": "Add background",
"apply": "Apply",
"backgroundEffectError": "Failed to apply background effect.",

View File

@@ -17,7 +17,6 @@ import { isEnabledFromState } from '../../react/features/av-moderation/functions
import {
endConference,
sendTones,
setAssumedBandwidthBps,
setFollowMe,
setLocalSubject,
setPassword,
@@ -118,6 +117,7 @@ import { getJitsiMeetTransport } from '../transport';
import {
API_ID,
ASSUMED_BANDWIDTH_BPS,
ENDPOINT_TEXT_MESSAGE_NAME
} from './constants';
@@ -321,7 +321,13 @@ function initCommands() {
return;
}
APP.store.dispatch(setAssumedBandwidthBps(value));
const { conference } = APP.store.getState()['features/base/conference'];
if (conference) {
conference.setAssumedBandwidthBps(value < ASSUMED_BANDWIDTH_BPS
? ASSUMED_BANDWIDTH_BPS
: value);
}
},
'set-follow-me': value => {
logger.debug('Set follow me command received');
@@ -2027,23 +2033,6 @@ class API {
});
}
/**
* Notify external application (if API is enabled) if non participant message
* is received.
*
* @param {string} id - The resource id of the sender.
* @param {Object} json - The json carried by the message.
* @returns {void}
*/
notifyNonParticipantMessageReceived(id, json) {
this._sendEvent({
name: 'non-participant-message-received',
id,
message: json
});
}
/**
* Notify the external application (if API is enabled) if the connection type changed.
*

View File

@@ -21,4 +21,4 @@ export const ENDPOINT_TEXT_MESSAGE_NAME = 'endpoint-text-message';
* Setting it to this value means not assuming any bandwidth,
* but rather allowing the estimations to take place.
*/
export const MIN_ASSUMED_BANDWIDTH_BPS = -1;
export const ASSUMED_BANDWIDTH_BPS = -1;

View File

@@ -128,7 +128,6 @@ const events = {
'mouse-enter': 'mouseEnter',
'mouse-leave': 'mouseLeave',
'mouse-move': 'mouseMove',
'non-participant-message-received': 'nonParticipantMessageReceived',
'notification-triggered': 'notificationTriggered',
'outgoing-message': 'outgoingMessage',
'p2p-status-changed': 'p2pStatusChanged',

View File

@@ -508,7 +508,7 @@ export class VideoContainer extends LargeContainer {
*/
setLocalFlipX(val) {
this.localFlipX = val;
if (!this.video || !this.stream || !this.stream.isLocal() || this.isScreenSharing()) {
if (!this.video || !this.stream || !this.stream.isLocal()) {
return;
}
this.video.style.transform = this.localFlipX ? 'scaleX(-1)' : 'none';

423
package-lock.json generated
View File

@@ -17,7 +17,7 @@
"@giphy/react-components": "6.8.1",
"@giphy/react-native-sdk": "2.3.0",
"@hapi/bourne": "2.0.0",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.0",
"@jitsi/rnnoise-wasm": "0.1.0",
@@ -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.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",
"@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",
"@svgr/webpack": "6.3.1",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
@@ -60,7 +60,7 @@
"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/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet#d949c0efe590e19658ecbbc26dc314329695b30f",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -71,7 +71,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
"react-focus-on": "3.8.1",
"react-focus-lock": "2.9.4",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.69.10",
@@ -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.6.4",
"react-native-screens": "3.22.0",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.13.1",
"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.3",
"react-native-webrtc": "111.0.1",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
@@ -3100,9 +3100,9 @@
}
},
"node_modules/@jitsi/excalidraw": {
"version": "0.0.14",
"resolved": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
"integrity": "sha512-iK7p7i6qJFOkjTVZhWDvurDW1u+eMoOhAVgpab9CZEqCTX+W4Ih4AOPrUpf+mjaAHK5XqmQZSc5nVEpMg+xIGQ==",
"version": "0.0.13",
"resolved": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
"integrity": "sha512-GcH+KwBTuE+3bdf73lS2X+TpVp/QFyXBHps8jntSWjz5UOfmXhF4SAoUe+550eVCHiZex78AaLaVflR34Lv0VA==",
"license": "MIT",
"peerDependencies": {
"react": "^17.0.2 || ^18.2.0",
@@ -4704,11 +4704,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"node_modules/@react-navigation/bottom-tabs": {
"version": "6.5.8",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz",
"integrity": "sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg==",
"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==",
"dependencies": {
"@react-navigation/elements": "^1.3.18",
"@react-navigation/elements": "^1.3.13",
"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.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.9.tgz",
"integrity": "sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g==",
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
"integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"dependencies": {
"@react-navigation/routers": "^6.1.9",
"@react-navigation/routers": "^6.1.6",
"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.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q==",
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
"integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA==",
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
@@ -4781,9 +4781,9 @@
}
},
"node_modules/@react-navigation/material-top-tabs": {
"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==",
"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==",
"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.7",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.7.tgz",
"integrity": "sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
"integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"dependencies": {
"@react-navigation/core": "^6.4.9",
"@react-navigation/core": "^6.4.6",
"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.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
"integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==",
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz",
"integrity": "sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==",
"dependencies": {
"nanoid": "^3.1.23"
}
},
"node_modules/@react-navigation/stack": {
"version": "6.3.17",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.17.tgz",
"integrity": "sha512-8/8ZvJROK3fp6PRmQ9MrXd9epBowA8NkfCaWW/N9H5arqwNX9lTXAkmcjicRhjpX+UNlMBR9dTLkWvPRe2vY9A==",
"version": "6.3.11",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
"integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"dependencies": {
"@react-navigation/elements": "^1.3.18",
"@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -6681,6 +6681,14 @@
"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",
@@ -6918,17 +6926,6 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/aria-hidden": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
"integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
"dependencies": {
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -7785,7 +7782,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"optional": true,
"engines": {
"node": ">=10"
}
@@ -10534,7 +10530,6 @@
"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"
},
@@ -10645,14 +10640,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-nonce": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
"engines": {
"node": ">=6"
}
},
"node_modules/get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -12762,8 +12749,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"integrity": "sha512-uGRFpvKj6FSDhVHWvMerNwzaLflUrHQLXiP7Py0ITqV5Ix0d+hTFw9+OgI/JXzdBM3SLOP3GVNQLQfNR45oveA==",
"resolved": "git+ssh://git@github.com/jitsi/lib-jitsi-meet.git#d949c0efe590e19658ecbbc26dc314329695b30f",
"integrity": "sha512-tNYZ+vLWM/067tfrEXm4uJx+fisMYMl0yf8Tf53+Y4cbV5KtiGeuEPMiA1JD4FyGlQ9BcgphSGAjuNZkxvqUwA==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -13888,7 +13875,6 @@
"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"
},
@@ -13900,7 +13886,6 @@
"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"
@@ -14009,15 +13994,9 @@
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
"node_modules/nanoid": {
"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"
}
],
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -15602,32 +15581,6 @@
}
}
},
"node_modules/react-focus-on": {
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.8.1.tgz",
"integrity": "sha512-fQcBx+SZMgXoRL+69r5+ic4bdVgqaCeKeoFPra8yhcSuL/3unWavfdirEFBGgH71K+RiocMTS6DETHcX0SlOZg==",
"dependencies": {
"aria-hidden": "^1.2.2",
"react-focus-lock": "^2.9.2",
"react-remove-scroll": "^2.5.6",
"react-style-singleton": "^2.2.0",
"tslib": "^2.3.1",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
},
"engines": {
"node": ">=8.5.0"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-freeze": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.0.tgz",
@@ -15865,18 +15818,18 @@
}
},
"node_modules/react-native-safe-area-context": {
"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==",
"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==",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-screens": {
"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==",
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.13.1.tgz",
"integrity": "sha512-xcrnuUs0qUrGpc2gOTDY4VgHHADQwp80mwR1prU/Q0JqbZN5W3koLhuOsT6FkSRKjR5t40l+4LcjhHdpqRB2HA==",
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -16029,13 +15982,15 @@
}
},
"node_modules/react-native-webrtc": {
"version": "111.0.3",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.3.tgz",
"integrity": "sha512-flharkWM5QTSlik+ppK5tf5W86IeabHnrMI7bKkhUJJyibDDMz6X3ReH3dtHWFbiRjDGLktZ4FGwqOCGhL68DA==",
"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==",
"dependencies": {
"adm-zip": "0.5.9",
"base64-js": "1.5.1",
"debug": "4.3.4",
"event-target-shim": "6.0.2"
"event-target-shim": "6.0.2",
"tar": "6.1.11"
},
"peerDependencies": {
"react-native": ">=0.60.0"
@@ -16152,51 +16107,6 @@
"node": ">=0.10.0"
}
},
"node_modules/react-remove-scroll": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.6.tgz",
"integrity": "sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==",
"dependencies": {
"react-remove-scroll-bar": "^2.3.4",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-remove-scroll-bar": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz",
"integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==",
"dependencies": {
"react-style-singleton": "^2.2.1",
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-shallow-renderer": {
"version": "16.15.0",
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
@@ -16209,28 +16119,6 @@
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-style-singleton": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
"dependencies": {
"get-nonce": "^1.0.0",
"invariant": "^2.2.4",
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-textarea-autosize": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz",
@@ -17962,7 +17850,6 @@
"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",
@@ -17979,7 +17866,6 @@
"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"
},
@@ -18800,12 +18686,9 @@
}
},
"node_modules/use-latest-callback": {
"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"
}
"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=="
},
"node_modules/use-sidecar": {
"version": "1.1.2",
@@ -19814,8 +19697,7 @@
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
"version": "1.10.2",
@@ -22015,8 +21897,8 @@
"dev": true
},
"@jitsi/excalidraw": {
"version": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
"integrity": "sha512-iK7p7i6qJFOkjTVZhWDvurDW1u+eMoOhAVgpab9CZEqCTX+W4Ih4AOPrUpf+mjaAHK5XqmQZSc5nVEpMg+xIGQ=="
"version": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
"integrity": "sha512-GcH+KwBTuE+3bdf73lS2X+TpVp/QFyXBHps8jntSWjz5UOfmXhF4SAoUe+550eVCHiZex78AaLaVflR34Lv0VA=="
},
"@jitsi/js-utils": {
"version": "2.0.5",
@@ -23154,11 +23036,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"@react-navigation/bottom-tabs": {
"version": "6.5.8",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz",
"integrity": "sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg==",
"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==",
"requires": {
"@react-navigation/elements": "^1.3.18",
"@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -23188,11 +23070,11 @@
}
},
"@react-navigation/core": {
"version": "6.4.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.9.tgz",
"integrity": "sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g==",
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
"integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"requires": {
"@react-navigation/routers": "^6.1.9",
"@react-navigation/routers": "^6.1.6",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.23",
"query-string": "^7.1.3",
@@ -23208,14 +23090,14 @@
}
},
"@react-navigation/elements": {
"version": "1.3.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q=="
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
"integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA=="
},
"@react-navigation/material-top-tabs": {
"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==",
"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==",
"requires": {
"color": "^4.2.3",
"warn-once": "^0.1.0"
@@ -23246,30 +23128,30 @@
}
},
"@react-navigation/native": {
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.7.tgz",
"integrity": "sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
"integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"requires": {
"@react-navigation/core": "^6.4.9",
"@react-navigation/core": "^6.4.6",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
}
},
"@react-navigation/routers": {
"version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
"integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==",
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz",
"integrity": "sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==",
"requires": {
"nanoid": "^3.1.23"
}
},
"@react-navigation/stack": {
"version": "6.3.17",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.17.tgz",
"integrity": "sha512-8/8ZvJROK3fp6PRmQ9MrXd9epBowA8NkfCaWW/N9H5arqwNX9lTXAkmcjicRhjpX+UNlMBR9dTLkWvPRe2vY9A==",
"version": "6.3.11",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
"integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"requires": {
"@react-navigation/elements": "^1.3.18",
"@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -24664,6 +24546,11 @@
"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",
@@ -24851,14 +24738,6 @@
"sprintf-js": "~1.0.2"
}
},
"aria-hidden": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
"integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
"requires": {
"tslib": "^2.0.0"
}
},
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -25511,8 +25390,7 @@
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"optional": true
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"chrome-trace-event": {
"version": "1.0.3",
@@ -27614,7 +27492,6 @@
"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"
}
@@ -27694,11 +27571,6 @@
"has-symbols": "^1.0.3"
}
},
"get-nonce": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -29269,8 +29141,9 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"integrity": "sha512-uGRFpvKj6FSDhVHWvMerNwzaLflUrHQLXiP7Py0ITqV5Ix0d+hTFw9+OgI/JXzdBM3SLOP3GVNQLQfNR45oveA==",
"version": "git+ssh://git@github.com/jitsi/lib-jitsi-meet.git#d949c0efe590e19658ecbbc26dc314329695b30f",
"integrity": "sha512-tNYZ+vLWM/067tfrEXm4uJx+fisMYMl0yf8Tf53+Y4cbV5KtiGeuEPMiA1JD4FyGlQ9BcgphSGAjuNZkxvqUwA==",
"from": "lib-jitsi-meet@https://github.com/jitsi/lib-jitsi-meet#d949c0efe590e19658ecbbc26dc314329695b30f",
"requires": {
"@jitsi/js-utils": "2.0.0",
"@jitsi/logger": "2.0.0",
@@ -30170,7 +30043,6 @@
"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"
}
@@ -30179,7 +30051,6 @@
"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"
@@ -30268,9 +30139,9 @@
}
},
"nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
},
"nanomatch": {
"version": "1.2.13",
@@ -31417,20 +31288,6 @@
"use-sidecar": "^1.1.2"
}
},
"react-focus-on": {
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.8.1.tgz",
"integrity": "sha512-fQcBx+SZMgXoRL+69r5+ic4bdVgqaCeKeoFPra8yhcSuL/3unWavfdirEFBGgH71K+RiocMTS6DETHcX0SlOZg==",
"requires": {
"aria-hidden": "^1.2.2",
"react-focus-lock": "^2.9.2",
"react-remove-scroll": "^2.5.6",
"react-style-singleton": "^2.2.0",
"tslib": "^2.3.1",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
}
},
"react-freeze": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.0.tgz",
@@ -31614,14 +31471,14 @@
"integrity": "sha512-Q3dFPN7whBCY7X8nvQe7TBw4F5g1PyB78KwyKDXpJENcDrBodlFtj9/c5T2ZkRwAPb+bxr39b+lq9FyT6WQWtg=="
},
"react-native-safe-area-context": {
"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=="
"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=="
},
"react-native-screens": {
"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==",
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.13.1.tgz",
"integrity": "sha512-xcrnuUs0qUrGpc2gOTDY4VgHHADQwp80mwR1prU/Q0JqbZN5W3koLhuOsT6FkSRKjR5t40l+4LcjhHdpqRB2HA==",
"requires": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -31730,13 +31587,15 @@
}
},
"react-native-webrtc": {
"version": "111.0.3",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.3.tgz",
"integrity": "sha512-flharkWM5QTSlik+ppK5tf5W86IeabHnrMI7bKkhUJJyibDDMz6X3ReH3dtHWFbiRjDGLktZ4FGwqOCGhL68DA==",
"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==",
"requires": {
"adm-zip": "0.5.9",
"base64-js": "1.5.1",
"debug": "4.3.4",
"event-target-shim": "6.0.2"
"event-target-shim": "6.0.2",
"tar": "6.1.11"
},
"dependencies": {
"base64-js": {
@@ -31800,27 +31659,6 @@
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
"integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA=="
},
"react-remove-scroll": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.6.tgz",
"integrity": "sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==",
"requires": {
"react-remove-scroll-bar": "^2.3.4",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
}
},
"react-remove-scroll-bar": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz",
"integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==",
"requires": {
"react-style-singleton": "^2.2.1",
"tslib": "^2.0.0"
}
},
"react-shallow-renderer": {
"version": "16.15.0",
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
@@ -31830,16 +31668,6 @@
"react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
}
},
"react-style-singleton": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
"requires": {
"get-nonce": "^1.0.0",
"invariant": "^2.2.4",
"tslib": "^2.0.0"
}
},
"react-textarea-autosize": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz",
@@ -33175,7 +33003,6 @@
"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",
@@ -33188,8 +33015,7 @@
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"optional": true
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
}
}
},
@@ -33779,9 +33605,9 @@
}
},
"use-latest-callback": {
"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=="
"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=="
},
"use-sidecar": {
"version": "1.1.2",
@@ -34502,8 +34328,7 @@
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"yaml": {
"version": "1.10.2",

View File

@@ -22,7 +22,7 @@
"@giphy/react-components": "6.8.1",
"@giphy/react-native-sdk": "2.3.0",
"@hapi/bourne": "2.0.0",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.0",
"@jitsi/rnnoise-wasm": "0.1.0",
@@ -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.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",
"@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",
"@svgr/webpack": "6.3.1",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
@@ -65,7 +65,7 @@
"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/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet#d949c0efe590e19658ecbbc26dc314329695b30f",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -76,7 +76,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
"react-focus-on": "3.8.1",
"react-focus-lock": "2.9.4",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.69.10",
@@ -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.6.4",
"react-native-screens": "3.22.0",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.13.1",
"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.3",
"react-native-webrtc": "111.0.1",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",

View File

@@ -1,2 +0,0 @@
package-lock=true
legacy-peer-deps=true

View File

@@ -1,86 +0,0 @@
# <p align="center">Jitsi Meet React Native SDK</p>
## Installation
Inside your project, run `npm i @jitsi/react-native-sdk`.<br/><br/>Additionally, if not already installed, some dependencies will need to be added.
This can be done by running the following script:
```
"update-deps": "node node_modules/@jitsi/react-native-sdk/update_dependencies.js"
```
This will check and update all your dependencies.<br/><br/>
[comment]: # (These deps definitely need to be added manually, more could be neccesary)
Because of SVG use in react native, you need to update metro.config your project's file:
```
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: {
sourceExts,
assetExts
}
} = await getDefaultConfig();
return {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg']
}
}
})();
```
### iOS
#### Project Info.plist
- Add a *Privacy - Camera Usage Description*
- Add a *Privacy - Microphone Usage Description*
#### General
- Signing & capabilites:
- Add Background modes
- Audio
- Voice over IP
- Background fetch
- Add Copy Sounds step:
1. Open XCode, go to Build Phases and add this step and the script below.
```
SOUNDS_DIR="${PROJECT_DIR}/../node_modules/@jitsi/react-native-sdk/sounds"
cp $SOUNDS_DIR/* ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/
```
#### Podfile
- At the beginning of your target step add `pod 'ObjectiveDropboxOfficial', :modular_headers => true`
Run `cd ios && pod install && cd ..`
### Android
- In your build.gradle have at least `minSdkVersion = 24`
- TODO: HOW TO ADD COPY SOUNDS STEP
- In `android/app/src/debug/AndroidManifest.xml` and `android/app/src/main/AndroidManifest.xml`, under the `</application>` tag, include
```
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
```
### TODOS
- Ref ConnectionService to not rely on ReactInstanceHolder anymore
- Add Copy Sounds step to build.gradle
- Include copy sounds step in podspec (if possible)
- Add ranges for dependencies
- Add Build_Config for react native to AppInfoModule

View File

@@ -1,140 +0,0 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
}
}
def isNewArchitectureEnabled() {
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}
apply plugin: 'com.android.library'
if (isNewArchitectureEnabled()) {
apply plugin: 'com.facebook.react'
}
def getExtOrDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['JitsiMeetReactNative_' + name]
}
def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['JitsiMeetReactNative_' + name]).toInteger()
}
android {
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
defaultConfig {
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}
buildTypes {
release {
minifyEnabled false
}
}
lintOptions {
disable 'GradleCompatible'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
mavenCentral()
google()
def found = false
def defaultDir = null
def androidSourcesName = 'React Native sources'
if (rootProject.ext.has('reactNativeAndroidRoot')) {
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
} else {
defaultDir = new File(
projectDir,
'/../../../node_modules/react-native/android'
)
}
if (defaultDir.exists()) {
maven {
url defaultDir.toString()
name androidSourcesName
}
logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
found = true
} else {
def parentDir = rootProject.projectDir
1.upto(5, {
if (found) return true
parentDir = parentDir.parentFile
def androidSourcesDir = new File(
parentDir,
'node_modules/react-native'
)
def androidPrebuiltBinaryDir = new File(
parentDir,
'node_modules/react-native/android'
)
if (androidPrebuiltBinaryDir.exists()) {
maven {
url androidPrebuiltBinaryDir.toString()
name androidSourcesName
}
logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
found = true
} else if (androidSourcesDir.exists()) {
maven {
url androidSourcesDir.toString()
name androidSourcesName
}
logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
found = true
}
})
}
if (!found) {
throw new GradleException(
"${project.name}: unable to locate React Native android sources. " +
"Ensure you have you installed React Native as a dependency in your project and try again."
)
}
}
dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation 'com.squareup.duktape:duktape-android:1.3.0'
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
implementation 'com.jakewharton.timber:timber:4.7.1'
// From node_modules
}
if (isNewArchitectureEnabled()) {
react {
jsRootDir = file("../src/")
libraryName = "JitsiMeetReactNative"
codegenJavaPackageName = "org.jitsi.meet.sdk"
}
}

View File

@@ -1,5 +0,0 @@
JitsiMeetReactNative_kotlinVersion=1.7.0
JitsiMeetReactNative_minSdkVersion=21
JitsiMeetReactNative_targetSdkVersion=31
JitsiMeetReactNative_compileSdkVersion=31
JitsiMeetReactNative_ndkversion=21.4.7075529

View File

@@ -1,4 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.jitsi.meet.sdk">
</manifest>

View File

@@ -1,39 +0,0 @@
package org.jitsi.meet.sdk;
import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class JitsiMeetReactNativePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules
= new ArrayList<>(Arrays.<NativeModule>asList(
new AndroidSettingsModule(reactContext),
new AppInfoModule(reactContext),
new AudioModeModule(reactContext),
new JavaScriptSandboxModule(reactContext),
new LocaleDetector(reactContext),
new LogBridgeModule(reactContext),
new PictureInPictureModule(reactContext),
new ProximityModule(reactContext),
new org.jitsi.meet.sdk.net.NAT64AddrInfoModule(reactContext)
));
return modules;
}
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

View File

@@ -1,96 +0,0 @@
/* eslint-disable lines-around-comment, no-undef, no-unused-vars */
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';
// @ts-ignore
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { View } from 'react-native';
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.native';
interface IAppProps {
flags: [];
meetingOptions: {
domain: string;
roomName: string;
onReadyToClose?: Function;
onConferenceJoined?: Function;
onConferenceWillJoin?: Function;
onConferenceLeft?: Function;
onParticipantJoined?: Function;
settings?: {
startWithAudioMuted?: boolean;
startAudioOnly?: boolean;
startWithVideoMuted?: boolean;
}
};
style?: Object;
}
/**
* Main React Native SDK component that displays a Jitsi Meet conference and gets all required params as props
*/
export const JitsiMeeting = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref) => {
const [ appProps, setAppProps ] = useState({});
const app = useRef(null);
// eslint-disable-next-line arrow-body-style
useImperativeHandle(ref, () => ({
close: () => {
const dispatch = app.current.state.store.dispatch;
dispatch(appNavigate(undefined));
},
setAudioMuted: muted => {
const dispatch = app.current.state.store.dispatch;
dispatch(setAudioMuted(muted));
},
setVideoMuted: muted => {
const dispatch = app.current.state.store.dispatch;
dispatch(setVideoMuted(muted));
}
}));
useEffect(
() => {
const url = `${meetingOptions.domain}/${meetingOptions.roomName}`;
setAppProps({
'url': {
url,
config: meetingOptions.settings
},
'rnSdkHandlers': {
onReadyToClose: meetingOptions.onReadyToClose,
onConferenceJoined: meetingOptions.onConferenceJoined,
onConferenceWillJoin: meetingOptions.onConferenceWillJoin,
onConferenceLeft: meetingOptions.onConferenceLeft,
onParticipantJoined: meetingOptions.onParticipantJoined
},
'flags': { ...flags }
});
}, []
);
return (
<View style = { style }>
<JitsiThemePaperProvider>
{/* @ts-ignore */}
<App
{ ...appProps }
ref = { app } />
</JitsiThemePaperProvider>
</View>
);
});

View File

@@ -1,26 +0,0 @@
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = 'jitsi-meet-rnsdk'
s.version = package['version']
s.summary = package['description']
s.description = package['description']
s.license = package['license']
s.author = package['author']
s.homepage = package['homepage']
s.source = { :git => package['repository']['url'], :tag => s.version }
s.requires_arc = true
s.platform = :ios, '12.4'
s.preserve_paths = 'ios/**/*'
s.source_files = 'ios/**/*.{h,m,swift}'
s.dependency 'React-Core'
s.dependency 'ObjectiveDropboxOfficial', '6.2.3'
s.dependency 'JitsiWebRTC', '~> 111.0.0'
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,103 +0,0 @@
{
"name": "@jitsi/react-native-sdk",
"version": "0.1.0",
"description": "React Native SDK for Jitsi Meet.",
"main": "index.tsx",
"license": "Apache-2.0",
"author": "",
"homepage": "https://jitsi.org",
"repository": {
"type": "git",
"url": "git+https://github.com/jitsi/jitsi-meet.git"
},
"dependencies": {
"@hapi/bourne": "2.0.0",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.0",
"@jitsi/rtcstats": "9.5.1",
"@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-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/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.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",
"redux": "4.0.4",
"redux-thunk": "2.4.1",
"unorm": "1.6.0",
"util": "0.12.1",
"uuid": "8.3.2",
"zxcvbn": "4.4.2"
},
"peerDependencies": {
"@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": "*",
"react": "*",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-default-preference": "1.4.4",
"react-native-device-info": "8.4.8",
"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": "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-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-webview": "11.15.1"
},
"overrides": {
"strophe.js@1.5.0": {
"@xmldom/xmldom": "0.8.7"
}
},
"scripts": {
"postinstall": "node sdk_instructions.js",
"prepare": "node prepare_sdk.js"
},
"bugs": {
"url": "https://github.com/jitsi/jitsi-meet/issues"
},
"keywords": [
"react-native"
]
}

View File

@@ -1,213 +0,0 @@
const fs = require('fs');
const path = require('path');
const packageJSON = require('../package.json');
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.
*/
function copyFileSync(source, target) {
let targetFile = target;
// If target is a directory, a new file with the same name will be created
if (fs.existsSync(target)) {
if (fs.lstatSync(target).isDirectory()) {
targetFile = path.join(target, path.basename(source));
}
}
fs.copyFileSync(source, targetFile);
}
/**
* Copies a specified directory recursively.
*/
function copyFolderRecursiveSync(source, target) {
let files = [];
const targetFolder = path.join(target, path.basename(source));
if (!fs.existsSync(targetFolder)) {
fs.mkdirSync(targetFolder, { recursive: true });
}
if (fs.lstatSync(source).isDirectory()) {
files = fs.readdirSync(source);
files.forEach(file => {
const curSource = path.join(source, file);
if (fs.lstatSync(curSource).isDirectory()) {
copyFolderRecursiveSync(curSource, targetFolder);
} else {
copyFileSync(curSource, targetFolder);
}
});
}
}
/**
* Merges the dependency versions from the root package.json with the dependencies of the SDK package.json.
*/
function mergeDependencyVersions() {
for (const key in SDKPackageJSON.dependencies) {
if (SDKPackageJSON.dependencies.hasOwnProperty(key)) {
SDKPackageJSON.dependencies[key] = packageJSON.dependencies[key] || packageJSON.devDependencies[key];
}
}
const data = JSON.stringify(SDKPackageJSON, null, 4);
fs.writeFileSync('package.json', data);
}
// TODO: put this in a seperate step
mergeDependencyVersions();
copyFolderRecursiveSync(
'../images',
'.'
);
copyFolderRecursiveSync(
'../sounds',
'.'
);
copyFolderRecursiveSync(
'../lang',
'.'
);
copyFolderRecursiveSync(
'../modules',
'.'
);
copyFolderRecursiveSync(
'../react',
'.'
);
copyFolderRecursiveSync(
'../service',
'.'
);
copyFolderRecursiveSync(
'../ios/sdk/sdk.xcodeproj',
'./ios'
);
copyFolderRecursiveSync(
`${iosSrcPath}/callkit`,
iosDestPath
);
copyFolderRecursiveSync(
`${iosSrcPath}/dropbox`,
iosDestPath
);
copyFolderRecursiveSync(
'../ios/sdk/src/picture-in-picture',
iosDestPath
);
fs.copyFileSync(
`${iosSrcPath}/AppInfo.m`,
`${iosDestPath}/AppInfo.m`
);
fs.copyFileSync(
`${iosSrcPath}/AudioMode.m`,
`${iosDestPath}/AudioMode.m`
);
fs.copyFileSync(
`${iosSrcPath}/InfoPlistUtil.m`,
`${iosDestPath}/InfoPlistUtil.m`
);
fs.copyFileSync(
`${iosSrcPath}/InfoPlistUtil.h`,
`${iosDestPath}/InfoPlistUtil.h`
);
fs.copyFileSync(
`${iosSrcPath}/JavaScriptSandbox.m`,
`${iosDestPath}/JavaScriptSandbox.m`
);
fs.copyFileSync(
`${iosSrcPath}/JitsiAudioSession.m`,
`${iosDestPath}/JitsiAudioSession.m`
);
fs.copyFileSync(
`${iosSrcPath}/JitsiAudioSession.h`,
`${iosDestPath}/JitsiAudioSession.h`
);
fs.copyFileSync(
`${iosSrcPath}/JitsiAudioSession+Private.h`,
`${iosDestPath}/JitsiAudioSession+Private.h`
);
fs.copyFileSync(
`${iosSrcPath}/LocaleDetector.m`,
`${iosDestPath}/LocaleDetector.m`
);
fs.copyFileSync(
`${iosSrcPath}/POSIX.m`,
`${iosDestPath}/POSIX.m`
);
fs.copyFileSync(
`${iosSrcPath}/Proximity.m`,
`${iosDestPath}/Proximity.m`
);
copyFolderRecursiveSync(
`${androidSourcePath}/log`,
`${androidTargetPath}/log`
);
copyFolderRecursiveSync(
`${androidSourcePath}/net`,
`${androidTargetPath}/log`
);
fs.copyFileSync(
`${androidSourcePath}/AndroidSettingsModule.java`,
`${androidTargetPath}/AndroidSettingsModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/AppInfoModule.java`,
`${androidTargetPath}/AppInfoModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/AudioDeviceHandlerConnectionService.java`,
`${androidTargetPath}/AudioDeviceHandlerConnectionService.java`
);
fs.copyFileSync(
`${androidSourcePath}/AudioDeviceHandlerGeneric.java`,
`${androidTargetPath}/AudioDeviceHandlerGeneric.java`
);
fs.copyFileSync(
`${androidSourcePath}/AudioModeModule.java`,
`${androidTargetPath}/AudioModeModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/ConnectionService.java`,
`${androidTargetPath}/ConnectionService.java`
);
fs.copyFileSync(
`${androidSourcePath}/JavaScriptSandboxModule.java`,
`${androidTargetPath}/JavaScriptSandboxModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/LocaleDetector.java`,
`${androidTargetPath}/LocaleDetector.java`
);
fs.copyFileSync(
`${androidSourcePath}/LogBridgeModule.java`,
`${androidTargetPath}/LogBridgeModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/PictureInPictureModule.java`,
`${androidTargetPath}/PictureInPictureModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/ProximityModule.java`,
`${androidTargetPath}/ProximityModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/RNConnectionService.java`,
`${androidTargetPath}/RNConnectionService.java`
);

View File

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

View File

@@ -1,58 +0,0 @@
/* 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

@@ -3,12 +3,20 @@ import { API_ID } from '../../../modules/API';
import { setRoom } from '../base/conference/actions';
import {
configWillLoad,
setConfig
loadConfigError,
setConfig,
storeConfig
} from '../base/config/actions';
import { createFakeConfig, restoreConfig } from '../base/config/functions.web';
import { setLocationURL } from '../base/connection/actions.web';
import { loadConfig } from '../base/lib-jitsi-meet/functions.web';
import { inIframe } from '../base/util/iframeUtils';
import { parseURIString } from '../base/util/uri';
import { parseURLParams } from '../base/util/parseURLParams';
import {
appendURLParam,
getBackendSafeRoomName,
parseURIString
} from '../base/util/uri';
import { isVpaasMeeting } from '../jaas/functions';
import { clearNotifications, showNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
@@ -60,8 +68,7 @@ export function appNavigate(uri?: string) {
}
location.protocol || (location.protocol = 'https:');
const { room } = location;
const { contextRoot, host, room } = location;
const locationURL = new URL(location.toString());
// There are notifications now that gets displayed after we technically left
@@ -70,7 +77,55 @@ export function appNavigate(uri?: string) {
dispatch(configWillLoad(locationURL, room));
const config = await loadConfig();
let protocol = location.protocol.toLowerCase();
// The React Native app supports an app-specific scheme which is sure to not
// be supported by fetch.
protocol !== 'http:' && protocol !== 'https:' && (protocol = 'https:');
const baseURL = `${protocol}//${host}${contextRoot || '/'}`;
let url = `${baseURL}config.js`;
// XXX In order to support multiple shards, tell the room to the deployment.
room && (url = appendURLParam(url, 'room', getBackendSafeRoomName(room) ?? ''));
const { release } = parseURLParams(location, true, 'search');
release && (url = appendURLParam(url, 'release', release));
let config;
// Avoid (re)loading the config when there is no room.
if (!room) {
config = restoreConfig(baseURL);
}
if (!config) {
try {
config = await loadConfig(url);
dispatch(storeConfig(baseURL, config));
} catch (error: any) {
config = restoreConfig(baseURL);
if (!config) {
if (room) {
dispatch(loadConfigError(error, locationURL));
return;
}
// If there is no room (we are on the welcome page), don't fail, just create a fake one.
logger.warn('Failed to load config but there is no room, applying a fake one');
config = createFakeConfig(baseURL);
}
}
}
if (getState()['features/base/config'].locationURL !== locationURL) {
dispatch(loadConfigError(new Error('Config no longer needed!'), locationURL));
return;
}
dispatch(setLocationURL(locationURL));
dispatch(setConfig(config));

View File

@@ -10,7 +10,6 @@ import '../mobile/navigation/middleware';
import '../mobile/permissions/middleware';
import '../mobile/proximity/middleware';
import '../mobile/wake-lock/middleware';
import '../mobile/react-native-sdk/middleware';
import '../mobile/watchos/middleware';
import '../share-room/middleware';
import '../shared-video/middleware';

View File

@@ -31,7 +31,7 @@ interface IProps {
domain: string;
focus?: string;
muc: string;
visitorFocus?: string;
visitorFocus: string;
};
/**

View File

@@ -268,7 +268,6 @@ class LoginDialog extends Component<IProps, IState> {
titleKey = { t('dialog.authenticationRequired') }>
<Input
autoFocus = { true }
id = 'login-dialog-username'
label = { t('dialog.user') }
name = 'username'
onChange = { this._onUsernameChange }
@@ -278,7 +277,6 @@ class LoginDialog extends Component<IProps, IState> {
<br />
<Input
className = 'dialog-bottom-margin'
id = 'login-dialog-password'
label = { t('dialog.userPassword') }
name = 'password'
onChange = { this._onPasswordChange }

View File

@@ -48,7 +48,6 @@ import {
ASKED_TO_UNMUTE_NOTIFICATION_ID,
ASKED_TO_UNMUTE_SOUND_ID,
AUDIO_MODERATION_NOTIFICATION_ID,
CS_MODERATION_NOTIFICATION_ID,
VIDEO_MODERATION_NOTIFICATION_ID
} from './constants';
import {
@@ -89,11 +88,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
uid = VIDEO_MODERATION_NOTIFICATION_ID;
break;
}
case MEDIA_TYPE.SCREENSHARE: {
titleKey = 'notify.moderationInEffectCSTitle';
uid = CS_MODERATION_NOTIFICATION_ID;
break;
}
}
dispatch(showNotification({

View File

@@ -57,14 +57,6 @@ let mounted: boolean;
interface IProps {
/**
* The invisible text for screen readers.
*
* Intended to give the same info as `displayedText`, but can be customized to give more necessary context.
* If not given, `displayedText` will be used.
*/
accessibilityText?: string;
/**
* Css class to apply on container.
*/
@@ -101,15 +93,7 @@ interface IProps {
*
* @returns {React$Element<any>}
*/
function CopyButton({
accessibilityText,
className = '',
displayedText,
textToCopy,
textOnHover,
textOnCopySuccess,
id
}: IProps) {
function CopyButton({ className = '', displayedText, textToCopy, textOnHover, textOnCopySuccess, id }: IProps) {
const { classes, cx } = useStyles();
const [ isClicked, setIsClicked ] = useState(false);
const [ isHovered, setIsHovered ] = useState(false);
@@ -212,33 +196,20 @@ function CopyButton({
}
return (
<>
<div
aria-describedby = { displayedText === textOnHover
? undefined
: `${id}-sr-text` }
aria-label = { displayedText === textOnHover ? accessibilityText : textOnHover }
className = { cx(className, classes.copyButton, isClicked ? ' clicked' : '') }
id = { id }
onBlur = { onHoverOut }
onClick = { onClick }
onFocus = { onHoverIn }
onKeyPress = { onKeyPress }
onMouseOut = { onHoverOut }
onMouseOver = { onHoverIn }
role = 'button'
tabIndex = { 0 }>
{ renderContent() }
</div>
{ displayedText !== textOnHover && (
<span
className = 'sr-only'
id = { `${id}-sr-text` }>
{ accessibilityText }
</span>
)}
</>
<div
aria-label = { textOnHover }
className = { cx(className, classes.copyButton, isClicked ? ' clicked' : '') }
id = { id }
onBlur = { onHoverOut }
onClick = { onClick }
onFocus = { onHoverIn }
onKeyPress = { onKeyPress }
onMouseOut = { onHoverOut }
onMouseOver = { onHoverIn }
role = 'button'
tabIndex = { 0 }>
{ renderContent() }
</div>
);
}

View File

@@ -295,13 +295,3 @@ export const SET_ROOM = 'SET_ROOM';
* }
*/
export const SET_START_MUTED_POLICY = 'SET_START_MUTED_POLICY';
/**
* The type of (redux) action which updates the assumed bandwidth bps.
*
* {
* type: SET_ASSUMED_BANDWIDTH_BPS,
* assumedBandwidthBps: number
* }
*/
export const SET_ASSUMED_BANDWIDTH_BPS = 'SET_ASSUMED_BANDWIDTH_BPS';

View File

@@ -51,7 +51,6 @@ import {
NON_PARTICIPANT_MESSAGE_RECEIVED,
P2P_STATUS_CHANGED,
SEND_TONES,
SET_ASSUMED_BANDWIDTH_BPS,
SET_FOLLOW_ME,
SET_OBFUSCATED_ROOM,
SET_PASSWORD,
@@ -957,20 +956,3 @@ export function setLocalSubject(localSubject: string) {
localSubject
};
}
/**
* Sets the assumed bandwidth bps.
*
* @param {number} assumedBandwidthBps - The new assumed bandwidth.
* @returns {{
* type: SET_ASSUMED_BANDWIDTH_BPS,
* assumedBandwidthBps: number
* }}
*/
export function setAssumedBandwidthBps(assumedBandwidthBps: number) {
return {
type: SET_ASSUMED_BANDWIDTH_BPS,
assumedBandwidthBps
};
}

View File

@@ -1,7 +1,5 @@
import { AnyAction } from 'redux';
// @ts-ignore
import { MIN_ASSUMED_BANDWIDTH_BPS } from '../../../../modules/API/constants';
import {
ACTION_PINNED,
ACTION_UNPINNED,
@@ -41,7 +39,6 @@ import {
CONFERENCE_WILL_LEAVE,
P2P_STATUS_CHANGED,
SEND_TONES,
SET_ASSUMED_BANDWIDTH_BPS,
SET_PENDING_SUBJECT_CHANGE,
SET_ROOM
} from './actionTypes';
@@ -100,9 +97,6 @@ MiddlewareRegistry.register(store => next => action => {
_conferenceWillLeave(store);
break;
case P2P_STATUS_CHANGED:
return _p2pStatusChanged(next, action);
case PARTICIPANT_UPDATED:
return _updateLocalParticipantInConference(store, next, action);
@@ -119,8 +113,8 @@ MiddlewareRegistry.register(store => next => action => {
case TRACK_REMOVED:
return _trackAddedOrRemoved(store, next, action);
case SET_ASSUMED_BANDWIDTH_BPS:
return _setAssumedBandwidthBps(store, next, action);
case P2P_STATUS_CHANGED:
return _p2pStatusChanged(next, action);
}
return next(action);
@@ -696,33 +690,3 @@ function _p2pStatusChanged(next: Function, action: AnyAction) {
return result;
}
/**
* Notifies the feature base/conference that the action
* {@code SET_ASSUMED_BANDWIDTH_BPS} is being dispatched within a specific
* redux store.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
* specified {@code action} to the specified {@code store}.
* @param {Action} action - The redux action {@code SET_ASSUMED_BANDWIDTH_BPS}
* which is being dispatched in the specified {@code store}.
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _setAssumedBandwidthBps({ getState }: IStore, next: Function, action: AnyAction) {
const state = getState();
const conference = getCurrentConference(state);
const payload = Number(action.assumedBandwidthBps);
const assumedBandwidthBps = isNaN(payload) || payload < MIN_ASSUMED_BANDWIDTH_BPS
? MIN_ASSUMED_BANDWIDTH_BPS
: payload;
if (conference) {
conference.setAssumedBandwidthBps(assumedBandwidthBps);
}
return next(action);
}

View File

@@ -20,7 +20,6 @@ import {
CONFERENCE_WILL_LEAVE,
LOCK_STATE_CHANGED,
P2P_STATUS_CHANGED,
SET_ASSUMED_BANDWIDTH_BPS,
SET_FOLLOW_ME,
SET_OBFUSCATED_ROOM,
SET_PASSWORD,
@@ -32,7 +31,6 @@ import {
import { isRoomValid } from './functions';
const DEFAULT_STATE = {
assumedBandwidthBps: undefined,
conference: undefined,
e2eeSupported: undefined,
joining: undefined,
@@ -126,7 +124,6 @@ export interface IJitsiConference {
}
export interface IConferenceState {
assumedBandwidthBps?: number;
authEnabled?: boolean;
authLogin?: string;
authRequired?: IJitsiConference;
@@ -200,13 +197,6 @@ ReducerRegistry.register<IConferenceState>('features/base/conference',
case P2P_STATUS_CHANGED:
return _p2pStatusChanged(state, action);
case SET_ASSUMED_BANDWIDTH_BPS: {
const assumedBandwidthBps = action.assumedBandwidthBps >= 0
? Number(action.assumedBandwidthBps)
: undefined;
return set(state, 'assumedBandwidthBps', assumedBandwidthBps);
}
case SET_FOLLOW_ME:
return set(state, 'followMeEnabled', action.enabled);

View File

@@ -293,6 +293,12 @@ export interface IConfig {
};
dynamicBrandingUrl?: string;
e2ee?: {
e2eeLabels?: {
description?: string;
label?: string;
tooltip?: string;
warning?: string;
};
externallyManagedKey?: boolean;
labels?: {
description?: string;
@@ -390,7 +396,7 @@ export interface IConfig {
domain: string;
focus?: string;
muc: string;
visitorFocus?: string;
visitorFocus: string;
};
iAmRecorder?: boolean;
iAmSipGateway?: boolean;
@@ -441,10 +447,10 @@ export interface IConfig {
opusMaxAverageBitrate?: number;
p2p?: {
backToP2PDelay?: number;
codecPreferenceOrder?: Array<string>;
disabledCodec?: string;
enabled?: boolean;
iceTransportPolicy?: string;
mobileCodecPreferenceOrder?: Array<string>;
preferredCodec?: string;
stunServers?: Array<{ urls: string; }>;
};
participantsPane?: {
@@ -512,7 +518,6 @@ export interface IConfig {
stereo?: boolean;
subject?: string;
testing?: {
assumeBandwidth?: boolean;
callStatsThreshold?: number;
disableE2EE?: boolean;
mobileXmppWsThreshold?: number;
@@ -545,7 +550,8 @@ export interface IConfig {
useHostPageLocalStorage?: boolean;
useTurnUdp?: boolean;
videoQuality?: {
codecPreferenceOrder?: Array<string>;
disabledCodec?: string;
enforcePreferredCodec?: boolean;
maxBitratesVideo?: {
[key: string]: {
high?: number;
@@ -556,8 +562,8 @@ export interface IConfig {
minHeightForQualityLvl?: {
[key: number]: string;
};
mobileCodecPreferenceOrder?: Array<string>;
persist?: boolean;
preferredCodec?: string;
};
webhookProxyUrl?: string;
webrtcIceTcpDisable?: boolean;

View File

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

View File

@@ -43,6 +43,18 @@ 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'
}
};
/**
@@ -424,7 +436,7 @@ function _translateLegacyConfig(oldValue: IConfig) {
newValue.e2ee = newValue.e2ee || {};
if (oldValue.e2eeLabels) {
newValue.e2ee.labels = oldValue.e2eeLabels;
newValue.e2ee.e2eeLabels = oldValue.e2eeLabels;
}
newValue.defaultLocalDisplayName

View File

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

View File

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

View File

@@ -7,16 +7,6 @@ import { IIconProps } from './types';
interface IProps extends IIconProps {
/**
* Optional label for screen reader users.
*
* If set, this is will add a `aria-label` attribute on the svg element,
* contrary to the aria* props which set attributes on the container element.
*
* Use this if the icon conveys meaning and is not clickable.
*/
alt?: string;
/**
* The id of the element this button icon controls.
*/
@@ -124,7 +114,6 @@ export const DEFAULT_SIZE = navigator.product === 'ReactNative' ? 36 : 22;
*/
export default function Icon(props: IProps) {
const {
alt,
className,
color,
id,
@@ -167,13 +156,6 @@ export default function Icon(props: IProps) {
const jitsiIconClassName = calculatedColor ? 'jitsi-icon' : 'jitsi-icon jitsi-icon-default';
const iconProps = alt ? {
'aria-label': alt,
role: 'img'
} : {
'aria-hidden': true
};
return (
<Container
{ ...rest }
@@ -194,7 +176,6 @@ export default function Icon(props: IProps) {
style = { restStyle }
tabIndex = { tabIndex }>
<IconComponent
{ ...iconProps }
fill = { calculatedColor }
height = { calculatedSize }
id = { id }

View File

@@ -7,14 +7,6 @@ import { COLORS } from '../../constants';
interface IProps {
/**
* Optional label for screen reader users, invisible in the UI.
*
* Note: if the text prop is set, a screen reader will first announce
* the accessibilityText, then the text.
*/
accessibilityText?: string;
/**
* Own CSS class name.
*/
@@ -90,7 +82,6 @@ const useStyles = makeStyles()(theme => {
});
const Label = ({
accessibilityText,
className,
color,
icon,
@@ -126,7 +117,6 @@ const Label = ({
color = { iconColor }
size = '16'
src = { icon } />}
{accessibilityText && <span className = 'sr-only'>{accessibilityText}</span>}
{text && <span className = { icon && classes.withIcon }>{text}</span>}
</div>
);

View File

@@ -3,10 +3,10 @@ export * from './functions.any';
/**
* Loads config.js from a specific remote server.
*
* @param {string} _url - The URL to load.
* @returns {Promise<IConfig>}
* @param {string} url - The URL to load.
* @returns {Promise<Object>}
*/
export async function loadConfig(_url?: string) {
export async function loadConfig(url: string) { // eslint-disable-line @typescript-eslint/no-unused-vars
// Return "the config.js file" from the global scope - that is how the
// Web app on both the client and the server was implemented before the
// React Native app was even conceived.

View File

@@ -597,8 +597,7 @@ class VideoTransform extends Component<IProps, IState> {
this._onGesture('scale', scale);
}
} else if (gestureState.numberActiveTouches === 1
&& (this.initialDistance === undefined
|| isNaN(this.initialDistance))
&& isNaN(this.initialDistance ?? 0)
&& this._didMove(gestureState)) {
// this is a move event
const position = this._getTouchPosition(evt);

View File

@@ -152,7 +152,7 @@ class AudioTrack extends Component<IProps> {
const currentMuted = this._ref.muted;
const nextMuted = nextProps._muted;
if (typeof nextMuted === 'boolean' && currentMuted !== nextMuted) {
if (typeof nextMuted === 'boolean' && currentMuted !== nextVolume) {
this._ref.muted = nextMuted;
}
}

View File

@@ -1,5 +1,5 @@
import React, { Component, ReactNode } from 'react';
import { FocusOn } from 'react-focus-on';
import ReactFocusLock from 'react-focus-lock';
import { connect } from 'react-redux';
import { IReduxState } from '../../../app/types';
@@ -40,16 +40,6 @@ interface IProps {
*/
disablePopover?: boolean;
/**
* Whether we can reach the popover element via keyboard or not when trigger is 'hover' (true by default).
*
* Only works when trigger is set to 'hover'.
*
* There are some rare cases where we want to set this to false,
* when the popover content is not necessary for screen reader users, because accessible elsewhere.
*/
focusable?: boolean;
/**
* The id of the dom element acting as the Popover label (matches aria-labelledby).
*/
@@ -113,14 +103,6 @@ interface IState {
position: string;
top?: string;
} | null;
/**
* Whether the popover should be focus locked or not.
*
* This is enabled if we notice the popover is interactive
* (trigger is click or focusable is true).
*/
enableFocusLock: boolean;
}
/**
@@ -137,7 +119,6 @@ class Popover extends Component<IProps, IState> {
*/
static defaultProps = {
className: '',
focusable: true,
id: '',
trigger: 'hover'
};
@@ -159,12 +140,10 @@ class Popover extends Component<IProps, IState> {
super(props);
this.state = {
contextMenuStyle: null,
enableFocusLock: false
contextMenuStyle: null
};
// Bind event handlers so they are only bound once for every instance.
this._enableFocusLock = this._enableFocusLock.bind(this);
this._onHideDialog = this._onHideDialog.bind(this);
this._onShowDialog = this._onShowDialog.bind(this);
this._onKeyPress = this._onKeyPress.bind(this);
@@ -228,8 +207,8 @@ class Popover extends Component<IProps, IState> {
const { children,
className,
content,
focusable,
headingId,
headingLabel,
id,
overflowDrawer,
visible,
@@ -263,40 +242,35 @@ class Popover extends Component<IProps, IState> {
onKeyPress = { this._onKeyPress }
{ ...(trigger === 'hover' ? {
onMouseEnter: this._onShowDialog,
onMouseLeave: this._onHideDialog
} : {}) }
{ ...(trigger === 'hover' && focusable && {
role: 'button',
onMouseLeave: this._onHideDialog,
tabIndex: 0
}) }
} : {}) }
ref = { this._containerRef }>
{ visible && (
<DialogPortal
getRef = { this._setContextMenuRef }
onVisible = { this._isInteractive() ? this._enableFocusLock : undefined }
setSize = { this._setContextMenuStyle }
style = { this.state.contextMenuStyle }
targetSelector = '.popover-content'>
<FocusOn
// 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 = { Boolean(this._contextMenuRef) && this.state.enableFocusLock }
<ReactFocusLock
lockProps = {{
role: 'dialog',
'aria-modal': true,
'aria-labelledby': headingId,
'aria-label': !headingId && headingLabel ? headingLabel : undefined
}}
returnFocus = {
// If we return the focus to an element outside the viewport the page will scroll to
// this element which in our case is undesirable and the element is outside of the
// viewport on purpose (to be hidden). For example if we return the focus to the
// toolbox when it is hidden the whole page will move up in order to show the
// toolbox. This is usually followed up with displaying the toolbox (because now it
// is on focus) but because of the animation the whole scenario looks like jumping
// large video.
// viewport on purpose (to be hidden). For example if we return the focus to the toolbox
// when it is hidden the whole page will move up in order to show the toolbox. This is
// usually followed up with displaying the toolbox (because now it is on focus) but
// because of the animation the whole scenario looks like jumping large video.
isElementInTheViewport
}
shards = { this._contextMenuRef && [ this._contextMenuRef ] }>
}>
{this._renderContent()}
</FocusOn>
</ReactFocusLock>
</DialogPortal>
)}
{ children }
@@ -325,9 +299,7 @@ class Popover extends Component<IProps, IState> {
* @returns {void}
*/
_setContextMenuRef(elem: HTMLElement) {
if (!elem || document.body.contains(elem)) {
this._contextMenuRef = elem;
}
this._contextMenuRef = elem;
}
/**
@@ -389,12 +361,12 @@ class Popover extends Component<IProps, IState> {
* @returns {void}
*/
_onClick(event: React.MouseEvent) {
const { allowClick, trigger, focusable, visible } = this.props;
const { allowClick, trigger, visible } = this.props;
if (!allowClick) {
event.stopPropagation();
}
if (trigger === 'click' || focusable) {
if (trigger === 'click') {
if (visible) {
this._onHideDialog();
} else {
@@ -411,9 +383,7 @@ class Popover extends Component<IProps, IState> {
* @returns {void}
*/
_onKeyPress(e: React.KeyboardEvent) {
// first check that the element we pressed is the actual popover toggle or any of its descendant,
// otherwise pressing space or enter in any child element of the popover _dialog_ will trigger this.
if (e.currentTarget.contains(e.target as Node) && (e.key === ' ' || e.key === 'Enter')) {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
if (this.props.visible) {
this._onHideDialog();
@@ -465,49 +435,18 @@ class Popover extends Component<IProps, IState> {
* @returns {ReactElement}
*/
_renderContent() {
const { content, position, trigger, headingId, headingLabel } = this.props;
const { content, position, trigger } = this.props;
return (
<div className = { `popover ${trigger}` }>
<div
className = { `popover-content ${position.split('-')[0]}` }
data-autofocus = { this.state.enableFocusLock }
onKeyDown = { this._onEscKey }
{ ...(this.state.enableFocusLock && {
'aria-modal': true,
'aria-label': !headingId && headingLabel ? headingLabel : undefined,
'aria-labelledby': headingId,
role: 'dialog',
tabIndex: -1
}) }>
<div
className = { `popover ${trigger}` }
onKeyDown = { this._onEscKey }>
<div className = { `popover-content ${position.split('-')[0]}` }>
{ content }
</div>
</div>
);
}
/**
* Returns whether the popover is considered interactive or not.
*
* Interactive means the popover content is certainly composed of buttons, links…
* Non-interactive popovers are mostly tooltips.
*
* @private
* @returns {boolean}
*/
_isInteractive() {
return this.props.trigger === 'click' || Boolean(this.props.focusable);
}
/**
* Enables the focus lock in the popover dialog.
*
* @private
* @returns {void}
*/
_enableFocusLock() {
this.setState({ enableFocusLock: true });
}
}
/**

View File

@@ -103,7 +103,6 @@ const BaseIndicator = ({
className = { className }
id = { id }>
<Icon
alt = { t(tooltipKey) }
className = { iconClassName }
color = { iconColor }
id = { iconId }

View File

@@ -24,11 +24,6 @@ interface IProps {
*/
footer?: any;
/**
* Id for the included input, necessary for screen readers.
*/
id: string;
/**
* Indicates if the component is disabled.
*/
@@ -179,7 +174,6 @@ class MultiSelectAutocomplete extends Component<IProps, IState> {
error = { this.state.error }
errorDialog = { errorDialog }
filterValue = { this.state.filterValue }
id = { this.props.id }
isOpen = { this.state.isOpen }
items = { this.state.items }
noMatchesText = { noMatchesFound }

View File

@@ -1,3 +1,7 @@
import Platform from '../react/Platform';
import { ColorPalette } from './components/styles/ColorPalette';
declare type StyleSheet = {
[key: string]: string | number | { [key: string]: string | number; };
};
@@ -117,6 +121,28 @@ 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

@@ -5,7 +5,7 @@ import AbstractButton, { IProps } from './AbstractButton';
/**
* An abstract implementation of a button for toggling audio mute.
*/
export default class BaseAudioMuteButton<P extends IProps, S=any>
export default class AbstractAudioMuteButton<P extends IProps, S=any>
extends AbstractButton<P, S> {
icon = IconMic;

View File

@@ -5,7 +5,7 @@ import AbstractButton, { IProps } from './AbstractButton';
/**
* An abstract implementation of a button for toggling video mute.
*/
export default class BaseVideoMuteButton<P extends IProps, S=any>
export default class AbstractVideoMuteButton<P extends IProps, S=any>
extends AbstractButton<P, S> {
icon = IconVideo;

View File

@@ -5,6 +5,21 @@ import Popover from '../../../popover/components/Popover.web';
interface IProps {
/**
* The id of the element this button icon controls.
*/
ariaControls?: string;
/**
* Whether the element popup is expanded.
*/
ariaExpanded?: boolean;
/**
* Whether the element has a popup.
*/
ariaHasPopup?: boolean;
/**
* Aria label for the Icon.
*/
@@ -25,6 +40,11 @@ interface IProps {
*/
iconDisabled?: boolean;
/**
* The ID of the icon button.
*/
iconId?: string;
/**
* Popover close callback.
*/
@@ -64,10 +84,14 @@ interface IProps {
*/
export default function ToolboxButtonWithPopup(props: IProps) {
const {
ariaControls,
ariaExpanded,
ariaHasPopup,
ariaLabel,
children,
icon,
iconDisabled,
iconId,
onPopoverClose,
onPopoverOpen,
popoverContent,
@@ -95,6 +119,28 @@ export default function ToolboxButtonWithPopup(props: IProps) {
);
}
const iconProps: {
ariaControls?: string;
ariaExpanded?: boolean;
className?: string;
containerId?: string;
role?: string;
tabIndex?: number;
} = {};
if (iconDisabled) {
iconProps.className
= 'settings-button-small-icon settings-button-small-icon--disabled';
} else {
iconProps.className = 'settings-button-small-icon';
iconProps.role = 'button';
iconProps.tabIndex = 0;
iconProps.ariaControls = ariaControls;
iconProps.ariaExpanded = ariaExpanded;
iconProps.containerId = iconId;
}
return (
<div
className = 'settings-button-container'
@@ -109,10 +155,9 @@ export default function ToolboxButtonWithPopup(props: IProps) {
position = 'top'
visible = { visible }>
<Icon
alt = { ariaLabel }
className = { `settings-button-small-icon ${iconDisabled
? 'settings-button-small-icon--disabled'
: ''}` }
{ ...iconProps }
ariaHasPopup = { ariaHasPopup }
ariaLabel = { ariaLabel }
size = { 16 }
src = { icon } />
</Popover>

View File

@@ -145,7 +145,6 @@ const Tooltip = ({ containerClassName, content, children, position = 'top' }: IP
allowClick = { true }
className = { containerClassName }
content = { contentComponent }
focusable = { false }
onPopoverClose = { onPopoverClose }
onPopoverOpen = { onPopoverOpen }
position = { position }

View File

@@ -1,7 +1,6 @@
// @ts-expect-error
import { AUDIO_ONLY_SCREEN_SHARE_NO_TRACK } from '../../../../modules/UI/UIErrors';
import { IReduxState, IStore } from '../../app/types';
import { showModeratedNotification } from '../../av-moderation/actions';
import { shouldShowModeratedNotification } from '../../av-moderation/functions';
import { setNoiseSuppressionEnabled } from '../../noise-suppression/actions';
import { showNotification } from '../../notifications/actions';
@@ -45,7 +44,6 @@ export function toggleScreensharing(
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
// check for A/V Moderation when trying to start screen sharing
if ((enabled || enabled === undefined) && shouldShowModeratedNotification(MEDIA_TYPE.VIDEO, getState())) {
dispatch(showModeratedNotification(MEDIA_TYPE.SCREENSHARE));
return Promise.reject();
}

View File

@@ -1,5 +1,5 @@
import React, { ReactNode, useCallback, useContext, useEffect } from 'react';
import { FocusOn } from 'react-focus-on';
import FocusLock from 'react-focus-lock';
import { useTranslation } from 'react-i18next';
import { keyframes } from 'tss-react';
import { makeStyles } from 'tss-react/mui';
@@ -180,10 +180,11 @@ const BaseDialog = ({
return (
<div className = { cx(classes.container, isUnmounting && 'unmount') }>
<div className = { classes.backdrop } />
<FocusOn
<div
className = { classes.backdrop }
onClick = { onBackdropClick } />
<FocusLock
className = { classes.focusLock }
onClickOutside = { onBackdropClick }
returnFocus = {
// If we return the focus to an element outside the viewport the page will scroll to
@@ -195,16 +196,14 @@ const BaseDialog = ({
isElementInTheViewport
}>
<div
aria-description = { description }
aria-label = { title ?? t(titleKey ?? '') }
aria-describedby = { description }
aria-labelledby = { title ?? t(titleKey ?? '') }
aria-modal = { true }
className = { cx(classes.modal, isUnmounting && 'unmount', size, className) }
data-autofocus = { true }
role = 'dialog'
tabIndex = { -1 }>
role = 'dialog'>
{children}
</div>
</FocusOn>
</FocusLock>
</div>
);
};

View File

@@ -156,8 +156,8 @@ const Checkbox = ({
const isMobile = isMobileBrowser();
return (
<label className = { cx(styles.formControl, isMobile && 'is-mobile', className) }>
<div className = { cx(styles.activeArea, isMobile && 'is-mobile', disabled && styles.disabled) }>
<div className = { cx(styles.formControl, isMobile && 'is-mobile', className) }>
<label className = { cx(styles.activeArea, isMobile && 'is-mobile', disabled && styles.disabled) }>
<input
checked = { checked }
disabled = { disabled }
@@ -165,14 +165,13 @@ const Checkbox = ({
onChange = { onChange }
type = 'checkbox' />
<Icon
aria-hidden = { true }
className = 'checkmark'
color = { disabled ? theme.palette.icon03 : theme.palette.icon01 }
size = { 18 }
src = { IconCheck } />
</div>
<div>{label}</div>
</label>
</label>
<label>{label}</label>
</div>
);
};

View File

@@ -1,4 +1,4 @@
import React, { ReactNode, useCallback } from 'react';
import React, { ReactNode } from 'react';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
@@ -76,9 +76,6 @@ export interface IProps {
/**
* You can use this item as a tab. Defaults to button if not set.
*
* If no onClick handler is provided, we assume the context menu item is
* not interactive and no role will be set.
*/
role?: 'tab' | 'button';
@@ -182,28 +179,6 @@ const ContextMenuItem = ({
const { classes: styles, cx } = useStyles();
const _overflowDrawer: boolean = useSelector(showOverflowDrawer);
const onKeyPressHandler = useCallback(e => {
// only trigger the fallback behavior (onClick) if we dont have any explicit keyboard event handler
if (onClick && !onKeyPress && !onKeyDown && (e.key === 'Enter' || e.key === ' ')) {
e.preventDefault();
onClick(e);
}
if (onKeyPress) {
onKeyPress(e);
}
}, [ onClick, onKeyPress, onKeyDown ]);
let tabIndex: undefined | 0 | -1;
if (role === 'tab') {
tabIndex = selected ? 0 : -1;
}
if (role === 'button' && !disabled) {
tabIndex = 0;
}
return (
<div
aria-controls = { controls }
@@ -221,9 +196,12 @@ const ContextMenuItem = ({
key = { text }
onClick = { disabled ? undefined : onClick }
onKeyDown = { disabled ? undefined : onKeyDown }
onKeyPress = { disabled ? undefined : onKeyPressHandler }
role = { onClick ? role : undefined }
tabIndex = { onClick ? tabIndex : undefined }>
onKeyPress = { disabled ? undefined : onKeyPress }
role = { role }
tabIndex = { role === 'tab'
? selected ? 0 : -1
: disabled ? undefined : 0
}>
{customIcon ? customIcon
: icon && <Icon
className = { styles.contextMenuItemIcon }

View File

@@ -6,7 +6,6 @@ import { makeStyles } from 'tss-react/mui';
import { hideDialog } from '../../../dialog/actions';
import { IconCloseLarge } from '../../../icons/svg';
import { withPixelLineHeight } from '../../../styles/functions.web';
import { operatesWithEnterKey } from '../../functions.web';
import BaseDialog, { IProps as IBaseDialogProps } from './BaseDialog';
import Button from './Button';
@@ -109,13 +108,8 @@ const Dialog = ({
}, [ onCancel ]);
const submit = useCallback(() => {
if (onSubmit && (
(document.activeElement && !operatesWithEnterKey(document.activeElement))
|| !document.activeElement
)) {
!disableAutoHideOnSubmit && dispatch(hideDialog());
onSubmit();
}
!disableAutoHideOnSubmit && dispatch(hideDialog());
onSubmit?.();
}, [ onSubmit ]);
return (
@@ -130,11 +124,11 @@ const Dialog = ({
title = { title }
titleKey = { titleKey }>
<div className = { classes.header }>
<h1
<p
className = { classes.title }
id = 'dialog-title'>
{title ?? t(titleKey ?? '')}
</h1>
</p>
{!hideCloseButton && (
<ClickableIcon
accessibilityLabel = { t('dialog.accessibilityLabel.close') }
@@ -166,7 +160,6 @@ const Dialog = ({
accessibilityLabel = { t(ok.translationKey ?? '') }
disabled = { ok.disabled }
id = 'modal-dialog-ok-button'
isSubmit = { true }
labelKey = { ok.translationKey }
onClick = { submit } />}
</div>

View File

@@ -1,4 +1,5 @@
import React, { ComponentType, useCallback, useEffect, useMemo, useState } from 'react';
import { MoveFocusInside } from 'react-focus-lock';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
@@ -186,7 +187,7 @@ const DialogWithTabs = ({
useEffect(() => {
if (isMobile) {
setSelectedTab(defaultTab);
setSelectedTab(undefined);
} else {
setSelectedTab(defaultTab ?? tabs[0].name);
}
@@ -316,19 +317,20 @@ const DialogWithTabs = ({
<BaseDialog
className = { cx(classes.dialog, className) }
onClose = { onClose }
size = 'large'
titleKey = { titleKey }>
size = 'large'>
{(!isMobile || !selectedTab) && (
<div
aria-orientation = 'vertical'
className = { classes.sidebar }
role = { isMobile ? undefined : 'tablist' }>
<div className = { classes.titleContainer }>
<h1
className = { classes.title }
tabIndex = { -1 }>
{t(titleKey ?? '')}
</h1>
<MoveFocusInside>
<h2
className = { classes.title }
tabIndex = { -1 }>
{t(titleKey ?? '')}
</h2>
</MoveFocusInside>
{isMobile && closeIcon}
</div>
{tabs.map((tab, index) => {
@@ -364,11 +366,11 @@ const DialogWithTabs = ({
{isMobile && (
<div className = { cx(classes.buttonContainer, classes.header) }>
<span className = { classes.backContainer }>
<h1
<h2
className = { classes.title }
tabIndex = { -1 }>
{(selectedTabIndex !== null) && t(tabs[selectedTabIndex].labelKey)}
</h1>
</h2>
<ClickableIcon
accessibilityLabel = { t('dialog.Back') }
icon = { IconArrowBack }
@@ -399,13 +401,13 @@ const DialogWithTabs = ({
<div
className = { cx(classes.buttonContainer, classes.footer) }>
<Button
accessibilityLabel = { t('dialog.accessibilityLabel.Cancel') }
accessibilityLabel = { t('dialog.Cancel') }
id = 'modal-dialog-cancel-button'
labelKey = { 'dialog.Cancel' }
onClick = { onClose }
type = 'tertiary' />
<Button
accessibilityLabel = { t('dialog.accessibilityLabel.Ok') }
accessibilityLabel = { t('dialog.Ok') }
id = 'modal-dialog-ok-button'
labelKey = { 'dialog.Ok' }
onClick = { onSubmit } />

View File

@@ -15,18 +15,10 @@ interface IProps extends IInputProps {
bottomLabel?: string;
className?: string;
iconClick?: () => void;
/**
* The id to set on the input element.
* This is required because we need it internally to tie the input to its
* info (label, error) so that screen reader users don't get lost.
*/
id: string;
id?: string;
maxLength?: number;
maxRows?: number;
maxValue?: number;
minRows?: number;
minValue?: number;
mode?: 'text' | 'none' | 'decimal' | 'numeric' | 'tel' | 'search' | ' email' | 'url';
name?: string;
onBlur?: (e: any) => void;
@@ -101,15 +93,6 @@ const useStyles = makeStyles()(theme => {
}
},
'input::-webkit-outer-spin-button, input::-webkit-inner-spin-button': {
'-webkit-appearance': 'none',
margin: 0
},
'input[type=number]': {
'-moz-appearance': 'textfield'
},
icon: {
position: 'absolute',
top: '50%',
@@ -164,10 +147,8 @@ const Input = React.forwardRef<any, IProps>(({
iconClick,
id,
label,
maxValue,
maxLength,
maxRows,
minValue,
minRows,
mode,
name,
@@ -193,11 +174,7 @@ const Input = React.forwardRef<any, IProps>(({
return (
<div className = { cx(styles.inputContainer, className) }>
{label && <label
className = { cx(styles.label, isMobile && 'is-mobile') }
htmlFor = { id } >
{label}
</label>}
{label && <span className = { cx(styles.label, isMobile && 'is-mobile') }>{label}</span>}
<div className = { styles.fieldContainer }>
{icon && <Icon
{ ...(iconClick ? { tabIndex: 0 } : {}) }
@@ -213,7 +190,7 @@ const Input = React.forwardRef<any, IProps>(({
className = { cx(styles.input, isMobile && 'is-mobile',
error && 'error', clearable && styles.clearableInput, icon && 'icon-input') }
disabled = { disabled }
id = { id }
{ ...(id ? { id } : {}) }
maxLength = { maxLength }
maxRows = { maxRows }
minRows = { minRows }
@@ -227,7 +204,6 @@ const Input = React.forwardRef<any, IProps>(({
value = { value } />
) : (
<input
aria-describedby = { bottomLabel ? `${id}-description` : undefined }
aria-label = { accessibilityLabel }
autoComplete = { autoComplete }
autoFocus = { autoFocus }
@@ -235,11 +211,9 @@ const Input = React.forwardRef<any, IProps>(({
error && 'error', clearable && styles.clearableInput, icon && 'icon-input') }
data-testid = { testId }
disabled = { disabled }
id = { id }
{ ...(id ? { id } : {}) }
{ ...(mode ? { inputmode: mode } : {}) }
{ ...(type === 'number' ? { max: maxValue } : {}) }
maxLength = { maxLength }
{ ...(type === 'number' ? { min: minValue } : {}) }
name = { name }
onBlur = { onBlur }
onChange = { handleChange }
@@ -260,9 +234,7 @@ const Input = React.forwardRef<any, IProps>(({
</button>}
</div>
{bottomLabel && (
<span
className = { cx(styles.bottomLabel, isMobile && 'is-mobile', error && 'error') }
id = { `${id}-description` }>
<span className = { cx(styles.bottomLabel, isMobile && 'is-mobile', error && 'error') }>
{bottomLabel}
</span>
)}

View File

@@ -14,7 +14,6 @@ interface IProps {
error?: boolean;
errorDialog?: JSX.Element | null;
filterValue?: string;
id: string;
isOpen?: boolean;
items: MultiSelectItem[];
noMatchesText?: string;
@@ -102,7 +101,6 @@ const MultiSelect = ({
error,
errorDialog,
placeholder,
id,
items,
filterValue,
onFilterChange,
@@ -147,7 +145,6 @@ const MultiSelect = ({
<Input
autoFocus = { autoFocus }
disabled = { disabled }
id = { id }
onChange = { onFilterChange }
placeholder = { placeholder }
ref = { inputRef }

View File

@@ -28,12 +28,6 @@ interface ISelectProps {
*/
error?: boolean;
/**
* Id of the <select> element.
* Necessary for screen reader users, to link the label and error to the select.
*/
id: string;
/**
* Label to be displayed above the select.
*/
@@ -146,7 +140,6 @@ const Select = ({
className,
disabled,
error,
id,
label,
onChange,
options,
@@ -156,17 +149,11 @@ const Select = ({
return (
<div className = { classes.container }>
{label && <label
className = { cx(classes.label, isMobile && 'is-mobile') }
htmlFor = { id } >
{label}
</label>}
{label && <span className = { cx(classes.label, isMobile && 'is-mobile') }>{label}</span>}
<div className = { classes.selectContainer }>
<select
aria-describedby = { bottomLabel ? `${id}-description` : undefined }
className = { cx(classes.select, isMobile && 'is-mobile', className, error && 'error') }
disabled = { disabled }
id = { id }
onChange = { onChange }
value = { value }>
{options.map(option => (<option
@@ -180,9 +167,7 @@ const Select = ({
src = { IconArrowDown } />
</div>
{bottomLabel && (
<span
className = { cx(classes.bottomLabel, isMobile && 'is-mobile', error && 'error') }
id = { `${id}-description` }>
<span className = { cx(classes.bottomLabel, isMobile && 'is-mobile', error && 'error') }>
{bottomLabel}
</span>
)}

View File

@@ -52,7 +52,6 @@ const useStyles = makeStyles()(theme => {
width: '16px',
height: '16px',
position: 'absolute',
zIndex: 5,
top: '4px',
left: '4px',
backgroundColor: theme.palette.ui10,
@@ -74,38 +73,8 @@ const useStyles = makeStyles()(theme => {
},
checkbox: {
position: 'absolute',
zIndex: 10,
cursor: 'pointer',
left: 0,
right: 0,
top: 0,
bottom: 0,
width: '100%',
height: '100%',
opacity: 0,
'&.focus-visible + .toggle-checkbox-ring': {
outline: 0,
boxShadow: `0px 0px 0px 2px ${theme.palette.focus01}`
}
},
checkboxRing: {
position: 'absolute',
pointerEvents: 'none',
zIndex: 6,
left: 0,
right: 0,
top: 0,
bottom: 0,
width: '100%',
height: '100%',
borderRadius: '12px',
'&.is-mobile': {
borderRadius: '32px'
}
height: 0,
width: 0
}
};
});
@@ -119,7 +88,7 @@ const Switch = ({ className, id, checked, disabled, onChange }: IProps) => {
}, []);
return (
<span
<label
className = { cx('toggle-container', styles.container, checked && styles.containerOn,
isMobile && 'is-mobile', disabled && 'disabled', className) }>
<input
@@ -129,9 +98,8 @@ const Switch = ({ className, id, checked, disabled, onChange }: IProps) => {
className = { styles.checkbox }
disabled = { disabled }
onChange = { change } />
<div className = { cx('toggle-checkbox-ring', styles.checkboxRing, isMobile && 'is-mobile') } />
<div className = { cx('toggle', styles.toggle, checked && styles.toggleOn, isMobile && 'is-mobile') } />
</span>
</label>
);
};

View File

@@ -82,28 +82,3 @@ export function isElementInTheViewport(element?: Element): boolean {
return false;
}
const enterKeyElements = [ 'select', 'textarea', 'summary', 'a' ];
/**
* Informs whether or not the given element does something on its own when pressing the Enter key.
*
* This is useful to correctly submit custom made "forms" that are not using the native form element,
* only when the user is not using an element that needs the enter key to work.
* Note the implementation is incomplete and should be updated as needed if more complex use cases arise
* (for example, the Tabs aria pattern is not handled).
*
* @param {Element} element - The element.
* @returns {boolean}
*/
export function operatesWithEnterKey(element: Element): boolean {
if (enterKeyElements.includes(element.tagName.toLowerCase())) {
return true;
}
if (element.tagName.toLowerCase() === 'button' && element.getAttribute('role') === 'button') {
return true;
}
return false;
}

View File

@@ -1,14 +1,10 @@
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';
@@ -63,24 +59,6 @@ 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

@@ -135,7 +135,6 @@ class ChatInput extends Component<IProps, IState> {
className = 'chat-input'
icon = { this.props._areSmileysDisabled ? undefined : IconFaceSmile }
iconClick = { this._toggleSmileysPanel }
id = 'chat-input-messagebox'
maxRows = { 5 }
onChange = { this._onMessageChange }
onKeyPress = { this._onDetectSubmit }

View File

@@ -1,3 +1,4 @@
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;
@@ -37,11 +38,11 @@ export default {
/**
* {@code Conference} Style.
*/
conference: {
conference: fixAndroidViewClipping({
alignSelf: 'stretch',
backgroundColor: BaseTheme.palette.uiBackground,
flex: 1
},
}),
displayNameContainer: {
margin: 10

View File

@@ -32,7 +32,6 @@ const RaisedHandsCountLabel = () => {
content = { t('raisedHandsLabel') }
position = { 'bottom' }>
<Label
accessibilityText = { t('raisedHandsLabel') }
className = { styles.label }
icon = { IconRaiseHand }
iconColor = { theme.palette.icon04 }

View File

@@ -1,143 +0,0 @@
import React, { KeyboardEvent, useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
// @ts-ignore
import { MIN_ASSUMED_BANDWIDTH_BPS } from '../../../../../modules/API/constants';
import { IReduxState } from '../../../app/types';
import { setAssumedBandwidthBps as saveAssumedBandwidthBps } from '../../../base/conference/actions';
import { IconInfoCircle } from '../../../base/icons/svg';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
import Dialog from '../../../base/ui/components/web/Dialog';
import Input from '../../../base/ui/components/web/Input';
const useStyles = makeStyles()(theme => {
return {
content: {
color: theme.palette.text01
},
info: {
background: theme.palette.ui01,
...withPixelLineHeight(theme.typography.labelRegular),
color: theme.palette.text02,
marginTop: theme.spacing(2)
},
possibleValues: {
margin: 0,
paddingLeft: theme.spacing(4)
}
};
});
/**
* Bandwidth settings dialog component.
*
* @returns {ReactElement}
*/
const BandwidthSettingsDialog = () => {
const { classes } = useStyles();
const { t } = useTranslation();
const dispatch = useDispatch();
const [ showAssumedBandwidthInfo, setShowAssumedBandwidthInfo ] = useState(false);
const currentAssumedBandwidthBps = useSelector(
(state: IReduxState) => state['features/base/conference'].assumedBandwidthBps
);
const [ assumedBandwidthBps, setAssumedBandwidthBps ] = useState(
currentAssumedBandwidthBps === MIN_ASSUMED_BANDWIDTH_BPS
|| currentAssumedBandwidthBps === undefined
? ''
: currentAssumedBandwidthBps
);
/**
* Changes the assumed bandwidth bps.
*
* @param {string} value - The key event to handle.
*
* @returns {void}
*/
const onAssumedBandwidthBpsChange = useCallback((value: string) => {
setAssumedBandwidthBps(value);
}, [ setAssumedBandwidthBps ]);
/**
* Persists the assumed bandwidth bps.
*
* @param {string} value - The key event to handle.
*
* @returns {void}
*/
const onAssumedBandwidthBpsSave = useCallback(() => {
if (assumedBandwidthBps !== currentAssumedBandwidthBps) {
dispatch(saveAssumedBandwidthBps(Number(
assumedBandwidthBps === '' ? MIN_ASSUMED_BANDWIDTH_BPS : assumedBandwidthBps
)));
}
}, [ assumedBandwidthBps, currentAssumedBandwidthBps, dispatch, saveAssumedBandwidthBps ]);
/**
* Validates the assumed bandwidth bps.
*
* @param {KeyboardEvent<any>} e - The key event to handle.
*
* @returns {void}
*/
const onAssumedBandwidthBpsKeyPress = useCallback((e: KeyboardEvent<any>) => {
const isValid = (e.charCode !== 8 && e.charCode === 0) || (e.charCode >= 48 && e.charCode <= 57);
if (!isValid) {
e.preventDefault();
}
}, []);
/**
* Callback invoked to hide or show the possible values
* of the assumed bandwidth setting.
*
* @returns {void}
*/
const toggleInfoPanel = useCallback(() => {
setShowAssumedBandwidthInfo(!showAssumedBandwidthInfo);
}, [ setShowAssumedBandwidthInfo, showAssumedBandwidthInfo ]);
return (
<Dialog
onSubmit = { onAssumedBandwidthBpsSave }
titleKey = 'bandwidthSettings.title'>
<div className = { classes.content }>
<Input
bottomLabel = { t('bandwidthSettings.assumedBandwidthBpsWarning') }
icon = { IconInfoCircle }
iconClick = { toggleInfoPanel }
id = 'setAssumedBandwidthBps'
label = { t('bandwidthSettings.setAssumedBandwidthBps') }
minValue = { 0 }
name = 'assumedBandwidthBps'
onChange = { onAssumedBandwidthBpsChange }
onKeyPress = { onAssumedBandwidthBpsKeyPress }
placeholder = { t('bandwidthSettings.assumedBandwidthBps') }
type = 'number'
value = { assumedBandwidthBps } />
{showAssumedBandwidthInfo && (
<div className = { classes.info }>
<span>{t('bandwidthSettings.possibleValues')}:</span>
<ul className = { classes.possibleValues }>
<li>
<b>{t('bandwidthSettings.leaveEmpty')}</b> {t('bandwidthSettings.leaveEmptyEffect')}
</li>
<li><b>0</b> {t('bandwidthSettings.zeroEffect')}</li>
<li>
<b>{t('bandwidthSettings.customValue')}</b> {t('bandwidthSettings.customValueEffect')}
</li>
</ul>
</div>
)}
</div>
</Dialog>
);
};
export default BandwidthSettingsDialog;

View File

@@ -347,14 +347,12 @@ class ConnectionIndicator extends AbstractConnectionIndicator<IProps, IState> {
_connectionIndicatorInactiveDisabled,
_videoTrack,
classes,
iconSize,
t
iconSize
} = this.props;
return (
<div
style = {{ fontSize: iconSize }}>
<span className = 'sr-only'>{ t('videothumbnail.connectionInfo') }</span>
<ConnectionIndicatorIcon
classes = { classes }
colorClass = { this._getConnectionColorClass() }

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