mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 14:14:17 +00:00
refactor: type improvements (#751)
This commit is contained in:
@@ -23,7 +23,7 @@ class ErrorBoundary extends React.Component {
|
|||||||
|
|
||||||
componentDidCatch(error, info) {
|
componentDidCatch(error, info) {
|
||||||
this.setState({
|
this.setState({
|
||||||
error: error,
|
error,
|
||||||
errorInfo: info,
|
errorInfo: info,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import { useLocalStorage } from '../../../common/hooks/useLocalStorage';
|
import { useLocalStorage } from '../../hooks/useLocalStorage';
|
||||||
|
|
||||||
import ParamInput from './ParamInput';
|
import ParamInput from './ParamInput';
|
||||||
import { ParamField } from './types';
|
import { ParamField } from './types';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { IoTrashOutline } from '@react-icons/all-files/io5/IoTrashOutline';
|
|||||||
import { SupportedEvent } from 'ontime-types';
|
import { SupportedEvent } from 'ontime-types';
|
||||||
|
|
||||||
import { useEventAction } from '../../common/hooks/useEventAction';
|
import { useEventAction } from '../../common/hooks/useEventAction';
|
||||||
import { useEventSelection } from '../../features/rundown/useEventSelection';
|
import { useEventSelection } from '../rundown/useEventSelection';
|
||||||
|
|
||||||
const RundownMenu = ({ children }: { children: ReactNode }) => {
|
const RundownMenu = ({ children }: { children: ReactNode }) => {
|
||||||
const { clearSelectedEvents } = useEventSelection();
|
const { clearSelectedEvents } = useEventSelection();
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default function Operator() {
|
|||||||
const scrollRef = useRef<HTMLDivElement | null>(null);
|
const scrollRef = useRef<HTMLDivElement | null>(null);
|
||||||
const scrollToComponent = useFollowComponent({
|
const scrollToComponent = useFollowComponent({
|
||||||
followRef: selectedRef,
|
followRef: selectedRef,
|
||||||
scrollRef: scrollRef,
|
scrollRef,
|
||||||
doFollow: !lockAutoScroll,
|
doFollow: !lockAutoScroll,
|
||||||
topOffset: selectedOffset,
|
topOffset: selectedOffset,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export const useEventSelection = create<EventSelectionStore>()((set, get) => ({
|
|||||||
selectedEvents.delete(id);
|
selectedEvents.delete(id);
|
||||||
|
|
||||||
return set({
|
return set({
|
||||||
selectedEvents: selectedEvents,
|
selectedEvents,
|
||||||
anchoredIndex: newAnchoredIndex?.index ?? 0,
|
anchoredIndex: newAnchoredIndex?.index ?? 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ export const startServer = async () => {
|
|||||||
* @param overrideConfig
|
* @param overrideConfig
|
||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
export const startOSCServer = async (overrideConfig = null) => {
|
export const startOSCServer = async (overrideConfig?: { port: number }) => {
|
||||||
checkStart(OntimeStartOrder.InitIO);
|
checkStart(OntimeStartOrder.InitIO);
|
||||||
|
|
||||||
const { osc } = DataProvider.getData();
|
const { osc } = DataProvider.getData();
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ export class SimpleTimer {
|
|||||||
private startedAt: number | null = null;
|
private startedAt: number | null = null;
|
||||||
private pausedAt: number | null = null;
|
private pausedAt: number | null = null;
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
public reset() {
|
public reset() {
|
||||||
this.state = {
|
this.state = {
|
||||||
duration: 0,
|
duration: 0,
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ describe('SimpleTimer count-down', () => {
|
|||||||
expect(newState).toStrictEqual(expected);
|
expect(newState).toStrictEqual(expected);
|
||||||
|
|
||||||
newState = timer.update(1800);
|
newState = timer.update(1800);
|
||||||
(expected.current = initialTime - 1800 + pausedTime), expect(newState).toStrictEqual(expected);
|
expected.current = initialTime - 1800 + pausedTime;
|
||||||
|
expect(newState).toStrictEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('stopping the timer clears the running data', () => {
|
test('stopping the timer clears the running data', () => {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export function updateEvent(
|
|||||||
const event = EventLoader.getEventWithId(eventId);
|
const event = EventLoader.getEventWithId(eventId);
|
||||||
if (event) {
|
if (event) {
|
||||||
if (!isOntimeEvent(event)) {
|
if (!isOntimeEvent(event)) {
|
||||||
throw new Error(`Can only update events`);
|
throw new Error('Can only update events');
|
||||||
}
|
}
|
||||||
const propertiesToUpdate = { [propertyName]: newValue };
|
const propertiesToUpdate = { [propertyName]: newValue };
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ const parseAndApply = async (file, _req, res, options) => {
|
|||||||
*/
|
*/
|
||||||
const getNetworkInterfaces = () => {
|
const getNetworkInterfaces = () => {
|
||||||
const nets = networkInterfaces();
|
const nets = networkInterfaces();
|
||||||
const results = [];
|
const results: { name: string; address: string }[] = [];
|
||||||
|
|
||||||
for (const name of Object.keys(nets)) {
|
for (const name of Object.keys(nets)) {
|
||||||
for (const net of nets[name]) {
|
for (const net of nets[name]) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const populateDemo = () => {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
resolveDemoPath.map((to, index) => {
|
resolveDemoPath.map((to, index) => {
|
||||||
const from = pathToStartDemo[index];
|
const from = pathToStartDemo[index];
|
||||||
copyFile(from, to);
|
return copyFile(from, to);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|||||||
@@ -34,18 +34,10 @@ export class HttpIntegration implements IIntegration<HttpSubscriptionOptions> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.initSubscriptions(subscriptions);
|
this.initSubscriptions(subscriptions);
|
||||||
|
return {
|
||||||
try {
|
success: true,
|
||||||
return {
|
message: 'HTTP integration client ready',
|
||||||
success: true,
|
};
|
||||||
message: `HTTP integration client ready`,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
message: `Failed initialising HTTP integration: ${error}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initSubscriptions(subscriptionOptions: HttpSubscription) {
|
initSubscriptions(subscriptionOptions: HttpSubscription) {
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ export class OscIntegration implements IIntegration<OscSubscriptionOptions> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit(path: string, payload?: ArgumentType) {
|
emit(path: string, payload?: ArgumentType) {
|
||||||
|
if (!this.oscClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const message = new Message(path);
|
const message = new Message(path);
|
||||||
if (payload) {
|
if (payload) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import * as runtimeState from '../../stores/runtimeState.js';
|
|||||||
class RuntimeService {
|
class RuntimeService {
|
||||||
private eventTimer: TimerService | null = null;
|
private eventTimer: TimerService | null = null;
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
init(resumable: RestorePoint | null) {
|
init(resumable: RestorePoint | null) {
|
||||||
logger.info(LogOrigin.Server, 'Runtime service started');
|
logger.info(LogOrigin.Server, 'Runtime service started');
|
||||||
// TODO: refresh at 32ms, slowing down now to keep UI responsive while we dont have granular updates
|
// TODO: refresh at 32ms, slowing down now to keep UI responsive while we dont have granular updates
|
||||||
@@ -339,6 +337,11 @@ class RuntimeService {
|
|||||||
const { selectedEventId, playback } = restorePoint;
|
const { selectedEventId, playback } = restorePoint;
|
||||||
if (playback === Playback.Roll) {
|
if (playback === Playback.Roll) {
|
||||||
this.roll();
|
this.roll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedEventId) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the db would have to change for the event not to exist
|
// the db would have to change for the event not to exist
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MaybeNumber, OntimeEvent, TimerType } from 'ontime-types';
|
import { MaybeNumber, MaybeString, OntimeEvent, TimerType } from 'ontime-types';
|
||||||
import { dayInMs } from 'ontime-utils';
|
import { dayInMs } from 'ontime-utils';
|
||||||
import { RuntimeState } from '../stores/runtimeState.js';
|
import { RuntimeState } from '../stores/runtimeState.js';
|
||||||
import { sortArrayByProperty } from '../utils/arrayUtils.js';
|
import { sortArrayByProperty } from '../utils/arrayUtils.js';
|
||||||
@@ -94,13 +94,26 @@ export function skippedOutOfEvent(state: RuntimeState, previousTime: number, ski
|
|||||||
return hasSkipped && (adjustedClock > adjustedExpectedFinish || adjustedClock < startedAt);
|
return hasSkipped && (adjustedClock > adjustedExpectedFinish || adjustedClock < startedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RollTimers = {
|
||||||
|
nowIndex: MaybeNumber;
|
||||||
|
nowId: MaybeString;
|
||||||
|
publicIndex: MaybeNumber;
|
||||||
|
nextIndex: MaybeNumber;
|
||||||
|
publicNextIndex: MaybeNumber;
|
||||||
|
timeToNext: MaybeNumber;
|
||||||
|
nextEvent: OntimeEvent | null;
|
||||||
|
nextPublicEvent: OntimeEvent | null;
|
||||||
|
currentEvent: OntimeEvent | null;
|
||||||
|
currentPublicEvent: OntimeEvent | null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds loading information given a current rundown and time
|
* Finds loading information given a current rundown and time
|
||||||
* @param {OntimeEvent[]} rundown - List of playable events
|
* @param {OntimeEvent[]} rundown - List of playable events
|
||||||
* @param {number} timeNow - time now in ms
|
* @param {number} timeNow - time now in ms
|
||||||
* @returns {{}}
|
* @returns {{}}
|
||||||
*/
|
*/
|
||||||
export const getRollTimers = (rundown: OntimeEvent[], timeNow: number) => {
|
export const getRollTimers = (rundown: OntimeEvent[], timeNow: number): RollTimers => {
|
||||||
let nowIndex: number | null = null; // index of event now
|
let nowIndex: number | null = null; // index of event now
|
||||||
let nowId: string | null = null; // id of event now
|
let nowId: string | null = null; // id of event now
|
||||||
let publicIndex: number | null = null; // index of public event now
|
let publicIndex: number | null = null; // index of public event now
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class Sheet {
|
|||||||
this.authServerTimeout = setTimeout(
|
this.authServerTimeout = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
Sheet.authUrl = null;
|
Sheet.authUrl = null;
|
||||||
server.unref;
|
server.unref();
|
||||||
},
|
},
|
||||||
2 * 60 * 1000,
|
2 * 60 * 1000,
|
||||||
);
|
);
|
||||||
@@ -140,7 +140,7 @@ class Sheet {
|
|||||||
}
|
}
|
||||||
if (!searchParams.has('code')) {
|
if (!searchParams.has('code')) {
|
||||||
res.end('No authentication code provided.');
|
res.end('No authentication code provided.');
|
||||||
logger.info(LogOrigin.Server, `Sheet: Cannot read authentication code`);
|
logger.info(LogOrigin.Server, 'Sheet: Cannot read authentication code');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const code = searchParams.get('code');
|
const code = searchParams.get('code');
|
||||||
@@ -151,7 +151,7 @@ class Sheet {
|
|||||||
client.credentials = tokens;
|
client.credentials = tokens;
|
||||||
Sheet.client = client;
|
Sheet.client = client;
|
||||||
res.end('Authentication successful! Please close this tab and return to OnTime.');
|
res.end('Authentication successful! Please close this tab and return to OnTime.');
|
||||||
logger.info(LogOrigin.Server, `Sheet: Authentication successful`);
|
logger.info(LogOrigin.Server, 'Sheet: Authentication successful');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(LogOrigin.Server, `Sheet: ${e}`);
|
logger.error(LogOrigin.Server, `Sheet: ${e}`);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -277,7 +277,7 @@ class Sheet {
|
|||||||
spreadsheetId: id,
|
spreadsheetId: id,
|
||||||
valueRenderOption: 'FORMATTED_VALUE',
|
valueRenderOption: 'FORMATTED_VALUE',
|
||||||
majorDimension: 'ROWS',
|
majorDimension: 'ROWS',
|
||||||
range: range,
|
range,
|
||||||
});
|
});
|
||||||
if (readResponse.status === 200) {
|
if (readResponse.status === 200) {
|
||||||
const { rundownMetadata } = parseExcel(readResponse.data.values, options);
|
const { rundownMetadata } = parseExcel(readResponse.data.values, options);
|
||||||
@@ -364,7 +364,7 @@ class Sheet {
|
|||||||
const dataFromSheet = parseExcel(googleResponse.data.values, options);
|
const dataFromSheet = parseExcel(googleResponse.data.values, options);
|
||||||
res.data.rundown = parseRundown(dataFromSheet);
|
res.data.rundown = parseRundown(dataFromSheet);
|
||||||
if (res.data.rundown.length < 1) {
|
if (res.data.rundown.length < 1) {
|
||||||
throw new Error(`Sheet: Could not find data to import in the worksheet`);
|
throw new Error('Sheet: Could not find data to import in the worksheet');
|
||||||
}
|
}
|
||||||
res.data.userFields = parseUserFields(dataFromSheet);
|
res.data.userFields = parseUserFields(dataFromSheet);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { ensureDirectory } from './fileManagement.js';
|
|||||||
import { getAppDataPath } from '../setup.js';
|
import { getAppDataPath } from '../setup.js';
|
||||||
|
|
||||||
function generateNewFileName(filePath, callback) {
|
function generateNewFileName(filePath, callback) {
|
||||||
let baseName = path.basename(filePath, path.extname(filePath));
|
const baseName = path.basename(filePath, path.extname(filePath));
|
||||||
let extension = path.extname(filePath);
|
const extension = path.extname(filePath);
|
||||||
let counter = 1;
|
let counter = 1;
|
||||||
|
|
||||||
const checkExistence = (newPath) => {
|
const checkExistence = (newPath) => {
|
||||||
@@ -24,7 +24,7 @@ function generateNewFileName(filePath, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let newPath = path.join(path.dirname(filePath), `${baseName} (${counter})${extension}`);
|
const newPath = path.join(path.dirname(filePath), `${baseName} (${counter})${extension}`);
|
||||||
checkExistence(newPath);
|
checkExistence(newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +75,6 @@ const filterAllowed = (req, file, cb) => {
|
|||||||
|
|
||||||
// Build multer uploader for a single file
|
// Build multer uploader for a single file
|
||||||
export const uploadFile = multer({
|
export const uploadFile = multer({
|
||||||
storage: storage,
|
storage,
|
||||||
fileFilter: filterAllowed,
|
fileFilter: filterAllowed,
|
||||||
}).single('userFile');
|
}).single('userFile');
|
||||||
Reference in New Issue
Block a user