mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-17 05:13:32 +00:00
V2 ws store (#310)
* Update TimerService.ts * refactor: message service publishes to store * refactor: several type improvements * V2 ws store wss (#309) * refactor: shared logging types * refactor: simplify message service consumption * refactor: create discrete logging system * refactor: move socket.io > websocket
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
export default function createStore<T>(initialState: T) {
|
||||
let currentState = initialState;
|
||||
const listeners = new Set<(state: T) => void>();
|
||||
|
||||
return {
|
||||
get: () => currentState,
|
||||
set: (newState: T) => {
|
||||
currentState = newState;
|
||||
listeners.forEach((listener) => listener(currentState));
|
||||
},
|
||||
subscribe: (listener: (state: T) => void) => {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { useCallback } from 'react';
|
||||
import { Log, LogLevel } from 'ontime-types';
|
||||
import { generateId, millisToString } from 'ontime-utils';
|
||||
import { useStore } from 'zustand';
|
||||
import { createStore } from 'zustand/vanilla';
|
||||
|
||||
import { socketSendJson } from '../utils/socket';
|
||||
import { nowInMillis } from '../utils/time';
|
||||
|
||||
type LogStore = {
|
||||
logs: Log[];
|
||||
};
|
||||
|
||||
export const logger = createStore<LogStore>(() => ({
|
||||
logs: [],
|
||||
}));
|
||||
|
||||
export const useLogData = () => useStore(logger);
|
||||
|
||||
export const addLog = (log: Log) =>
|
||||
logger.setState((state) => ({
|
||||
logs: [...state.logs, log],
|
||||
}));
|
||||
|
||||
export const clearLogs = () => logger.setState({ logs: [] });
|
||||
|
||||
export function useEmitLog() {
|
||||
/**
|
||||
* Utility function sends message over socket
|
||||
* @param text
|
||||
* @param level
|
||||
* @private
|
||||
*/
|
||||
const _emit = useCallback((text: string, level: LogLevel) => {
|
||||
const log = {
|
||||
id: generateId(),
|
||||
origin: 'CLIENT',
|
||||
time: millisToString(nowInMillis()),
|
||||
level,
|
||||
text,
|
||||
};
|
||||
|
||||
addLog(log);
|
||||
socketSendJson('ontime-log', log);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Sends a message with level INFO
|
||||
* @param text
|
||||
*/
|
||||
const emitInfo = useCallback(
|
||||
(text: string) => {
|
||||
_emit(text, LogLevel.Info);
|
||||
},
|
||||
[_emit],
|
||||
);
|
||||
|
||||
/**
|
||||
* Sends a message with level WARN
|
||||
* @param text
|
||||
*/
|
||||
const emitWarning = useCallback(
|
||||
(text: string) => {
|
||||
_emit(text, LogLevel.Warn);
|
||||
},
|
||||
[_emit],
|
||||
);
|
||||
|
||||
/**
|
||||
* Sends a message with level ERROR
|
||||
* @param text
|
||||
*/
|
||||
const emitError = useCallback(
|
||||
(text: string) => {
|
||||
_emit(text, LogLevel.Error);
|
||||
},
|
||||
[_emit],
|
||||
);
|
||||
|
||||
return {
|
||||
emitInfo,
|
||||
emitWarning,
|
||||
emitError,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import isEqual from 'react-fast-compare';
|
||||
import { Playback, RuntimeStore } from 'ontime-types';
|
||||
import { useStore } from 'zustand';
|
||||
import { createStore } from 'zustand/vanilla';
|
||||
|
||||
export const runtimeStorePlaceholder = {
|
||||
timer: {
|
||||
clock: 0,
|
||||
current: null,
|
||||
elapsed: null,
|
||||
expectedFinish: null,
|
||||
addedTime: 0,
|
||||
startedAt: null,
|
||||
finishedAt: null,
|
||||
secondaryTimer: null,
|
||||
selectedEventId: null,
|
||||
duration: null,
|
||||
timerType: null,
|
||||
},
|
||||
playback: Playback.Stop,
|
||||
timerMessage: {
|
||||
text: '',
|
||||
visible: false,
|
||||
},
|
||||
publicMessage: {
|
||||
text: '',
|
||||
visible: false,
|
||||
},
|
||||
lowerMessage: {
|
||||
text: '',
|
||||
visible: false,
|
||||
},
|
||||
onAir: false,
|
||||
loaded: {
|
||||
numEvents: 0,
|
||||
selectedEventIndex: null,
|
||||
selectedEventId: null,
|
||||
selectedPublicEventId: null,
|
||||
nextEventId: null,
|
||||
nextPublicEventId: null,
|
||||
},
|
||||
titles: {
|
||||
titleNow: null,
|
||||
subtitleNow: null,
|
||||
presenterNow: null,
|
||||
noteNow: null,
|
||||
titleNext: null,
|
||||
subtitleNext: null,
|
||||
presenterNext: null,
|
||||
noteNext: null,
|
||||
},
|
||||
titlesPublic: {
|
||||
titleNow: null,
|
||||
subtitleNow: null,
|
||||
presenterNow: null,
|
||||
noteNow: null,
|
||||
titleNext: null,
|
||||
subtitleNext: null,
|
||||
presenterNext: null,
|
||||
noteNext: null,
|
||||
},
|
||||
};
|
||||
|
||||
export const runtime = createStore<RuntimeStore>(() => ({
|
||||
...runtimeStorePlaceholder,
|
||||
}));
|
||||
|
||||
export const deepCompare = <T>(a: T, b: T) => isEqual(a, b);
|
||||
|
||||
export const useRuntimeStore = <T>(
|
||||
selector: (state: RuntimeStore) => T,
|
||||
equalityFn?: (a: unknown, b: unknown) => boolean,
|
||||
) => useStore(runtime, selector, equalityFn);
|
||||
Reference in New Issue
Block a user