diff --git a/bigbluebutton-html5/imports/api/users/server/methods.js b/bigbluebutton-html5/imports/api/users/server/methods.js
index bf7007de1e..5e70dbd470 100644
--- a/bigbluebutton-html5/imports/api/users/server/methods.js
+++ b/bigbluebutton-html5/imports/api/users/server/methods.js
@@ -6,6 +6,7 @@ import changeRole from './methods/changeRole';
import removeUser from './methods/removeUser';
import toggleUserLock from './methods/toggleUserLock';
import userActivitySign from './methods/userActivitySign';
+import userLeftMeeting from './methods/userLeftMeeting';
Meteor.methods({
setEmojiStatus,
@@ -15,4 +16,5 @@ Meteor.methods({
validateAuthToken,
toggleUserLock,
userActivitySign,
+ userLeftMeeting,
});
diff --git a/bigbluebutton-html5/imports/api/users/server/methods/userLeftMeeting.js b/bigbluebutton-html5/imports/api/users/server/methods/userLeftMeeting.js
new file mode 100644
index 0000000000..4723ba94e5
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/methods/userLeftMeeting.js
@@ -0,0 +1,39 @@
+import { Meteor } from 'meteor/meteor';
+import { check } from 'meteor/check';
+import Logger from '/imports/startup/server/logger';
+import Users from '/imports/api/users';
+
+export default function userLeftMeeting(credentials) {
+ const {
+ meetingId,
+ requesterUserId,
+ } = credentials;
+
+ check(meetingId, String);
+ check(requesterUserId, String);
+
+ const selector = {
+ meetingId,
+ userId: requesterUserId,
+ };
+
+ const cb = (err, numChanged) => {
+ if (err) {
+ Logger.error(`leaving dummy user to collection: ${err}`);
+ return;
+ }
+ if (numChanged) {
+ Logger.info(`user left id=${requesterUserId} meeting=${meetingId}`);
+ }
+ };
+
+ return Users.update(
+ selector,
+ {
+ $set: {
+ loggedOut: true,
+ },
+ },
+ cb,
+ );
+}
diff --git a/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js b/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
index cc5781dbd9..d10c706ace 100755
--- a/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
+++ b/bigbluebutton-html5/imports/api/users/server/modifiers/addUser.js
@@ -82,6 +82,7 @@ export default function addUser(meetingId, user) {
},
inactivityCheck: false,
responseDelay: 0,
+ loggedOut: false,
},
flat(user),
),
diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx
index 24912538b2..bc90953982 100755
--- a/bigbluebutton-html5/imports/startup/client/base.jsx
+++ b/bigbluebutton-html5/imports/startup/client/base.jsx
@@ -161,6 +161,7 @@ class Base extends Component {
meetingHasEnded,
meetingIsBreakout,
subscriptionsReady,
+ User,
} = this.props;
if ((loading || !subscriptionsReady) && !meetingHasEnded && meetingExist) {
@@ -175,7 +176,7 @@ class Base extends Component {
if (meetingHasEnded && meetingIsBreakout) window.close();
- if (meetingHasEnded && !meetingIsBreakout) {
+ if (((meetingHasEnded && !meetingIsBreakout)) || (codeError && (User && User.loggedOut))) {
AudioManager.exitAudio();
return ();
}
@@ -216,6 +217,7 @@ const BaseContainer = withTracker(() => {
let breakoutRoomSubscriptionHandler;
let meetingModeratorSubscriptionHandler;
+ const User = Users.findOne({ intId: credentials.requesterUserId });
const meeting = Meetings.findOne({ meetingId });
if (meeting) {
const { meetingEnded } = meeting;
@@ -226,6 +228,7 @@ const BaseContainer = withTracker(() => {
const ejected = Users.findOne({ userId: Auth.userID, ejected: true });
if (Session.get('codeError')) {
return {
+ User,
meetingHasEnded: !!meeting && meeting.meetingEnded,
approved,
ejected,
@@ -235,7 +238,6 @@ const BaseContainer = withTracker(() => {
let userSubscriptionHandler;
- const User = Users.findOne({ intId: credentials.requesterUserId });
Breakouts.find().observeChanges({
added() {
diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx
index bf79a4e706..bbf74258ad 100755
--- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx
@@ -4,7 +4,7 @@ import _ from 'lodash';
import PropTypes from 'prop-types';
import { withModalMounter } from '/imports/ui/components/modal/service';
import EndMeetingConfirmationContainer from '/imports/ui/components/end-meeting-confirmation/container';
-import MeetingEndedComponent from '/imports/ui/components/meeting-ended/component';
+import { makeCall } from '/imports/ui/services/api';
import AboutContainer from '/imports/ui/components/about/container';
import SettingsMenuContainer from '/imports/ui/components/settings/container';
import Button from '/imports/ui/components/button/component';
@@ -110,6 +110,15 @@ const defaultProps = {
};
class SettingsDropdown extends PureComponent {
+ static leaveSession() {
+ document.dispatchEvent(new Event('exitVideo'));
+ const LOGOUT_CODE = '403';
+ makeCall('userLeftMeeting');
+ // we don't check askForFeedbackOnLogout here,
+ // it is checked in meeting-ended component
+ Session.set('codeError', LOGOUT_CODE);
+ // mountModal();
+ }
constructor(props) {
super(props);
@@ -164,15 +173,6 @@ class SettingsDropdown extends PureComponent {
);
}
- leaveSession() {
- document.dispatchEvent(new Event('exitVideo'));
- const { mountModal } = this.props;
- const LOGOUT_CODE = '430';
- // we don't check askForFeedbackOnLogout here,
- // it is checked in meeting-ended component
- mountModal();
- }
-
renderMenuItems() {
const {
intl, mountModal, amIModerator, isBreakoutRoom,