Merge pull request #5722 from antobinary/breakouts-improvements-3
Improvements to Breakouts on HTML5
This commit is contained in:
commit
1e1e605d7a
@ -23,7 +23,7 @@ export default function userLeaving(credentials, userId, connectionId) {
|
||||
const User = Users.findOne(selector);
|
||||
|
||||
if (!User) {
|
||||
Logger.info(`Skipping userLeaving. Could not find ${userId} in ${meetingId}`);
|
||||
return Logger.info(`Skipping userLeaving. Could not find ${userId} in ${meetingId}`);
|
||||
}
|
||||
|
||||
// If the current user connection is not the same that triggered the leave we skip
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cx from 'classnames';
|
||||
import { defineMessages, intlShape, injectIntl } from 'react-intl';
|
||||
import Button from '/imports/ui/components/button/component';
|
||||
import { styles } from './styles';
|
||||
import cx from 'classnames';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
joinAudio: {
|
||||
@ -29,7 +29,7 @@ const propTypes = {
|
||||
handleJoinAudio: PropTypes.func.isRequired,
|
||||
handleLeaveAudio: PropTypes.func.isRequired,
|
||||
disable: PropTypes.bool.isRequired,
|
||||
unmute: PropTypes.bool.isRequired,
|
||||
unmute: PropTypes.bool,
|
||||
mute: PropTypes.bool.isRequired,
|
||||
join: PropTypes.bool.isRequired,
|
||||
intl: intlShape.isRequired,
|
||||
@ -38,6 +38,7 @@ const propTypes = {
|
||||
|
||||
const defaultProps = {
|
||||
glow: false,
|
||||
unmute: false,
|
||||
};
|
||||
|
||||
const SHORTCUTS_CONFIG = Meteor.settings.public.app.shortcuts;
|
||||
|
@ -356,7 +356,6 @@ class AudioModal extends Component {
|
||||
handleBack={this.handleGoToAudioOptions}
|
||||
handleRetry={this.handleRetryGoToEchoTest}
|
||||
joinEchoTest={this.joinEchoTest}
|
||||
exitAudio={this.exitAudio}
|
||||
changeInputDevice={this.changeInputDevice}
|
||||
changeOutputDevice={this.changeOutputDevice}
|
||||
isConnecting={isConnecting}
|
||||
|
@ -21,23 +21,23 @@ const intlMessages = defineMessages({
|
||||
},
|
||||
genericError: {
|
||||
id: 'app.audioManager.genericError',
|
||||
description: 'Generic error messsage',
|
||||
description: 'Generic error message',
|
||||
},
|
||||
connectionError: {
|
||||
id: 'app.audioManager.connectionError',
|
||||
description: 'Connection error messsage',
|
||||
description: 'Connection error message',
|
||||
},
|
||||
requestTimeout: {
|
||||
id: 'app.audioManager.requestTimeout',
|
||||
description: 'Request timeout error messsage',
|
||||
description: 'Request timeout error message',
|
||||
},
|
||||
invalidTarget: {
|
||||
id: 'app.audioManager.invalidTarget',
|
||||
description: 'Invalid target error messsage',
|
||||
description: 'Invalid target error message',
|
||||
},
|
||||
mediaError: {
|
||||
id: 'app.audioManager.mediaError',
|
||||
description: 'Media error messsage',
|
||||
description: 'Media error message',
|
||||
},
|
||||
});
|
||||
|
||||
@ -71,6 +71,12 @@ export default withModalMounter(injectIntl(withTracker(({ mountModal, intl }) =>
|
||||
|
||||
Breakouts.find().observeChanges({
|
||||
removed() {
|
||||
// if the user joined a breakout room, the main room's audio was
|
||||
// programmatically dropped to avoid interference. On breakout end,
|
||||
// offer to rejoin main room audio only if the user is not in audio already
|
||||
if (Service.isUsingAudio()) {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => openAudioModal(), 0);
|
||||
},
|
||||
});
|
||||
|
@ -2,7 +2,6 @@ import Users from '/imports/api/users';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import AudioManager from '/imports/ui/services/audio-manager';
|
||||
import Meetings from '/imports/api/meetings';
|
||||
import VoiceUsers from '/imports/api/voice-users';
|
||||
|
||||
const init = (messages) => {
|
||||
AudioManager.setAudioMessages(messages);
|
||||
@ -30,9 +29,6 @@ const init = (messages) => {
|
||||
AudioManager.init(userData);
|
||||
};
|
||||
|
||||
const isVoiceUserTalking = () =>
|
||||
VoiceUsers.findOne({ intId: Auth.userID }).talking;
|
||||
|
||||
export default {
|
||||
init,
|
||||
exitAudio: () => AudioManager.exitAudio(),
|
||||
@ -44,8 +40,9 @@ export default {
|
||||
changeInputDevice: inputDeviceId => AudioManager.changeInputDevice(inputDeviceId),
|
||||
changeOutputDevice: outputDeviceId => AudioManager.changeOutputDevice(outputDeviceId),
|
||||
isConnected: () => AudioManager.isConnected,
|
||||
isTalking: () => isVoiceUserTalking(),
|
||||
isTalking: () => AudioManager.isTalking,
|
||||
isHangingUp: () => AudioManager.isHangingUp,
|
||||
isUsingAudio: () => AudioManager.isUsingAudio(),
|
||||
isWaitingPermissions: () => AudioManager.isWaitingPermissions,
|
||||
isMuted: () => AudioManager.isMuted,
|
||||
isConnecting: () => AudioManager.isConnecting,
|
||||
|
@ -83,19 +83,9 @@ const setRetrySeconds = (sec = 0) => {
|
||||
}
|
||||
};
|
||||
|
||||
const changeDocumentTitle = (sec) => {
|
||||
if (sec >= 0) {
|
||||
const affix = `(${humanizeSeconds(sec)}`;
|
||||
const splitTitle = document.title.split(') ');
|
||||
const title = splitTitle[1] || splitTitle[0];
|
||||
document.title = [affix, title].join(') ');
|
||||
}
|
||||
};
|
||||
|
||||
const setTimeRemaining = (sec = 0) => {
|
||||
if (sec !== timeRemaining) {
|
||||
timeRemaining = sec;
|
||||
changeDocumentTitle(sec);
|
||||
timeRemainingDep.changed();
|
||||
}
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ import Meetings from '/imports/api/meetings';
|
||||
|
||||
import Icon from '../icon/component';
|
||||
import { styles } from './styles';
|
||||
import AudioService from '../audio/service';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
|
||||
@ -41,7 +42,9 @@ class ToastContainer extends React.Component {
|
||||
export default injectIntl(injectNotify(withTracker(({ notify, intl }) => {
|
||||
Breakouts.find().observeChanges({
|
||||
removed() {
|
||||
notify(intl.formatMessage(intlMessages.toastBreakoutRoomEnded), 'info', 'rooms');
|
||||
if (!AudioService.isUsingAudio()) {
|
||||
notify(intl.formatMessage(intlMessages.toastBreakoutRoomEnded), 'info', 'rooms');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -30,6 +30,7 @@ class AudioManager {
|
||||
isHangingUp: false,
|
||||
isListenOnly: false,
|
||||
isEchoTest: false,
|
||||
isTalking: false,
|
||||
isWaitingPermissions: false,
|
||||
error: null,
|
||||
outputDeviceId: null,
|
||||
@ -164,6 +165,7 @@ class AudioManager {
|
||||
if (!this.isConnected) return Promise.resolve();
|
||||
|
||||
this.isHangingUp = true;
|
||||
this.isEchoTest = false;
|
||||
return this.bridge.exitAudio();
|
||||
}
|
||||
|
||||
@ -185,8 +187,17 @@ class AudioManager {
|
||||
const query = VoiceUsers.find({ intId: Auth.userID });
|
||||
this.muteHandle = query.observeChanges({
|
||||
changed: (id, fields) => {
|
||||
if (fields.muted === this.isMuted) return;
|
||||
this.isMuted = fields.muted;
|
||||
if (fields.muted !== undefined && fields.muted !== this.isMuted) {
|
||||
this.isMuted = fields.muted;
|
||||
}
|
||||
|
||||
if (fields.talking !== undefined && fields.talking !== this.isTalking) {
|
||||
this.isTalking = fields.talking;
|
||||
}
|
||||
|
||||
if (this.isMuted) {
|
||||
this.isTalking = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -205,6 +216,7 @@ class AudioManager {
|
||||
this.isConnected = false;
|
||||
this.isConnecting = false;
|
||||
this.isHangingUp = false;
|
||||
this.isListenOnly = false;
|
||||
|
||||
if (this.inputStream) {
|
||||
window.defaultInputStream.forEach(track => track.stop());
|
||||
@ -258,6 +270,11 @@ class AudioManager {
|
||||
return this.listenOnlyAudioContext.createMediaStreamDestination().stream;
|
||||
}
|
||||
|
||||
isUsingAudio() {
|
||||
return this.isConnected || this.isConnecting ||
|
||||
this.isHangingUp || this.isEchoTest;
|
||||
}
|
||||
|
||||
setDefaultInputDevice() {
|
||||
return this.changeInputDevice();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user