Repository navigation
Expand file tree
/
Copy pathai-session-clock.ts
More file actions
28 lines (26 loc) · 1.72 KB
/
Copy pathai-session-clock.ts
File metadata and controls
28 lines (26 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
export type RecordingTime = { readonly seconds: number; readonly active?: boolean };
export function recordingClockLabel(recording: RecordingTime | undefined, now = new Date()) {
const local = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
if (!recording) return `--:-- · ${local}`;
const seconds = Math.max(0, Math.floor(recording.seconds));
const minutes = Math.floor(seconds / 60);
const elapsed = minutes >= 60
? `${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}:${String(seconds % 60).padStart(2, "0")}`
: `${String(minutes).padStart(2, "0")}:${String(seconds % 60).padStart(2, "0")}`;
return `${recording.active === false ? "○" : "●"} ${elapsed} · ${local}`;
}
export function createRecordingClock(tick: () => void, now = () => performance.now()) {
let started: number | undefined, frozen: RecordingTime | undefined;
let accumulated = 0;
let timer: ReturnType<typeof setInterval> | undefined;
const get = (): RecordingTime | undefined => started === undefined ? frozen : { seconds: accumulated + Math.max(0, (now() - started) / 1000), active: true };
const pause = () => { const value = get(); frozen = value ? { seconds: value.seconds, active: false } : undefined; started = undefined; };
const stop = () => { pause(); clearInterval(timer); timer = undefined; };
const watch = () => { timer ??= setInterval(tick, 1_000); };
return {
get, stop, pause, watch,
resume() { if (started !== undefined) return; accumulated = frozen?.seconds ?? 0; started = now(); watch(); },
reset() { stop(); frozen = undefined; },
start() { stop(); frozen = undefined; accumulated = 0; started = now(); watch(); },
};
}