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