mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-15 04:13:47 +00:00
2f29060fa4
Addresses review feedback on the aux timer naming feature:
- Automation action labels now reference the timers by index
("Aux timer 1: start") rather than the custom names, keeping the
automation config stable regardless of naming.
- Expose the custom names through the consumer-facing runtime interface:
the aux timer objects broadcast over the websocket now carry a `name`
field. Names are seeded from the persisted settings at bootstrap and
kept in sync whenever the settings change, so every consumer (views and
integrations) reads them from the same runtime data.
- The client control and view consumers now read the name from the
runtime store instead of querying settings directly; the settings form
remains the persisted editing source.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCZejVTzuAY3tHTE6nB3JH
103 lines
3.3 KiB
TypeScript
103 lines
3.3 KiB
TypeScript
import { Playback, SimpleDirection, SimplePlayback } from 'ontime-types';
|
|
import { millisToString, parseUserTime } from 'ontime-utils';
|
|
import { IoArrowDown, IoArrowUp, IoPause, IoPlay, IoStop } from 'react-icons/io5';
|
|
|
|
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
|
|
import { setAuxTimer, useAuxTimerControl, useAuxTimerTime } from '../../../../common/hooks/useSocket';
|
|
import { getAuxTimerLabel } from '../../../../common/utils/auxTimerUtils';
|
|
import TapButton from '../tap-button/TapButton';
|
|
|
|
import style from './AuxTimer.module.scss';
|
|
|
|
interface AuxTimerProps {
|
|
index: number;
|
|
}
|
|
|
|
export function AuxTimer({ index }: AuxTimerProps) {
|
|
const { playback, direction, name } = useAuxTimerControl(index);
|
|
|
|
const { stop, setDirection } = setAuxTimer;
|
|
|
|
const label = getAuxTimerLabel(name, `Aux Timer ${index}`);
|
|
|
|
const toggleDirection = () => {
|
|
const newDirection = direction === SimpleDirection.CountDown ? SimpleDirection.CountUp : SimpleDirection.CountDown;
|
|
setDirection(index, newDirection);
|
|
};
|
|
|
|
const isActive = playback !== SimplePlayback.Stop;
|
|
const playbackAction = playback === SimplePlayback.Start ? 'pause' : 'play';
|
|
|
|
return (
|
|
<label className={style.label}>
|
|
{label}
|
|
<div className={style.controls}>
|
|
<div className={style.input}>
|
|
<AuxTimerInput index={index} isActive={isActive} placeholder={label} />
|
|
<TapButton onClick={toggleDirection} aspect='tight' disabled={isActive}>
|
|
{direction === SimpleDirection.CountDown && <IoArrowDown data-testid={`aux-timer-direction-${index}`} />}
|
|
{direction === SimpleDirection.CountUp && <IoArrowUp data-testid={`aux-timer-direction-${index}`} />}
|
|
</TapButton>
|
|
</div>
|
|
<div className={style.twoSides}>
|
|
<AuxTogglePlay index={index} action={playbackAction} />
|
|
<TapButton onClick={() => stop(index)} theme={Playback.Stop} disabled={!isActive}>
|
|
<IoStop data-testid={`aux-timer-stop-${index}`} />
|
|
</TapButton>
|
|
</div>
|
|
</div>
|
|
</label>
|
|
);
|
|
}
|
|
|
|
interface AuxTimerInputProps {
|
|
index: number;
|
|
isActive: boolean;
|
|
placeholder: string;
|
|
}
|
|
|
|
function AuxTimerInput({ index, isActive, placeholder }: AuxTimerInputProps) {
|
|
const newTimeInMs = useAuxTimerTime(index);
|
|
const { setDuration } = setAuxTimer;
|
|
|
|
const handleTimeUpdate = (_field: string, value: string) => {
|
|
const newTimeInMs = parseUserTime(value);
|
|
setDuration(index, newTimeInMs);
|
|
};
|
|
|
|
if (isActive) {
|
|
return (
|
|
<div className={style.fakeInput} data-testid={`time-label-aux${index}`}>
|
|
{millisToString(newTimeInMs)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<TimeInput submitHandler={handleTimeUpdate} name={`aux${index}`} time={newTimeInMs} placeholder={placeholder} />
|
|
);
|
|
}
|
|
|
|
interface AuxTogglePlayProps {
|
|
index: number;
|
|
action: 'play' | 'pause';
|
|
}
|
|
|
|
function AuxTogglePlay({ index, action }: AuxTogglePlayProps) {
|
|
const { start, pause } = setAuxTimer;
|
|
|
|
if (action === 'play') {
|
|
return (
|
|
<TapButton onClick={() => start(index)} theme={Playback.Play}>
|
|
<IoPlay data-testid={`aux-timer-start-${index}`} />
|
|
</TapButton>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<TapButton onClick={() => pause(index)} theme={Playback.Pause}>
|
|
<IoPause data-testid={`aux-timer-pause-${index}`} />
|
|
</TapButton>
|
|
);
|
|
}
|