Skip to content

Commit

Permalink
refactor: v2 event loader (#260)
Browse files Browse the repository at this point in the history
* refactor: extract jest config

* refactor: rename params in reoder endpoint

* refactor: avoid app exports

* refactor: small code smells

* refactor: run development server

* refactor: extract rundown service and event loader logic

* refactor: rename events > rundown

* refactor: code style

* fix: handle external change of title

* refactor: cleanup dictionary

* refactor: rename MessageService

* refactor: use eventID for operations

* refactor: migrate OSC controller to service

* refactor: migrate Socket controller to service

* refactor: migrate HTTP controller to service

* refactor: extract logic into discrete services

* refactor: remove rundown from event timer

* refactor: remove duplicate

* refactor: remove unused

* chore: update tests
  • Loading branch information
cpvalente authored Nov 22, 2022
1 parent c1f8773 commit ff5735f
Show file tree
Hide file tree
Showing 32 changed files with 1,232 additions and 1,182 deletions.
6 changes: 3 additions & 3 deletions client/src/common/hooks/useEventAction.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useContext } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { RUNDOWN_TABLE_KEY,RUNDOWN_TABLE } from '../api/apiConstants';
import { RUNDOWN_TABLE, RUNDOWN_TABLE_KEY } from '../api/apiConstants';
import {
requestApplyDelay,
requestDelete,
Expand Down Expand Up @@ -106,7 +106,7 @@ export const useEventAction = () => {
emitError(`Error updating event: ${error.message}`);
}
},
[_updateEventMutation, emitError]
[_updateEventMutation, emitError],
);

