mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 23:19:09 +00:00
@@ -27,6 +27,7 @@ $button-size: 48px;
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -46,7 +47,7 @@ $button-size: 48px;
|
|||||||
|
|
||||||
.navButton {
|
.navButton {
|
||||||
@extend .button;
|
@extend .button;
|
||||||
z-index: 2;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuContainer {
|
.menuContainer {
|
||||||
|
|||||||
@@ -18,5 +18,6 @@ $progress-bar-br: 6px;
|
|||||||
height: $progress-bar-size;
|
height: $progress-bar-size;
|
||||||
background-color: var(--timer-progress-override, $accent-color);
|
background-color: var(--timer-progress-override, $accent-color);
|
||||||
transition: 1s linear;
|
transition: 1s linear;
|
||||||
|
border-radius: $progress-bar-br 0 0 $progress-bar-br;
|
||||||
transition-property: width;
|
transition-property: width;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ interface EditFormInputProps {
|
|||||||
paramField: ParamField;
|
paramField: ParamField;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EditFormInput({ paramField }: EditFormInputProps) {
|
export default function ParamInput({ paramField }: EditFormInputProps) {
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const { id, type } = paramField;
|
const { id, type } = paramField;
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export default function EditFormInput({ paramField }: EditFormInputProps) {
|
|||||||
if (type === 'number') {
|
if (type === 'number') {
|
||||||
const defaultNumberValue = searchParams.get(id) ?? '';
|
const defaultNumberValue = searchParams.get(id) ?? '';
|
||||||
|
|
||||||
return <Input type='number' variant='ontime-filled' name={id} defaultValue={defaultNumberValue} />;
|
return <Input type='number' step='any' variant='ontime-filled' name={id} defaultValue={defaultNumberValue} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultStringValue = searchParams.get(id) ?? '';
|
const defaultStringValue = searchParams.get(id) ?? '';
|
||||||
+6
@@ -13,8 +13,14 @@
|
|||||||
.drawerFooter {
|
.drawerFooter {
|
||||||
@extend .drawerContent;
|
@extend .drawerContent;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: start;
|
||||||
gap: $element-spacing;
|
gap: $element-spacing;
|
||||||
|
|
||||||
|
button[type='reset'] {
|
||||||
|
padding: 0 2em;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
button[type='submit'] {
|
button[type='submit'] {
|
||||||
padding: 0 2em;
|
padding: 0 2em;
|
||||||
}
|
}
|
||||||
+12
-6
@@ -12,16 +12,16 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
import EditFormInput from './EditFormInput';
|
import ParamInput from './ParamInput';
|
||||||
import { ParamField } from './types';
|
import { ParamField } from './types';
|
||||||
|
|
||||||
import style from './EditFormDrawer.module.scss';
|
import style from './ViewParamsEditor.module.scss';
|
||||||
|
|
||||||
interface EditFormDrawerProps {
|
interface EditFormDrawerProps {
|
||||||
paramFields: ParamField[];
|
paramFields: ParamField[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EditFormDrawer({ paramFields }: EditFormDrawerProps) {
|
export default function ViewParamsEditor({ paramFields }: EditFormDrawerProps) {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
const { isOpen, onClose, onOpen } = useDisclosure();
|
||||||
|
|
||||||
@@ -40,6 +40,11 @@ export default function EditFormDrawer({ paramFields }: EditFormDrawerProps) {
|
|||||||
setSearchParams(searchParams);
|
setSearchParams(searchParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearParams = () => {
|
||||||
|
setSearchParams();
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
const onParamsFormSubmit = (formEvent: FormEvent<HTMLFormElement>) => {
|
const onParamsFormSubmit = (formEvent: FormEvent<HTMLFormElement>) => {
|
||||||
formEvent.preventDefault();
|
formEvent.preventDefault();
|
||||||
|
|
||||||
@@ -53,8 +58,6 @@ export default function EditFormDrawer({ paramFields }: EditFormDrawerProps) {
|
|||||||
|
|
||||||
return newSearchParams;
|
return newSearchParams;
|
||||||
}, new URLSearchParams());
|
}, new URLSearchParams());
|
||||||
|
|
||||||
onEditDrawerClose();
|
|
||||||
setSearchParams(newSearchParams);
|
setSearchParams(newSearchParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,7 +77,7 @@ export default function EditFormDrawer({ paramFields }: EditFormDrawerProps) {
|
|||||||
<label className={style.label}>
|
<label className={style.label}>
|
||||||
<span className={style.title}>{field.title}</span>
|
<span className={style.title}>{field.title}</span>
|
||||||
<span className={style.description}>{field.description}</span>
|
<span className={style.description}>{field.description}</span>
|
||||||
<EditFormInput key={field.title} paramField={field} />
|
<ParamInput key={field.title} paramField={field} />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -82,6 +85,9 @@ export default function EditFormDrawer({ paramFields }: EditFormDrawerProps) {
|
|||||||
</DrawerBody>
|
</DrawerBody>
|
||||||
|
|
||||||
<DrawerFooter className={style.drawerFooter}>
|
<DrawerFooter className={style.drawerFooter}>
|
||||||
|
<Button variant='ontime-ghosted' onClick={clearParams} type='reset'>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
<Button variant='ontime-subtle' onClick={onEditDrawerClose}>
|
<Button variant='ontime-subtle' onClick={onEditDrawerClose}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
+16
-32
@@ -9,9 +9,10 @@ export const TIME_FORMAT_OPTION: ParamField = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CLOCK_OPTIONS: ParamField[] = [
|
export const CLOCK_OPTIONS: ParamField[] = [
|
||||||
|
TIME_FORMAT_OPTION,
|
||||||
{
|
{
|
||||||
id: 'key',
|
id: 'key',
|
||||||
title: 'Key',
|
title: 'Key Colour',
|
||||||
description: 'Background colour in hexadecimal',
|
description: 'Background colour in hexadecimal',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
@@ -65,30 +66,14 @@ export const CLOCK_OPTIONS: ParamField[] = [
|
|||||||
description: 'Offsets the timer vertical position by a given amount in pixels',
|
description: 'Offsets the timer vertical position by a given amount in pixels',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'hidenav',
|
|
||||||
title: 'Hide Nav',
|
|
||||||
description: 'Whether to hide the nav logo in the right corner',
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
TIME_FORMAT_OPTION,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const TIMER_OPTIONS: ParamField[] = [
|
export const TIMER_OPTIONS: ParamField[] = [TIME_FORMAT_OPTION];
|
||||||
{
|
|
||||||
id: 'progress',
|
|
||||||
title: 'Progress Bar',
|
|
||||||
description: 'Whether bar counts up or down',
|
|
||||||
type: 'option',
|
|
||||||
values: ['up', 'down'],
|
|
||||||
},
|
|
||||||
TIME_FORMAT_OPTION,
|
|
||||||
];
|
|
||||||
|
|
||||||
export const MINIMAL_TIMER_OPTIONS: ParamField[] = [
|
export const MINIMAL_TIMER_OPTIONS: ParamField[] = [
|
||||||
{
|
{
|
||||||
id: 'key',
|
id: 'key',
|
||||||
title: 'Key',
|
title: 'Key Colour',
|
||||||
description: 'Background colour in hexadecimal',
|
description: 'Background colour in hexadecimal',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
@@ -142,12 +127,6 @@ export const MINIMAL_TIMER_OPTIONS: ParamField[] = [
|
|||||||
description: 'Offsets the timer vertical position by a given amount in pixels',
|
description: 'Offsets the timer vertical position by a given amount in pixels',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'hidenav',
|
|
||||||
title: 'Hide Nav',
|
|
||||||
description: 'Whether to hide the nav logo in the right corner',
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'hideovertime',
|
id: 'hideovertime',
|
||||||
title: 'Hide Overtime',
|
title: 'Hide Overtime',
|
||||||
@@ -160,13 +139,19 @@ export const MINIMAL_TIMER_OPTIONS: ParamField[] = [
|
|||||||
description: 'Whether to hide the overlay from showing timer screen messages',
|
description: 'Whether to hide the overlay from showing timer screen messages',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'hideendmessage',
|
||||||
|
title: 'Hide End Message',
|
||||||
|
description: 'Whether to hide end message and continue showing the clock if timer is in overtime',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const LOWER_THIRDS_OPTIONS: ParamField[] = [
|
export const LOWER_THIRDS_OPTIONS: ParamField[] = [
|
||||||
{
|
{
|
||||||
id: 'preset',
|
id: 'preset',
|
||||||
title: 'Preset',
|
title: 'Preset',
|
||||||
description: 'Selects a style preset',
|
description: 'Selects a style preset (0-1)',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -183,19 +168,19 @@ export const LOWER_THIRDS_OPTIONS: ParamField[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'text',
|
id: 'text',
|
||||||
title: 'Text',
|
title: 'Text Colour',
|
||||||
description: 'Text colour in hexadecimal',
|
description: 'Text colour in hexadecimal',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'bg',
|
id: 'bg',
|
||||||
title: 'BG',
|
title: 'Text Background',
|
||||||
description: 'Text background colour in hexadecimal',
|
description: 'Text background colour in hexadecimal',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'key',
|
id: 'key',
|
||||||
title: 'Key',
|
title: 'Key Colour',
|
||||||
description: 'Screen background colour in hexadecimal',
|
description: 'Screen background colour in hexadecimal',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
@@ -205,15 +190,14 @@ export const LOWER_THIRDS_OPTIONS: ParamField[] = [
|
|||||||
description: 'Time (in seconds) the lower third displays before fading out',
|
description: 'Time (in seconds) the lower third displays before fading out',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
TIME_FORMAT_OPTION,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const STUDIO_CLOCK_OPTIONS: ParamField[] = [
|
export const STUDIO_CLOCK_OPTIONS: ParamField[] = [
|
||||||
|
TIME_FORMAT_OPTION,
|
||||||
{
|
{
|
||||||
id: 'seconds',
|
id: 'seconds',
|
||||||
title: 'Seconds',
|
title: 'Show Seconds',
|
||||||
description: 'Shows seconds in clock',
|
description: 'Shows seconds in clock',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
TIME_FORMAT_OPTION,
|
|
||||||
];
|
];
|
||||||
@@ -5,14 +5,14 @@ import { EventData, Message, OntimeEvent, ViewSettings } from 'ontime-types';
|
|||||||
import { formatDisplay } from 'ontime-utils';
|
import { formatDisplay } from 'ontime-utils';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { TIME_FORMAT_OPTION } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
import ProgressBar from '../../../common/components/progress-bar/ProgressBar';
|
import ProgressBar from '../../../common/components/progress-bar/ProgressBar';
|
||||||
import Schedule from '../../../common/components/schedule/Schedule';
|
import Schedule from '../../../common/components/schedule/Schedule';
|
||||||
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
|
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
|
||||||
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
|
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
|
||||||
import TitleCard from '../../../common/components/title-card/TitleCard';
|
import TitleCard from '../../../common/components/title-card/TitleCard';
|
||||||
|
import { TIME_FORMAT_OPTION } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
||||||
import { getEventsWithDelay } from '../../../common/utils/eventsManager';
|
import { getEventsWithDelay } from '../../../common/utils/eventsManager';
|
||||||
@@ -79,7 +79,7 @@ export default function Backstage(props: BackstageProps) {
|
|||||||
return (
|
return (
|
||||||
<div className={`backstage ${isMirrored ? 'mirror' : ''}`} data-testid='backstage-view'>
|
<div className={`backstage ${isMirrored ? 'mirror' : ''}`} data-testid='backstage-view'>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={[TIME_FORMAT_OPTION]} />
|
<ViewParamsEditor paramFields={[TIME_FORMAT_OPTION]} />
|
||||||
<div className='event-header'>
|
<div className='event-header'>
|
||||||
{general.title}
|
{general.title}
|
||||||
<div className='clock-container'>
|
<div className='clock-container'>
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { useSearchParams } from 'react-router-dom';
|
|||||||
import { ViewSettings } from 'ontime-types';
|
import { ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { CLOCK_OPTIONS } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
|
import { CLOCK_OPTIONS } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
||||||
import { OverridableOptions } from '../../../common/models/View.types';
|
import { OverridableOptions } from '../../../common/models/View.types';
|
||||||
@@ -129,12 +129,12 @@ export default function Clock(props: ClockProps) {
|
|||||||
style={{
|
style={{
|
||||||
backgroundColor: userOptions.keyColour,
|
backgroundColor: userOptions.keyColour,
|
||||||
justifyContent: userOptions.justifyContent,
|
justifyContent: userOptions.justifyContent,
|
||||||
alignItems: userOptions.alignItems,
|
alignContent: userOptions.alignItems,
|
||||||
}}
|
}}
|
||||||
data-testid='clock-view'
|
data-testid='clock-view'
|
||||||
>
|
>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={CLOCK_OPTIONS} />
|
<ViewParamsEditor paramFields={CLOCK_OPTIONS} />
|
||||||
<div
|
<div
|
||||||
className='clock'
|
className='clock'
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { OntimeEvent, OntimeRundownEntry, Playback, SupportedEvent, ViewSettings
|
|||||||
import { formatDisplay } from 'ontime-utils';
|
import { formatDisplay } from 'ontime-utils';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { TIME_FORMAT_OPTION } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
|
import { TIME_FORMAT_OPTION } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
||||||
import getDelayTo from '../../../common/utils/getDelayTo';
|
import getDelayTo from '../../../common/utils/getDelayTo';
|
||||||
@@ -112,7 +112,7 @@ export default function Countdown(props: CountdownProps) {
|
|||||||
return (
|
return (
|
||||||
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
|
<div className={`countdown ${isMirrored ? 'mirror' : ''}`} data-testid='countdown-view'>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={[TIME_FORMAT_OPTION]} />
|
<ViewParamsEditor paramFields={[TIME_FORMAT_OPTION]} />
|
||||||
{follow === null ? (
|
{follow === null ? (
|
||||||
<CountdownSelect events={backstageEvents} />
|
<CountdownSelect events={backstageEvents} />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -1,131 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
|
||||||
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
|
||||||
|
|
||||||
import './LowerClean.scss';
|
|
||||||
|
|
||||||
export default function LowerClean(props) {
|
|
||||||
const { lower, title, options } = props;
|
|
||||||
const defaults = {
|
|
||||||
size: 1,
|
|
||||||
transitionIn: 3,
|
|
||||||
textColour: '#fffffa',
|
|
||||||
posX: 50,
|
|
||||||
posY: 700,
|
|
||||||
};
|
|
||||||
|
|
||||||
const [showLower, setShowLower] = useState(true);
|
|
||||||
// Unmount if fadeOut
|
|
||||||
useEffect(() => {
|
|
||||||
if (!options.fadeOut) return;
|
|
||||||
|
|
||||||
// Calculate time
|
|
||||||
const fadeOutTime = (parseInt(options.fadeOut, 10) + (options.transitionIn || defaults.transitionIn)) * 1000;
|
|
||||||
if (isNaN(fadeOutTime)) return;
|
|
||||||
|
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
setShowLower(false);
|
|
||||||
}, fadeOutTime);
|
|
||||||
|
|
||||||
return () => clearTimeout(timeout);
|
|
||||||
}, [options.fadeOut, options.transitionIn, defaults.transitionIn]);
|
|
||||||
|
|
||||||
// Format messages
|
|
||||||
const showLowerMessage = lower.text !== '' && lower.visible;
|
|
||||||
|
|
||||||
// motion
|
|
||||||
// transition segments
|
|
||||||
const t = options.transitionIn || defaults.transitionIn;
|
|
||||||
const quarter = t / 4;
|
|
||||||
const third = t / 3;
|
|
||||||
const half = t / 2;
|
|
||||||
|
|
||||||
const lowerThirdVariants = {
|
|
||||||
hidden: {
|
|
||||||
opacity: 0,
|
|
||||||
},
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
transition: {
|
|
||||||
duration: third,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
exit: {
|
|
||||||
opacity: 0,
|
|
||||||
transition: {
|
|
||||||
duration: third,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const titleVariants = {
|
|
||||||
hidden: {
|
|
||||||
opacity: 0,
|
|
||||||
},
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
transition: {
|
|
||||||
delay: quarter,
|
|
||||||
duration: half,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const sizeMultiplier = (options.size || 1) * 4;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className='lower-third clean'
|
|
||||||
style={{
|
|
||||||
backgroundColor: options.keyColour || defaults.keyColour,
|
|
||||||
color: options.textColour || defaults.textColour,
|
|
||||||
fontSize: `${sizeMultiplier}vh`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NavigationMenu isEditBtnHidden />
|
|
||||||
|
|
||||||
<AnimatePresence>
|
|
||||||
{showLower && (
|
|
||||||
<motion.div
|
|
||||||
className='lower-container'
|
|
||||||
style={{
|
|
||||||
backgroundColor: options.bgColour || defaults.bgColour,
|
|
||||||
top: options.posY || defaults.posY,
|
|
||||||
left: options.posX || defaults.posX,
|
|
||||||
}}
|
|
||||||
variants={lowerThirdVariants}
|
|
||||||
initial='hidden'
|
|
||||||
animate='visible'
|
|
||||||
exit='exit'
|
|
||||||
>
|
|
||||||
<motion.div className='title' variants={titleVariants}>
|
|
||||||
{title.titleNow}
|
|
||||||
</motion.div>
|
|
||||||
<motion.div className='subtitle' variants={titleVariants}>
|
|
||||||
{title.presenterNow}
|
|
||||||
</motion.div>
|
|
||||||
</motion.div>
|
|
||||||
)}
|
|
||||||
</AnimatePresence>
|
|
||||||
|
|
||||||
<AnimatePresence>
|
|
||||||
{showLowerMessage && (
|
|
||||||
<motion.div
|
|
||||||
className='message-container'
|
|
||||||
style={{
|
|
||||||
backgroundColor: options.bgColour || defaults.bgColour,
|
|
||||||
}}
|
|
||||||
key='modal'
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
exit={{ scaleY: 0, opacity: 0 }}
|
|
||||||
transition={{ duration: 0.5 }}
|
|
||||||
>
|
|
||||||
<div className='message'>{lower.text}</div>
|
|
||||||
</motion.div>
|
|
||||||
)}
|
|
||||||
</AnimatePresence>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
.lower-third.clean {
|
|
||||||
margin: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
color: #fffffa;
|
|
||||||
font-size: 4vh;
|
|
||||||
background-color: white;
|
|
||||||
|
|
||||||
.lower-container {
|
|
||||||
position: absolute;
|
|
||||||
padding: 1vh 2vh;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-container {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 2vh;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.message {
|
|
||||||
font-size: 3.5vh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+20
-17
@@ -1,20 +1,24 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
|
import { Message } from 'ontime-types';
|
||||||
|
|
||||||
import { LOWER_THIRDS_OPTIONS } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
|
import { LOWER_THIRDS_OPTIONS } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
|
import { TitleManager } from '../ViewWrapper';
|
||||||
|
|
||||||
|
import { LowerOptions } from './LowerWrapper';
|
||||||
|
|
||||||
import './LowerLines.scss';
|
import './LowerLines.scss';
|
||||||
|
|
||||||
export default function LowerLines(props) {
|
interface LowerLinesProps {
|
||||||
|
lower: Message;
|
||||||
|
title: TitleManager;
|
||||||
|
options: LowerOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function LowerLines(props: LowerLinesProps) {
|
||||||
const { lower, title, options } = props;
|
const { lower, title, options } = props;
|
||||||
const defaults = {
|
|
||||||
size: 1,
|
|
||||||
transitionIn: 3,
|
|
||||||
textColour: '#fffffa',
|
|
||||||
bgColour: '#00000033',
|
|
||||||
};
|
|
||||||
const [showLower, setShowLower] = useState(true);
|
const [showLower, setShowLower] = useState(true);
|
||||||
|
|
||||||
// Unmount if fadeOut
|
// Unmount if fadeOut
|
||||||
@@ -22,15 +26,14 @@ export default function LowerLines(props) {
|
|||||||
if (!options.fadeOut) return;
|
if (!options.fadeOut) return;
|
||||||
|
|
||||||
// Calculate time
|
// Calculate time
|
||||||
const fadeOutTime = (parseInt(options.fadeOut, 10) + (options.transitionIn || defaults.transitionIn)) * 1000;
|
const fadeOutTime = (options.fadeOut + options.transitionIn) * 1000;
|
||||||
if (isNaN(fadeOutTime)) return;
|
|
||||||
|
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
setShowLower(false);
|
setShowLower(false);
|
||||||
}, fadeOutTime);
|
}, fadeOutTime);
|
||||||
|
|
||||||
return () => clearTimeout(timeout);
|
return () => clearTimeout(timeout);
|
||||||
}, [options.fadeOut, options.transitionIn, defaults.transitionIn]);
|
}, [options.fadeOut, options.transitionIn]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setShowLower(title.showNow);
|
setShowLower(title.showNow);
|
||||||
@@ -41,7 +44,7 @@ export default function LowerLines(props) {
|
|||||||
|
|
||||||
// motion
|
// motion
|
||||||
// transition segments
|
// transition segments
|
||||||
const t = options.transitionIn || defaults.transitionIn;
|
const t = options.transitionIn;
|
||||||
const eight = t / 8;
|
const eight = t / 8;
|
||||||
const quarter = t / 4;
|
const quarter = t / 4;
|
||||||
const third = t / 3;
|
const third = t / 3;
|
||||||
@@ -123,19 +126,19 @@ export default function LowerLines(props) {
|
|||||||
<div
|
<div
|
||||||
className='lower-third lines'
|
className='lower-third lines'
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: options.keyColour || defaults.keyColour,
|
backgroundColor: options.keyColour,
|
||||||
color: options.textColour || defaults.textColour,
|
color: options.textColour,
|
||||||
fontSize: `${sizeMultiplier}vh`,
|
fontSize: `${sizeMultiplier}vh`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={LOWER_THIRDS_OPTIONS} />
|
<ViewParamsEditor paramFields={LOWER_THIRDS_OPTIONS} />
|
||||||
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{showLower && (
|
{showLower && (
|
||||||
<motion.div
|
<motion.div
|
||||||
className='lower-container'
|
className='lower-container'
|
||||||
style={{ backgroundColor: options.bgColour || defaults.bgColour }}
|
style={{ backgroundColor: options.bgColour }}
|
||||||
variants={lowerThirdVariants}
|
variants={lowerThirdVariants}
|
||||||
initial='hidden'
|
initial='hidden'
|
||||||
animate='visible'
|
animate='visible'
|
||||||
+60
-54
@@ -1,28 +1,46 @@
|
|||||||
import { memo, useEffect, useState } from 'react';
|
import { memo, useEffect, useState } from 'react';
|
||||||
import isEqual from 'react-fast-compare';
|
import isEqual from 'react-fast-compare';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
import { Message, ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import PropTypes from 'prop-types';
|
import { TitleManager } from '../ViewWrapper';
|
||||||
|
|
||||||
import LowerClean from './LowerClean';
|
|
||||||
import LowerLines from './LowerLines';
|
import LowerLines from './LowerLines';
|
||||||
|
|
||||||
const areEqual = (prevProps, nextProps) => {
|
export type LowerOptions = {
|
||||||
|
size: number;
|
||||||
|
transitionIn: number;
|
||||||
|
textColour: string;
|
||||||
|
bgColour: string;
|
||||||
|
keyColour?: string;
|
||||||
|
fadeOut: number;
|
||||||
|
};
|
||||||
|
interface LowerProps {
|
||||||
|
title: TitleManager;
|
||||||
|
lower: Message;
|
||||||
|
viewSettings: ViewSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent triggering animation without a content change
|
||||||
|
const areEqual = (prevProps: LowerProps, nextProps: LowerProps) => {
|
||||||
return isEqual(prevProps.title, nextProps.title) && isEqual(prevProps.lower, nextProps.lower);
|
return isEqual(prevProps.title, nextProps.title) && isEqual(prevProps.lower, nextProps.lower);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Lower = (props) => {
|
const Lower = (props: LowerProps) => {
|
||||||
const { title, lower, viewSettings } = props;
|
const { title, lower, viewSettings } = props;
|
||||||
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
|
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const [titles, setTitles] = useState({
|
const [titles, setTitles] = useState<TitleManager>({
|
||||||
titleNow: '',
|
titleNow: '',
|
||||||
titleNext: '',
|
titleNext: '',
|
||||||
subtitleNow: '',
|
subtitleNow: '',
|
||||||
subtitleNext: '',
|
subtitleNext: '',
|
||||||
presenterNow: '',
|
presenterNow: '',
|
||||||
presenterNext: '',
|
presenterNext: '',
|
||||||
|
noteNow: '',
|
||||||
|
noteNext: '',
|
||||||
showNow: false,
|
showNow: false,
|
||||||
showNext: false,
|
showNext: false,
|
||||||
});
|
});
|
||||||
@@ -36,7 +54,7 @@ const Lower = (props) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// clear titles if necessary
|
// clear titles if necessary
|
||||||
// will trigger an animation out in the component
|
// will trigger an animation out in the component
|
||||||
let timeout = null;
|
let timeout: NodeJS.Timeout | null = null;
|
||||||
if (
|
if (
|
||||||
title?.titleNow !== titles?.titleNow ||
|
title?.titleNow !== titles?.titleNow ||
|
||||||
title?.subtitleNow !== titles?.subtitleNow ||
|
title?.subtitleNow !== titles?.subtitleNow ||
|
||||||
@@ -56,7 +74,7 @@ const Lower = (props) => {
|
|||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line -- we do this to keep animations
|
||||||
}, [title.titleNow, title.subtitleNow, title.presenterNow]);
|
}, [title.titleNow, title.subtitleNow, title.presenterNow]);
|
||||||
|
|
||||||
// defer rendering until we load stylesheets
|
// defer rendering until we load stylesheets
|
||||||
@@ -64,72 +82,60 @@ const Lower = (props) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sanitize data
|
const options: LowerOptions = {
|
||||||
// getting config from URL: preset, size, transition, bg, text, key
|
size: 1,
|
||||||
// eg. http://localhost:3000/lower?bg=ff2&text=f00&size=0.6&transition=5
|
transitionIn: 3,
|
||||||
// Check for user options
|
textColour: '#fffffa',
|
||||||
// create aux
|
bgColour: '#00000033',
|
||||||
const options = {};
|
fadeOut: 3,
|
||||||
|
};
|
||||||
// preset: selector
|
|
||||||
// Should be a number 1-n
|
|
||||||
const p = parseInt(searchParams.get('preset'), 10);
|
|
||||||
const preset = !isNaN(p) ? 1 : p;
|
|
||||||
|
|
||||||
// size: multiplier
|
// size: multiplier
|
||||||
// Should be a number 0.0-n
|
// Should be a number 0.0-n
|
||||||
const s = searchParams.get('size');
|
const _size = searchParams.get('size');
|
||||||
if (s) options.size = s;
|
if (_size) {
|
||||||
|
const parsedValue = Number(_size);
|
||||||
|
if (!Number.isNaN(parsedValue)) {
|
||||||
|
options.size = parsedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// transitionIn: seconds
|
// transitionIn: seconds
|
||||||
// Should be a number 0-n
|
// Should be a number 0-n
|
||||||
const t = parseInt(searchParams.get('transition'), 10);
|
const _transitionIn = searchParams.get('transition');
|
||||||
if (!isNaN(t)) options.transitionIn = t;
|
if (_transitionIn) {
|
||||||
|
const parsedValue = Number(_transitionIn);
|
||||||
|
if (!Number.isNaN(parsedValue)) {
|
||||||
|
options.transitionIn = parsedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// textColour: string
|
// textColour: string
|
||||||
// Should be a hex string '#ffffff'
|
// Should be a hex string '#ffffff'
|
||||||
const c = searchParams.get('text');
|
const _textColour = searchParams.get('text');
|
||||||
if (c) options.textColour = `#${c}`;
|
if (_textColour) options.textColour = `#${_textColour}`;
|
||||||
|
|
||||||
// bgColour: string
|
// bgColour: string
|
||||||
// Should be a hex string '#ffffff'
|
// Should be a hex string '#ffffff'
|
||||||
const b = searchParams.get('bg');
|
const _bgColour = searchParams.get('bg');
|
||||||
if (b) options.bgColour = `#${b}`;
|
if (_bgColour) options.bgColour = `#${_bgColour}`;
|
||||||
|
|
||||||
// key: string
|
// key: string
|
||||||
// Should be a hex string '#00FF00' with key colour
|
// Should be a hex string '#00FF00' with key colour
|
||||||
const k = searchParams.get('key');
|
const _key = searchParams.get('key');
|
||||||
if (k) options.keyColour = `#${k}`;
|
if (_key) options.keyColour = `#${_key}`;
|
||||||
|
|
||||||
// fadeOut: seconds
|
// fadeOut: seconds
|
||||||
// Should be a number 0-n
|
// Should be a number 0-n
|
||||||
const f = parseInt(searchParams.get('fadeout'), 10);
|
const _fadeOut = searchParams.get('fadeout');
|
||||||
if (!isNaN(f)) options.fadeOut = f;
|
if (_fadeOut) {
|
||||||
|
const parsedValue = Number(_transitionIn);
|
||||||
// x: pixels
|
if (!Number.isNaN(parsedValue)) {
|
||||||
// Should be a number 0-n
|
options.fadeOut = parsedValue;
|
||||||
const x = parseInt(searchParams.get('x'), 10);
|
}
|
||||||
if (!isNaN(x)) options.posX = x;
|
|
||||||
|
|
||||||
// y: pixels
|
|
||||||
// Should be a number 0-n
|
|
||||||
const y = parseInt(searchParams.get('y'), 10);
|
|
||||||
if (!isNaN(y)) options.posY = y;
|
|
||||||
|
|
||||||
switch (preset) {
|
|
||||||
case 0:
|
|
||||||
return <LowerClean lower={lower} title={titles} options={options} />;
|
|
||||||
case 1:
|
|
||||||
return <LowerLines lower={lower} title={titles} options={options} />;
|
|
||||||
default:
|
|
||||||
return <LowerLines lower={lower} title={titles} options={options} />;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return <LowerLines lower={lower} title={titles} options={options} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(Lower, areEqual);
|
export default memo(Lower, areEqual);
|
||||||
|
|
||||||
Lower.propTypes = {
|
|
||||||
title: PropTypes.object,
|
|
||||||
lower: PropTypes.object,
|
|
||||||
viewSettings: PropTypes.object,
|
|
||||||
};
|
|
||||||
@@ -3,9 +3,9 @@ import { useSearchParams } from 'react-router-dom';
|
|||||||
import { EventData, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
|
import { EventData, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { MINIMAL_TIMER_OPTIONS } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
|
import { MINIMAL_TIMER_OPTIONS } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
||||||
import { OverridableOptions } from '../../../common/models/View.types';
|
import { OverridableOptions } from '../../../common/models/View.types';
|
||||||
@@ -169,12 +169,12 @@ export default function MinimalTimer(props: MinimalTimerProps) {
|
|||||||
style={{
|
style={{
|
||||||
backgroundColor: userOptions.keyColour,
|
backgroundColor: userOptions.keyColour,
|
||||||
justifyContent: userOptions.justifyContent,
|
justifyContent: userOptions.justifyContent,
|
||||||
alignItems: userOptions.alignItems,
|
alignContent: userOptions.alignItems,
|
||||||
}}
|
}}
|
||||||
data-testid='minimal-timer'
|
data-testid='minimal-timer'
|
||||||
>
|
>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={MINIMAL_TIMER_OPTIONS} />
|
<ViewParamsEditor paramFields={MINIMAL_TIMER_OPTIONS} />
|
||||||
{!hideMessagesOverlay && (
|
{!hideMessagesOverlay && (
|
||||||
<div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}>
|
<div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}>
|
||||||
<div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div>
|
<div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
grid-area: schedule;
|
grid-area: schedule;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-left: 16px;
|
margin-left: clamp(16px, 5vw, 64px);;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule-nav-container {
|
.schedule-nav-container {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { AnimatePresence, motion } from 'framer-motion';
|
|||||||
import { EventData, Message, OntimeEvent, ViewSettings } from 'ontime-types';
|
import { EventData, Message, OntimeEvent, ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { TIME_FORMAT_OPTION } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
import Schedule from '../../../common/components/schedule/Schedule';
|
import Schedule from '../../../common/components/schedule/Schedule';
|
||||||
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
|
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
|
||||||
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
|
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
|
||||||
import TitleCard from '../../../common/components/title-card/TitleCard';
|
import TitleCard from '../../../common/components/title-card/TitleCard';
|
||||||
|
import { TIME_FORMAT_OPTION } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
||||||
import { formatTime } from '../../../common/utils/time';
|
import { formatTime } from '../../../common/utils/time';
|
||||||
@@ -57,7 +57,7 @@ export default function Public(props: BackstageProps) {
|
|||||||
return (
|
return (
|
||||||
<div className={`public-screen ${isMirrored ? 'mirror' : ''}`} data-testid='public-view'>
|
<div className={`public-screen ${isMirrored ? 'mirror' : ''}`} data-testid='public-view'>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={[TIME_FORMAT_OPTION]} />
|
<ViewParamsEditor paramFields={[TIME_FORMAT_OPTION]} />
|
||||||
<div className='event-header'>
|
<div className='event-header'>
|
||||||
{general.title}
|
{general.title}
|
||||||
<div className='clock-container'>
|
<div className='clock-container'>
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { formatDisplay, millisToString } from 'ontime-utils';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { STUDIO_CLOCK_OPTIONS } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
|
import { STUDIO_CLOCK_OPTIONS } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import useFitText from '../../../common/hooks/useFitText';
|
import useFitText from '../../../common/hooks/useFitText';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { formatEventList, getEventsWithDelay, trimRundown } from '../../../common/utils/eventsManager';
|
import { formatEventList, getEventsWithDelay, trimRundown } from '../../../common/utils/eventsManager';
|
||||||
@@ -74,7 +74,7 @@ export default function StudioClock(props) {
|
|||||||
return (
|
return (
|
||||||
<div className={`studio-clock ${isMirrored ? 'mirror' : ''}`} data-testid='studio-view'>
|
<div className={`studio-clock ${isMirrored ? 'mirror' : ''}`} data-testid='studio-view'>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={STUDIO_CLOCK_OPTIONS} />
|
<ViewParamsEditor paramFields={STUDIO_CLOCK_OPTIONS} />
|
||||||
<div className='clock-container'>
|
<div className='clock-container'>
|
||||||
<div className={`studio-timer ${showSeconds ? 'studio-timer--with-seconds' : ''}`}>{clock}</div>
|
<div className={`studio-timer ${showSeconds ? 'studio-timer--with-seconds' : ''}`}>{clock}</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { AnimatePresence, motion } from 'framer-motion';
|
|||||||
import { EventData, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
|
import { EventData, Playback, TimerMessage, TimerType, ViewSettings } from 'ontime-types';
|
||||||
|
|
||||||
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
import { overrideStylesURL } from '../../../common/api/apiConstants';
|
||||||
import { TIMER_OPTIONS } from '../../../common/components/edit-form-drawer/constants';
|
|
||||||
import EditFormDrawer from '../../../common/components/edit-form-drawer/EditFormDrawer';
|
|
||||||
import MultiPartProgressBar from '../../../common/components/multi-part-progress-bar/MultiPartProgressBar';
|
import MultiPartProgressBar from '../../../common/components/multi-part-progress-bar/MultiPartProgressBar';
|
||||||
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
||||||
import TitleCard from '../../../common/components/title-card/TitleCard';
|
import TitleCard from '../../../common/components/title-card/TitleCard';
|
||||||
|
import { TIMER_OPTIONS } from '../../../common/components/view-params-editor/constants';
|
||||||
|
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
|
||||||
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
import { TimeManagerType } from '../../../common/models/TimeManager.type';
|
||||||
import { formatTime } from '../../../common/utils/time';
|
import { formatTime } from '../../../common/utils/time';
|
||||||
@@ -100,7 +100,7 @@ export default function Timer(props: TimerProps) {
|
|||||||
return (
|
return (
|
||||||
<div className={showFinished ? `${baseClasses} stage-timer--finished` : baseClasses} data-testid='timer-view'>
|
<div className={showFinished ? `${baseClasses} stage-timer--finished` : baseClasses} data-testid='timer-view'>
|
||||||
<NavigationMenu />
|
<NavigationMenu />
|
||||||
<EditFormDrawer paramFields={TIMER_OPTIONS} />
|
<ViewParamsEditor paramFields={TIMER_OPTIONS} />
|
||||||
<div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}>
|
<div className={showOverlay ? 'message-overlay message-overlay--active' : 'message-overlay'}>
|
||||||
<div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div>
|
<div className={`message ${showBlinking ? 'blink' : ''}`}>{pres.text}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ export const ontimeButtonSubtle = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ontimeButtonGhosted = {
|
||||||
|
...ontimeButtonSubtle,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
};
|
||||||
|
|
||||||
export const ontimeButtonSubtleOnLight = {
|
export const ontimeButtonSubtleOnLight = {
|
||||||
backgroundColor: '#ececec', // $gray-100
|
backgroundColor: '#ececec', // $gray-100
|
||||||
color: '#595959', // $gray-800
|
color: '#595959', // $gray-800
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { extendTheme } from '@chakra-ui/react';
|
|||||||
import { ontimeAlertOnLight } from './OntimeAlert';
|
import { ontimeAlertOnLight } from './OntimeAlert';
|
||||||
import {
|
import {
|
||||||
ontimeButtonFilled,
|
ontimeButtonFilled,
|
||||||
|
ontimeButtonGhosted,
|
||||||
ontimeButtonOutlined,
|
ontimeButtonOutlined,
|
||||||
ontimeButtonSubtle,
|
ontimeButtonSubtle,
|
||||||
ontimeButtonSubtleOnLight,
|
ontimeButtonSubtleOnLight,
|
||||||
@@ -42,6 +43,7 @@ const theme = extendTheme({
|
|||||||
'ontime-filled': { ...ontimeButtonFilled },
|
'ontime-filled': { ...ontimeButtonFilled },
|
||||||
'ontime-outlined': { ...ontimeButtonOutlined },
|
'ontime-outlined': { ...ontimeButtonOutlined },
|
||||||
'ontime-subtle': { ...ontimeButtonSubtle },
|
'ontime-subtle': { ...ontimeButtonSubtle },
|
||||||
|
'ontime-ghosted': { ...ontimeButtonGhosted },
|
||||||
'ontime-subtle-white': { ...ontimeButtonSubtleWhite },
|
'ontime-subtle-white': { ...ontimeButtonSubtleWhite },
|
||||||
'ontime-subtle-on-light': { ...ontimeButtonSubtleOnLight },
|
'ontime-subtle-on-light': { ...ontimeButtonSubtleOnLight },
|
||||||
'ontime-ghost-on-light': { ...ontimeGhostOnLight },
|
'ontime-ghost-on-light': { ...ontimeGhostOnLight },
|
||||||
|
|||||||
Reference in New Issue
Block a user