mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-12 19:03:47 +00:00
9fc154955a
* feat/62-logger request log data in app * feat/62-logger refact osc integration * feat/62-logger feedback on osc * feat/62-logger refact broadcast on triggers * feat/62-logger log triggers * feat/62-logger add link to studio * feat/62-logger replace toasts with logger context * feat/62-logger style improvements * feat/62-logger refactor code duplications * feat/62-logger cleanup and version bump
213 lines
5.9 KiB
JavaScript
213 lines
5.9 KiB
JavaScript
/**
|
|
* Utility variable: 24 hour in milliseconds .
|
|
* @type {number}
|
|
*/
|
|
export const DAY_TO_MS = 86400000;
|
|
|
|
/**
|
|
* @description handle events that span over midnight
|
|
* @param {number} start - When does the event start
|
|
* @param {number} end - When does the event end
|
|
* @returns {number} normalised time
|
|
*/
|
|
export const normaliseEndTime = (start, end) =>
|
|
end < start ? end + DAY_TO_MS : end;
|
|
|
|
/**
|
|
* @description Sorts an array of objects by given property
|
|
* @param {array} arr - array to be sorted
|
|
* @param {string} property - property to compare
|
|
* @returns {array} copy of array sorted in ascending order
|
|
*/
|
|
|
|
export const sortArrayByProperty = (arr, property) => {
|
|
return [...arr].sort((a, b) => {
|
|
return a[property] - b[property];
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @description Replaces placeholder variables in string with given data
|
|
* @param {string} str - string to analyse
|
|
* @param {object} values - map of variables: values to use
|
|
* @returns {string} finished string
|
|
*/
|
|
|
|
export const replacePlaceholder = (str, values) => {
|
|
for (let [k, v] of Object.entries(values)) {
|
|
str = str.replace(k, v);
|
|
}
|
|
return str;
|
|
};
|
|
|
|
/**
|
|
* @description Used in roll mode, returns selection variables from array
|
|
* @param {array} arr - event list
|
|
* @param {number} now - time now in millis
|
|
* @returns {object} object with selection variables
|
|
*/
|
|
|
|
export const getSelectionByRoll = (arr, now) => {
|
|
// Events now
|
|
let nowIndex = null; // index of event now
|
|
let nowId = null; // id of event now
|
|
let publicIndex = null; // index of public event now
|
|
let publicTime = -1; // counter:
|
|
|
|
// Events next
|
|
let nextIndex = null; // index of next event
|
|
let publicNextIndex = null; // index of next public event
|
|
let timeToNext = null; // counter: time for next event
|
|
let publicTimeToNext = null; // counter: time for next public event
|
|
|
|
// current timer
|
|
let timers = null;
|
|
|
|
// Order events by startTime
|
|
const orderedEvents = sortArrayByProperty(arr, 'timeStart');
|
|
|
|
// flags: select first event if several overlapping
|
|
let nowFound = false;
|
|
|
|
// exit early if we are past the events
|
|
const lastEvent = orderedEvents[orderedEvents.length - 1];
|
|
const lastNormalEnd = normaliseEndTime(
|
|
lastEvent.timeStart,
|
|
lastEvent.timeEnd
|
|
);
|
|
if (now > lastNormalEnd) {
|
|
return {
|
|
nowIndex,
|
|
nowId,
|
|
publicIndex,
|
|
nextIndex,
|
|
publicNextIndex,
|
|
timers,
|
|
timeToNext,
|
|
};
|
|
}
|
|
|
|
// loop through events, look for where we should be
|
|
for (const e of orderedEvents) {
|
|
// When does the event end (handle midnight)
|
|
const normalEnd = normaliseEndTime(e.timeStart, e.timeEnd);
|
|
|
|
if (normalEnd <= now) {
|
|
// event ran already
|
|
|
|
// public event might not be the one running
|
|
if (e.isPublic && normalEnd > publicTime) {
|
|
publicTime = normalEnd;
|
|
publicIndex = arr.findIndex((a) => a.id === e.id);
|
|
}
|
|
} else if (normalEnd > now && now >= e.timeStart && !nowFound) {
|
|
// event is running
|
|
|
|
// it could also be public
|
|
if (e.isPublic) {
|
|
publicTime = normalEnd;
|
|
publicIndex = arr.findIndex((a) => a.id === e.id);
|
|
}
|
|
|
|
nowIndex = arr.findIndex((a) => a.id === e.id);
|
|
nowId = e.id;
|
|
|
|
// set timers
|
|
timers = {
|
|
_startedAt: e.timeStart,
|
|
_finishAt: e.timeEnd,
|
|
duration: normalEnd - e.timeStart,
|
|
current: normalEnd - now,
|
|
};
|
|
nowFound = true;
|
|
} else if (normalEnd > now) {
|
|
// event will run
|
|
|
|
// no need to look after found first
|
|
if (nextIndex !== null && publicNextIndex !== null) continue;
|
|
|
|
// look for next events
|
|
// check how far the start is from now
|
|
const wait = e.timeStart - now;
|
|
|
|
if (nextIndex == null || wait < timeToNext) {
|
|
timeToNext = wait;
|
|
nextIndex = arr.findIndex((a) => a.id === e.id);
|
|
}
|
|
if ((publicNextIndex === null || wait < publicTimeToNext) && e.isPublic) {
|
|
publicTimeToNext = wait;
|
|
publicNextIndex = arr.findIndex((a) => a.id === e.id);
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
nowIndex,
|
|
nowId,
|
|
publicIndex,
|
|
nextIndex,
|
|
publicNextIndex,
|
|
timers,
|
|
timeToNext,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @description Implements update functions for roll mode
|
|
* @param {object} currentTimers
|
|
* @param {object} currentTimers.selectedEventId - Id of currently selected event
|
|
* @param {object} currentTimers.current - Running timer
|
|
* @param {object} currentTimers._finishAt - Expected finish time
|
|
* @param {object} currentTimers.clock - time now
|
|
* @param {object} currentTimers.secondaryTimer - secondary timer
|
|
* @param {object} currentTimers._secondaryTarget - finish time of secondary timer
|
|
* @returns {object} object with selection variables
|
|
*/
|
|
export const updateRoll = (currentTimers) => {
|
|
const {
|
|
selectedEventId,
|
|
current,
|
|
_finishAt,
|
|
clock,
|
|
secondaryTimer,
|
|
_secondaryTarget,
|
|
} = currentTimers;
|
|
|
|
// timers
|
|
let updatedTimer = current;
|
|
let updatedSecondaryTimer = secondaryTimer;
|
|
// whether rollLoad should be called
|
|
let doRollLoad = false;
|
|
// whether runCycle should be called
|
|
let isFinished = false;
|
|
|
|
if (selectedEventId && current >= 0) {
|
|
// if we have something selected and a timer, we are running
|
|
// this is true because roll never goes into negative times
|
|
|
|
// update timer
|
|
updatedTimer = _finishAt - clock;
|
|
if (updatedTimer < 0) {
|
|
isFinished = true;
|
|
}
|
|
} else if (secondaryTimer >= 0) {
|
|
// if secondaryTimer is running we are in waiting to roll
|
|
|
|
// update secondary
|
|
updatedSecondaryTimer = _secondaryTarget - clock;
|
|
}
|
|
|
|
// if nothing is running, we need to find out if
|
|
// a) we just finished an event (finished was set to true)
|
|
// b) we need to look for events
|
|
// this could be caused by a secondary timer or event finished
|
|
const secondaryRunning =
|
|
updatedSecondaryTimer <= 0 && updatedSecondaryTimer != null;
|
|
|
|
if (isFinished || secondaryRunning) {
|
|
// look for events
|
|
doRollLoad = true;
|
|
}
|
|
|
|
return { updatedTimer, updatedSecondaryTimer, doRollLoad, isFinished };
|
|
};
|