Merge pull request #14900 from ramonlsouza/merge-2425-apr27

chore: Merge 2.4 into 2.5
This commit is contained in:
Anton Georgiev 2022-04-27 15:15:28 -04:00 committed by GitHub
commit 7894dfb0e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1458 additions and 830 deletions

View File

@ -21236,11 +21236,11 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"ejs": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz",
"integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==",
"requires": {
"jake": "^10.6.1"
"jake": "^10.8.5"
}
},
"electron-to-chromium": {
@ -22007,11 +22007,29 @@
}
},
"filelist": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
"integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.3.tgz",
"integrity": "sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==",
"requires": {
"minimatch": "^3.0.4"
"minimatch": "^5.0.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"minimatch": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"filesize": {

View File

@ -8,10 +8,10 @@ mobile-experience@1.1.0
mongo@1.14.6
reactive-var@1.0.11
standard-minifier-css@1.7.4
standard-minifier-css@1.8.1
standard-minifier-js@2.8.0
es5-shim@4.8.0
ecmascript@0.16.1
ecmascript@0.16.2
shell-server@0.5.0
static-html@1.3.2

View File

@ -1 +1 @@
METEOR@2.6.1
METEOR@2.7.1

View File

@ -1,6 +1,6 @@
allow-deny@1.1.1
autoupdate@1.8.0
babel-compiler@7.8.1
babel-compiler@7.9.0
babel-runtime@1.5.0
base64@1.0.12
binary-heap@1.0.11
@ -16,11 +16,11 @@ ddp-common@1.4.0
ddp-server@2.5.0
diff-sequence@1.1.1
dynamic-import@0.7.2
ecmascript@0.16.1
ecmascript@0.16.2
ecmascript-runtime@0.8.0
ecmascript-runtime-client@0.12.1
ecmascript-runtime-server@0.11.0
ejson@1.1.1
ejson@1.1.2
es5-shim@4.8.0
fetch@0.1.1
geojson-utils@1.0.10
@ -39,13 +39,13 @@ meteortesting:browser-tests@1.3.5
meteortesting:mocha@2.0.3
meteortesting:mocha-core@8.1.2
minifier-css@1.6.0
minifier-js@2.7.3
minifier-js@2.7.4
minimongo@1.8.0
mobile-experience@1.1.0
mobile-status-bar@1.1.0
modern-browsers@0.1.7
modules@0.18.0
modules-runtime@0.12.0
modules-runtime@0.13.0
mongo@1.14.6
mongo-decimal@0.1.2
mongo-dev-server@1.1.0
@ -54,7 +54,7 @@ npm-mongo@4.3.1
ordered-dict@1.1.0
promise@0.12.0
random@1.2.0
react-fast-refresh@0.2.2
react-fast-refresh@0.2.3
react-meteor-data@2.4.0
reactive-dict@1.3.0
reactive-var@1.0.11
@ -66,7 +66,7 @@ session@1.2.0
shell-server@0.5.0
socket-stream-client@0.4.0
spacebars-compiler@1.3.0
standard-minifier-css@1.7.4
standard-minifier-css@1.8.1
standard-minifier-js@2.8.0
static-html@1.3.2
templating-tools@1.2.1

View File

@ -4,7 +4,6 @@ import Langmap from 'langmap';
import fs from 'fs';
import Users from '/imports/api/users';
import './settings';
import { lookup as lookupUserAgent } from 'useragent';
import { check } from 'meteor/check';
import Logger from './logger';
import Redis from './redis';
@ -304,20 +303,6 @@ WebApp.connectHandlers.use('/feedback', (req, res) => {
}));
});
WebApp.connectHandlers.use('/useragent', (req, res) => {
const userAgent = req.headers['user-agent'];
let response = 'No user agent found in header';
if (userAgent) {
response = lookupUserAgent(userAgent).toString();
}
Logger.info(`The requesting user agent is ${response}`);
// res.setHeader('Content-Type', 'application/json');
res.writeHead(200);
res.end(response);
});
WebApp.connectHandlers.use('/guestWait', (req, res) => {
if (!guestWaitHtml) {
try {

View File

@ -44,6 +44,7 @@ import Settings from '/imports/ui/services/settings';
import LayoutService from '/imports/ui/components/layout/service';
import { registerTitleView } from '/imports/utils/dom-utils';
import GlobalStyles from '/imports/ui/stylesheets/styled-components/globalStyles';
import MediaService from '/imports/ui/components/media/service';
const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
const APP_CONFIG = Meteor.settings.public.app;
@ -178,6 +179,10 @@ class App extends Component {
value: presentationOpen,
});
if (!presentationOpen && !MediaService.getSwapLayout()) {
MediaService.setSwapLayout(layoutContextDispatch);
}
Modal.setAppElement('#app');
const fontSize = isMobile() ? MOBILE_FONT_SIZE : DESKTOP_FONT_SIZE;

View File

@ -41,7 +41,7 @@ const handleLeaveAudio = () => {
Storage.setItem('getEchoTest', true);
}
Service.exitAudio();
Service.forceExitAudio();
logger.info({
logCode: 'audiocontrols_leave_audio',
extraInfo: { logType: 'user_action' },

View File

@ -267,28 +267,7 @@ class AudioModal extends Component {
disableActions: false,
});
}).catch((err) => {
const { type } = err;
switch (type) {
case 'MEDIA_ERROR':
this.setState({
content: 'help',
errCode: 0,
disableActions: false,
});
break;
case 'CONNECTION_ERROR':
this.setState({
errCode: 0,
disableActions: false,
});
break;
default:
this.setState({
errCode: 0,
disableActions: false,
});
break;
}
this.handleJoinMicrophoneError(err);
});
}
@ -342,7 +321,29 @@ class AudioModal extends Component {
this.setState({
disableActions: false,
});
}).catch(this.handleGoToAudioOptions);
}).catch((err) => {
this.handleJoinMicrophoneError(err);
});
}
handleJoinMicrophoneError(err) {
const { type } = err;
switch (type) {
case 'MEDIA_ERROR':
this.setState({
content: 'help',
errCode: 0,
disableActions: false,
});
break;
case 'CONNECTION_ERROR':
default:
this.setState({
errCode: 0,
disableActions: false,
});
break;
}
}
setContent(content) {

View File

@ -14,6 +14,8 @@ import { screenshareHasEnded } from '/imports/ui/components/screenshare/service'
import AudioManager from '/imports/ui/services/audio-manager';
import Settings from '/imports/ui/services/settings';
import BreakoutDropdown from '/imports/ui/components/breakout-room/breakout-dropdown/component';
import Users from '/imports/api/users';
import Auth from '/imports/ui/services/auth';
const intlMessages = defineMessages({
breakoutTitle: {
@ -282,7 +284,8 @@ class BreakoutRoom extends PureComponent {
amIPresenter,
intl,
isUserInBreakoutRoom,
exitAudio,
forceExitAudio,
rejoinAudio,
setBreakoutAudioTransferStatus,
getBreakoutAudioTransferStatus,
} = this.props;
@ -349,7 +352,7 @@ class BreakoutRoom extends PureComponent {
this.getBreakoutURL(breakoutId);
// leave main room's audio,
// and stops video and screenshare when joining a breakout room
exitAudio();
forceExitAudio();
logger.info({
logCode: 'breakoutroom_join',
extraInfo: { logType: 'user_action' },
@ -357,6 +360,31 @@ class BreakoutRoom extends PureComponent {
VideoService.storeDeviceIds();
VideoService.exitVideo();
if (amIPresenter) screenshareHasEnded();
Tracker.autorun((c) => {
const selector = {
meetingId: breakoutId,
};
const query = Users.find(selector, {
fields: {
loggedOut: 1,
extId: 1,
},
});
const observeLogOut = (user) => {
if (user?.loggedOut && user?.extId?.startsWith(Auth.userID)) {
rejoinAudio();
c.stop();
}
}
query.observe({
added: observeLogOut,
changed: observeLogOut,
});
});
}}
disabled={disable}
/>

View File

@ -7,6 +7,11 @@ import Service from './service';
import { layoutDispatch } from '../layout/context';
import Auth from '/imports/ui/services/auth';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import {
didUserSelectedMicrophone,
didUserSelectedListenOnly,
} from '/imports/ui/components/audio/audio-modal/service';
import { makeCall } from '/imports/ui/services/api';
const BreakoutContainer = (props) => {
const layoutContextDispatch = layoutDispatch();
@ -45,6 +50,30 @@ export default withTracker((props) => {
getBreakoutAudioTransferStatus,
} = AudioService;
const logUserCouldNotRejoinAudio = () => {
logger.warn({
logCode: 'mainroom_audio_rejoin',
extraInfo: { logType: 'user_action' },
}, 'leaving breakout room couldn\'t rejoin audio in the main room');
};
const rejoinAudio = () => {
if (didUserSelectedMicrophone()) {
AudioManager.joinMicrophone().then(() => {
makeCall('toggleVoice', null, true).catch(() => {
AudioManager.forceExitAudio();
logUserCouldNotRejoinAudio();
});
}).catch(() => {
logUserCouldNotRejoinAudio();
});
} else if (didUserSelectedListenOnly()) {
AudioManager.joinListenOnly().catch(() => {
logUserCouldNotRejoinAudio();
});
}
};
return {
...props,
breakoutRooms,
@ -61,7 +90,8 @@ export default withTracker((props) => {
amIModerator: amIModerator(),
isMeteorConnected,
isUserInBreakoutRoom,
exitAudio: () => AudioManager.exitAudio(),
forceExitAudio: () => AudioManager.forceExitAudio(),
rejoinAudio,
isReconnecting,
setBreakoutAudioTransferStatus,
getBreakoutAudioTransferStatus,

View File

@ -453,6 +453,7 @@ const CustomLayout = (props) => {
const mediaBounds = calculatesMediaBounds(
sidebarNavWidth.width, sidebarContentWidth.width, cameraDockBounds,
);
const sidebarSize = sidebarContentWidth.width + sidebarNavWidth.width;
const { height: actionBarHeight } = calculatesActionbarHeight();
let horizontalCameraDiff = 0;
@ -496,9 +497,9 @@ const CustomLayout = (props) => {
layoutContextDispatch({
type: ACTIONS.SET_CAPTIONS_OUTPUT,
value: {
left: !isRTL ? (mediaBounds.left + captionsMargin) : null,
right: isRTL ? (mediaBounds.right + captionsMargin) : null,
maxWidth: mediaBounds.width - (captionsMargin * 2),
left: !isRTL ? (sidebarSize + captionsMargin) : null,
right: isRTL ? (sidebarSize + captionsMargin) : null,
maxWidth: mediaAreaBounds.width - (captionsMargin * 2),
},
});

View File

@ -319,9 +319,9 @@ const PresentationFocusLayout = (props) => {
layoutContextDispatch({
type: ACTIONS.SET_CAPTIONS_OUTPUT,
value: {
left: !isRTL ? (mediaBounds.left + captionsMargin) : null,
right: isRTL ? (mediaBounds.right + captionsMargin) : null,
maxWidth: mediaBounds.width - (captionsMargin * 2),
left: !isRTL ? (sidebarSize + captionsMargin) : null,
right: isRTL ? (sidebarSize + captionsMargin) : null,
maxWidth: mediaAreaBounds.width - (captionsMargin * 2),
},
});

View File

@ -363,9 +363,9 @@ const SmartLayout = (props) => {
layoutContextDispatch({
type: ACTIONS.SET_CAPTIONS_OUTPUT,
value: {
left: !isRTL ? (mediaBounds.left + captionsMargin) : null,
right: isRTL ? (mediaBounds.right + captionsMargin) : null,
maxWidth: mediaBounds.width - (captionsMargin * 2),
left: !isRTL ? (sidebarSize + captionsMargin) : null,
right: isRTL ? (sidebarSize + captionsMargin) : null,
maxWidth: mediaAreaBounds.width - (captionsMargin * 2),
},
});

View File

@ -331,9 +331,9 @@ const VideoFocusLayout = (props) => {
layoutContextDispatch({
type: ACTIONS.SET_CAPTIONS_OUTPUT,
value: {
left: !isRTL ? (mediaBounds.left + captionsMargin) : null,
right: isRTL ? (mediaBounds.right + captionsMargin) : null,
maxWidth: mediaBounds.width - (captionsMargin * 2),
left: !isRTL ? (sidebarSize + captionsMargin) : null,
right: isRTL ? (sidebarSize + captionsMargin) : null,
maxWidth: mediaAreaBounds.width - (captionsMargin * 2),
},
});

View File

@ -353,9 +353,11 @@ class Poll extends Component {
diff -= 1;
}
} else {
let index = optList.length-1;
while (diff < 0) {
this.handleRemoveOption();
this.handleRemoveOption(index);
diff += 1;
index -=1;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -28,16 +28,16 @@
]
},
"dependencies": {
"@babel/runtime": "^7.13.10",
"@browser-bunyan/server-stream": "^1.6.1",
"@babel/runtime": "^7.17.9",
"@browser-bunyan/server-stream": "^1.8.0",
"@jitsi/sdp-interop": "0.1.14",
"@material-ui/core": "^4.11.4",
"autoprefixer": "^10.2.5",
"@material-ui/core": "^4.12.4",
"autoprefixer": "^10.4.4",
"axios": "^0.21.3",
"babel-runtime": "~6.26.0",
"bbb-diff": "^1.1.0",
"bowser": "^2.11.0",
"browser-bunyan": "^1.6.3",
"browser-bunyan": "^1.8.0",
"classnames": "^2.2.6",
"eventemitter2": "~5.0.1",
"fastdom": "^1.0.10",
@ -49,11 +49,11 @@
"langmap": "0.0.16",
"lodash": "^4.17.21",
"makeup-screenreader-trap": "0.0.5",
"meteor-node-stubs": "^1.0.3",
"postcss-nested": "^5.0.5",
"meteor-node-stubs": "^1.2.1",
"postcss-nested": "^5.0.6",
"probe-image-size": "^4.1.1",
"prom-client": "^13.2.0",
"prop-types": "^15.7.2",
"prop-types": "^15.8.1",
"queue": "^6.0.2",
"re-resizable": "^4.11.0",
"react": "^16.14.0",
@ -65,7 +65,7 @@
"react-intl": "^3.12.1",
"react-loading-skeleton": "^3.0.3",
"react-modal": "~3.6.1",
"react-player": "^2.9.0",
"react-player": "^2.10.0",
"react-render-in-browser": "^1.1.1",
"react-tabs": "^2.3.1",
"react-tether": "^2.0.7",
@ -82,23 +82,22 @@
"styled-components": "^5.3.3",
"tippy.js": "^5.1.3",
"use-context-selector": "^1.3.7",
"useragent": "^2.3.0",
"wasm-check": "^2.0.2",
"winston": "^3.3.3",
"wasm-check": "^2.0.3",
"winston": "^3.7.2",
"yaml": "^1.7.2"
},
"devDependencies": {
"chai": "~4.2.0",
"eslint": "^7.23.0",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"husky": "^1.3.1",
"lint-staged": "11.2.0",
"postcss": "^8.2.15",
"postcss": "^8.4.12",
"postcss-modules-extract-imports": "^3.0.0",
"postcss-modules-local-by-default": "^4.0.0",
"postcss-modules-scope": "^3.0.0",

View File

@ -23,7 +23,7 @@ class Join extends Create {
await breakoutUserPage.bringToFront();
if (!shouldJoinAudio) await breakoutUserPage.closeAudioModal();
await breakoutUserPage.hasElement(e.presentationPlaceholder);
await breakoutUserPage.waitForSelector(e.presentationTitle);
return breakoutUserPage;
}
@ -33,6 +33,7 @@ class Join extends Create {
const { videoPreviewTimeout } = breakoutPage.settings;
await breakoutPage.shareWebcam(true, videoPreviewTimeout);
await breakoutPage.hasElement(e.presentationPlaceholder);
await breakoutPage.waitForSelector(e.presentationTitle);
}
async joinAndShareScreen() {

View File

@ -202,7 +202,6 @@ exports.currentUser = 'div[data-test="userListItemCurrent"]';
exports.multiWhiteboardTool = 'span[data-test="multiWhiteboardTool"]';
exports.manageUsers = 'button[data-test="manageUsers"]';
exports.presenterClassName = 'presenter--';
exports.anyUser = 'div[data-test="userListItem"]';
exports.userListToggleBtn = 'button[data-test="toggleUserList"]';
exports.mobileUser = 'span[data-test="mobileUser"]';
exports.connectionStatusBtn = 'button[data-test="connectionStatusButton"]';

View File

@ -49,7 +49,7 @@ test.describe.parallel('Notifications', () => {
await presenterNotifications.publishPollResults();
});
test('Presentation upload notification', async ({ browser, context, page }) => {
test.fixme('Presentation upload notification', async ({ browser, context, page }) => { // this test is unstable, there's an apparent timing issue around the visibility of smallToastMsg
const presenterNotifications = new PresenterNotifications(browser, context);
await presenterNotifications.initPages(page);
await presenterNotifications.fileUploaderNotification();

View File

@ -13,7 +13,7 @@ class VirtualizeList {
// Join BigBlueButton meeting
async init() {
await this.page1.init(true, true, { fullName: 'BroadCaster1' });
await this.page1.waitForSelector(e.anyUser);
await this.page1.waitForSelector(e.firstUser);
for (let i = 1; i <= parseInt(USER_LIST_VLIST_BOTS_LISTENING); i++) {
const newPage = await this.browser.newPage();
const viewerPage = new Page(this.browser, newPage);
@ -26,7 +26,7 @@ class VirtualizeList {
}
async test() {
const USER_LIST_VLIST_VISIBLE_USERS = await this.page1.getSelectorCount(e.anyUser);
const USER_LIST_VLIST_VISIBLE_USERS = await this.page1.getSelectorCount(e.userListItem);
const totalNumberOfUsersMongo = await this.page1.page.evaluate(() => {
const collection = require('/imports/api/users/index.js');
return collection.default._collection.find().count();

View File

@ -60,7 +60,7 @@ source /etc/lsb-release
# Set up specific version of node
if [ "$DISTRIB_CODENAME" == "focal" ]; then
node_version="14.18.3"
node_version="14.19.1"
if [[ ! -d /usr/share/node-v${node_version}-linux-x64 ]]; then
cd /usr/share
tar xfz "node-v${node_version}-linux-x64.tar.gz"

View File

@ -92,11 +92,11 @@ cp bbb-html5-frontend@.service staging/usr/lib/systemd/system
mkdir -p staging/usr/share
if [ ! -f node-v14.18.3-linux-x64.tar.gz ]; then
wget https://nodejs.org/dist/v14.18.3/node-v14.18.3-linux-x64.tar.gz
if [ ! -f node-v14.19.1-linux-x64.tar.gz ]; then
wget https://nodejs.org/dist/v14.19.1/node-v14.19.1-linux-x64.tar.gz
fi
cp node-v14.18.3-linux-x64.tar.gz staging/usr/share
cp node-v14.19.1-linux-x64.tar.gz staging/usr/share
if [ -f staging/usr/share/meteor/bundle/programs/web.browser/head.html ]; then
sed -i "s/VERSION/$(($BUILD))/" staging/usr/share/meteor/bundle/programs/web.browser/head.html

View File

@ -49,7 +49,7 @@ fi
export MONGO_OPLOG_URL=mongodb://127.0.1.1/local
export MONGO_URL=mongodb://127.0.1.1/meteor
export NODE_ENV=production
export NODE_VERSION=node-v14.18.3-linux-x64
export NODE_VERSION=node-v14.19.1-linux-x64
export SERVER_WEBSOCKET_COMPRESSION=0
export BIND_IP=127.0.0.1
PORT=$PORT /usr/share/$NODE_VERSION/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js NODEJS_BACKEND_INSTANCE_ID=$INSTANCE_ID

View File

@ -49,7 +49,7 @@ fi
export MONGO_OPLOG_URL=mongodb://127.0.1.1/local
export MONGO_URL=mongodb://127.0.1.1/meteor
export NODE_ENV=production
export NODE_VERSION=node-v14.18.3-linux-x64
export NODE_VERSION=node-v14.19.1-linux-x64
export SERVER_WEBSOCKET_COMPRESSION=0
export BIND_IP=127.0.0.1
PORT=$PORT /usr/share/$NODE_VERSION/bin/node --max-old-space-size=2048 --max_semi_space_size=128 main.js