diff --git a/field-logic/src/components/TranscriptViewer.test.ts b/field-logic/src/components/TranscriptViewer.test.ts new file mode 100644 index 0000000..202238c --- /dev/null +++ b/field-logic/src/components/TranscriptViewer.test.ts @@ -0,0 +1,22 @@ +import { describe, it, expect } from "vitest"; +import { formatTimestamp } from "./TranscriptViewer"; + +describe("TranscriptViewer", () => { + describe("formatTimestamp", () => { + it("formats 0 seconds correctly", () => { + expect(formatTimestamp(0)).toBe("00:00"); + }); + + it("formats seconds less than a minute correctly", () => { + expect(formatTimestamp(45)).toBe("00:45"); + }); + + it("formats minutes and seconds correctly", () => { + expect(formatTimestamp(65)).toBe("01:05"); + }); + + it("formats longer durations correctly (ignoring hours)", () => { + expect(formatTimestamp(3665)).toBe("01:05"); + }); + }); +}); diff --git a/field-logic/src/components/TranscriptViewer.tsx b/field-logic/src/components/TranscriptViewer.tsx index 9929047..54d95b7 100644 --- a/field-logic/src/components/TranscriptViewer.tsx +++ b/field-logic/src/components/TranscriptViewer.tsx @@ -1,74 +1,90 @@ -import React from 'react'; +import React from "react"; interface TranscriptSegment { - start: number; - end: number; - text: string; - confidence: number; - flagged?: boolean; + start: number; + end: number; + text: string; + confidence: number; + flagged?: boolean; } interface TranscriptData { - meta: { - file: string; - duration: number; - engine: string; - }; - segments: TranscriptSegment[]; + meta: { + file: string; + duration: number; + engine: string; + }; + segments: TranscriptSegment[]; } interface Props { - data: TranscriptData; + data: TranscriptData; } +export const formatTimestamp = (start: number): string => { + return new Date(start * 1000).toISOString().substring(14, 19); +}; + export const TranscriptViewer: React.FC = ({ data }) => { - const handleDeepLink = (e: React.MouseEvent, start: number) => { - e.preventDefault(); - const file = data.meta.file; - // Construct custom protocol link - const url = `fieldlogic://open?file=${file}&t=${start}`; - window.location.href = url; - }; + const handleDeepLink = (e: React.MouseEvent, start: number) => { + e.preventDefault(); + const file = data.meta.file; + // Construct custom protocol link + const url = `fieldlogic://open?file=${file}&t=${start}`; + window.location.href = url; + }; - return ( -
-

Transcription Review: {data.meta.file}

+ return ( +
+

Transcription Review: {data.meta.file}

-
- {data.segments.map((seg, idx) => ( -
- - [{new Date(seg.start * 1000).toISOString().substr(14, 5)}] - +
+ {data.segments.map((seg, idx) => ( +
+ + [{formatTimestamp(seg.start)}] + - {seg.text} + {seg.text} -
- {/* Primary: In-browser audio (mock) */} - +
+ {/* Primary: In-browser audio (mock) */} + - {/* Secondary: VLC Deep Link */} - handleDeepLink(e, seg.start)} - title="Open in VLC" - style={{ textDecoration: 'none' }} - > - 🚀 - -
-
- ))} + {/* Secondary: VLC Deep Link */} + handleDeepLink(e, seg.start)} + title="Open in VLC" + style={{ textDecoration: "none" }} + > + 🚀 +
-
- ); +
+ ))} +
+
+ ); };