:
}
- onClick={() => setMessage.onAir(!data?.onAir)}
+ variant={data.onAir ? 'ontime-filled' : 'ontime-subtle'}
+ leftIcon={data.onAir ?
:
}
+ onClick={() => setMessage.onAir(!data.onAir)}
>
{data?.onAir ? 'Ontime is On Air' : 'Ontime is Off Air'}
diff --git a/apps/client/src/features/control/playback/PlaybackButtons.tsx b/apps/client/src/features/control/playback/PlaybackButtons.tsx
index 3fcffaefa..c459b0799 100644
--- a/apps/client/src/features/control/playback/PlaybackButtons.tsx
+++ b/apps/client/src/features/control/playback/PlaybackButtons.tsx
@@ -5,24 +5,15 @@ import Transport from './Transport';
interface PlaybackButtonsProps {
playback: Playback;
- selectedId: string | null;
noEvents: boolean;
}
export default function PlaybackButtons(props: PlaybackButtonsProps) {
- const { playback, selectedId, noEvents } = props;
+ const { playback, noEvents } = props;
return (
<>
-
-
+
+
>
);
};
diff --git a/apps/client/src/features/control/playback/PlaybackControl.tsx b/apps/client/src/features/control/playback/PlaybackControl.tsx
index aa8115709..4277e1618 100644
--- a/apps/client/src/features/control/playback/PlaybackControl.tsx
+++ b/apps/client/src/features/control/playback/PlaybackControl.tsx
@@ -8,19 +8,12 @@ import PlaybackTimer from './PlaybackTimer';
import style from './PlaybackControl.module.scss';
export default function PlaybackControl() {
- const { data } = usePlaybackControl();
+ const data = usePlaybackControl();
return (
);
}
diff --git a/apps/client/src/features/control/playback/PlaybackDisplay.tsx b/apps/client/src/features/control/playback/PlaybackDisplay.tsx
index f6f979ab4..d2000022a 100644
--- a/apps/client/src/features/control/playback/PlaybackDisplay.tsx
+++ b/apps/client/src/features/control/playback/PlaybackDisplay.tsx
@@ -11,23 +11,23 @@ import style from './PlaybackControl.module.scss';
interface PlaybackProps {
playback: Playback;
- selectedId: string | null;
noEvents: boolean;
}
export default function PlaybackDisplay(props: PlaybackProps) {
- const { playback, selectedId, noEvents } = props;
- const isRolling = playback === 'roll';
- const isPlaying = playback === 'play';
- const isPaused = playback === 'pause';
- const isArmed = playback === 'armed';
+ const { playback, noEvents } = props;
+ const isRolling = playback === Playback.Roll;
+ const isPlaying = playback === Playback.Play;
+ const isPaused = playback === Playback.Pause;
+ const isArmed = playback === Playback.Armed;
+ const isStopped = playback === Playback.Stop;
return (
setPlayback.start()}
- disabled={!selectedId || isRolling}
- theme='play'
+ disabled={isStopped || isRolling}
+ theme={Playback.Play}
active={isPlaying}
>
@@ -35,8 +35,8 @@ export default function PlaybackDisplay(props: PlaybackProps) {
setPlayback.pause()}
- disabled={!selectedId || isRolling || isArmed}
- theme='pause'
+ disabled={isStopped || isRolling || isArmed}
+ theme={Playback.Pause}
active={isPaused}
>
@@ -44,8 +44,8 @@ export default function PlaybackDisplay(props: PlaybackProps) {
setPlayback.roll()}
- disabled={noEvents}
- theme='roll'
+ disabled={!isStopped || noEvents}
+ theme={Playback.Roll}
active={isRolling}
>
diff --git a/apps/client/src/features/control/playback/PlaybackTimer.tsx b/apps/client/src/features/control/playback/PlaybackTimer.tsx
index c4dd8e2dd..2c382eafc 100644
--- a/apps/client/src/features/control/playback/PlaybackTimer.tsx
+++ b/apps/client/src/features/control/playback/PlaybackTimer.tsx
@@ -4,33 +4,33 @@ import { Playback } from 'ontime-types';
import TimerDisplay from '../../../common/components/timer-display/TimerDisplay';
import { setPlayback, useTimer } from '../../../common/hooks/useSocket';
import { millisToMinutes } from '../../../common/utils/dateConfig';
-import { stringFromMillis } from '../../../common/utils/time';
import { tooltipDelayMid } from '../../../ontimeConfig';
import TapButton from './TapButton';
import style from './PlaybackControl.module.scss';
+import { millisToString } from 'ontime-utils';
interface PlaybackTimerProps {
playback: Playback;
- selectedId: string | null;
}
export default function PlaybackTimer(props: PlaybackTimerProps) {
- const { playback, selectedId } = props;
- const { data: timerData } = useTimer();
+ const { playback } = props;
+ const data = useTimer();
// TODO: checkout typescript in utilities
- const started = stringFromMillis(timerData?.startedAt, true);
- const finish = stringFromMillis(timerData.expectedFinish, true);
- const isRolling = playback === 'roll';
- const isWaiting = timerData.secondaryTimer !== null && timerData.secondaryTimer > 0 && timerData.current === null;
- const disableButtons = selectedId === null || isRolling;
- const isOvertime = timerData.current !== null && timerData.current < 0;
- const hasAddedTime = Boolean(timerData.addedTime);
+ const started = millisToString(data.timer.startedAt);
+ const finish = millisToString(data.timer.expectedFinish);
+ const isRolling = playback === Playback.Roll;
+ const isStopped = playback === Playback.Stop;
+ const isWaiting = data.timer.secondaryTimer !== null && data.timer.secondaryTimer > 0 && data.timer.current === null;
+ const disableButtons = isStopped || isRolling;
+ const isOvertime = data.timer.current !== null && data.timer.current < 0;
+ const hasAddedTime = Boolean(data.timer.addedTime);
const rollLabel = isRolling ? 'Roll mode active' : '';
- const addedTimeLabel = hasAddedTime ? `Added ${millisToMinutes(timerData.addedTime)} minutes` : '';
+ const addedTimeLabel = hasAddedTime ? `Added ${millisToMinutes(data.timer.addedTime)} minutes` : '';
return (
@@ -44,7 +44,7 @@ export default function PlaybackTimer(props: PlaybackTimerProps) {
-
+
{isWaiting ? (
diff --git a/apps/client/src/features/control/playback/Transport.tsx b/apps/client/src/features/control/playback/Transport.tsx
index 0eb74f38b..918a037f2 100644
--- a/apps/client/src/features/control/playback/Transport.tsx
+++ b/apps/client/src/features/control/playback/Transport.tsx
@@ -14,46 +14,33 @@ import style from './PlaybackControl.module.scss';
interface TransportProps {
playback: Playback;
- selectedId: string | null;
noEvents: boolean;
}
export default function Transport(props: TransportProps) {
- const { playback, selectedId, noEvents } = props;
- const isRolling = playback === 'roll';
+ const { playback, noEvents } = props;
+ const isRolling = playback === Playback.Roll;
+ const isStopped = playback === Playback.Stop;
return (
- setPlayback.previous()}
- disabled={isRolling || noEvents}
- >
+ setPlayback.previous()} disabled={isRolling || noEvents}>
- setPlayback.next()}
- disabled={isRolling || noEvents}
- >
+ setPlayback.next()} disabled={isRolling || noEvents}>
- setPlayback.reload()}
- disabled={!selectedId || isRolling}
- >
+ setPlayback.reload()} disabled={isStopped || isRolling}>
- setPlayback.stop()}
- disabled={!selectedId && !isRolling}
- theme='stop'
- >
+ setPlayback.stop()} disabled={isStopped && !isRolling} theme={Playback.Stop}>
diff --git a/apps/client/src/features/event-editor/EventEditor.tsx b/apps/client/src/features/event-editor/EventEditor.tsx
index 5ffc5d8c2..2c5e18569 100644
--- a/apps/client/src/features/event-editor/EventEditor.tsx
+++ b/apps/client/src/features/event-editor/EventEditor.tsx
@@ -1,20 +1,20 @@
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { Button, Select, Switch } from '@chakra-ui/react';
import { IoBan } from '@react-icons/all-files/io5/IoBan';
import { useAtom } from 'jotai';
import { OntimeEvent, TimerType } from 'ontime-types';
+import { millisToString } from 'ontime-utils';
import { editorEventId } from '../../common/atoms/LocalEventSettings';
import CopyTag from '../../common/components/copy-tag/CopyTag';
import ColourInput from '../../common/components/input/colour-input/ColourInput';
import TextInput from '../../common/components/input/text-input/TextInput';
import TimeInput from '../../common/components/input/time-input/TimeInput';
-import { LoggingContext } from '../../common/context/LoggingContext';
import { useEventAction } from '../../common/hooks/useEventAction';
import useRundown from '../../common/hooks-query/useRundown';
+import { useEmitLog } from '../../common/stores/logger';
import { millisToMinutes } from '../../common/utils/dateConfig';
import getDelayTo from '../../common/utils/getDelayTo';
-import { stringFromMillis } from '../../common/utils/time';
import { calculateDuration, TimeEntryField, validateEntry } from '../../common/utils/timesManager';
import style from './EventEditor.module.scss';
@@ -25,7 +25,7 @@ export type EventEditorSubmitActions = keyof OntimeEvent | 'durationOverride';
export default function EventEditor() {
const [openId] = useAtom(editorEventId);
const { data } = useRundown();
- const { emitWarning, emitError } = useContext(LoggingContext);
+ const { emitWarning, emitError } = useEmitLog();
const { updateEvent } = useEventAction();
const [event, setEvent] = useState
(null);
const [delay, setDelay] = useState(0);
@@ -121,8 +121,8 @@ export default function EventEditor() {
const delayed = delay !== 0;
const addedTime = delayed ? `${delay >= 0 ? '+' : '-'} ${millisToMinutes(Math.abs(delay))} minutes` : null;
- const newStart = delayed ? `New start ${stringFromMillis(event.timeStart + delay)}` : null;
- const newEnd = delayed ? `New end ${stringFromMillis(event.timeEnd + delay)}` : null;
+ const newStart = delayed ? `New start ${millisToString(event.timeStart + delay)}` : null;
+ const newEnd = delayed ? `New end ${millisToString(event.timeEnd + delay)}` : null;
return (
diff --git a/apps/client/src/features/info/CollapsableInfo.tsx b/apps/client/src/features/info/CollapsableInfo.tsx
index 1a2e4929a..207052c4b 100644
--- a/apps/client/src/features/info/CollapsableInfo.tsx
+++ b/apps/client/src/features/info/CollapsableInfo.tsx
@@ -1,52 +1,21 @@
-import { useState } from 'react';
+import { PropsWithChildren, useState } from 'react';
import CollapseBar from '../../common/components/collapse-bar/CollapseBar';
import style from './Info.module.scss';
-type TitleShape = {
- title: string;
- presenter: string;
- subtitle: string;
- note: string;
-}
-
interface CollapsableInfoProps {
title: string;
- data: TitleShape;
}
-export default function CollapsableInfo(props: CollapsableInfoProps) {
- const { title, data } = props;
+export default function CollapsableInfo(props: PropsWithChildren
) {
+ const { title, children } = props;
const [collapsed, setCollapsed] = useState(false);
return (
-
setCollapsed((prev) => !prev)}
- />
- {!collapsed && (
-
-
- Title:
- {data.title}
-
-
- Presenter:
- {data.presenter}
-
-
- Subtitle:
- {data.subtitle}
-
-
- Note:
- {data.note}
-
-
- )}
+ setCollapsed((prev) => !prev)} />
+ {!collapsed && children}
);
}
diff --git a/apps/client/src/features/info/Info.jsx b/apps/client/src/features/info/Info.jsx
deleted file mode 100644
index 4ba685ff6..000000000
--- a/apps/client/src/features/info/Info.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useInfoPanel } from '../../common/hooks/useSocket';
-
-import InfoTitle from './CollapsableInfo';
-import InfoLogger from './InfoLogger';
-import InfoNif from './InfoNif';
-
-import style from './Info.module.scss';
-
-export default function Info() {
- const { data } = useInfoPanel();
-
- const titlesNow = {
- title: data.titles.titleNow,
- subtitle: data.titles.subtitleNow,
- presenter: data.titles.presenterNow,
- note: data.titles.noteNow,
- };
-
- const titlesNext = {
- title: data.titles.titleNext,
- subtitle: data.titles.subtitleNext,
- presenter: data.titles.presenterNext,
- note: data.titles.noteNext,
- };
-
- const selected = !data.numEvents
- ? 'No events'
- : `Event ${data.selectedEventIndex != null ? data.selectedEventIndex + 1 : '-'} / ${
- data.numEvents ? data.numEvents : '-'
- }`;
-
- return (
- <>
-
- Ontime running on port 4001
- {selected}
-
-
-
-
-
- >
- );
-}
diff --git a/apps/client/src/features/info/Info.tsx b/apps/client/src/features/info/Info.tsx
new file mode 100644
index 000000000..406ed85c6
--- /dev/null
+++ b/apps/client/src/features/info/Info.tsx
@@ -0,0 +1,53 @@
+import { useInfoPanel } from '../../common/hooks/useSocket';
+
+import CollapsableInfo from './CollapsableInfo';
+import InfoLogger from './InfoLogger';
+import InfoNif from './InfoNif';
+import InfoTitles from './InfoTitles';
+
+import style from './Info.module.scss';
+
+export default function Info() {
+ const data = useInfoPanel();
+
+ const titlesNow = {
+ title: data.titles.titleNow || '',
+ subtitle: data.titles.subtitleNow || '',
+ presenter: data.titles.presenterNow || '',
+ note: data.titles.noteNow || '',
+ };
+
+ const titlesNext = {
+ title: data.titles.titleNext || '',
+ subtitle: data.titles.subtitleNext || '',
+ presenter: data.titles.presenterNext || '',
+ note: data.titles.noteNext || '',
+ };
+
+ const selected = !data.numEvents
+ ? 'No events'
+ : `Event ${data.selectedEventIndex !== null ? data.selectedEventIndex + 1 : '-'} / ${
+ data.numEvents ? data.numEvents : '-'
+ }`;
+
+ return (
+ <>
+
+ Ontime running on port 4001
+ {selected}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/apps/client/src/features/info/InfoLogger.module.scss b/apps/client/src/features/info/InfoLogger.module.scss
index d1e86e4a9..33ba38860 100644
--- a/apps/client/src/features/info/InfoLogger.module.scss
+++ b/apps/client/src/features/info/InfoLogger.module.scss
@@ -6,12 +6,7 @@ $info-hover: $section-white;
.infoLoggerContainer {
max-height: 80%;
- margin-top: 32px;
-
- &.expanded {
- min-height: 50%;
- height: 100%
- }
+ height: 100%
}
.log {
@@ -24,6 +19,7 @@ $info-hover: $section-white;
.logEntry {
display: flex;
margin-bottom: 2px;
+
&.INFO {
color: $info-gray;
}
diff --git a/apps/client/src/features/info/InfoLogger.tsx b/apps/client/src/features/info/InfoLogger.tsx
index 9ded93754..5abab2ada 100644
--- a/apps/client/src/features/info/InfoLogger.tsx
+++ b/apps/client/src/features/info/InfoLogger.tsx
@@ -1,24 +1,22 @@
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useState } from 'react';
import { Button } from '@chakra-ui/react';
-import CollapseBar from '../../common/components/collapse-bar/CollapseBar';
-import { Log, LoggingContext } from '../../common/context/LoggingContext';
+import { clearLogs, useLogData } from '../../common/stores/logger';
import style from './InfoLogger.module.scss';
-enum LOG_FILTER {
- USER = 'USER',
- CLIENT = 'CLIENT',
- SERVER = 'SERVER',
+enum LogFilter {
+ User = 'USER',
+ Client = 'CLIENT',
+ Server = 'SERVER',
RX = 'RX',
TX = 'TX',
- PLAYBACK = 'PLAYBACK',
+ Playback = 'PLAYBACK',
}
export default function InfoLogger() {
- const { logData, clearLog } = useContext(LoggingContext);
- const [data, setData] = useState([]);
- const [collapsed, setCollapsed] = useState(false);
+ const { logs: logData } = useLogData();
+
const [showClient, setShowClient] = useState(true);
const [showServer, setShowServer] = useState(true);
const [showRx, setShowRx] = useState(true);
@@ -26,123 +24,107 @@ export default function InfoLogger() {
const [showPlayback, setShowPlayback] = useState(true);
const [showUser, setShowUser] = useState(true);
- useEffect(() => {
- if (!logData) {
- return;
- }
+ const matchers: LogFilter[] = [];
+ if (showUser) {
+ matchers.push(LogFilter.User);
+ }
+ if (showClient) {
+ matchers.push(LogFilter.Client);
+ }
+ if (showServer) {
+ matchers.push(LogFilter.Server);
+ }
+ if (showRx) {
+ matchers.push(LogFilter.RX);
+ }
+ if (showTx) {
+ matchers.push(LogFilter.TX);
+ }
+ if (showPlayback) {
+ matchers.push(LogFilter.Playback);
+ }
- const matchers: LOG_FILTER[] = [];
- if (showUser) {
- matchers.push(LOG_FILTER.USER);
- }
- if (showClient) {
- matchers.push(LOG_FILTER.CLIENT);
- }
- if (showServer) {
- matchers.push(LOG_FILTER.SERVER);
- }
- if (showRx) {
- matchers.push(LOG_FILTER.RX);
- }
- if (showTx) {
- matchers.push(LOG_FILTER.TX);
- }
- if (showPlayback) {
- matchers.push(LOG_FILTER.PLAYBACK);
- }
+ const filteredData = logData.filter((entry) => matchers.some((match) => entry.origin === match));
- const filteredData = logData.filter((entry) => matchers.some((match) => entry.origin === match));
- setData(filteredData);
- }, [logData, showUser, showClient, showServer, showPlayback, showRx, showTx]);
-
- const disableOthers = useCallback((toEnable: LOG_FILTER) => {
- toEnable === LOG_FILTER.USER ? setShowUser(true) : setShowUser(false);
- toEnable === LOG_FILTER.CLIENT ? setShowClient(true) : setShowClient(false);
- toEnable === LOG_FILTER.SERVER ? setShowServer(true) : setShowServer(false);
- toEnable === LOG_FILTER.RX ? setShowRx(true) : setShowRx(false);
- toEnable === LOG_FILTER.TX ? setShowTx(true) : setShowTx(false);
- toEnable === LOG_FILTER.PLAYBACK ? setShowPlayback(true) : setShowPlayback(false);
+ const disableOthers = useCallback((toEnable: LogFilter) => {
+ toEnable === LogFilter.User ? setShowUser(true) : setShowUser(false);
+ toEnable === LogFilter.Client ? setShowClient(true) : setShowClient(false);
+ toEnable === LogFilter.Server ? setShowServer(true) : setShowServer(false);
+ toEnable === LogFilter.RX ? setShowRx(true) : setShowRx(false);
+ toEnable === LogFilter.TX ? setShowTx(true) : setShowTx(false);
+ toEnable === LogFilter.Playback ? setShowPlayback(true) : setShowPlayback(false);
}, []);
return (
-
-
setCollapsed((prev) => !prev)} />
- {!collapsed && (
- <>
-
-
-
-
-
-
-
-
-
-
- {data.map((logEntry) => (
- -
- {logEntry.time}
- {logEntry.origin}
- {logEntry.text}
-
- ))}
-
- >
- )}
+
+
+
+
+
+
+
+
+
+
+
+ {filteredData.map((logEntry) => (
+ -
+ {logEntry.time}
+ {logEntry.origin}
+ {logEntry.text}
+
+ ))}
+
);
}
diff --git a/apps/client/src/features/info/InfoNif.tsx b/apps/client/src/features/info/InfoNif.tsx
index 907c5c04c..3b33aba7c 100644
--- a/apps/client/src/features/info/InfoNif.tsx
+++ b/apps/client/src/features/info/InfoNif.tsx
@@ -1,7 +1,5 @@
-import { useState } from 'react';
import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp';
-import CollapseBar from '../../common/components/collapse-bar/CollapseBar';
import useInfo from '../../common/hooks-query/useInfo';
import { openLink } from '../../common/utils/linkUtils';
@@ -9,7 +7,6 @@ import style from './Info.module.scss';
export default function InfoNif() {
const { data } = useInfo();
- const [collapsed, setCollapsed] = useState(false);
const handleClick = (address: string) => {
const baseURL = 'http://__IP__:4001';
@@ -17,18 +14,13 @@ export default function InfoNif() {
};
return (
-
-
setCollapsed((prev) => !prev)} />
- {!collapsed && (
-
- {data?.networkInterfaces.map((nif) => (
- handleClick(nif.address)} className={style.interface}>
- {`${nif.name} - ${nif.address}`}
-
-
- ))}
-
- )}
+
+ {data?.networkInterfaces.map((nif) => (
+ handleClick(nif.address)} className={style.interface}>
+ {`${nif.name} - ${nif.address}`}
+
+
+ ))}
);
}
diff --git a/apps/client/src/features/info/InfoTitles.tsx b/apps/client/src/features/info/InfoTitles.tsx
new file mode 100644
index 000000000..20b7bdb39
--- /dev/null
+++ b/apps/client/src/features/info/InfoTitles.tsx
@@ -0,0 +1,36 @@
+import style from './Info.module.scss';
+
+type TitleShape = {
+ title: string;
+ presenter: string;
+ subtitle: string;
+ note: string;
+};
+
+interface InfoTitleProps {
+ data: TitleShape;
+}
+
+export default function InfoTitles(props: InfoTitleProps) {
+ const { data } = props;
+ return (
+
+
+ Title:
+ {data.title}
+
+
+ Presenter:
+ {data.presenter}
+
+
+ Subtitle:
+ {data.subtitle}
+
+
+ Note:
+ {data.note}
+
+
+ );
+}
diff --git a/apps/client/src/features/modals/AliasesModal.jsx b/apps/client/src/features/modals/AliasesModal.jsx
index c7957750e..92222d9f1 100644
--- a/apps/client/src/features/modals/AliasesModal.jsx
+++ b/apps/client/src/features/modals/AliasesModal.jsx
@@ -1,13 +1,14 @@
/* eslint-disable jsx-a11y/anchor-has-content */
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { Button, IconButton, Input, ModalBody, Tooltip } from '@chakra-ui/react';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import { IoSunny } from '@react-icons/all-files/io5/IoSunny';
+import { useEmitLog } from '@/common/stores/logger';
+
import { viewerLocations } from '../../appConstants';
import { postAliases } from '../../common/api/ontimeApi';
-import { LoggingContext } from '../../common/context/LoggingContext';
import useAliases from '../../common/hooks-query/useAliases';
import { validateAlias } from '../../common/utils/aliases';
import { handleLinks, host } from '../../common/utils/linkUtils';
@@ -19,7 +20,7 @@ import style from './Modals.module.scss';
export default function AliasesModal() {
const { data, status, refetch } = useAliases();
- const { emitError } = useContext(LoggingContext);
+ const { emitError } = useEmitLog();
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [aliases, setAliases] = useState([]);
@@ -111,29 +112,32 @@ export default function AliasesModal() {
* @param {string} id - object id
* @param {boolean} isEnabled - whether to enable / disable flag
*/
- const setEnabled = useCallback((id, isEnabled) => {
- const aliasesState = [...aliases];
- for (const a of aliasesState) {
- if (a.id === id) {
- if (isEnabled) {
- if (a.alias === '' || a.pathAndParams === '') {
- emitError('Alias incomplete');
- break;
- }
+ const setEnabled = useCallback(
+ (id, isEnabled) => {
+ const aliasesState = [...aliases];
+ for (const a of aliasesState) {
+ if (a.id === id) {
+ if (isEnabled) {
+ if (a.alias === '' || a.pathAndParams === '') {
+ emitError('Alias incomplete');
+ break;
+ }
- const isRepeated = aliases.some((r) => a.alias === r.alias && r.enabled);
- if (isRepeated) {
- emitError('There is already an alias with this name');
- break;
+ const isRepeated = aliases.some((r) => a.alias === r.alias && r.enabled);
+ if (isRepeated) {
+ emitError('There is already an alias with this name');
+ break;
+ }
}
+ a.enabled = isEnabled;
+ break;
}
- a.enabled = isEnabled;
- break;
}
- }
- setChanged(true);
- setAliases(aliasesState);
- }, [aliases, emitError]);
+ setChanged(true);
+ setAliases(aliasesState);
+ },
+ [aliases, emitError],
+ );
/**
* Reverts local state equals to server state
@@ -194,16 +198,16 @@ export default function AliasesModal() {
eg. a lower third url with some custom parameters
-
- |
- Alias
- |
- Page URL |
-
-
- | mylower |
- lower?bg=ff2&text=f00&size=0.6&transition=5 |
-
+
+ |
+ Alias
+ |
+ Page URL |
+
+
+ | mylower |
+ lower?bg=ff2&text=f00&size=0.6&transition=5 |
+
@@ -212,16 +216,16 @@ export default function AliasesModal() {
eg. an unattended screen that you would need to change route from the app
-
- |
- Alias
- |
- Page URL |
-
-
- | thirdfloor |
- public |
-
+
+ |
+ Alias
+ |
+ Page URL |
+
+
+ | thirdfloor |
+ public |
+
@@ -254,12 +258,7 @@ export default function AliasesModal() {
onChange={(event) => handleChange(index, 'pathAndParams', event.target.value)}
/>
- handleLinks(e, alias.pathAndParams)}
- />
+ handleLinks(e, alias.pathAndParams)} />
- {alias.aliasError ? (
- {`Alias error: ${alias.aliasError}`}
- ) : null}
- {alias.urlError ? (
- {`URL error: ${alias.urlError}`}
- ) : null}
+ {alias.aliasError ? {`Alias error: ${alias.aliasError}`}
: null}
+ {alias.urlError ? {`URL error: ${alias.urlError}`}
: null}
))}
@@ -296,12 +291,7 @@ export default function AliasesModal() {
-
+
);
diff --git a/apps/client/src/features/modals/AppSettingsModal.jsx b/apps/client/src/features/modals/AppSettingsModal.jsx
index 69d62f63d..b22f844c9 100644
--- a/apps/client/src/features/modals/AppSettingsModal.jsx
+++ b/apps/client/src/features/modals/AppSettingsModal.jsx
@@ -1,4 +1,4 @@
-import { useContext, useEffect, useState } from 'react';
+import { useEffect, useState } from 'react';
import isEqual from 'react-fast-compare';
import {
Button,
@@ -16,11 +16,12 @@ import { FiEye } from '@react-icons/all-files/fi/FiEye';
import { FiX } from '@react-icons/all-files/fi/FiX';
import { useAtom } from 'jotai';
+import { useEmitLog } from '@/common/stores/logger';
+
import { version } from '../../../package.json';
import { getLatestVersion, postSettings } from '../../common/api/ontimeApi';
import { eventSettingsAtom } from '../../common/atoms/LocalEventSettings';
import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn';
-import { LoggingContext } from '../../common/context/LoggingContext';
import useSettings from '../../common/hooks-query/useSettings';
import { ontimePlaceholderSettings } from '../../common/models/OntimeSettings';
@@ -31,7 +32,7 @@ import style from './Modals.module.scss';
export default function AppSettingsModal() {
const { data, status, refetch } = useSettings();
- const { emitError, emitWarning } = useContext(LoggingContext);
+ const { emitError, emitWarning } = useEmitLog();
const [formData, setFormData] = useState(ontimePlaceholderSettings);
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
diff --git a/apps/client/src/features/modals/EventSettingsModal.jsx b/apps/client/src/features/modals/EventSettingsModal.jsx
index b6f15c3af..d449ecc1d 100644
--- a/apps/client/src/features/modals/EventSettingsModal.jsx
+++ b/apps/client/src/features/modals/EventSettingsModal.jsx
@@ -1,8 +1,9 @@
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { FormLabel, Input, ModalBody, Textarea } from '@chakra-ui/react';
+import { useEmitLog } from '@/common/stores/logger';
+
import { postEventData } from '../../common/api/eventDataApi';
-import { LoggingContext } from '../../common/context/LoggingContext';
import useEventData from '../../common/hooks-query/useEventData';
import { eventDataPlaceholder } from '../../common/models/EventData';
@@ -13,7 +14,7 @@ import style from './Modals.module.scss';
export default function SettingsModal() {
const { data, status, refetch } = useEventData();
- const { emitError } = useContext(LoggingContext);
+ const { emitError } = useEmitLog();
const [formData, setFormData] = useState(eventDataPlaceholder);
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
diff --git a/apps/client/src/features/modals/TableOptionsModal.jsx b/apps/client/src/features/modals/TableOptionsModal.jsx
index fd7193a9d..bd8df8281 100644
--- a/apps/client/src/features/modals/TableOptionsModal.jsx
+++ b/apps/client/src/features/modals/TableOptionsModal.jsx
@@ -1,9 +1,10 @@
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { Input, ModalBody } from '@chakra-ui/react';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
+import { useEmitLog } from '@/common/stores/logger';
+
import { postUserFields } from '../../common/api/ontimeApi';
-import { LoggingContext } from '../../common/context/LoggingContext';
import useUserFields from '../../common/hooks-query/useUserFields';
import { userFieldsPlaceholder } from '../../common/models/UserFields';
import { handleLinks, host } from '../../common/utils/linkUtils';
@@ -14,7 +15,7 @@ import style from './Modals.module.scss';
export default function TableOptionsModal() {
const { data, status, refetch } = useUserFields();
- const { emitError } = useContext(LoggingContext);
+ const { emitError } = useEmitLog();
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [userFields, setUserFields] = useState(userFieldsPlaceholder);
diff --git a/apps/client/src/features/modals/ViewsSettingsModal.jsx b/apps/client/src/features/modals/ViewsSettingsModal.jsx
index 5b2ab4f92..bfca2194b 100644
--- a/apps/client/src/features/modals/ViewsSettingsModal.jsx
+++ b/apps/client/src/features/modals/ViewsSettingsModal.jsx
@@ -1,11 +1,12 @@
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { FormControl, FormLabel, ModalBody } from '@chakra-ui/react';
import { IoCheckmarkSharp } from '@react-icons/all-files/io5/IoCheckmarkSharp';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
+import { useEmitLog } from '@/common/stores/logger';
+
import { postView } from '../../common/api/ontimeApi';
import EnableBtn from '../../common/components/buttons/EnableBtn';
-import { LoggingContext } from '../../common/context/LoggingContext';
import useViewSettings from '../../common/hooks-query/useViewSettings';
import { viewsSettingsPlaceholder } from '../../common/models/ViewSettings.type';
import { openLink } from '../../common/utils/linkUtils';
@@ -17,7 +18,7 @@ import style from './Modals.module.scss';
export default function ViewsSettingsModal() {
const { data, status, refetch } = useViewSettings();
- const { emitError } = useContext(LoggingContext);
+ const { emitError } = useEmitLog();
const [formData, setFormData] = useState(viewsSettingsPlaceholder);
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
diff --git a/apps/client/src/features/modals/integration-modal/OscIntegrationSettings.tsx b/apps/client/src/features/modals/integration-modal/OscIntegrationSettings.tsx
index 917e7d02b..7e98b74a4 100644
--- a/apps/client/src/features/modals/integration-modal/OscIntegrationSettings.tsx
+++ b/apps/client/src/features/modals/integration-modal/OscIntegrationSettings.tsx
@@ -1,18 +1,17 @@
-import { useContext } from 'react';
import { useForm } from 'react-hook-form';
import { Button, FormControl, Input, ModalBody, ModalFooter, Switch } from '@chakra-ui/react';
import { postOSC } from '../../../common/api/ontimeApi';
-import { LoggingContext } from '../../../common/context/LoggingContext';
import useOscSettings from '../../../common/hooks-query/useOscSettings';
import { PlaceholderSettings } from '../../../common/models/OscSettings';
+import { useEmitLog } from '../../../common/stores/logger';
import { isIPAddress, isOnlyNumbers } from '../../../common/utils/regex';
import styles from '../Modal.module.scss';
export default function OscIntegrationSettings() {
const { data } = useOscSettings();
- const { emitError } = useContext(LoggingContext);
+ const { emitError } = useEmitLog();
const {
handleSubmit,
register,
diff --git a/apps/client/src/features/modals/integration-modal/OscSettingsModal.jsx b/apps/client/src/features/modals/integration-modal/OscSettingsModal.jsx
index a6d4f64e2..e65702a68 100644
--- a/apps/client/src/features/modals/integration-modal/OscSettingsModal.jsx
+++ b/apps/client/src/features/modals/integration-modal/OscSettingsModal.jsx
@@ -1,10 +1,11 @@
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { FormControl, FormLabel, Input, ModalBody } from '@chakra-ui/react';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
+import { useEmitLog } from '@/common/stores/logger';
+
import { postOSC } from '../../../common/api/ontimeApi';
import EnableBtn from '../../../common/components/buttons/EnableBtn';
-import { LoggingContext } from '../../../common/context/LoggingContext';
import useOscSettings from '../../../common/hooks-query/useOscSettings';
import { oscPlaceholderSettings } from '../../../common/models/OscSettings';
import { inputProps, portInputProps } from '../modalHelper';
@@ -76,7 +77,7 @@ const oscTriggerEndpoints = [
export default function OscSettingsModal() {
const { data, status, refetch } = useOscSettings();
- const { emitError } = useContext(LoggingContext);
+ const { emitError } = useEmitLog();
const [formData, setFormData] = useState(oscPlaceholderSettings);
const [changed, setChanged] = useState(false);
const [submitting, setSubmitting] = useState(false);
@@ -122,8 +123,8 @@ export default function OscSettingsModal() {
} else {
try {
await postOSC(formData);
- } catch (error){
- emitError(`Error setting OSC: ${error}`)
+ } catch (error) {
+ emitError(`Error setting OSC: ${error}`);
} finally {
await refetch();
setChanged(false);
@@ -131,7 +132,7 @@ export default function OscSettingsModal() {
}
setSubmitting(false);
},
- [emitError, formData, refetch]
+ [emitError, formData, refetch],
);
/**
@@ -154,7 +155,7 @@ export default function OscSettingsModal() {
setFormData(temp);
setChanged(true);
},
- [formData]
+ [formData],
);
return (
@@ -283,12 +284,7 @@ export default function OscSettingsModal() {
-