refactor: rename external message to secondary message

This commit is contained in:
Carlos Valente
2025-06-21 20:17:22 +02:00
committed by Carlos Valente
parent 0aeec12ccd
commit 3cd6cd2f55
18 changed files with 49 additions and 48 deletions
+4 -4
View File
@@ -32,8 +32,8 @@ export const useTimerMessageInput = createSelector((state: RuntimeStore) => ({
}));
export const useExternalMessageInput = createSelector((state: RuntimeStore) => ({
text: state.message.external,
visible: state.message.timer.secondarySource === 'external',
text: state.message.secondary,
visible: state.message.timer.secondarySource === 'secondary',
}));
export const useMessagePreview = createSelector((state: RuntimeStore) => ({
@@ -41,7 +41,7 @@ export const useMessagePreview = createSelector((state: RuntimeStore) => ({
blackout: state.message.timer.blackout,
phase: state.timer.phase,
showAuxTimer: state.message.timer.secondarySource === 'aux',
showExternalMessage: state.message.timer.secondarySource === 'external' && Boolean(state.message.external),
showSecondaryMessage: state.message.timer.secondarySource === 'secondary' && Boolean(state.message.secondary),
showTimerMessage: state.message.timer.visible && Boolean(state.message.timer.text),
timerType: state.eventNow?.timerType ?? null,
countToEnd: state.eventNow?.countToEnd ?? false,
@@ -50,7 +50,7 @@ export const useMessagePreview = createSelector((state: RuntimeStore) => ({
export const setMessage = {
timerText: (payload: string) => sendSocket('message', { timer: { text: payload } }),
timerVisible: (payload: boolean) => sendSocket('message', { timer: { visible: payload } }),
externalText: (payload: string) => sendSocket('message', { external: payload }),
secondaryMessage: (payload: string) => sendSocket('message', { secondary: payload }),
timerBlink: (payload: boolean) => sendSocket('message', { timer: { blink: payload } }),
timerBlackout: (payload: boolean) => sendSocket('message', { timer: { blackout: payload } }),
timerSecondary: (payload: TimerMessage['secondarySource']) =>
@@ -1,7 +1,7 @@
import { IoEye, IoEyeOffOutline } from 'react-icons/io5';
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
import { setMessage, useExternalMessageInput, useTimerMessageInput } from '../../../common/hooks/useSocket';
import { setMessage, useExternalMessageInput as useSecondaryMessageInput, useTimerMessageInput } from '../../../common/hooks/useSocket';
import { tooltipDelayMid } from '../../../ontimeConfig';
import InputRow from './InputRow';
@@ -12,7 +12,7 @@ export default function MessageControl() {
<>
<TimerControlsPreview />
<TimerMessageInput />
<ExternalInput />
<SecondaryInput />
</>
);
}
@@ -41,29 +41,29 @@ function TimerMessageInput() {
);
}
function ExternalInput() {
const { text, visible } = useExternalMessageInput();
function SecondaryInput() {
const { text, visible } = useSecondaryMessageInput();
const toggleExternal = () => {
const toggleSecondary = () => {
if (visible) {
setMessage.timerSecondary(null);
} else {
setMessage.timerSecondary('external');
setMessage.timerSecondary('secondary');
}
};
return (
<InputRow
label='External Message'
label='Secondary Message'
placeholder='Message shown as secondary text in stage timer'
text={text}
visible={visible}
changeHandler={(newValue) => setMessage.externalText(newValue)}
changeHandler={(newValue) => setMessage.secondaryMessage(newValue)}
>
<TooltipActionBtn
clickHandler={toggleExternal}
clickHandler={toggleSecondary}
tooltip={visible ? 'Make invisible' : 'Make visible'}
aria-label='Toggle external message visibility'
aria-label='Toggle secondary message visibility'
openDelay={tooltipDelayMid}
icon={visible ? <IoEye size='18px' /> : <IoEyeOffOutline size='18px' />}
variant={visible ? 'ontime-filled' : 'ontime-subtle'}
@@ -12,7 +12,7 @@ import { Corner } from '../../editors/editor-utils/EditorUtils';
import style from './MessageControl.module.scss';
export default function TimerPreview() {
const { blink, blackout, countToEnd, phase, showAuxTimer, showExternalMessage, showTimerMessage, timerType } =
const { blink, blackout, countToEnd, phase, showAuxTimer, showSecondaryMessage, showTimerMessage, timerType } =
useMessagePreview();
const { data } = useViewSettings();
@@ -34,7 +34,7 @@ export default function TimerPreview() {
// we need to check aux first since it takes priority
if (showAuxTimer) return 'Aux Timer';
if (showExternalMessage) return 'External message';
if (showSecondaryMessage) return 'Secondary message';
return null;
})();
@@ -1,4 +1,5 @@
import { Button } from '@chakra-ui/react';
import { SecondarySource } from 'ontime-types';
import { setMessage, useTimerViewControl } from '../../../common/hooks/useSocket';
@@ -9,7 +10,7 @@ import style from './MessageControl.module.scss';
export default function TimerControlsPreview() {
const { blackout, blink, secondarySource } = useTimerViewControl();
const toggleSecondary = (newValue: 'aux' | 'external' | null) => {
const toggleSecondary = (newValue: SecondarySource) => {
if (secondarySource === newValue) {
setMessage.timerSecondary(null);
} else {
@@ -31,10 +32,10 @@ export default function TimerControlsPreview() {
</Button>
<Button
size='sm'
variant={secondarySource === 'external' ? 'ontime-filled' : 'ontime-subtle'}
onClick={() => toggleSecondary('external')}
variant={secondarySource === 'secondary' ? 'ontime-filled' : 'ontime-subtle'}
onClick={() => toggleSecondary('secondary')}
>
Show external
Show secondary
</Button>
<hr className={style.divider} />
+2 -2
View File
@@ -59,7 +59,7 @@ export default function Timer(props: TimerProps) {
hideCards,
hideProgress,
hideMessage,
hideExternal,
hideSecondary,
hideTimerSeconds,
removeLeadingZeros,
mainSource,
@@ -110,7 +110,7 @@ export default function Timer(props: TimerProps) {
localisedMinutes,
hideTimerSeconds,
removeLeadingZeros,
hideExternal,
hideSecondary,
);
// gather presentation styles
+4 -4
View File
@@ -99,8 +99,8 @@ export const getTimerOptions = (timeFormat: string, customFields: CustomFields):
defaultValue: false,
},
{
id: 'hideExternal',
title: 'Hide Auxiliary timer / External message',
id: 'hideSecondary',
title: 'Hide Auxiliary timer / Secondary message',
description: 'Prevents the screen from displaying the secondary timer field',
type: 'boolean',
defaultValue: false,
@@ -115,7 +115,7 @@ type TimerOptions = {
hideCards: boolean;
hideProgress: boolean;
hideMessage: boolean;
hideExternal: boolean;
hideSecondary: boolean;
hideTimerSeconds: boolean;
removeLeadingZeros: boolean;
mainSource: keyof OntimeEvent | null;
@@ -135,7 +135,7 @@ function getOptionsFromParams(searchParams: URLSearchParams): TimerOptions {
hideCards: isStringBoolean(searchParams.get('hideCards')),
hideProgress: isStringBoolean(searchParams.get('hideProgress')),
hideMessage: isStringBoolean(searchParams.get('hideMessage')),
hideExternal: isStringBoolean(searchParams.get('hideExternal')),
hideSecondary: isStringBoolean(searchParams.get('hideSecondary')),
hideTimerSeconds: isStringBoolean(searchParams.get('hideTimerSeconds')),
removeLeadingZeros: !isStringBoolean(searchParams.get('showLeadingZeros')),
+4 -4
View File
@@ -111,9 +111,9 @@ export function getSecondaryDisplay(
localisedMinutes: string,
removeSeconds: boolean,
removeLeadingZero: boolean,
hideExternal: boolean,
hideSecondary: boolean,
): string | undefined {
if (hideExternal) {
if (hideSecondary) {
return;
}
if (message.timer.secondarySource === 'aux') {
@@ -122,8 +122,8 @@ export function getSecondaryDisplay(
removeLeadingZero,
});
}
if (message.timer.secondarySource === 'external' && message.external) {
return message.external;
if (message.timer.secondarySource === 'secondary' && message.secondary) {
return message.secondary;
}
return;
}
@@ -158,10 +158,10 @@ describe('parseOutput', () => {
parseOutput({
type: 'ontime',
action: 'message-secondary',
secondarySource: 'external',
secondarySource: 'secondary',
}),
).toMatchObject({
secondarySource: 'external',
secondarySource: 'secondary',
});
});
});
@@ -254,6 +254,6 @@ function indeterminateBooleanString(value: string): boolean | undefined {
*/
function chooseSecondarySource(value: string): SecondarySource {
if (value === 'aux') return 'aux';
if (value === 'external') return 'external';
if (value === 'secondary') return 'secondary';
return null;
}
@@ -2,7 +2,7 @@ import { LogOrigin, OntimeAction } from 'ontime-types';
import { logger } from '../../../classes/Logger.js';
import { auxTimerService } from '../../../services/aux-timer-service/AuxTimerService.js';
import * as messageService from '../../../services/message-service/MessageService.js';
import * as messageService from '../../../services/message-service/message.service.js';
export function toOntimeAction(action: OntimeAction) {
const actionType = action.action;
@@ -13,8 +13,8 @@ import { DeepPartial } from 'ts-essentials';
import { ONTIME_VERSION } from '../ONTIME_VERSION.js';
import { auxTimerService } from '../services/aux-timer-service/AuxTimerService.js';
import * as messageService from '../services/message-service/MessageService.js';
import { validateMessage, validateTimerMessage } from '../services/message-service/messageUtils.js';
import * as messageService from '../services/message-service/message.service.js';
import { validateMessage, validateTimerMessage } from '../services/message-service/message.utils.js';
import { runtimeService } from '../services/runtime-service/RuntimeService.js';
import { eventStore } from '../stores/EventStore.js';
import * as assert from '../utils/assert.js';
@@ -101,7 +101,7 @@ const actionHandlers: Record<ApiAction, ActionHandler> = {
const patch: DeepPartial<MessageState> = {
timer: 'timer' in payload ? validateTimerMessage(payload.timer) : undefined,
external: 'external' in payload ? validateMessage(payload.external) : undefined,
secondary: 'secondary' in payload ? validateMessage(payload.secondary) : undefined,
};
const newMessage = messageService.patch(patch);
+1 -1
View File
@@ -33,7 +33,7 @@ import { populateStyles } from './setup/loadStyles.js';
import { eventStore } from './stores/EventStore.js';
import { runtimeService } from './services/runtime-service/RuntimeService.js';
import { restoreService } from './services/RestoreService.js';
import * as messageService from './services/message-service/MessageService.js';
import * as messageService from './services/message-service/message.service.js';
import { populateDemo } from './setup/loadDemo.js';
import { getState } from './stores/runtimeState.js';
import { initRundown } from './api-data/rundown/rundown.service.js';
@@ -1,6 +1,6 @@
import { RuntimeStore } from 'ontime-types';
import * as messageService from '../MessageService.js';
import * as messageService from '../message.service.js';
describe('MessageService', () => {
let store: Partial<RuntimeStore>;
@@ -17,12 +17,12 @@ describe('MessageService', () => {
it('should patch the message state', () => {
const newState = messageService.patch({
timer: { text: 'new text', visible: true },
external: 'external',
secondary: 'secondary',
});
expect(newState).toMatchObject({
timer: { text: 'new text', visible: true, blackout: false, blink: false, secondarySource: null },
external: 'external',
secondary: 'secondary',
});
});
@@ -33,7 +33,7 @@ describe('MessageService', () => {
expect(newState).toMatchObject({
timer: { text: 'initial text', visible: true, blackout: false, blink: false, secondarySource: null },
external: '',
secondary: '',
});
});
});
@@ -1,4 +1,4 @@
import { validateMessage, validateTimerMessage } from '../messageUtils.js';
import { validateMessage, validateTimerMessage } from '../message.utils.js';
describe('validateMessage()', () => {
it('returns a valid Message object', () => {
@@ -43,7 +43,7 @@ export function patch(patch: DeepPartial<MessageState>): MessageState {
const newState = { ...getState() };
if ('timer' in patch) newState.timer = { ...newState.timer, ...patch.timer };
if ('external' in patch && patch.external !== undefined) newState.external = patch.external;
if ('secondary' in patch && patch.secondary !== undefined) newState.secondary = patch.secondary;
throttledSet('message', newState);
return newState;
@@ -33,7 +33,7 @@ export function validateTimerMessage(message: unknown): Partial<TimerMessage> {
* Asserts that the secondary value is one of the permitted values
*/
function assertSecondary(source: unknown): source is TimerMessage['secondarySource'] {
return source === 'aux' || source === 'external' || source === null;
return source === 'aux' || source === 'secondary' || source === null;
}
/**
@@ -1,4 +1,4 @@
export type SecondarySource = 'aux' | 'external' | null;
export type SecondarySource = 'aux' | 'secondary' | null;
export type TimerMessage = {
text: string;
@@ -10,5 +10,5 @@ export type TimerMessage = {
export type MessageState = {
timer: TimerMessage;
external: string;
secondary: string;
};
@@ -27,7 +27,7 @@ export const runtimeStorePlaceholder: Readonly<RuntimeStore> = {
blackout: false,
secondarySource: null,
},
external: '',
secondary: '',
},
runtime: {
selectedEventIndex: null, // changes if rundown changes or we load a new event