bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/timer/service.js
2023-05-18 15:29:32 -03:00

382 lines
8.1 KiB
JavaScript

import { Meteor } from 'meteor/meteor';
import Timer from '/imports/api/timer';
import Auth from '/imports/ui/services/auth';
import { makeCall } from '/imports/ui/services/api';
import { Session } from 'meteor/session';
import Users from '/imports/api/users';
import Logger from '/imports/startup/client/logger';
import { ACTIONS, PANELS } from '../layout/enums';
const TIMER_CONFIG = Meteor.settings.public.timer;
const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator;
const OFFSET_INTERVAL = TIMER_CONFIG.interval.offset;
const MILLI_IN_HOUR = 3600000;
const MILLI_IN_MINUTE = 60000;
const MILLI_IN_SECOND = 1000;
const MAX_HOURS = 23;
const MAX_TIME = 999
+ (59 * MILLI_IN_SECOND)
+ (59 * MILLI_IN_MINUTE)
+ (MAX_HOURS * MILLI_IN_HOUR);
const getMaxHours = () => MAX_HOURS;
const isAlarmEnabled = () => TIMER_CONFIG.alarm;
isActive = () => {
const timer = Timer.findOne(
{ meetingId: Auth.meetingID },
{ fields: { active: 1 } },
);
if (timer) return timer.active;
return false;
};
const isEnabled = () => TIMER_CONFIG.enabled;
const getDefaultTime = () => TIMER_CONFIG.time * MILLI_IN_MINUTE;
const getInterval = () => TIMER_CONFIG.interval.clock;
const getPreset = () => {
const { preset } = TIMER_CONFIG;
return preset.map(minutes => minutes * MILLI_IN_MINUTE);
};
const isRunning = () => {
const timer = Timer.findOne(
{ meetingId: Auth.meetingID },
{ fields: { running: 1 } },
);
if (timer) return timer.running;
return false;
};
const isStopwatch = () => {
const timer = Timer.findOne(
{ meetingId: Auth.meetingID },
{ fields: { stopwatch: 1 } },
);
if (timer) return timer.stopwatch;
return false;
};
const startTimer = () => makeCall('startTimer');
const stopTimer = () => makeCall('stopTimer');
const switchTimer = (stopwatch) => makeCall('switchTimer', stopwatch);
const setTimer = (time) => makeCall('setTimer', time);
const resetTimer = () => makeCall('resetTimer');
const activateTimer = () => makeCall('activateTimer');
const deactivateTimer = () => makeCall('deactivateTimer');
const fetchTimeOffset = () => {
return new Promise((resolve, reject) => {
const t0 = Date.now();
makeCall('getServerTime').then(result => {
const t3 = Date.now();
const ts = result;
const rtt = t3 - t0;
const offset = Math.round(ts - rtt/2 - t0);
resolve(offset);
}).catch(error => reject(error));
});
};
const getElapsedTime = (running, timestamp, offset, accumulated) => {
if (!running) return accumulated;
const now = Date.now();
return accumulated + Math.abs(now - timestamp - offset);
};
const getTimer = () => {
const timer = Timer.findOne(
{ meetingId: Auth.meetingID },
{ fields:
{
stopwatch: 1,
running: 1,
time: 1,
accumulated: 1,
timestamp: 1,
},
},
);
if (timer) {
const {
stopwatch,
running,
time,
accumulated,
timestamp,
} = timer;
return {
stopwatch,
running,
time,
accumulated,
timestamp,
}
}
return {
stopwatch: true,
running: false,
time: getDefaultTime(),
accumulated: 0,
timestamp: 0,
}
};
const getTimerStatus = () => {
const timerStatus = Timer.findOne(
{ meetingId: Auth.meetingID },
{ fields:
{
stopwatch: 1,
running: 1,
time: 1,
},
},
);
if (timerStatus) {
const {
stopwatch,
running,
time,
} = timerStatus;
return {
stopwatch,
running,
time,
}
}
return {
stopwatch: true,
running: false,
time: getDefaultTime(),
}
};
const getTimeAsString = (time, stopwatch) => {
let milliseconds = time;
let hours = Math.floor(milliseconds / MILLI_IN_HOUR);
const mHours = hours * MILLI_IN_HOUR;
let minutes = Math.floor((milliseconds - mHours) / MILLI_IN_MINUTE);
const mMinutes = minutes * MILLI_IN_MINUTE;
let seconds = Math.floor((milliseconds - mHours - mMinutes) / MILLI_IN_SECOND);
const mSeconds = seconds * MILLI_IN_SECOND;
milliseconds = milliseconds - mHours - mMinutes - mSeconds;
let timeAsString = '';
// Only add hour if it exists
if (hours > 0) {
if (hours < 10) {
timeAsString += `0${hours}:`;
} else {
timeAsString += `${hours}:`;
}
}
// Add minute if exists, has at least an hour
// or is not stopwatch
if (minutes > 0 || hours > 0 || !stopwatch) {
if (minutes < 10) {
timeAsString += `0${minutes}:`;
} else {
timeAsString += `${minutes}:`;
}
}
// Always add seconds
if (seconds < 10) {
timeAsString += `0${seconds}`;
} else {
timeAsString += `${seconds}`;
}
// Only add milliseconds if it's a stopwatch
if (stopwatch) {
if (milliseconds < 10) {
timeAsString += `:00${milliseconds}`;
} else if (milliseconds < 100) {
timeAsString += `:0${milliseconds}`;
} else {
timeAsString += `:${milliseconds}`;
}
}
return timeAsString;
};
const isPanelOpen = () => Session.get('openPanel') === 'timer';
const closePanel = (layoutContextDispatch) => {
layoutContextDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
value: false,
});
layoutContextDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
value: PANELS.NONE,
});
};
const togglePanel = (sidebarContentPanel, layoutContextDispatch) => {
layoutContextDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
value: sidebarContentPanel !== PANELS.TIMER,
});
layoutContextDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
value: sidebarContentPanel === PANELS.TIMER
? PANELS.NONE
: PANELS.TIMER,
});
};
const isModerator = () => {
return Users.findOne(
{ userId: Auth.userID },
{ fields: { role: 1 } },
).role === ROLE_MODERATOR;
};
const setHours = (hours, time) => {
if (!isNaN(hours) && hours >= 0 && hours <= MAX_HOURS) {
const currentHours = Math.floor(time / MILLI_IN_HOUR);
const diff = (hours - currentHours) * MILLI_IN_HOUR;
setTimer(time + diff);
} else {
Logger.warn('Invalid time');
}
};
const setMinutes = (minutes, time) => {
if (!isNaN(minutes) && minutes >= 0 && minutes <= 59) {
const currentHours = Math.floor(time / MILLI_IN_HOUR);
const mHours = currentHours * MILLI_IN_HOUR;
const currentMinutes = Math.floor((time - mHours) / MILLI_IN_MINUTE);
const diff = (minutes - currentMinutes) * MILLI_IN_MINUTE;
setTimer(time + diff);
} else {
Logger.warn('Invalid time');
}
};
const setSeconds = (seconds, time) => {
if (!isNaN(seconds) && seconds >= 0 && seconds <= 59) {
const currentHours = Math.floor(time / MILLI_IN_HOUR);
const mHours = currentHours * MILLI_IN_HOUR;
const currentMinutes = Math.floor((time - mHours) / MILLI_IN_MINUTE);
const mMinutes = currentMinutes * MILLI_IN_MINUTE;
const currentSeconds = Math.floor((time - mHours - mMinutes) / MILLI_IN_SECOND);
const diff = (seconds - currentSeconds) * MILLI_IN_SECOND;
setTimer(time + diff);
} else {
Logger.warn('Invalid time');
}
};
const subtractTime = (preset, time) => {
if (!isNaN(preset)) {
const min = 0;
setTimer(Math.max(time - preset, min));
} else {
Logger.warn('Invalid time');
}
};
const setTime = (preset) => {
if (!isNaN(preset)) {
setTimer(preset);
} else {
Logger.warn('Invalid time');
}
};
const addTime = (preset, time) => {
if (!isNaN(preset)) {
const max = MAX_TIME;
setTimer(Math.min(time + preset, max));
} else {
Logger.warn('Invalid time');
}
};
const buildPresetLabel = (preset) => {
const minutes = preset / MILLI_IN_MINUTE;
if (minutes < 10) {
return `0${minutes}"00'`;
}
return `${minutes}"00'`;
};
export default {
OFFSET_INTERVAL,
isActive,
isEnabled,
isRunning,
isStopwatch,
isAlarmEnabled,
startTimer,
stopTimer,
switchTimer,
setHours,
setMinutes,
setSeconds,
setTime,
subtractTime,
addTime,
resetTimer,
activateTimer,
deactivateTimer,
fetchTimeOffset,
getElapsedTime,
getInterval,
getPreset,
getMaxHours,
getTimer,
getTimerStatus,
getTimeAsString,
closePanel,
togglePanel,
isModerator,
buildPresetLabel,
};