mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-10 18:03:47 +00:00
v2:feat (#231)
* style: element relationship * feat: utility to add first element * refactor: organise dir * ux: deleting element closes drawer * fix: issue with escaped characters * fix: issue with overflow in events list * fix: prevent event timer from receiving non event * style: prevent small shift on class change * style: visually detach event editor * fix: entry block knows last event * fix: skip event timer updates on non events * fix: prevent electron OPENGL error * style: cleanup text styles * style: unify input styles * refactor: simplify style and composition * refactor: tweaks on style + ts * refactor: add validation to events post * fix: handle non events in event timer * refactor: cleanup unused
This commit is contained in:
+1
-1
@@ -141,7 +141,7 @@ export const startServer = async (overrideConfig = null) => {
|
||||
|
||||
// init timer
|
||||
global.timer = new EventTimer(socket, config.timer, oscConfig, http);
|
||||
global.timer.setupWithEventList(events);
|
||||
global.timer.setupWithEventList(events.filter((entry) => entry.type === 'event'));
|
||||
|
||||
socket.info('SERVER', returnMessage);
|
||||
socket.startListener();
|
||||
|
||||
@@ -95,7 +95,9 @@ export class DataProvider {
|
||||
*/
|
||||
static async insertEventAfterId(entry, id) {
|
||||
const index = [...data.events].findIndex((event) => event.id === id);
|
||||
await DataProvider.insertEventAt(entry, index + 1);
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { _after, ...sanitisedEvent } = entry;
|
||||
await DataProvider.insertEventAt(sanitisedEvent, index + 1);
|
||||
}
|
||||
|
||||
static getSettings() {
|
||||
|
||||
@@ -772,40 +772,45 @@ export class EventTimer extends Timer {
|
||||
* @param previousId
|
||||
*/
|
||||
insertEventAfterId(event, previousId) {
|
||||
// find object in events
|
||||
const previousIndex = this._eventlist.findIndex((e) => e.id === previousId);
|
||||
if (previousIndex === -1) {
|
||||
throw 'Event not found';
|
||||
}
|
||||
|
||||
if (previousIndex + 1 >= this._eventlist.length) {
|
||||
this._eventlist.push(event);
|
||||
if (typeof previousId === 'undefined') {
|
||||
// Insert at beginning
|
||||
this._eventlist.unshift(event);
|
||||
} else {
|
||||
this._eventlist.splice(previousIndex + 1, 0, event);
|
||||
}
|
||||
// find object in events
|
||||
const previousIndex = this._eventlist.findIndex((e) => e.id === previousId);
|
||||
if (previousIndex === -1) {
|
||||
throw 'Event not found';
|
||||
}
|
||||
|
||||
try {
|
||||
// check if entry is running
|
||||
if (event.id === this.selectedEventId) {
|
||||
// handle reload selected
|
||||
// Reload data if running
|
||||
const type =
|
||||
this.selectedEventId === event.id && this._startedAt != null ? 'reload' : 'load';
|
||||
this.loadEvent(this.selectedEventIndex, type);
|
||||
} else if (event.id === this.nextEventId) {
|
||||
// roll needs to recalculate
|
||||
if (this.state === 'roll') {
|
||||
this.rollLoad();
|
||||
if (previousIndex + 1 >= this._eventlist.length) {
|
||||
this._eventlist.push(event);
|
||||
} else {
|
||||
this._eventlist.splice(previousIndex + 1, 0, event);
|
||||
}
|
||||
|
||||
try {
|
||||
// check if entry is running
|
||||
if (event.id === this.selectedEventId) {
|
||||
// handle reload selected
|
||||
// Reload data if running
|
||||
const type =
|
||||
this.selectedEventId === event.id && this._startedAt != null ? 'reload' : 'load';
|
||||
this.loadEvent(this.selectedEventIndex, type);
|
||||
} else if (event.id === this.nextEventId) {
|
||||
// roll needs to recalculate
|
||||
if (this.state === 'roll') {
|
||||
this.rollLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load titles
|
||||
if ('title' in event || 'subtitle' in event || 'presenter' in event) {
|
||||
this._loadTitlesNext();
|
||||
this._loadTitlesNow();
|
||||
// load titles
|
||||
if ('title' in event || 'subtitle' in event || 'presenter' in event) {
|
||||
this._loadTitlesNext();
|
||||
this._loadTitlesNow();
|
||||
}
|
||||
} catch (error) {
|
||||
this.socket.error('SERVER', error);
|
||||
}
|
||||
} catch (error) {
|
||||
this.socket.error('SERVER', error);
|
||||
}
|
||||
|
||||
// update clients
|
||||
@@ -815,21 +820,6 @@ export class EventTimer extends Timer {
|
||||
this.runCycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description inserts an event in the first position of the list
|
||||
* @param event
|
||||
*/
|
||||
insertEventAtStart(event) {
|
||||
// Insert at beginning
|
||||
this._eventlist.unshift(event);
|
||||
|
||||
// update clients
|
||||
this.broadcastState();
|
||||
|
||||
// run cycle
|
||||
this.runCycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleted an event from the list by its id
|
||||
* @param {string} eventId
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { body, validationResult } from 'express-validator';
|
||||
|
||||
export const eventSanitizer = [
|
||||
body('title').optional().isString().trim().escape(),
|
||||
body('url').optional().isString().trim().escape(),
|
||||
body('publicInfo').optional().isString().trim().escape(),
|
||||
body('backstageInfo').optional().isString().trim().escape(),
|
||||
body('endMessage').optional().isString().trim().escape(),
|
||||
body('title').optional().isString().trim(),
|
||||
body('url').optional().isString().trim(),
|
||||
body('publicInfo').optional().isString().trim(),
|
||||
body('backstageInfo').optional().isString().trim(),
|
||||
body('endMessage').optional().isString().trim(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
|
||||
@@ -14,17 +14,20 @@ import { socketProvider } from '../classes/socket/SocketController.js';
|
||||
const socket = socketProvider;
|
||||
|
||||
async function _insertAndSync(newEvent) {
|
||||
if (newEvent.order) {
|
||||
const events = DataProvider.getEvents();
|
||||
await DataProvider.insertEventAt(newEvent, newEvent.order);
|
||||
const previousId = events?.[newEvent.order - 1]?.id;
|
||||
_insertEventInTimerAfterId(newEvent, previousId);
|
||||
} else if (newEvent.after) {
|
||||
await DataProvider.insertEventAfterId(newEvent, newEvent.after);
|
||||
_insertEventInTimerAfterId(newEvent, newEvent.after);
|
||||
} else {
|
||||
const afterId = newEvent?.after;
|
||||
if (typeof afterId === 'undefined') {
|
||||
await DataProvider.insertEventAt(newEvent, 0);
|
||||
_insertEventInTimerAfterId(newEvent);
|
||||
if (newEvent.type === 'event') {
|
||||
_insertEventInTimerAfterId(newEvent);
|
||||
}
|
||||
} else {
|
||||
delete newEvent.after;
|
||||
await DataProvider.insertEventAfterId(newEvent, afterId);
|
||||
if (newEvent.type === 'event') {
|
||||
const events = DataProvider.getEvents();
|
||||
const { id } = getPreviousPlayable(events, newEvent.id);
|
||||
_insertEventInTimerAfterId(newEvent, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +54,10 @@ function _updateTimers() {
|
||||
* @private
|
||||
*/
|
||||
function _insertEventInTimerAfterId(event, previousId) {
|
||||
if (typeof previousId === 'undefined') {
|
||||
global.timer.insertEventAtStart(event);
|
||||
} else {
|
||||
try {
|
||||
global.timer.insertEventAfterId(event, previousId);
|
||||
} catch (error) {
|
||||
socket.error('SERVER', `Unable to update object: ${error}`);
|
||||
}
|
||||
try {
|
||||
global.timer.insertEventAfterId(event, previousId);
|
||||
} catch (error) {
|
||||
socket.error('SERVER', `Unable to update object: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,28 +146,29 @@ export const eventsPut = async (req, res) => {
|
||||
|
||||
const eventDataFromRequest = req.body;
|
||||
const eventId = eventDataFromRequest.id;
|
||||
const event = DataProvider.getEventById(eventId);
|
||||
const eventInMemory = DataProvider.getEventById(eventId);
|
||||
|
||||
if (typeof event === 'undefined') {
|
||||
if (typeof eventInMemory === 'undefined') {
|
||||
res.status(400).send(`No event with ID found`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const newData = await DataProvider.updateEventById(eventId, eventDataFromRequest);
|
||||
const patchedObject = await DataProvider.updateEventById(eventId, eventDataFromRequest);
|
||||
|
||||
if (newData.skip) {
|
||||
_deleteTimerId(eventId);
|
||||
// if it is a skip, make sure it is deleted from timer
|
||||
// event id might already not exist
|
||||
} else {
|
||||
try {
|
||||
_updateTimersSingle(newData.id, eventDataFromRequest);
|
||||
} catch (error) {
|
||||
if (error === 'Event not found') {
|
||||
if (patchedObject.type === 'event') {
|
||||
if (patchedObject.skip) {
|
||||
// if it is a skip, make sure it is deleted from timer
|
||||
_deleteTimerId(patchedObject.id);
|
||||
} else {
|
||||
if (eventInMemory.skip) {
|
||||
// if it was skipped before we add it to the timer
|
||||
const events = DataProvider.getEvents();
|
||||
const { id: previousId } = getPreviousPlayable(events, newData.id);
|
||||
_insertEventInTimerAfterId(newData, previousId);
|
||||
const { id } = getPreviousPlayable(events, patchedObject.id);
|
||||
_insertEventInTimerAfterId(patchedObject, id);
|
||||
} else {
|
||||
// otherwise update as normal
|
||||
_updateTimersSingle(patchedObject.id, patchedObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { body, param, validationResult } from 'express-validator';
|
||||
|
||||
export const eventsPostValidator = [
|
||||
body('type').isString().exists().isIn(['event', 'delay', 'block']),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
export const eventsPutValidator = [
|
||||
body('id').isString().exists(),
|
||||
(req, res, next) => {
|
||||
|
||||
@@ -56,7 +56,7 @@ const uploadAndParse = async (file, req, res, options) => {
|
||||
} else {
|
||||
await DataProvider.mergeIntoData(result.data);
|
||||
}
|
||||
global.timer.setupWithEventList(newEvents);
|
||||
global.timer.setupWithEventList(newEvents.filter((entry) => entry.type === 'event'));
|
||||
}
|
||||
res.sendStatus(200);
|
||||
} else {
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import express from 'express';
|
||||
export const router = express.Router();
|
||||
|
||||
// import events controller
|
||||
import {
|
||||
eventsApplyDelay,
|
||||
eventsDelete,
|
||||
eventsDeleteAll,
|
||||
eventsGetAll,
|
||||
eventsGetById,
|
||||
eventsPatch,
|
||||
eventsPost,
|
||||
eventsPut,
|
||||
eventsPatch,
|
||||
eventsReorder,
|
||||
eventsApplyDelay,
|
||||
eventsDeleteAll,
|
||||
eventsDelete,
|
||||
} from '../controllers/eventsController.js';
|
||||
import {
|
||||
eventsPostValidator,
|
||||
eventsPutValidator,
|
||||
paramsMustHaveEventId,
|
||||
} from '../controllers/eventsController.validate.js';
|
||||
|
||||
export const router = express.Router();
|
||||
|
||||
// create route between controller and '/events/' endpoint
|
||||
router.get('/', eventsGetAll);
|
||||
|
||||
@@ -25,7 +26,7 @@ router.get('/', eventsGetAll);
|
||||
router.get('/:eventId', eventsGetById);
|
||||
|
||||
// create route between controller and '/events/' endpoint
|
||||
router.post('/', eventsPost);
|
||||
router.post('/', eventsPostValidator, eventsPost);
|
||||
|
||||
// create route between controller and '/events/' endpoint
|
||||
router.put('/', eventsPutValidator, eventsPut);
|
||||
|
||||
Reference in New Issue
Block a user