mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-09 01:13:55 +00:00
Merge remote-tracking branch 'origin/master' into feat/http-integration
This commit is contained in:
@@ -34,6 +34,7 @@ import { populateStyles } from './modules/loadStyles.js';
|
||||
import { eventStore, getInitialPayload } from './stores/EventStore.js';
|
||||
import { PlaybackService } from './services/PlaybackService.js';
|
||||
import { RestorePoint, restoreService } from './services/RestoreService.js';
|
||||
import { messageService } from './services/message-service/MessageService.js';
|
||||
|
||||
console.log(`Starting Ontime version ${ONTIME_VERSION}`);
|
||||
|
||||
@@ -156,6 +157,9 @@ export const startServer = async () => {
|
||||
const initialPayload = getInitialPayload();
|
||||
eventStore.init(initialPayload);
|
||||
|
||||
// eventStore set is a dependency of the services that publish to it
|
||||
messageService.init(eventStore.set.bind(eventStore));
|
||||
|
||||
expressServer.listen(serverPort, '0.0.0.0');
|
||||
|
||||
return { message: returnMessage, serverPort };
|
||||
|
||||
@@ -109,6 +109,20 @@ export function dispatchFromAdapter(
|
||||
break;
|
||||
}
|
||||
|
||||
case 'set-external-message-text': {
|
||||
if (typeof payload !== 'string') {
|
||||
throw new Error(`Unable to parse payload: ${payload}`);
|
||||
}
|
||||
messageService.setExternalText(payload);
|
||||
return;
|
||||
}
|
||||
case 'set-external-message-visible': {
|
||||
if (typeof payload === 'undefined') {
|
||||
throw new Error(`Unable to parse payload: ${payload}`);
|
||||
}
|
||||
messageService.setExternalVisibility(Boolean(payload));
|
||||
break;
|
||||
}
|
||||
case 'start': {
|
||||
PlaybackService.start();
|
||||
break;
|
||||
|
||||
@@ -12,10 +12,17 @@
|
||||
--timer-progress-bg-override: #fff;
|
||||
--timer-progress-override: #202020;
|
||||
|
||||
--external-color-override: #161616;
|
||||
|
||||
--cuesheet-running-bg-override: #D20300;
|
||||
|
||||
--operator-running-bg-override: #D20300;
|
||||
--operator-highlight-override: #FFAB33;
|
||||
|
||||
--studio-active: #101010;
|
||||
--studio-idle: #cfcfcf;
|
||||
--studio-active-label: #101010;
|
||||
--studio-idle-label: #595959;
|
||||
}
|
||||
|
||||
.timer {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Message } from 'ontime-types';
|
||||
|
||||
import { eventStore } from '../../stores/EventStore.js';
|
||||
import { TimerMessage } from 'ontime-types/src/definitions/runtime/MessageControl.type.js';
|
||||
import { throttle } from '../../utils/throttle.js';
|
||||
|
||||
import type { PublishFn } from '../../stores/EventStore.js';
|
||||
|
||||
let instance;
|
||||
|
||||
@@ -9,8 +11,12 @@ class MessageService {
|
||||
timerMessage: TimerMessage;
|
||||
publicMessage: Message;
|
||||
lowerMessage: Message;
|
||||
externalMessage: Message;
|
||||
onAir: boolean;
|
||||
|
||||
private throttledSet: PublishFn;
|
||||
private publish: PublishFn | null;
|
||||
|
||||
constructor() {
|
||||
if (instance) {
|
||||
throw new Error('There can be only one');
|
||||
@@ -36,7 +42,40 @@ class MessageService {
|
||||
visible: false,
|
||||
};
|
||||
|
||||
this.externalMessage = {
|
||||
text: '',
|
||||
visible: false,
|
||||
};
|
||||
|
||||
this.onAir = false;
|
||||
this.throttledSet = () => {
|
||||
throw new Error('Published called before initialisation');
|
||||
};
|
||||
}
|
||||
|
||||
init(publish: PublishFn) {
|
||||
this.publish = publish;
|
||||
this.throttledSet = throttle((key, value) => this.publish(key, value), 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description sets message on stage timer screen
|
||||
*/
|
||||
setExternalText(payload: string) {
|
||||
if (this.externalMessage.text !== payload) {
|
||||
this.externalMessage.text = payload;
|
||||
this.throttledSet('externalMessage', this.externalMessage);
|
||||
}
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description sets message visibility on stage timer screen
|
||||
*/
|
||||
setExternalVisibility(status: boolean) {
|
||||
this.externalMessage.visible = status;
|
||||
this.throttledSet('externalMessage', this.externalMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +83,7 @@ class MessageService {
|
||||
*/
|
||||
setTimerText(payload: string) {
|
||||
this.timerMessage.text = payload;
|
||||
eventStore.set('timerMessage', this.timerMessage);
|
||||
this.throttledSet('timerMessage', this.timerMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -53,7 +92,7 @@ class MessageService {
|
||||
*/
|
||||
setTimerVisibility(status: boolean) {
|
||||
this.timerMessage.visible = status;
|
||||
eventStore.set('timerMessage', this.timerMessage);
|
||||
this.throttledSet('timerMessage', this.timerMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -62,7 +101,7 @@ class MessageService {
|
||||
*/
|
||||
setPublicText(payload: string) {
|
||||
this.publicMessage.text = payload;
|
||||
eventStore.set('publicMessage', this.publicMessage);
|
||||
this.throttledSet('publicMessage', this.publicMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -71,7 +110,7 @@ class MessageService {
|
||||
*/
|
||||
setPublicVisibility(status: boolean) {
|
||||
this.publicMessage.visible = status;
|
||||
eventStore.set('publicMessage', this.publicMessage);
|
||||
this.throttledSet('publicMessage', this.publicMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -80,7 +119,7 @@ class MessageService {
|
||||
*/
|
||||
setLowerText(payload: string) {
|
||||
this.lowerMessage.text = payload;
|
||||
eventStore.set('lowerMessage', this.lowerMessage);
|
||||
this.throttledSet('lowerMessage', this.lowerMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -89,7 +128,7 @@ class MessageService {
|
||||
*/
|
||||
setLowerVisibility(status: boolean) {
|
||||
this.lowerMessage.visible = status;
|
||||
eventStore.set('lowerMessage', this.lowerMessage);
|
||||
this.throttledSet('lowerMessage', this.lowerMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -102,7 +141,7 @@ class MessageService {
|
||||
} else {
|
||||
this.onAir = status;
|
||||
}
|
||||
eventStore.set('onAir', this.onAir);
|
||||
this.throttledSet('onAir', this.onAir);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -116,7 +155,7 @@ class MessageService {
|
||||
} else {
|
||||
this.timerMessage.timerBlink = status;
|
||||
}
|
||||
eventStore.set('timerMessage', this.timerMessage);
|
||||
this.throttledSet('timerMessage', this.timerMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
@@ -130,7 +169,7 @@ class MessageService {
|
||||
} else {
|
||||
this.timerMessage.timerBlackout = status;
|
||||
}
|
||||
eventStore.set('timerMessage', this.timerMessage);
|
||||
this.throttledSet('timerMessage', this.timerMessage);
|
||||
return this.getAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import { eventTimer } from '../services/TimerService.js';
|
||||
import { messageService } from '../services/message-service/MessageService.js';
|
||||
import { eventLoader } from '../classes/event-loader/EventLoader.js';
|
||||
|
||||
export type PublishFn = <T extends keyof RuntimeStore>(key: T, value: RuntimeStore[T]) => void;
|
||||
|
||||
let store: Partial<RuntimeStore> = {};
|
||||
|
||||
/**
|
||||
@@ -68,6 +70,7 @@ export const getInitialPayload = () => ({
|
||||
timerMessage: messageService.timerMessage,
|
||||
publicMessage: messageService.publicMessage,
|
||||
lowerMessage: messageService.lowerMessage,
|
||||
externalMessage: messageService.externalMessage,
|
||||
onAir: messageService.onAir,
|
||||
loaded: eventLoader.loaded,
|
||||
eventNow: eventLoader.eventNow,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Creates a throttled version of the passed function
|
||||
* This function uses a leading algorithm
|
||||
* which means that the function will be executed immediately on first call
|
||||
* @param {Function} cb - function to throttle
|
||||
* @param {number} delay - time (in ms) to throttle
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function throttle<T extends any[], U>(cb: (...args: T) => U, delay: number) {
|
||||
let shouldWait = false;
|
||||
let waitingArgs;
|
||||
const timeoutFunc = () => {
|
||||
if (waitingArgs == null) {
|
||||
shouldWait = false;
|
||||
} else {
|
||||
cb(...waitingArgs);
|
||||
waitingArgs = null;
|
||||
setTimeout(timeoutFunc, delay);
|
||||
}
|
||||
};
|
||||
|
||||
return (...args: T) => {
|
||||
if (shouldWait) {
|
||||
waitingArgs = args;
|
||||
return;
|
||||
}
|
||||
|
||||
cb(...args);
|
||||
shouldWait = true;
|
||||
setTimeout(timeoutFunc, delay);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user