From 22e9b6d971a4f7ecb9c1f1ad1f4ab5c69170e296 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 03:51:53 +0000 Subject: [PATCH] Replace deprecated substr with substring in TranscriptViewer - Replaced `substr(14, 5)` with `substring(14, 19)` for timestamp formatting. - Extracted logic to `formatTimestamp` helper function. - Added unit tests in `TranscriptViewer.test.ts`. Co-authored-by: alfieprojectsdev <11991855+alfieprojectsdev@users.noreply.github.com> --- .../src/components/TranscriptViewer.test.ts | 22 +++ .../src/components/TranscriptViewer.tsx | 128 ++++++++++-------- 2 files changed, 94 insertions(+), 56 deletions(-) create mode 100644 field-logic/src/components/TranscriptViewer.test.ts 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" }} + > + 🚀 +
-
- ); +
+ ))} +
+
+ ); };