TranscriptColumn Component
Relevant source files
The following files were used as context for generating this wiki page:
The TranscriptColumn is a key React component in the application, responsible for rendering the synchronized transcript of a YouTube video. It provides a scrollable view of transcript segments, highlights the currently playing segment, and allows users to interact with the text. Its primary functions include displaying the transcript, enabling text selection for AI note generation, searching within the transcript, and allowing users to seek to specific points in the video by clicking on a transcript line.
This component is a direct child of the main App component and works in tandem with the VideoPlayer and SmartBoard to create an interactive note-taking experience. It receives the transcript data from the useTranscript hook and communicates user interactions, such as text selection and seek requests, back to the App component to orchestrate state changes across the application.
Sources: components/TranscriptColumn.tsx, App.tsx:186-193
Component Architecture
The TranscriptColumn is composed of a main container and a memoized child component, TranscriptSegmentItem, for performance optimization when rendering long lists.
Sources: components/TranscriptColumn.tsx:15, 20, 151
Component & Prop Flow
The App component manages the state for the video and transcript, passing down necessary data and callbacks to TranscriptColumn. TranscriptColumn then maps over the segments array and renders a TranscriptSegmentItem for each one.
This diagram illustrates the flow of props from the parent App component down to the individual TranscriptSegmentItem components.
TranscriptColumn Props
The component receives the following props from its parent (App.tsx):
| Prop | Type | Description |
|---|---|---|
segments | TranscriptSegment[] | An array of transcript segments to be displayed. |
onSelection | (data: SelectionData | null) => void | Callback function triggered when the user selects text in the transcript. Passes SelectionData or null. |
onSeek | (time: number) => void | Callback function triggered when a user clicks a transcript segment to jump to that time in the video. |
currentTime | number | The current playback time of the video in seconds, used to highlight the active segment. |
isLoading | boolean (optional) | If true, a skeleton loader is displayed instead of the transcript content. |
Sources: components/TranscriptColumn.tsx:9-15, types.ts:1-4, 15-19
Core Functionality
Transcript Rendering and State
The component displays the transcript segments or handles various UI states based on the isLoading and segments props.
- Loading State: When
isLoadingistrue, theTranscriptSkeletoncomponent is rendered, showing an animated placeholder. - Empty State: If
isLoadingisfalseand thesegmentsarray is empty, a message "No transcript available." is shown. - Data State: When
segmentsare available, they are rendered as a list ofTranscriptSegmentItemcomponents.
Sources: components/TranscriptColumn.tsx:145-161, components/TranscriptSkeleton.tsx
Active Segment Highlighting
The component determines which transcript segment is "active" by comparing the currentTime prop with each segment's startTime and duration. The active TranscriptSegmentItem receives an isActive prop, which triggers conditional styling (a blue background and border) and automatically scrolls the segment into view.
The duration is defaulted to 5 seconds if not provided in the TranscriptSegment object.
// components/TranscriptColumn.tsx:152-153
const isActive = currentTime >= segment.startTime && currentTime < (segment.startTime + (segment.duration || 5));
Sources: components/TranscriptColumn.tsx:28-31, 35-38, 152-153
Text Selection Handling
A key feature is capturing user text selections to enable AI note generation. This is managed by a useEffect hook that adds mouseup and keyup event listeners to the document.
When a selection event occurs, the handler performs the following steps:
- Checks if the selection is within the component's container and is not collapsed.
- Trims the selected text and ensures it's at least 5 characters long.
- Gets the
DOMRectof the selection to position theFloatingActionButton. - Traverses up the DOM from the selection's anchor node to find the parent
divwith adata-timestampattribute to get thestartTime. - Calls the
onSelectionprop with aSelectionDataobject containing the text, timestamp, and rect. - If the selection is cleared, it calls
onSelection(null).
Sources: components/TranscriptColumn.tsx:93-122, App.tsx:50-63
The following sequence diagram shows the flow of this interaction:
Search Functionality
The component includes a search input that allows users to filter the transcript.
- The
searchQueryis stored in the component's local state. - A
useMemohook filters thesegmentsarray based on thesearchQuery, making the filtering process efficient. - The
filteredSegmentsare then rendered. - The
TranscriptSegmentItemcomponent takes ahighlightQueryprop and uses a regular expression to wrap matching text in a<mark>tag for visual highlighting.
Sources: components/TranscriptColumn.tsx:75-78, 137-144, 159
This flowchart demonstrates the search and rendering logic.
Video Seeking
Users can click on any TranscriptSegmentItem to navigate the video to that point.
- The
TranscriptSegmentItemhas anonClickhandler. - This handler calls the
onSeekfunction, passing the segment'sstartTime. - The
onSeekfunction is passed down from theAppcomponent, which then uses arefto thereact-youtubeplayer instance to call itsseekTomethod.
Sources: components/TranscriptColumn.tsx:32, 158, App.tsx:67-73
Conclusion
The TranscriptColumn component is a central piece of the user interface, acting as the bridge between the video's content and the user's interactions. It efficiently displays large transcripts, provides crucial interactivity for navigation and note-taking, and includes user-friendly features like search and active segment highlighting. Its design, using memoization and controlled callbacks, ensures a responsive and performant user experience.
Sources: components/TranscriptColumn.tsx, App.tsx