Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] VIDEO/JITSI multiple calls before video call #13855

Merged
merged 9 commits into from
Mar 26, 2019
152 changes: 81 additions & 71 deletions app/videobridge/client/views/videoFlexTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { Template } from 'meteor/templating';
import { settings } from '../../../settings';
import { modal, TabBar } from '../../../ui-utils';
import { t } from '../../../utils';
import { Users, Rooms } from '../../../models';

ggazzo marked this conversation as resolved.
Show resolved Hide resolved
import CONSTANTS from '../../constants';

Template.videoFlexTab.helpers({
openInNewWindow() {
Expand All @@ -14,11 +17,14 @@ Template.videoFlexTab.helpers({
Template.videoFlexTab.onCreated(function() {
this.tabBar = Template.currentData().tabBar;
});
Template.videoFlexTab.onDestroyed(function() {
return this.stop && this.stop();
});

Template.videoFlexTab.onRendered(function() {
this.api = null;

let timeOut = null;
const rid = Session.get('openedRoom');

const width = 'auto';
const height = 500;
Expand All @@ -40,6 +46,30 @@ Template.videoFlexTab.onRendered(function() {
TabBar.updateButton('video', { class: '' });
};

const stop = () => {
if (this.timeOut) {
Meteor.defer(() => this.api && this.api.dispose());
clearInterval(this.timeOut);
}
};

this.stop = stop;

const start = () => {

ggazzo marked this conversation as resolved.
Show resolved Hide resolved
const update = () => {
const { jitsiTimeout } = Rooms.findOne({ _id: rid }, { fields: { jitsiTimeout: 1 }, reactive: false });

if (jitsiTimeout && (new Date() - new Date(jitsiTimeout) + CONSTANTS.TIMEOUT < CONSTANTS.HEARTBEAT / 2)) {
return;
}
return Meteor.status().connected && Meteor.call('jitsi:updateTimeout', rid);
};
update();
this.timeOut = Meteor.setInterval(update, CONSTANTS.HEARTBEAT);
tassoevan marked this conversation as resolved.
Show resolved Hide resolved
TabBar.updateButton('video', { class: 'red' });
};

modal.open({
title: t('Video_Conference'),
text: t('Start_video_call'),
Expand All @@ -54,84 +84,64 @@ Template.videoFlexTab.onRendered(function() {
}
this.timeout = null;
this.autorun(() => {
if (settings.get('Jitsi_Enabled')) {
if (this.tabBar.getState() === 'opened') {
const roomId = Session.get('openedRoom');
if (!settings.get('Jitsi_Enabled')) {
return closePanel();
}

const domain = settings.get('Jitsi_Domain');
const jitsiRoom = settings.get('Jitsi_URL_Room_Prefix') + settings.get('uniqueID') + roomId;
const noSsl = !settings.get('Jitsi_SSL');
if (this.tabBar.getState() !== 'opened') {
TabBar.updateButton('video', { class: '' });
return stop();
}

if (jitsiRoomActive !== null && jitsiRoomActive !== jitsiRoom) {
jitsiRoomActive = null;
const domain = settings.get('Jitsi_Domain');
const jitsiRoom = settings.get('Jitsi_URL_Room_Prefix') + settings.get('uniqueID') + rid;
const noSsl = !settings.get('Jitsi_SSL');

closePanel();
if (jitsiRoomActive !== null && jitsiRoomActive !== jitsiRoom) {
jitsiRoomActive = null;

// Clean up and stop updating timeout.
Meteor.defer(() => this.api && this.api.dispose());
if (timeOut) {
clearInterval(timeOut);
}
} else {
jitsiRoomActive = jitsiRoom;

TabBar.updateButton('video', { class: 'red' });

if (settings.get('Jitsi_Open_New_Window')) {
Meteor.call('jitsi:updateTimeout', roomId);

timeOut = Meteor.setInterval(() => Meteor.call('jitsi:updateTimeout', roomId), 10 * 1000);
const newWindow = window.open(`${ (noSsl ? 'http://' : 'https://') + domain }/${ jitsiRoom }`, jitsiRoom);
const closeInterval = setInterval(() => {
if (newWindow.closed !== false) {
closePanel();
clearInterval(closeInterval);
clearInterval(timeOut);
}
}, 300);
if (newWindow) {
newWindow.focus();
}


// Lets make sure its loaded before we try to show it.
} else if (typeof JitsiMeetExternalAPI !== 'undefined') {

// Keep it from showing duplicates when re-evaluated on variable change.
if (!$('[id^=jitsiConference]').length) {
this.api = new JitsiMeetExternalAPI(domain, jitsiRoom, width, height, this.$('.video-container').get(0), configOverwrite, interfaceConfigOverwrite, noSsl);

/*
* Hack to send after frame is loaded.
* postMessage converts to events in the jitsi meet iframe.
* For some reason those aren't working right.
*/
Meteor.setTimeout(() => {
this.api.executeCommand('displayName', [Meteor.user().name]);
}, 5000);

Meteor.call('jitsi:updateTimeout', roomId);

timeOut = Meteor.setInterval(() => Meteor.call('jitsi:updateTimeout', roomId), 10 * 1000);
}

// Execute any commands that might be reactive. Like name changing.
this.api && this.api.executeCommand('displayName', [Meteor.user().name]);
closePanel();

return stop();
}

jitsiRoomActive = jitsiRoom;

if (settings.get('Jitsi_Open_New_Window')) {
start();
const newWindow = window.open(`${ (noSsl ? 'http://' : 'https://') + domain }/${ jitsiRoom }`, jitsiRoom);
if (newWindow) {
const closeInterval = setInterval(() => {
if (newWindow.closed === false) {
return;
}
}
} else {
TabBar.updateButton('video', { class: '' });

// Clean up and stop updating timeout.
if (timeOut) {
Meteor.defer(() => this.api && this.api.dispose());
clearInterval(timeOut);
}
closePanel();
stop();
clearInterval(closeInterval);
}, 300);
return newWindow.focus();
}

// Lets make sure its loaded before we try to show it.
}

if (typeof JitsiMeetExternalAPI !== 'undefined') {
// Keep it from showing duplicates when re-evaluated on variable change.
const name = Users.findOne(Meteor.userId(), { fields: { name: 1 } });
if (!$('[id^=jitsiConference]').length) {
this.api = new JitsiMeetExternalAPI(domain, jitsiRoom, width, height, this.$('.video-container').get(0), configOverwrite, interfaceConfigOverwrite, noSsl);

/*
* Hack to send after frame is loaded.
* postMessage converts to events in the jitsi meet iframe.
* For some reason those aren't working right.
*/
Meteor.setTimeout(() => this.api.executeCommand('displayName', [name]), 5000);
return start();
}

// Execute any commands that might be reactive. Like name changing.
this.api && this.api.executeCommand('displayName', [name]);
}
});
});
});

4 changes: 4 additions & 0 deletions app/videobridge/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default {
tassoevan marked this conversation as resolved.
Show resolved Hide resolved
HEARTBEAT: 35 * 1000 / 2,
TIMEOUT: 35 * 1000,
};
13 changes: 7 additions & 6 deletions app/videobridge/server/methods/jitsiSetTimeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/tap:i18n';
import { Rooms, Messages } from '../../../models';
import { callbacks } from '../../../callbacks';
import CONSTANTS from '../../constants';
ggazzo marked this conversation as resolved.
Show resolved Hide resolved

Meteor.methods({
'jitsi:updateTimeout': (rid) => {
Expand All @@ -15,24 +16,24 @@ Meteor.methods({

const jitsiTimeout = new Date((room && room.jitsiTimeout) || currentTime).getTime();

if (jitsiTimeout <= currentTime) {
Rooms.setJitsiTimeout(rid, new Date(currentTime + 35 * 1000));
if (currentTime > jitsiTimeout - CONSTANTS.TIMEOUT / 2) {
Rooms.setJitsiTimeout(rid, new Date(currentTime + CONSTANTS.TIMEOUT));
}

if (currentTime > jitsiTimeout) {
const message = Messages.createWithTypeRoomIdMessageAndUser('jitsi_call_started', rid, '', Meteor.user(), {
actionLinks : [
{ icon: 'icon-videocam', label: TAPi18n.__('Click_to_join'), method_id: 'joinJitsiCall', params: '' },
],
});
const room = Rooms.findOneById(rid);
message.msg = TAPi18n.__('Started_a_video_call');
message.mentions = [
{
_id:'here',
username:'here',
},
];
callbacks.run('afterSaveMessage', message, room);
} else if ((jitsiTimeout - currentTime) / 1000 <= 15) {
Rooms.setJitsiTimeout(rid, new Date(jitsiTimeout + 25 * 1000));
callbacks.run('afterSaveMessage', message, { ...room, jitsiTimeout: currentTime + CONSTANTS.TIMEOUT });
}
},
});