import { Meteor } from 'meteor/meteor'; import { createContainer } from 'meteor/react-meteor-data'; import React from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import _ from 'lodash'; import Auth from '/imports/ui/services/auth'; import humanizeSeconds from '/imports/utils/humanizeSeconds'; import NavBarService from '../nav-bar/service'; import NotificationsBar from './component'; // disconnected and trying to open a new connection const STATUS_CONNECTING = 'connecting'; // permanently failed to connect; e.g., the client and server support different versions of DDP const STATUS_FAILED = 'failed'; // failed to connect and waiting to try to reconnect const STATUS_WAITING = 'waiting'; const intlMessages = defineMessages({ failedMessage: { id: 'app.failedMessage', description: 'Notification for connecting to server problems', }, connectingMessage: { id: 'app.connectingMessage', description: 'Notification message for when client is connecting to server', }, waitingMessage: { id: 'app.waitingMessage', description: 'Notification message for disconnection with reconnection counter', }, breakoutTimeRemaining: { id: 'app.breakoutTimeRemainingMessage', description: 'Message that tells how much time is remaining for the breakout room', }, breakoutWillClose: { id: 'app.breakoutWillCloseMessage', description: 'Message that tells time has ended and breakout will close', }, calculatingBreakoutTimeRemaining: { id: 'app.calculatingBreakoutTimeRemaining', description: 'Message that tells that the remaining time is being calculated', }, }); const NotificationsBarContainer = (props) => { if (_.isEmpty(props.message)) { return null; } const { message, color } = props; return ( {message} ); }; let retrySeconds = 0; let timeRemaining = 0; const retrySecondsDep = new Tracker.Dependency(); const timeRemainingDep = new Tracker.Dependency(); let retryInterval = null; let timeRemainingInterval = null; const getRetrySeconds = () => { retrySecondsDep.depend(); return retrySeconds; }; const getTimeRemaining = () => { timeRemainingDep.depend(); return timeRemaining; }; const setRetrySeconds = (sec = 0) => { if (sec !== retrySeconds) { retrySeconds = sec; retrySecondsDep.changed(); } }; 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(); } }; const startCounter = (sec, set, get, interval) => { clearInterval(interval); set(sec); return setInterval(() => { set(get() - 1); }, 1000); }; export default injectIntl(createContainer(({ intl }) => { const { status, connected, retryTime } = Meteor.status(); const data = {}; if (!connected) { data.color = 'primary'; switch (status) { case STATUS_FAILED: { data.color = 'danger'; data.message = intl.formatMessage(intlMessages.failedMessage); break; } case STATUS_CONNECTING: { data.message = intl.formatMessage(intlMessages.connectingMessage); break; } case STATUS_WAITING: { const sec = Math.round((retryTime - (new Date()).getTime()) / 1000); retryInterval = startCounter(sec, setRetrySeconds, getRetrySeconds, retryInterval); data.message = intl.formatMessage( intlMessages.waitingMessage, { 0: getRetrySeconds() }, ); break; } default: break; } return data; } const meetingId = Auth.meetingID; const breakouts = NavBarService.getBreakouts(); if (breakouts.length > 0) { const currentBreakout = breakouts.find(b => b.breakoutId === meetingId); if (currentBreakout) { const roomRemainingTime = currentBreakout.timeRemaining; if (!timeRemainingInterval && roomRemainingTime) { timeRemainingInterval = startCounter(roomRemainingTime, setTimeRemaining, getTimeRemaining, timeRemainingInterval); } } else if (timeRemainingInterval) { clearInterval(timeRemainingInterval); } timeRemaining = getTimeRemaining(); if (timeRemaining) { if (timeRemaining > 0) { data.message = intl.formatMessage( intlMessages.breakoutTimeRemaining, { 0: humanizeSeconds(timeRemaining) }, ); } else { clearInterval(timeRemainingInterval); data.message = intl.formatMessage(intlMessages.breakoutWillClose); } } else if (!timeRemaining && currentBreakout) { data.message = intl.formatMessage(intlMessages.calculatingBreakoutTimeRemaining); } } data.color = 'primary'; return data; }, NotificationsBarContainer));