fix: keep editor identifying timers by index, revert secondary-source labels

- AuxTimer.tsx (editor playback control) now always shows the timer's
  index alongside its custom name, eg. "Aux 1: Speaker", instead of
  replacing the index entirely. Truncates to a single line with an
  ellipsis (and a title tooltip) so long names don't wrap and break the
  compact three-column layout.
- Revert the secondary-source select and its preview label
  (TimerViewControl.tsx, TimerPreview.tsx) back to plain "Aux 1/2/3" -
  these identify a fixed technical source, not the timer's identity, so
  they should stay stable regardless of naming.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCZejVTzuAY3tHTE6nB3JH
This commit is contained in:
Claude
2026-08-01 07:25:18 +00:00
parent 59bff62f76
commit 469d83dc0b
5 changed files with 31 additions and 20 deletions
@@ -2,3 +2,9 @@ export function getAuxTimerLabel(name: string | undefined, fallback: string): st
const custom = name?.trim();
return custom ? custom : fallback;
}
/** Combines the aux timer's index with its custom name, eg. "Aux 1: Speaker" */
export function getAuxTimerIndexedLabel(name: string | undefined, index: number): string {
const custom = name?.trim();
return custom ? `Aux ${index}: ${custom}` : `Aux ${index}`;
}
@@ -5,25 +5,23 @@ import { LuArrowDownToLine } from 'react-icons/lu';
import { CornerWithPip } from '../../../common/components/editor-utils/EditorUtils';
import Tooltip from '../../../common/components/tooltip/Tooltip';
import useViewSettings from '../../../common/hooks-query/useViewSettings';
import { useAuxTimersName, useMessagePreview } from '../../../common/hooks/useSocket';
import { getAuxTimerLabel } from '../../../common/utils/auxTimerUtils';
import { useMessagePreview } from '../../../common/hooks/useSocket';
import { handleLinks } from '../../../common/utils/linkUtils';
import { cx, timerPlaceholder } from '../../../common/utils/styleUtils';
import PipRoot from '../../../views/editor/pip-timer/PipRoot';
import style from './TimerPreview.module.scss';
const secondarySourceLabels: Record<string, string> = {
aux1: 'Aux 1',
aux2: 'Aux 2',
aux3: 'Aux 3',
secondary: 'Secondary message',
};
export default function TimerPreview() {
const { blink, blackout, countToEnd, phase, secondarySource, showTimerMessage, timerType } = useMessagePreview();
const { data } = useViewSettings();
const auxName = useAuxTimersName();
const secondarySourceLabels: Record<string, string> = {
aux1: getAuxTimerLabel(auxName.aux1, 'Aux 1'),
aux2: getAuxTimerLabel(auxName.aux2, 'Aux 2'),
aux3: getAuxTimerLabel(auxName.aux3, 'Aux 3'),
secondary: 'Secondary message',
};
const main = (() => {
if (showTimerMessage) return 'Message';
@@ -4,8 +4,7 @@ import { useEffect, useState } from 'react';
import Button from '../../../common/components/buttons/Button';
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
import Select from '../../../common/components/select/Select';
import { setMessage, useAuxTimersName, useTimerViewControl } from '../../../common/hooks/useSocket';
import { getAuxTimerLabel } from '../../../common/utils/auxTimerUtils';
import { setMessage, useTimerViewControl } from '../../../common/hooks/useSocket';
import TimerPreview from './TimerPreview';
import style from './TimerViewControl.module.scss';
@@ -44,7 +43,6 @@ export default function TimerControlsPreview() {
function SecondarySourceControl() {
const { secondarySource } = useTimerViewControl();
const auxName = useAuxTimersName();
const [value, setValue] = useState<SecondarySource>('aux1');
// sync secondary source with external changes
@@ -67,9 +65,9 @@ function SecondarySourceControl() {
<Select
value={value}
options={[
{ value: 'aux1', label: getAuxTimerLabel(auxName.aux1, 'Aux 1') },
{ value: 'aux2', label: getAuxTimerLabel(auxName.aux2, 'Aux 2') },
{ value: 'aux3', label: getAuxTimerLabel(auxName.aux3, 'Aux 3') },
{ value: 'aux1', label: 'Aux 1' },
{ value: 'aux2', label: 'Aux 2' },
{ value: 'aux3', label: 'Aux 3' },
{ value: 'secondary', label: 'Secondary message' },
]}
onValueChange={(value: SecondarySource | null) => {
@@ -1,8 +1,15 @@
.label {
display: block;
margin-top: 1rem;
}
.labelText {
display: block;
font-size: $inner-section-text-size;
color: $label-gray;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.controls {
@@ -4,7 +4,7 @@ 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 { getAuxTimerIndexedLabel } from '../../../../common/utils/auxTimerUtils';
import TapButton from '../tap-button/TapButton';
import style from './AuxTimer.module.scss';
@@ -18,7 +18,7 @@ export function AuxTimer({ index }: AuxTimerProps) {
const { stop, setDirection } = setAuxTimer;
const label = getAuxTimerLabel(name, `Aux Timer ${index}`);
const label = getAuxTimerIndexedLabel(name, index);
const toggleDirection = () => {
const newDirection = direction === SimpleDirection.CountDown ? SimpleDirection.CountUp : SimpleDirection.CountDown;
@@ -30,10 +30,12 @@ export function AuxTimer({ index }: AuxTimerProps) {
return (
<label className={style.label}>
{label}
<span className={style.labelText} title={label}>
{label}
</span>
<div className={style.controls}>
<div className={style.input}>
<AuxTimerInput index={index} isActive={isActive} placeholder={label} />
<AuxTimerInput index={index} isActive={isActive} placeholder={`Aux ${index}`} />
<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}`} />}