mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-12 19:03:47 +00:00
refactor: review timer styles
This commit is contained in:
committed by
Carlos Valente
parent
a69c5f354c
commit
7305edc398
@@ -13,8 +13,13 @@ interface FitTextProps extends HTMLAttributes<HTMLDivElement> {
|
||||
max?: number; // inclusive
|
||||
}
|
||||
|
||||
export function FitText(props: PropsWithChildren<FitTextProps>) {
|
||||
const { children, mode = 'multi', min = 16, max = 256, ...elementProps } = props;
|
||||
export function FitText({
|
||||
children,
|
||||
mode = 'multi',
|
||||
min = 16,
|
||||
max = 256,
|
||||
...elementProps
|
||||
}: PropsWithChildren<FitTextProps>) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const isOverflown = useCallback(() => {
|
||||
|
||||
+2
-3
@@ -25,9 +25,8 @@
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
background-color: $gray-1300;
|
||||
border: 2px solid $ui-white;
|
||||
outline: 2px solid $blue-500;
|
||||
background-color: $gray-1350;
|
||||
}
|
||||
|
||||
&.current {
|
||||
|
||||
@@ -18,7 +18,9 @@ export default function PopoverContents({
|
||||
<Popover.Positioner sideOffset={8} {...popoverProps}>
|
||||
<Popover.Popup className={style.popup}>
|
||||
{title && <Popover.Title className={style.title}>{title}</Popover.Title>}
|
||||
<Popover.Description className={className}>{children}</Popover.Description>
|
||||
<Popover.Description className={className} render={<div />}>
|
||||
{children}
|
||||
</Popover.Description>
|
||||
</Popover.Popup>
|
||||
</Popover.Positioner>
|
||||
</Popover.Portal>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
// attempt to match with ontimeTextInputs
|
||||
|
||||
@@ -43,8 +43,7 @@ export default function ParamInput({ paramField }: ParamInputProps) {
|
||||
}
|
||||
|
||||
if (type === 'boolean') {
|
||||
const defaultCheckedValue = isStringBoolean(searchParams.get(id)) || defaultValue;
|
||||
return <Switch size='large' name={id} defaultChecked={defaultCheckedValue} />;
|
||||
return <ControlledSwitch id={id} initialValue={isStringBoolean(searchParams.get(id)) || defaultValue} />;
|
||||
}
|
||||
|
||||
if (type === 'number') {
|
||||
@@ -123,3 +122,12 @@ function MultiOption({ paramField }: EditFormMultiOptionProps) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface ControlledSwitchProps {
|
||||
id: string;
|
||||
initialValue: boolean;
|
||||
}
|
||||
function ControlledSwitch({ id, initialValue }: ControlledSwitchProps) {
|
||||
const [checked, setChecked] = useState(initialValue);
|
||||
return <Switch size='large' name={id} checked={checked} onCheckedChange={setChecked} />;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ export default function Operator() {
|
||||
const { process } = makeOperatorMetadata(selectedEventId);
|
||||
|
||||
return (
|
||||
<div className={style.operatorContainer}>
|
||||
<div className={style.operatorContainer} data-testid='operator-view'>
|
||||
<ViewParamsEditor viewOptions={operatorOptions} />
|
||||
{editEvent && <EditModal event={editEvent} onClose={() => setEditEvent(null)} />}
|
||||
|
||||
|
||||
@@ -35,9 +35,18 @@ interface BackstageProps {
|
||||
settings: Settings | undefined;
|
||||
}
|
||||
|
||||
export default function Backstage(props: BackstageProps) {
|
||||
const { events, customFields, eventNext, eventNow, general, time, isMirrored, runtime, selectedId, settings } = props;
|
||||
|
||||
export default function Backstage({
|
||||
events,
|
||||
customFields,
|
||||
eventNext,
|
||||
eventNow,
|
||||
general,
|
||||
time,
|
||||
isMirrored,
|
||||
runtime,
|
||||
selectedId,
|
||||
settings,
|
||||
}: BackstageProps) {
|
||||
const { getLocalizedString } = useTranslation();
|
||||
const { secondarySource } = useBackstageOptions();
|
||||
const [blinkClass, setBlinkClass] = useState(false);
|
||||
|
||||
@@ -38,7 +38,12 @@ export default function StudioTimers({
|
||||
const formattedSecondaryMessage = secondaryMessage || '-';
|
||||
|
||||
// gather presentation styles
|
||||
const timerColour = getTimerColour(viewSettings, time.phase === TimerPhase.Warning, time.phase === TimerPhase.Danger);
|
||||
const timerColour = getTimerColour(
|
||||
viewSettings,
|
||||
undefined,
|
||||
time.phase === TimerPhase.Warning,
|
||||
time.phase === TimerPhase.Danger,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='studio__timers'>
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
.timer {
|
||||
opacity: 1;
|
||||
font-family: var(--timer-font, var(--font-family-override, $viewer-font-family));
|
||||
color: var(--timer-colour, var(--timer-color-override, var(--phase-color)));
|
||||
color: var(--timer-colour, var(--timer-color-override, $ui-white));
|
||||
line-height: 0.9em;
|
||||
text-align: center;
|
||||
letter-spacing: 0.05em;
|
||||
@@ -117,14 +117,14 @@
|
||||
|
||||
// use a class instead of a phase, to allow suppressing overtime style
|
||||
&--finished {
|
||||
color: var(--timer-overtime-color-override, $timer-finished-color);
|
||||
color: var(--timer-colour, var(--timer-overtime-color-override, $timer-finished-color));
|
||||
}
|
||||
|
||||
&[data-phase="warning"] {
|
||||
color: var(--timer-warning-color-override, var(--phase-color));
|
||||
color: var(--timer-colour, var(--timer-warning-color-override));
|
||||
}
|
||||
&[data-phase="danger"] {
|
||||
color: var(--timer-danger-color-override, var(--phase-color));
|
||||
color: var(--timer-colour, var(--timer-danger-color-override));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export default function Timer({
|
||||
timerType,
|
||||
freezeOvertime,
|
||||
freezeMessage,
|
||||
hideOvertime,
|
||||
hidePhase,
|
||||
font,
|
||||
keyColour,
|
||||
textColour,
|
||||
@@ -88,7 +88,7 @@ export default function Timer({
|
||||
time.phase,
|
||||
freezeOvertime,
|
||||
freezeMessage,
|
||||
hideOvertime,
|
||||
hidePhase,
|
||||
);
|
||||
const isPlaying = getIsPlaying(time.playback);
|
||||
const showClock = !hideClock && getShowClock(viewTimerType);
|
||||
@@ -136,11 +136,11 @@ export default function Timer({
|
||||
);
|
||||
|
||||
// gather presentation styles
|
||||
const timerColour = getTimerColour(viewSettings, showWarning, showDanger);
|
||||
const timerColour = getTimerColour(viewSettings, textColour, showWarning, showDanger);
|
||||
const { timerFontSize, externalFontSize } = getEstimatedFontSize(display, secondaryContent);
|
||||
const userStyles = {
|
||||
...(keyColour && { '--timer-bg': keyColour }),
|
||||
...(textColour && { '--timer-colour': textColour }),
|
||||
...(textColour && { '--timer-colour': timerColour }),
|
||||
...(font && { '--timer-font': font }),
|
||||
};
|
||||
|
||||
@@ -183,10 +183,7 @@ export default function Timer({
|
||||
) : (
|
||||
<div
|
||||
className={cx(['timer', !isPlaying && 'timer--paused', showFinished && 'timer--finished'])}
|
||||
style={{
|
||||
fontSize: `${timerFontSize}vw`,
|
||||
'--phase-color': timerColour,
|
||||
}}
|
||||
style={{ fontSize: `${timerFontSize}vw` }}
|
||||
data-phase={time.phase}
|
||||
>
|
||||
{display}
|
||||
|
||||
@@ -65,9 +65,9 @@ export const getTimerOptions = (timeFormat: string, customFields: CustomFields):
|
||||
placeholder: 'e.g. Time is up!',
|
||||
},
|
||||
{
|
||||
id: 'hideOvertime',
|
||||
title: 'Hide Overtime',
|
||||
description: 'Whether to suppress overtime styles (red borders and red text)',
|
||||
id: 'hidePhase',
|
||||
title: 'Hide progress styles',
|
||||
description: 'Whether to suppress the progress styles (warning, danger and overtime)',
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
@@ -187,7 +187,7 @@ type TimerOptions = {
|
||||
timerType?: TimerType;
|
||||
freezeOvertime: boolean;
|
||||
freezeMessage: string;
|
||||
hideOvertime: boolean;
|
||||
hidePhase: boolean;
|
||||
font?: string;
|
||||
keyColour?: string;
|
||||
textColour?: string;
|
||||
@@ -217,7 +217,7 @@ function getOptionsFromParams(searchParams: URLSearchParams): TimerOptions {
|
||||
timerType: timerType === TimerType.None ? undefined : timerType,
|
||||
freezeOvertime: isStringBoolean(searchParams.get('freezeOvertime')),
|
||||
freezeMessage: searchParams.get('freezeMessage') ?? '',
|
||||
hideOvertime: isStringBoolean(searchParams.get('hideOvertime')),
|
||||
hidePhase: isStringBoolean(searchParams.get('hidePhase')),
|
||||
|
||||
font: searchParams.get('font') ?? undefined,
|
||||
keyColour: makeColourString(searchParams.get('keyColour')),
|
||||
|
||||
@@ -83,15 +83,32 @@ export function getShowModifiers(
|
||||
phase: TimerPhase,
|
||||
freezeOvertime: boolean,
|
||||
freezeMessage: string,
|
||||
hideOvertime: boolean,
|
||||
hidePhase: boolean,
|
||||
) {
|
||||
if (hidePhase) {
|
||||
return {
|
||||
showEndMessage: false,
|
||||
showFinished: false,
|
||||
showWarning: false,
|
||||
showDanger: false,
|
||||
};
|
||||
}
|
||||
|
||||
const showModifiers = timerType === TimerType.CountDown || countToEnd;
|
||||
const finished = phase === TimerPhase.Overtime;
|
||||
if (!showModifiers) {
|
||||
return {
|
||||
showEndMessage: false,
|
||||
showFinished: false,
|
||||
showWarning: false,
|
||||
showDanger: false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
showEndMessage: showModifiers && finished && freezeOvertime && freezeMessage !== '',
|
||||
showFinished: showModifiers && !hideOvertime && finished,
|
||||
showWarning: showModifiers && phase === TimerPhase.Warning,
|
||||
showDanger: showModifiers && phase === TimerPhase.Danger,
|
||||
showEndMessage: freezeOvertime && freezeMessage !== '',
|
||||
showFinished: phase === TimerPhase.Overtime,
|
||||
showWarning: phase === TimerPhase.Warning,
|
||||
showDanger: phase === TimerPhase.Danger,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,13 @@ import { ViewSettings } from 'ontime-types';
|
||||
/**
|
||||
* Which colour should the timer have at a given moment
|
||||
*/
|
||||
export function getTimerColour(viewSettings: ViewSettings, showWarning: boolean, showDanger: boolean) {
|
||||
export function getTimerColour(
|
||||
viewSettings: ViewSettings,
|
||||
timerColour: string | undefined,
|
||||
showWarning: boolean,
|
||||
showDanger: boolean,
|
||||
) {
|
||||
if (showWarning) return viewSettings.warningColor;
|
||||
if (showDanger) return viewSettings.dangerColor;
|
||||
return viewSettings.normalColor;
|
||||
return timerColour || viewSettings.normalColor;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user