/**
Expand Down Expand Up @@ -272,7 +272,7 @@ export const useEventAction = () => {
async (eventId, from, to) => {
try {
const reorderObject = {
index: eventId,
eventId: eventId,
from: from,
to: to,
};
Expand Down
34 changes: 17 additions & 17 deletions client/src/features/rundown/Rundown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,51 +193,51 @@ export default function Rundown(props) {
<Droppable droppableId='eventlist'>
{(provided) => (
<div className={style.list} {...provided.droppableProps} ref={provided.innerRef}>
{entries.map((e, index) => {
{entries.map((entry, index) => {
if (index === 0) {
cumulativeDelay = 0;
eventIndex = -1;
}
if (e.type === 'delay' && e.duration != null) {
cumulativeDelay += e.duration;
} else if (e.type === 'block') {
if (entry.type === 'delay' && entry.duration != null) {
cumulativeDelay += entry.duration;
} else if (entry.type === 'block') {
cumulativeDelay = 0;
} else if (e.type === 'event') {
} else if (entry.type === 'event') {
eventIndex++;
previousEnd = thisEnd;
thisEnd = e.timeEnd;
previousEventId = e.id;
thisEnd = entry.timeEnd;
previousEventId = entry.id;
}
const isLast = index === entries.length - 1;
return (
<div
key={e.id}
key={entry.id}
className={`${style.bgElement}
${e.type === 'event' && cumulativeDelay !== 0 ? style.delayed : ''}`}
${entry.type === 'event' && cumulativeDelay !== 0 ? style.delayed : ''}`}
>
<div
ref={cursor === index ? cursorRef : undefined}
className={cursor === index ? style.cursor : ''}
>
<RundownEntry
type={e.type}
type={entry.type}
index={index}
eventIndex={eventIndex}
data={e}
selected={selectedId === e.id}
next={nextId === e.id}
data={entry}
selected={selectedId === entry.id}
next={nextId === entry.id}
delay={cumulativeDelay}
previousEnd={previousEnd}
playback={selectedId === e.id ? data.playback : undefined}
playback={selectedId === entry.id ? data.playback : undefined}
/>
</div>
{((showQuickEntry && index === cursor) || isLast) && (
<QuickAddBlock
showKbd={index === cursor}
previousId={e.id}
previousId={entry.id}
previousEventId={previousEventId}
disableAddDelay={e.type === 'delay'}
disableAddBlock={e.type === 'block'}
disableAddDelay={entry.type === 'delay'}
disableAddBlock={entry.type === 'block'}
/>
)}
</div>
Expand Down
9 changes: 7 additions & 2 deletions client/src/features/rundown/event-block/EventBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { Draggable } from 'react-beautiful-dnd';
import { Editable, EditableInput, EditablePreview, Tooltip } from '@chakra-ui/react';
import { FiUsers } from '@react-icons/all-files/fi/FiUsers';
Expand Down Expand Up @@ -85,6 +85,11 @@ export default function EventBlock(props: EventBlockProps) {
const binderColours = colour && getAccessibleColour(colour);
const hasDelay = delay !== 0 && delay !== null;

// Todo: could I re-render the item without causing a state change here?
useEffect(() => {
setBlockTitle(title);
}, [title]);

const handleTitle = useCallback(
(text: string) => {
if (text === title) {
Expand All @@ -107,7 +112,7 @@ export default function EventBlock(props: EventBlockProps) {
if (!skip && eventIsPlaying) {
playBtnStyles._hover = { bg: '#c05621' };
} else if (!skip && !eventIsPlaying) {
playBtnStyles._hover = { };
playBtnStyles._hover = {};
}

return (
Expand Down
16 changes: 8 additions & 8 deletions client/src/features/table/TableWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { makeCSV, makeTable } from './utils';
import style from './Table.module.scss';

export default function TableWrapper() {
const { data: events } = useRundown();
const { data: rundown } = useRundown();
const { data: userFields } = useUserFields();
const { data: featureData } = useCuesheet();

Expand All @@ -32,7 +32,7 @@ export default function TableWrapper() {
}

// check if value is the same
const event = events[rowIndex];
const event = rundown[rowIndex];
if (event == null) {
return;
}
Expand All @@ -59,15 +59,15 @@ export default function TableWrapper() {
} catch (error) {
console.error(error);
}
}, [mutation, events]);
}, [mutation, rundown]);

const exportHandler = useCallback(
(headerData) => {
if (!headerData || !events || !userFields) {
if (!headerData || !rundown || !userFields) {
return;
}

const sheetData = makeTable(headerData, events, userFields);
const sheetData = makeTable(headerData, rundown, userFields);
const csvContent = makeCSV(sheetData);
const encodedUri = encodeURI(csvContent);
const link = document.createElement('a');
Expand All @@ -76,10 +76,10 @@ export default function TableWrapper() {
document.body.appendChild(link);
link.click();
},
[events, userFields]
[rundown, userFields]
);

if (typeof events === 'undefined' || typeof userFields === 'undefined') {
if (typeof rundown === 'undefined' || typeof userFields === 'undefined') {
return <span>loading...</span>;
}
return (
Expand All @@ -89,7 +89,7 @@ export default function TableWrapper() {
>
<TableHeader handleCSVExport={exportHandler} featureData={featureData} />
<OntimeTable
tableData={events}
tableData={rundown}
userFields={userFields}
handleUpdate={handleUpdate}
selectedId={featureData.selectedEventId}
Expand Down
8 changes: 8 additions & 0 deletions server/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const config = {
verbose: true,
testEnvironment: 'node',
rootDir: 'src',
transform: {},
};

module.exports = config;
3 changes: 3 additions & 0 deletions server/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const nodePath = isProduction

(async () => {
try {
const dbLoader = await import('./src/modules/loadDb.js');

await dbLoader.promise;
const { startServer, startOSCServer } = await import(nodePath);
// Start express server
loaded = await startServer();
Expand Down
6 changes: 1 addition & 5 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"prep": "yarn clean && yarn setdb",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
"start": "NODE_ENV=development electron .",
"start:server": "nodemon --experimental-modules --es-module-specifier-resolution=node src/run.js",
"start:server": "NODE_ENV=development nodemon --experimental-modules --es-module-specifier-resolution=node src/run.js",
"e2e": "set IS_TEST=true && playwright test",
"pack": "electron-builder --dir",
"dist": "electron-builder",
Expand All @@ -41,10 +41,6 @@
"dist-linux": "electron-builder --publish=never --x64 --linux",
"dist-all": "electron-builder -mw"
},
"jest": {
"testEnvironment": "node",
"rootDir": "src"
},
"build": {
"productName": "ontime",
"appId": "no.lightdev.ontime",
Expand Down
27 changes: 11 additions & 16 deletions server/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { config } from './config/config.js';

// import dependencies
import { dirname, join, resolve } from 'path';
// init database
import loadDb from './modules/loadDb.js';

// dependencies
import express from 'express';
import http from 'http';
Expand All @@ -22,6 +21,7 @@ import { router as playbackRouter } from './routes/playbackRouter.js';
// Global Objects
import { EventTimer } from './classes/timer/EventTimer.js';
import { socketProvider } from './classes/socket/SocketController.js';

// Start OSC server
import { initiateOSC, shutdownOSCServer } from './controllers/OscController.js';
import { fileURLToPath } from 'url';
Expand All @@ -33,7 +33,6 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const isTest = process.env.IS_TEST;

export const { db, data } = await loadDb(__dirname);
console.log(`Starting ontime version ${process.env.npm_package_version}`);

// import socket provider
Expand Down Expand Up @@ -74,14 +73,12 @@ const resolvedPath = () => {
app.use(express.static(join(__dirname, resolvedPath(), 'client/build')));

app.get('*', (req, res) => {
res.sendFile(
resolve(__dirname, resolvedPath(), 'client', 'build', 'index.html'),
);
res.sendFile(resolve(__dirname, resolvedPath(), 'client', 'build', 'index.html'));
});

// Implement route for errors
app.use((err, req, res, next) => {
res.status(500).send(err.stack);
// Implement catch all
app.use((error, response, _next) => {
response.status(400).send('Unhandled request');
});

/*************** START SERVICES ***************/
Expand All @@ -94,12 +91,12 @@ app.use((err, req, res, next) => {
*
*/

const { osc, settings } = DataProvider.getData();
const { osc } = DataProvider.getData();
const oscIP = osc?.targetIP || config.osc.targetIP;
const oscOutPort = osc?.portOut || config.osc.portOut;
const oscInPort = osc?.port || config.osc.port;
const oscInEnabled = osc?.enabled !== undefined ? osc.enabled : config.osc.inputEnabled;
const serverPort = settings.serverPort || config.server.port;
const serverPort = 4001; // hardcoded for now

/**
* @description starts OSC server
Expand Down Expand Up @@ -132,12 +129,11 @@ const server = http.createServer(app);
* @return {Promise<string>}
*/
export const startServer = async (overrideConfig = null) => {
const port = 4001; // port hardcoded
const { rundown, http } = DataProvider.getData();
const { http } = DataProvider.getData();

// Start server
const returnMessage = `Ontime is listening on port ${port}`;
server.listen(port, '0.0.0.0');
const returnMessage = `Ontime is listening on port ${serverPort}`;
server.listen(serverPort, '0.0.0.0');

// init socket controller
await socket.initServer(server);
Expand All @@ -151,7 +147,6 @@ export const startServer = async (overrideConfig = null) => {

// init timer
global.timer = new EventTimer(socket, config.timer, oscConfig, http);
global.timer.setupWithEventList(rundown.filter((entry) => entry.type === 'event'));

socket.info('SERVER', returnMessage);
socket.startListener();
Expand Down
4 changes: 2 additions & 2 deletions server/src/classes/data-provider/DataProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Class Event Provider is a mediator for handling the local db
* and adds logic specific to ontime data
*/
import { data, db } from '../../app.js';
import { db, data } from '../../modules/loadDb.js';

export class DataProvider {
static getData() {
Expand Down Expand Up @@ -96,7 +96,7 @@ export class DataProvider {
static async insertEventAfterId(entry, id) {
const index = [...data.rundown].findIndex((event) => event.id === id);
// eslint-disable-next-line no-unused-vars
const { _after, ...sanitisedEvent } = entry;
const { after, ...sanitisedEvent } = entry;
await DataProvider.insertEventAt(sanitisedEvent, index + 1);
}

Expand Down
Loading

0 comments on commit ff5735f

Please sign in to comment.