mirror of
https://github.com/cpvalente/ontime.git
synced 2026-07-26 10:38:55 +00:00
refactor: rename external message to secondary message
This commit is contained in:
committed by
Carlos Valente
parent
0aeec12ccd
commit
3cd6cd2f55
@@ -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} />
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')),
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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';
|
||||
|
||||
+4
-4
@@ -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
-1
@@ -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', () => {
|
||||
+1
-1
@@ -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;
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user