Files
ontime/apps/client/src/common/context/LoggingContext.tsx
T
Carlos Valente de9a7a87fd V2 monorepo (#285)
* refactor(project structure): UI

* refactor(project structure): extract utilities

* refactor(project structure): remove unused

* refactor(project structure): electron

* refactor(project structure): server

refactor: migrate to vitest

refactor: monorepo config

* refactor: extract application menu

* refactor: exit process

* refactor: extract tray menu

* chore: electron build

* Added Seconds in studio clock #282
---------

Co-authored-by: Fabian Posenau <fabian@fphome.de>

---------

Co-authored-by: Fabian Posenau <fabian.p99@gmx.de>
Co-authored-by: Fabian Posenau <fabian@fphome.de>
2023-02-14 22:02:15 +01:00

138 lines
2.9 KiB
TypeScript

import { createContext, ReactNode, useCallback, useEffect, useState } from 'react';
import { generateId } from 'ontime-utils';
import socket from '../utils/socket';
import { nowInMillis, stringFromMillis } from '../utils/time';
export enum LOG_LEVEL {
INFO = 'INFO',
WARN = 'WARN',
ERROR = 'ERROR',
}
export type Log = {
id: string;
origin: string;
time: string;
level: LOG_LEVEL;
text: string;
};
interface LoggingProviderState {
logData: Log[];
emitInfo: (text: string) => void;
emitWarning: (text: string) => void;
emitError: (text: string) => void;
clearLog: () => void;
}
type LoggingProviderProps = {
children: ReactNode;
};
const notInitialised = () => {
throw new Error('Not initialised');
};
export const LoggingContext = createContext<LoggingProviderState>({
logData: [],
emitInfo: notInitialised,
emitWarning: notInitialised,
emitError: notInitialised,
clearLog: notInitialised,
});
export const LoggingProvider = ({ children }: LoggingProviderProps) => {
const MAX_MESSAGES = 100;
const [logData, setLogData] = useState<Log[]>([]);
const origin = 'USER';
// todo: use react-query store
// todo: useSubscription or feature
// handle incoming messages
useEffect(() => {
socket.emit('get-logger');
socket.on('logger', (data: Log) => {
setLogData((currentLog) => [data, ...currentLog]);
});
// Clear listener
return () => {
socket.off('logger');
};
}, []);
/**
* Utility function sends message over socket
* @param text
* @param level
* @private
*/
const _send = useCallback(
(text: string, level: LOG_LEVEL) => {
if (socket != null) {
const newLogMessage: Log = {
id: generateId(),
origin,
time: stringFromMillis(nowInMillis()),
level,
text,
};
setLogData((currentLog) => [newLogMessage, ...currentLog]);
socket.emit('logger', newLogMessage);
}
if (logData.length > MAX_MESSAGES) {
setLogData((currentLog) => currentLog.slice(1));
}
},
[logData.length, setLogData],
);
/**
* Sends a message with level INFO
* @param text
*/
const emitInfo = useCallback(
(text: string) => {
_send(text, LOG_LEVEL.INFO);
},
[_send],
);
/**
* Sends a message with level WARN
* @param text
*/
const emitWarning = useCallback(
(text: string) => {
_send(text, LOG_LEVEL.WARN);
},
[_send],
);
/**
* Sends a message with level ERROR
* @param text
*/
const emitError = useCallback(
(text: string) => {
_send(text, LOG_LEVEL.ERROR);
},
[_send],
);
/**
* Clears running log
*/
const clearLog = useCallback(() => {
setLogData([]);
}, [setLogData]);
return (
<LoggingContext.Provider value={{ emitInfo, logData, emitWarning, emitError, clearLog }}>
{children}
</LoggingContext.Provider>
);
};