From 576bfec36255ceb9d13293869ac2071dc27c1183 Mon Sep 17 00:00:00 2001 From: saebyn Date: Sat, 25 Jan 2025 08:04:08 -0800 Subject: [PATCH 1/4] apply npm audit fix --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e83b57a..12af707 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3121,10 +3121,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", From aef3f53227ac4f805b8613a8bebc6f62c7c09bc4 Mon Sep 17 00:00:00 2001 From: saebyn Date: Sat, 25 Jan 2025 08:04:35 -0800 Subject: [PATCH 2/4] Complete the reorg to use atomic design principles. --- src/components/{ => atoms}/TimeDotMarker.tsx | 2 +- .../{ => atoms}/TimeSegmentMarker.tsx | 4 +-- src/components/{ => atoms}/TimelineLegend.tsx | 0 src/components/{ => atoms}/VideoCaption.tsx | 0 .../{ => atoms}/VideoPlayerControls.tsx | 0 .../{ => atoms}/VideoPlayerProgressBar.tsx | 0 .../EditableTimestampedEventLog.tsx | 0 src/components/{ => molecules}/TimeTable.tsx | 11 +++--- .../{ => molecules}/TimelineControls.tsx | 10 +++--- .../{ => molecules}/TimelineElement.tsx | 28 +++++++-------- .../{ => molecules}/TimestampedEventLog.tsx | 12 +++---- .../{ => molecules}/VideoPlayer.tsx | 7 ++-- src/components/{ => molecules}/Viewport.tsx | 0 src/components/{ => organisms}/Timeline.tsx | 36 +++++++++---------- src/components/pages/VideoSelectionPage.tsx | 36 ++++++++++--------- .../TimelineContext.tsx | 0 16 files changed, 74 insertions(+), 72 deletions(-) rename src/components/{ => atoms}/TimeDotMarker.tsx (88%) rename src/components/{ => atoms}/TimeSegmentMarker.tsx (89%) rename src/components/{ => atoms}/TimelineLegend.tsx (100%) rename src/components/{ => atoms}/VideoCaption.tsx (100%) rename src/components/{ => atoms}/VideoPlayerControls.tsx (100%) rename src/components/{ => atoms}/VideoPlayerProgressBar.tsx (100%) rename src/components/{ => molecules}/EditableTimestampedEventLog.tsx (100%) rename src/components/{ => molecules}/TimeTable.tsx (92%) rename src/components/{ => molecules}/TimelineControls.tsx (85%) rename src/components/{ => molecules}/TimelineElement.tsx (56%) rename src/components/{ => molecules}/TimestampedEventLog.tsx (75%) rename src/components/{ => molecules}/VideoPlayer.tsx (84%) rename src/components/{ => molecules}/Viewport.tsx (100%) rename src/components/{ => organisms}/Timeline.tsx (80%) rename src/{components => context}/TimelineContext.tsx (100%) diff --git a/src/components/TimeDotMarker.tsx b/src/components/atoms/TimeDotMarker.tsx similarity index 88% rename from src/components/TimeDotMarker.tsx rename to src/components/atoms/TimeDotMarker.tsx index 52afac7..62acaf1 100644 --- a/src/components/TimeDotMarker.tsx +++ b/src/components/atoms/TimeDotMarker.tsx @@ -1,4 +1,4 @@ -import { useLens } from "components/TimelineContext"; +import { useLens } from 'context/TimelineContext'; export function TimeDotMarker({ timestampMilliseconds, diff --git a/src/components/TimeSegmentMarker.tsx b/src/components/atoms/TimeSegmentMarker.tsx similarity index 89% rename from src/components/TimeSegmentMarker.tsx rename to src/components/atoms/TimeSegmentMarker.tsx index 7984bb1..71c4edc 100644 --- a/src/components/TimeSegmentMarker.tsx +++ b/src/components/atoms/TimeSegmentMarker.tsx @@ -1,4 +1,4 @@ -import { useLens } from "./TimelineContext"; +import { useLens } from '../../context/TimelineContext'; export default function TimeSegmentMarker({ startMilliseconds, @@ -18,7 +18,7 @@ export default function TimeSegmentMarker({ const width = relativeWidth !== undefined ? `max(${relativeWidth * 100.0}%, 0.125rem)` - : "0.125rem"; + : '0.125rem'; return (
- {includeEnd ? "Start Time" : "Time"} + {includeEnd ? 'Start Time' : 'Time'} {includeEnd && End Time} @@ -47,8 +46,8 @@ function TimeTable({ playheadTime && row.timestamp <= playheadTime && (row.timestamp_end || 0) >= playheadTime - ? "bg-gray-200 dark:bg-gray-700" - : "" + ? 'bg-gray-200 dark:bg-gray-700' + : '' }`} > diff --git a/src/components/TimelineControls.tsx b/src/components/molecules/TimelineControls.tsx similarity index 85% rename from src/components/TimelineControls.tsx rename to src/components/molecules/TimelineControls.tsx index eb4b266..4d6090d 100644 --- a/src/components/TimelineControls.tsx +++ b/src/components/molecules/TimelineControls.tsx @@ -1,6 +1,6 @@ -import { useLens } from "components/TimelineContext"; -import TimelineLegend from "components/TimelineLegend"; -import Button from "components/atoms/Button"; +import Button from 'components/atoms/Button'; +import TimelineLegend from 'components/atoms/TimelineLegend'; +import { useLens } from 'context/TimelineContext'; export type TimelineControlsProps = { followPlayback: boolean; @@ -18,11 +18,11 @@ export default function TimelineControls({ }; const handleZoomIn = () => { - lens.zoomIn(); + lens.zoomIn(0.5); }; const handleZoomOut = () => { - lens.zoomOut(); + lens.zoomOut(0.5); }; return ( diff --git a/src/components/TimelineElement.tsx b/src/components/molecules/TimelineElement.tsx similarity index 56% rename from src/components/TimelineElement.tsx rename to src/components/molecules/TimelineElement.tsx index 690ca13..76fc81a 100644 --- a/src/components/TimelineElement.tsx +++ b/src/components/molecules/TimelineElement.tsx @@ -1,10 +1,10 @@ -import type { TimelineItem } from "utils/timeline"; -import { TimeDotMarker } from "./TimeDotMarker"; -import TimeSegmentMarker from "./TimeSegmentMarker"; +import type { TimelineItem } from 'utils/timeline'; +import { TimeDotMarker } from '../atoms/TimeDotMarker'; +import TimeSegmentMarker from '../atoms/TimeSegmentMarker'; import { type TimelineElementType, timelineElementTypeColors, -} from "./TimelineLegend"; +} from '../atoms/TimelineLegend'; interface TimelineElementProps { content: TimelineItem; @@ -12,7 +12,7 @@ interface TimelineElementProps { export default function TimelineElement({ content: { startMilliseconds, endMilliseconds, type }, }: TimelineElementProps) { - if (type === "chat") { + if (type === 'chat') { return ( { log: T[]; @@ -33,11 +33,11 @@ export default function TimestampedEventLog({
  • - {" "} + {' '} {renderEvent(entry)}
  • ))} diff --git a/src/components/VideoPlayer.tsx b/src/components/molecules/VideoPlayer.tsx similarity index 84% rename from src/components/VideoPlayer.tsx rename to src/components/molecules/VideoPlayer.tsx index fc9a68e..085344e 100644 --- a/src/components/VideoPlayer.tsx +++ b/src/components/molecules/VideoPlayer.tsx @@ -1,6 +1,6 @@ -import VideoPlayerControls from "components/VideoPlayerControls"; -import VideoPlayerProgressBar from "components/VideoPlayerProgressBar"; -import { forwardRef, useImperativeHandle, useState } from "react"; +import VideoPlayerControls from 'components/atoms/VideoPlayerControls'; +import VideoPlayerProgressBar from 'components/atoms/VideoPlayerProgressBar'; +import { forwardRef, useImperativeHandle, useState } from 'react'; interface VideoPlayerProps { videoUrl: string; @@ -44,6 +44,7 @@ export default forwardRef( return ( <> + {/* biome-ignore lint/a11y/useMediaCaption: */} diff --git a/src/data.json b/src/data.json index ee16e3a..c3360c4 100644 --- a/src/data.json +++ b/src/data.json @@ -1,6 +1,6 @@ { "title": "Coding Livestream 1", - "video_url": "/ep131.mp4", + "video_url": "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8", "length": "PT56M35S", "transcript": [ { From 42432a01656758f5bb2d3d88988b493cb5543706 Mon Sep 17 00:00:00 2001 From: saebyn Date: Sat, 25 Jan 2025 08:20:23 -0800 Subject: [PATCH 4/4] Fix formatting --- src/components/atoms/TimeDotMarker.tsx | 2 +- src/components/atoms/TimeSegmentMarker.tsx | 4 +-- src/components/molecules/TimeTable.tsx | 10 +++--- src/components/molecules/TimelineControls.tsx | 6 ++-- src/components/molecules/TimelineElement.tsx | 28 +++++++-------- .../molecules/TimestampedEventLog.tsx | 12 +++---- src/components/organisms/Timeline.tsx | 36 +++++++++---------- src/components/pages/VideoSelectionPage.tsx | 34 +++++++++--------- 8 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/components/atoms/TimeDotMarker.tsx b/src/components/atoms/TimeDotMarker.tsx index 62acaf1..2cfb9be 100644 --- a/src/components/atoms/TimeDotMarker.tsx +++ b/src/components/atoms/TimeDotMarker.tsx @@ -1,4 +1,4 @@ -import { useLens } from 'context/TimelineContext'; +import { useLens } from "context/TimelineContext"; export function TimeDotMarker({ timestampMilliseconds, diff --git a/src/components/atoms/TimeSegmentMarker.tsx b/src/components/atoms/TimeSegmentMarker.tsx index 71c4edc..0462611 100644 --- a/src/components/atoms/TimeSegmentMarker.tsx +++ b/src/components/atoms/TimeSegmentMarker.tsx @@ -1,4 +1,4 @@ -import { useLens } from '../../context/TimelineContext'; +import { useLens } from "../../context/TimelineContext"; export default function TimeSegmentMarker({ startMilliseconds, @@ -18,7 +18,7 @@ export default function TimeSegmentMarker({ const width = relativeWidth !== undefined ? `max(${relativeWidth * 100.0}%, 0.125rem)` - : '0.125rem'; + : "0.125rem"; return (
    - {includeEnd ? 'Start Time' : 'Time'} + {includeEnd ? "Start Time" : "Time"} {includeEnd && End Time} @@ -46,8 +46,8 @@ function TimeTable({ playheadTime && row.timestamp <= playheadTime && (row.timestamp_end || 0) >= playheadTime - ? 'bg-gray-200 dark:bg-gray-700' - : '' + ? "bg-gray-200 dark:bg-gray-700" + : "" }`} > diff --git a/src/components/molecules/TimelineControls.tsx b/src/components/molecules/TimelineControls.tsx index 4d6090d..0421ee3 100644 --- a/src/components/molecules/TimelineControls.tsx +++ b/src/components/molecules/TimelineControls.tsx @@ -1,6 +1,6 @@ -import Button from 'components/atoms/Button'; -import TimelineLegend from 'components/atoms/TimelineLegend'; -import { useLens } from 'context/TimelineContext'; +import Button from "components/atoms/Button"; +import TimelineLegend from "components/atoms/TimelineLegend"; +import { useLens } from "context/TimelineContext"; export type TimelineControlsProps = { followPlayback: boolean; diff --git a/src/components/molecules/TimelineElement.tsx b/src/components/molecules/TimelineElement.tsx index 76fc81a..6fc7624 100644 --- a/src/components/molecules/TimelineElement.tsx +++ b/src/components/molecules/TimelineElement.tsx @@ -1,10 +1,10 @@ -import type { TimelineItem } from 'utils/timeline'; -import { TimeDotMarker } from '../atoms/TimeDotMarker'; -import TimeSegmentMarker from '../atoms/TimeSegmentMarker'; +import type { TimelineItem } from "utils/timeline"; +import { TimeDotMarker } from "../atoms/TimeDotMarker"; +import TimeSegmentMarker from "../atoms/TimeSegmentMarker"; import { type TimelineElementType, timelineElementTypeColors, -} from '../atoms/TimelineLegend'; +} from "../atoms/TimelineLegend"; interface TimelineElementProps { content: TimelineItem; @@ -12,7 +12,7 @@ interface TimelineElementProps { export default function TimelineElement({ content: { startMilliseconds, endMilliseconds, type }, }: TimelineElementProps) { - if (type === 'chat') { + if (type === "chat") { return ( { log: T[]; @@ -33,11 +33,11 @@ export default function TimestampedEventLog({
  • - {' '} + {" "} {renderEvent(entry)}
  • ))} diff --git a/src/components/organisms/Timeline.tsx b/src/components/organisms/Timeline.tsx index 2a70ca4..0c718e0 100644 --- a/src/components/organisms/Timeline.tsx +++ b/src/components/organisms/Timeline.tsx @@ -1,13 +1,13 @@ -import TimeSegmentMarker from 'components/atoms/TimeSegmentMarker'; +import TimeSegmentMarker from "components/atoms/TimeSegmentMarker"; import { type TimelineElementType, timelineElementTypeColors, -} from 'components/atoms/TimelineLegend'; -import TimelineElement from 'components/molecules/TimelineElement'; -import { useLens } from 'context/TimelineContext'; -import { useEffect, useRef, useState } from 'react'; -import type { VideoMetadata } from 'types'; -import { createTimeline, generateKey } from 'utils/timeline'; +} from "components/atoms/TimelineLegend"; +import TimelineElement from "components/molecules/TimelineElement"; +import { useLens } from "context/TimelineContext"; +import { useEffect, useRef, useState } from "react"; +import type { VideoMetadata } from "types"; +import { createTimeline, generateKey } from "utils/timeline"; export default function Timeline({ content: { @@ -30,12 +30,12 @@ export default function Timeline({ const [dragging, setDragging] = useState(0); useEffect(() => { - document.addEventListener('mouseup', handleDragEnd); - document.addEventListener('mousemove', handleDrag); + document.addEventListener("mouseup", handleDragEnd); + document.addEventListener("mousemove", handleDrag); return () => { - document.removeEventListener('mouseup', handleDragEnd); - document.removeEventListener('mousemove', handleDrag); + document.removeEventListener("mouseup", handleDragEnd); + document.removeEventListener("mousemove", handleDrag); }; }); @@ -64,36 +64,36 @@ export default function Timeline({ } }; - container.addEventListener('wheel', handleWheel, { passive: false }); + container.addEventListener("wheel", handleWheel, { passive: false }); return () => { - container.removeEventListener('wheel', handleWheel); + container.removeEventListener("wheel", handleWheel); }; }, [lens]); const timeline = createTimeline([ ...silences.map((silence) => ({ - type: 'silence' as TimelineElementType, + type: "silence" as TimelineElementType, startMilliseconds: silence.timestamp, endMilliseconds: silence.timestamp_end && silence.timestamp_end, })), ...highlights.map((highlight) => ({ - type: 'highlight' as TimelineElementType, + type: "highlight" as TimelineElementType, startMilliseconds: highlight.timestamp, endMilliseconds: highlight.timestamp_end && highlight.timestamp_end, })), ...attentions.map((attention) => ({ - type: 'attention' as TimelineElementType, + type: "attention" as TimelineElementType, startMilliseconds: attention.timestamp, endMilliseconds: attention.timestamp_end && attention.timestamp_end, })), ...transcription_errors.map((error) => ({ - type: 'error' as TimelineElementType, + type: "error" as TimelineElementType, startMilliseconds: error.timestamp, endMilliseconds: error.timestamp_end && error.timestamp_end, })), ...chat_history.map((chat) => ({ - type: 'chat' as TimelineElementType, + type: "chat" as TimelineElementType, startMilliseconds: chat.timestamp, })), ]); diff --git a/src/components/pages/VideoSelectionPage.tsx b/src/components/pages/VideoSelectionPage.tsx index e737dd9..c402a69 100644 --- a/src/components/pages/VideoSelectionPage.tsx +++ b/src/components/pages/VideoSelectionPage.tsx @@ -1,20 +1,20 @@ -import Heading from 'components/atoms/Heading'; -import EditableTimestampedEventLog from 'components/molecules/EditableTimestampedEventLog'; -import TimeTable from 'components/molecules/TimeTable'; -import TimelineControls from 'components/molecules/TimelineControls'; -import TimestampedEventLog from 'components/molecules/TimestampedEventLog'; +import Heading from "components/atoms/Heading"; +import EditableTimestampedEventLog from "components/molecules/EditableTimestampedEventLog"; +import TimeTable from "components/molecules/TimeTable"; +import TimelineControls from "components/molecules/TimelineControls"; +import TimestampedEventLog from "components/molecules/TimestampedEventLog"; import VideoPlayer, { type VideoPlayerRef, -} from 'components/molecules/VideoPlayer'; -import Viewport from 'components/molecules/Viewport'; -import Sidebar from 'components/organisms/Sidebar'; -import Timeline from 'components/organisms/Timeline'; -import { TimelineProvider } from 'context/TimelineContext'; -import rawContent from 'data.json'; -import useKeyboardShortcuts from 'hooks/useKeyboardShortcuts'; -import { useRef, useState } from 'react'; -import type { ChatMessage, TranscriptSegment } from 'types'; -import parseContent from 'utils/parseData'; +} from "components/molecules/VideoPlayer"; +import Viewport from "components/molecules/Viewport"; +import Sidebar from "components/organisms/Sidebar"; +import Timeline from "components/organisms/Timeline"; +import { TimelineProvider } from "context/TimelineContext"; +import rawContent from "data.json"; +import useKeyboardShortcuts from "hooks/useKeyboardShortcuts"; +import { useRef, useState } from "react"; +import type { ChatMessage, TranscriptSegment } from "types"; +import parseContent from "utils/parseData"; function VideoSelectionPage() { const [playheadTime, setPlayheadTime] = useState(0); @@ -26,7 +26,7 @@ function VideoSelectionPage() { } useKeyboardShortcuts({ - '1': () => { + "1": () => { if (videoPlayerRef.current) { videoPlayerRef.current.seekTo(0); } @@ -66,7 +66,7 @@ function VideoSelectionPage() { renderEvent={(chat) => { return ( <> - {chat.username}:{' '} + {chat.username}:{" "} {chat.message} );