mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 14:39:06 +00:00
refactor: simplify l3
This commit is contained in:
committed by
Carlos Valente
parent
b14ac07568
commit
dd81b92584
@@ -249,12 +249,11 @@ export const MINIMAL_TIMER_OPTIONS: ParamField[] = [
|
|||||||
export const getLowerThirdOptions = (customFields: CustomFields): ParamField[] => {
|
export const getLowerThirdOptions = (customFields: CustomFields): ParamField[] => {
|
||||||
const topSourceOptions = makeOptionsFromCustomFields(customFields, {
|
const topSourceOptions = makeOptionsFromCustomFields(customFields, {
|
||||||
title: 'Title',
|
title: 'Title',
|
||||||
lowerMsg: 'Lower Third Message',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const bottomSourceOptions = makeOptionsFromCustomFields(customFields, {
|
const bottomSourceOptions = makeOptionsFromCustomFields(customFields, {
|
||||||
title: 'Title',
|
title: 'Title',
|
||||||
lowerMsg: 'Lower Third Message',
|
none: 'None',
|
||||||
});
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -267,7 +266,7 @@ export const getLowerThirdOptions = (customFields: CustomFields): ParamField[] =
|
|||||||
event: 'Event Load',
|
event: 'Event Load',
|
||||||
manual: 'Manual',
|
manual: 'Manual',
|
||||||
},
|
},
|
||||||
defaultValue: 'event',
|
defaultValue: 'manual',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'top-src',
|
id: 'top-src',
|
||||||
@@ -283,7 +282,7 @@ export const getLowerThirdOptions = (customFields: CustomFields): ParamField[] =
|
|||||||
description: 'Select the data source for the bottom element',
|
description: 'Select the data source for the bottom element',
|
||||||
type: 'option',
|
type: 'option',
|
||||||
values: bottomSourceOptions,
|
values: bottomSourceOptions,
|
||||||
defaultValue: 'lowerMsg',
|
defaultValue: 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'top-colour',
|
id: 'top-colour',
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export const useOperator = () => {
|
|||||||
export const useMessageControl = () => {
|
export const useMessageControl = () => {
|
||||||
const featureSelector = (state: RuntimeStore) => ({
|
const featureSelector = (state: RuntimeStore) => ({
|
||||||
timer: state.message.timer,
|
timer: state.message.timer,
|
||||||
lower: state.message.lower,
|
|
||||||
external: state.message.external,
|
external: state.message.external,
|
||||||
onAir: state.onAir,
|
onAir: state.onAir,
|
||||||
});
|
});
|
||||||
@@ -36,8 +35,6 @@ export const useMessageControl = () => {
|
|||||||
export const setMessage = {
|
export const setMessage = {
|
||||||
timerText: (payload: string) => socketSendJson('message', { timer: { text: payload } }),
|
timerText: (payload: string) => socketSendJson('message', { timer: { text: payload } }),
|
||||||
timerVisible: (payload: boolean) => socketSendJson('message', { timer: { visible: payload } }),
|
timerVisible: (payload: boolean) => socketSendJson('message', { timer: { visible: payload } }),
|
||||||
lowerText: (payload: string) => socketSendJson('message', { lower: { text: payload } }),
|
|
||||||
lowerVisible: (payload: boolean) => socketSendJson('message', { lower: { visible: payload } }),
|
|
||||||
timerBlink: (payload: boolean) => socketSendJson('message', { timer: { blink: payload } }),
|
timerBlink: (payload: boolean) => socketSendJson('message', { timer: { blink: payload } }),
|
||||||
timerBlackout: (payload: boolean) => socketSendJson('message', { timer: { blackout: payload } }),
|
timerBlackout: (payload: boolean) => socketSendJson('message', { timer: { blackout: payload } }),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ export const runtimeStorePlaceholder: RuntimeStore = {
|
|||||||
blink: false,
|
blink: false,
|
||||||
blackout: false,
|
blackout: false,
|
||||||
},
|
},
|
||||||
lower: {
|
|
||||||
text: '',
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
external: {
|
external: {
|
||||||
text: '',
|
text: '',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import "./MessageControl.module.scss";
|
||||||
|
|
||||||
.inputItems {
|
.inputItems {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
@@ -6,10 +8,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
font-size: $inner-section-text-size;
|
@extend .label;
|
||||||
color: $label-gray;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: $action-text-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,19 @@
|
|||||||
gap: $element-spacing;
|
gap: $element-spacing;
|
||||||
margin-top: -0.5rem;
|
margin-top: -0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.singleAction {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $element-spacing;
|
||||||
|
margin-top: $element-inner-spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: $inner-section-text-size;
|
||||||
|
color: $label-gray;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $action-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,21 +17,14 @@ export default function MessageControl() {
|
|||||||
const message = useMessageControl();
|
const message = useMessageControl();
|
||||||
const blink = message.timer.blink;
|
const blink = message.timer.blink;
|
||||||
const blackout = message.timer.blackout;
|
const blackout = message.timer.blackout;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.messageContainer}>
|
<div className={style.messageContainer}>
|
||||||
<InputRow
|
|
||||||
label='Lower third message'
|
|
||||||
placeholder='Shown in lower third'
|
|
||||||
text={message.lower.text || ''}
|
|
||||||
visible={message.lower.visible || false}
|
|
||||||
changeHandler={(newValue) => setMessage.lowerText(newValue)}
|
|
||||||
actionHandler={() => setMessage.lowerVisible(!message.lower.visible)}
|
|
||||||
/>
|
|
||||||
<InputRow
|
<InputRow
|
||||||
label='Timer'
|
label='Timer'
|
||||||
placeholder='Message shown in stage timer'
|
placeholder='Message shown in stage timer'
|
||||||
text={message.timer.text || ''}
|
text={message.timer.text}
|
||||||
visible={message.timer.visible || false}
|
visible={message.timer.visible}
|
||||||
changeHandler={(newValue) => setMessage.timerText(newValue)}
|
changeHandler={(newValue) => setMessage.timerText(newValue)}
|
||||||
actionHandler={() => setMessage.timerVisible(!message.timer.visible)}
|
actionHandler={() => setMessage.timerVisible(!message.timer.visible)}
|
||||||
/>
|
/>
|
||||||
@@ -61,8 +54,8 @@ export default function MessageControl() {
|
|||||||
label='External Message (read only)'
|
label='External Message (read only)'
|
||||||
placeholder={enDash}
|
placeholder={enDash}
|
||||||
readonly
|
readonly
|
||||||
text={message.external.text || ''}
|
text={message.external.text}
|
||||||
visible={message.external.visible || false}
|
visible={message.external.visible}
|
||||||
changeHandler={noop}
|
changeHandler={noop}
|
||||||
actionHandler={noop}
|
actionHandler={noop}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ type WithDataProps = {
|
|||||||
external: Message;
|
external: Message;
|
||||||
general: ProjectData;
|
general: ProjectData;
|
||||||
isMirrored: boolean;
|
isMirrored: boolean;
|
||||||
lower: Message;
|
|
||||||
nextId: string | null;
|
nextId: string | null;
|
||||||
onAir: boolean;
|
onAir: boolean;
|
||||||
pres: TimerMessage;
|
pres: TimerMessage;
|
||||||
@@ -105,7 +104,6 @@ const withData = <P extends WithDataProps>(Component: ComponentType<P>) => {
|
|||||||
external={message.external}
|
external={message.external}
|
||||||
general={project}
|
general={project}
|
||||||
isMirrored={isMirrored}
|
isMirrored={isMirrored}
|
||||||
lower={message.lower}
|
|
||||||
nextId={nextId}
|
nextId={nextId}
|
||||||
onAir={onAir}
|
onAir={onAir}
|
||||||
pres={message.timer}
|
pres={message.timer}
|
||||||
|
|||||||
@@ -41,10 +41,7 @@ export function isStringBoolean(text: string | null) {
|
|||||||
* Considers custom fields
|
* Considers custom fields
|
||||||
*/
|
*/
|
||||||
export function getPropertyValue(event: OntimeEvent | null, property: MaybeString): string | undefined {
|
export function getPropertyValue(event: OntimeEvent | null, property: MaybeString): string | undefined {
|
||||||
if (!event) {
|
if (!event || typeof property !== 'string' || property === 'none') {
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (typeof property !== 'string') {
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,9 @@
|
|||||||
font-family: var(--lowerThird-font-family-override), Lato, Arial, sans-serif;
|
font-family: var(--lowerThird-font-family-override), Lato, Arial, sans-serif;
|
||||||
text-align: var(--lowerThird-text-align-override, left);
|
text-align: var(--lowerThird-text-align-override, left);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
&::after {
|
||||||
|
content: '\200b';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-top {
|
.data-top {
|
||||||
@@ -86,7 +89,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@keyframes in {
|
@keyframes in {
|
||||||
0% {
|
0% {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { CustomFields, Message, OntimeEvent, ViewSettings } from 'ontime-types';
|
import { CustomFields, OntimeEvent, ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/constants';
|
import { overrideStylesURL } from '../../../common/api/constants';
|
||||||
import { getLowerThirdOptions } from '../../../common/components/view-params-editor/constants';
|
import { getLowerThirdOptions } from '../../../common/components/view-params-editor/constants';
|
||||||
@@ -11,14 +11,8 @@ import { getPropertyValue } from '../common/viewUtils';
|
|||||||
|
|
||||||
import './LowerThird.scss';
|
import './LowerThird.scss';
|
||||||
|
|
||||||
enum TriggerType {
|
|
||||||
Event = 'event',
|
|
||||||
Manual = 'manual',
|
|
||||||
}
|
|
||||||
|
|
||||||
type LowerOptions = {
|
type LowerOptions = {
|
||||||
width: number;
|
width: number;
|
||||||
trigger: TriggerType;
|
|
||||||
topSrc: string;
|
topSrc: string;
|
||||||
bottomSrc: string;
|
bottomSrc: string;
|
||||||
topColour: string;
|
topColour: string;
|
||||||
@@ -38,12 +32,10 @@ interface LowerProps {
|
|||||||
customFields: CustomFields;
|
customFields: CustomFields;
|
||||||
eventNow: OntimeEvent | null;
|
eventNow: OntimeEvent | null;
|
||||||
viewSettings: ViewSettings;
|
viewSettings: ViewSettings;
|
||||||
lower: Message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: Readonly<LowerOptions> = {
|
const defaultOptions: Readonly<LowerOptions> = {
|
||||||
width: 45,
|
width: 45,
|
||||||
trigger: TriggerType.Event,
|
|
||||||
topSrc: 'title',
|
topSrc: 'title',
|
||||||
bottomSrc: 'lowerMsg',
|
bottomSrc: 'lowerMsg',
|
||||||
topColour: '000000ff',
|
topColour: '000000ff',
|
||||||
@@ -60,8 +52,14 @@ const defaultOptions: Readonly<LowerOptions> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function LowerThird(props: LowerProps) {
|
export default function LowerThird(props: LowerProps) {
|
||||||
const { customFields, eventNow, lower, viewSettings } = props;
|
const { customFields, eventNow, viewSettings } = props;
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
|
const previousId = useRef<string>();
|
||||||
|
const animationTimeout = useRef<NodeJS.Timeout>();
|
||||||
|
const [playState, setPlayState] = useState<'pre' | 'in' | 'out'>('pre');
|
||||||
|
useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
|
||||||
|
|
||||||
|
useWindowTitle('Lower Third');
|
||||||
|
|
||||||
const options = useMemo(() => {
|
const options = useMemo(() => {
|
||||||
const newOptions = { ...defaultOptions };
|
const newOptions = { ...defaultOptions };
|
||||||
@@ -71,11 +69,6 @@ export default function LowerThird(props: LowerProps) {
|
|||||||
newOptions.width = Number(width);
|
newOptions.width = Number(width);
|
||||||
}
|
}
|
||||||
|
|
||||||
const trigger = Object.values(TriggerType).find((s) => s === searchParams.get('trigger'));
|
|
||||||
if (trigger) {
|
|
||||||
newOptions.trigger = trigger;
|
|
||||||
}
|
|
||||||
|
|
||||||
const topSrc = searchParams.get('top-src');
|
const topSrc = searchParams.get('top-src');
|
||||||
if (topSrc) {
|
if (topSrc) {
|
||||||
newOptions.topSrc = topSrc;
|
newOptions.topSrc = topSrc;
|
||||||
@@ -139,50 +132,51 @@ export default function LowerThird(props: LowerProps) {
|
|||||||
return newOptions;
|
return newOptions;
|
||||||
}, [searchParams]);
|
}, [searchParams]);
|
||||||
|
|
||||||
const [playState, setPlayState] = useState<'pre' | 'in' | 'out'>('pre');
|
// on unmount, cancel any ongoing animations
|
||||||
useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
|
|
||||||
|
|
||||||
useWindowTitle('Lower Third');
|
|
||||||
|
|
||||||
const trigger = useMemo(() => {
|
|
||||||
if (options.trigger === TriggerType.Event) {
|
|
||||||
return eventNow?.id;
|
|
||||||
} else if (options.trigger === TriggerType.Manual) {
|
|
||||||
return lower.visible;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}, [eventNow?.id, lower.visible, options.trigger]);
|
|
||||||
|
|
||||||
// coordinate load-unload of lower third
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (options.trigger === TriggerType.Event && trigger) {
|
return () => {
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
clearTimeout(animationTimeout.current);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// check if data has changed and schedule animations
|
||||||
|
useEffect(() => {
|
||||||
|
const hasChanged = eventNow?.id !== previousId.current;
|
||||||
|
if (!hasChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousId.current = eventNow?.id;
|
||||||
|
const animateOutInMs = options.delay * 1000 + options.transition * 1000;
|
||||||
|
|
||||||
|
const reschedule = (newState: 'pre' | 'in' | 'out') => {
|
||||||
|
clearTimeout(animationTimeout.current);
|
||||||
|
animationTimeout.current = setTimeout(() => setPlayState(newState), animateOutInMs);
|
||||||
|
};
|
||||||
|
if (eventNow?.id == null) {
|
||||||
|
setPlayState('out');
|
||||||
|
reschedule('pre');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventNow.id && !previousId.current) {
|
||||||
setPlayState('in');
|
setPlayState('in');
|
||||||
const animateOutInMs = options.delay * 1000 + options.transition * 1000;
|
reschedule('out');
|
||||||
const timeout = setTimeout(() => {
|
return;
|
||||||
setPlayState('out');
|
|
||||||
}, animateOutInMs);
|
|
||||||
return () => clearTimeout(timeout);
|
|
||||||
} else if (options.trigger === TriggerType.Manual) {
|
|
||||||
setPlayState(trigger ? 'in' : 'out');
|
|
||||||
} else {
|
|
||||||
setPlayState('pre');
|
|
||||||
}
|
}
|
||||||
return () => null;
|
|
||||||
}, [options.delay, options.transition, options.trigger, trigger]);
|
|
||||||
|
|
||||||
const topText = useMemo(() => {
|
if (playState === 'in') {
|
||||||
if (options.topSrc === 'lowerMsg') {
|
// event has changed, we just reschedule the timeout
|
||||||
return lower.text;
|
reschedule('out');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return getPropertyValue(eventNow, options.topSrc) ?? '';
|
setPlayState('in');
|
||||||
}, [eventNow, lower.text, options]);
|
reschedule('out');
|
||||||
|
}, [eventNow?.id, options.delay, options.transition, playState, previousId]);
|
||||||
|
|
||||||
const bottomText = useMemo(() => {
|
const topText = getPropertyValue(eventNow, options.topSrc) ?? '';
|
||||||
if (options.bottomSrc === 'lowerMsg') {
|
const bottomText = getPropertyValue(eventNow, options.bottomSrc) ?? '';
|
||||||
return lower.text;
|
|
||||||
}
|
|
||||||
return getPropertyValue(eventNow, options.bottomSrc) ?? '';
|
|
||||||
}, [eventNow, lower.text, options]);
|
|
||||||
|
|
||||||
const transition = `${options.transition}s`;
|
const transition = `${options.transition}s`;
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ const actionHandlers: Record<string, ActionHandler> = {
|
|||||||
|
|
||||||
const patch: DeepPartial<MessageState> = {
|
const patch: DeepPartial<MessageState> = {
|
||||||
timer: 'timer' in payload ? validateTimerMessage(payload.timer) : undefined,
|
timer: 'timer' in payload ? validateTimerMessage(payload.timer) : undefined,
|
||||||
lower: 'lower' in payload ? validateMessage(payload.lower) : undefined,
|
|
||||||
external: 'external' in payload ? validateMessage(payload.external) : undefined,
|
external: 'external' in payload ? validateMessage(payload.external) : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ let instance: MessageService | null = null;
|
|||||||
|
|
||||||
class MessageService {
|
class MessageService {
|
||||||
timer: TimerMessage;
|
timer: TimerMessage;
|
||||||
lower: Message;
|
|
||||||
external: Message;
|
external: Message;
|
||||||
|
|
||||||
private throttledSet: PublishFn;
|
private throttledSet: PublishFn;
|
||||||
@@ -37,11 +36,6 @@ class MessageService {
|
|||||||
blackout: false,
|
blackout: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.lower = {
|
|
||||||
text: '',
|
|
||||||
visible: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.external = {
|
this.external = {
|
||||||
text: '',
|
text: '',
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -56,14 +50,12 @@ class MessageService {
|
|||||||
getState(): MessageState {
|
getState(): MessageState {
|
||||||
return {
|
return {
|
||||||
timer: this.timer,
|
timer: this.timer,
|
||||||
lower: this.lower,
|
|
||||||
external: this.external,
|
external: this.external,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
patch(message: DeepPartial<MessageState>) {
|
patch(message: DeepPartial<MessageState>) {
|
||||||
if (message.timer) this.timer = { ...this.timer, ...message.timer };
|
if (message.timer) this.timer = { ...this.timer, ...message.timer };
|
||||||
if (message.lower) this.lower = { ...this.lower, ...message.lower };
|
|
||||||
if (message.external) this.external = { ...this.external, ...message.external };
|
if (message.external) this.external = { ...this.external, ...message.external };
|
||||||
|
|
||||||
const newState = this.getState();
|
const newState = this.getState();
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ describe('MessageService', () => {
|
|||||||
it('should patch the message state', () => {
|
it('should patch the message state', () => {
|
||||||
const message = {
|
const message = {
|
||||||
timer: { text: 'new text', visible: true },
|
timer: { text: 'new text', visible: true },
|
||||||
lower: { text: 'lower text' },
|
|
||||||
external: { visible: true },
|
external: { visible: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,10 +21,6 @@ describe('MessageService', () => {
|
|||||||
|
|
||||||
expect(newState).toEqual({
|
expect(newState).toEqual({
|
||||||
timer: { text: 'new text', visible: true, blackout: false, blink: false },
|
timer: { text: 'new text', visible: true, blackout: false, blink: false },
|
||||||
lower: {
|
|
||||||
text: 'lower text',
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
external: {
|
external: {
|
||||||
text: '',
|
text: '',
|
||||||
visible: true,
|
visible: true,
|
||||||
@@ -42,10 +37,6 @@ describe('MessageService', () => {
|
|||||||
|
|
||||||
expect(newState).toEqual({
|
expect(newState).toEqual({
|
||||||
timer: { text: 'initial text', visible: true, blackout: false, blink: false },
|
timer: { text: 'initial text', visible: true, blackout: false, blink: false },
|
||||||
lower: {
|
|
||||||
text: '',
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
external: {
|
external: {
|
||||||
text: '',
|
text: '',
|
||||||
visible: false,
|
visible: false,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
test('message control sends messages to screens', async ({ context }) => {
|
test('message control sends messages to screens', async ({ context }) => {
|
||||||
const editorPage = await context.newPage();
|
const editorPage = await context.newPage();
|
||||||
@@ -6,15 +6,6 @@ test('message control sends messages to screens', async ({ context }) => {
|
|||||||
|
|
||||||
await editorPage.goto('http://localhost:4001/messagecontrol');
|
await editorPage.goto('http://localhost:4001/messagecontrol');
|
||||||
|
|
||||||
// lower third message
|
|
||||||
await editorPage.getByPlaceholder('Shown in lower third').click();
|
|
||||||
await editorPage.getByPlaceholder('Shown in lower third').fill('testing lower');
|
|
||||||
await editorPage.getByRole('button', { name: /toggle lower third message/i }).click();
|
|
||||||
|
|
||||||
await featurePage.goto('http://localhost:4001/lower?trigger=manual&bottom-src=lowerMsg');
|
|
||||||
await featurePage.waitForLoadState('load', { timeout: 5000 });
|
|
||||||
await featurePage.getByText('testing lower').click({ timeout: 5000 });
|
|
||||||
|
|
||||||
// stage timer message
|
// stage timer message
|
||||||
await editorPage.getByPlaceholder('Timer').click();
|
await editorPage.getByPlaceholder('Timer').click();
|
||||||
await editorPage.getByPlaceholder('Timer').fill('testing stage');
|
await editorPage.getByPlaceholder('Timer').fill('testing stage');
|
||||||
@@ -22,5 +13,5 @@ test('message control sends messages to screens', async ({ context }) => {
|
|||||||
|
|
||||||
await featurePage.goto('http://localhost:4001/timer');
|
await featurePage.goto('http://localhost:4001/timer');
|
||||||
await featurePage.waitForLoadState('load', { timeout: 5000 });
|
await featurePage.waitForLoadState('load', { timeout: 5000 });
|
||||||
await featurePage.getByText('testing stage').click();
|
await expect(featurePage.getByText('testing stage')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,5 @@ export type TimerMessage = Message & {
|
|||||||
|
|
||||||
export type MessageState = {
|
export type MessageState = {
|
||||||
timer: TimerMessage;
|
timer: TimerMessage;
|
||||||
lower: Message;
|
|
||||||
external: Message;
|
external: Message;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user