profileShare

rasmusjy / voicetask

Read-only snapshot

No repository description.

main default branch 105 files Expires Sep 13, 2026, 9:06 AM

Commit

Add recording timer and 120 second cap

commit 816c093

1 changed file with +26 and −1

modified client/src/components/PushToTalkButton.tsx +26 −1
@@ -13,8 +13,17 @@function isTypingTarget(target: EventTarget | null): boolean {
13 13 return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable
14 14 }
15 15
16 +const MAX_RECORDING_SECONDS = 120
17 +
18 +function formatElapsed(seconds: number): string {
19 + const m = Math.floor(seconds / 60)
20 + const s = seconds % 60
21 + return `${m}:${String(s).padStart(2, '0')}`
22 +}
23 +
16 24 export function PushToTalkButton({ disabled, onRecorded, onRecordingChange, onLevel }: PushToTalkButtonProps) {
17 25 const [recording, setRecording] = useState(false)
26 + const [elapsed, setElapsed] = useState(0)
18 27 const [error, setError] = useState<string | null>(null)
19 28 const recorderRef = useRef(createPushToTalkRecorder())
20 29 const activeRef = useRef(false)
@@ -46,6 +55,20 @@export function PushToTalkButton({ disabled, onRecorded, onRecordingChange, onLe
46 55 }
47 56 }, [onRecorded, onRecordingChange])
48 57
58 + useEffect(() => {
59 + if (!recording) {
60 + setElapsed(0)
61 + return
62 + }
63 + const startedAt = Date.now()
64 + const interval = window.setInterval(() => {
65 + const seconds = Math.floor((Date.now() - startedAt) / 1000)
66 + setElapsed(seconds)
67 + if (seconds >= MAX_RECORDING_SECONDS) void stopRecording()
68 + }, 500)
69 + return () => window.clearInterval(interval)
70 + }, [recording, stopRecording])
71 +
49 72 useEffect(() => {
50 73 function handleKeyDown(event: KeyboardEvent) {
51 74 if (event.code !== 'Space' || event.repeat || isTypingTarget(event.target)) return
@@ -94,7 +117,9 @@export function PushToTalkButton({ disabled, onRecorded, onRecordingChange, onLe
94 117 <path d="M12 18v3" />
95 118 </svg>
96 119 </button>
97 - <p className="mic-hint">{recording ? 'release to send' : 'hold to talk · or press space'}</p>
120 + <p className="mic-hint">
121 + {recording ? `${formatElapsed(elapsed)} · release to send` : 'hold to talk · or press space'}
122 + </p>
98 123 {error && <p className="error">{error}</p>}
99 124 </div>
100 125 )