Component Library
Relevant source files
The following files were used as context for generating this wiki page:The youtube_notes component library is a collection of reusable React components, written in TypeScript and styled with Tailwind CSS, that constitute the entire frontend user interface. These components are designed to be modular and manage specific pieces of UI logic, from user input and data display to contextual actions and settings management. The library follows a dark-themed, modern aesthetic defined in index.html and tailwind.config.
The core of the application is structured within the App.tsx component, which orchestrates the main layout and state management, composing various smaller components to create a cohesive user experience. The components interact through props and callbacks to handle events, manage application state, and display data fetched from services.
Core Architectural Components
The application's UI is built around a few primary components that define the main layout and functionality.
Sources: App.tsx
App.tsx - The Root Component
App.tsx serves as the main entry point for the UI. It manages the top-level state, including the current videoId, user selections, and the open/closed state of the settings modal. It composes the primary layout sections: Header, a central content area for the video player, and a side panel containing the TranscriptColumn and SmartBoard.
The following diagram illustrates the high-level component hierarchy orchestrated by App.tsx.
Sources: App.tsx:13-205
Header.tsx
The Header component is the main navigation and action bar at the top of the application. Its primary responsibilities are:
- Displaying the application title "TLDW Margin Notes".
- Providing an input field for users to paste a YouTube URL.
- Handling URL submission, extracting the video ID, and triggering the video loading process via the
onVideoLoadcallback. - Offering a button to open the settings modal for API key configuration.
The URL input includes a "Paste from clipboard" button and displays a loading spinner when a video is being loaded.
The user flow for loading a video is as follows:
Sources: components/Header.tsx:16-70
SmartBoard.tsx
The SmartBoard is a multi-tabbed component that serves as the primary dashboard for displaying all AI-generated content and user notes. It uses a TabButton sub-component to switch between different content views.
The available tabs are:
- Takeaways: Displays a list of key takeaways with emojis.
- Thread: Shows a preview of a generated Twitter thread and provides a button to open the full
ThreadModal. - LinkedIn: Renders a formatted LinkedIn post with a hook, body, CTA, and hashtags.
- Blog: Presents a blog post outline with a title, SEO keywords, and section-based bullet points.
- Notes: Lists all user-generated
NoteCardcomponents.
The component shows loading indicators for each content type while generation is in progress, managed by the progress prop.
The internal structure of the SmartBoard is shown below.
Sources: components/SmartBoard.tsx:29-301
Interactive & Contextual Components
These components respond directly to user actions within the application, providing contextual UI elements.
FloatingActionButton.tsx
This component appears when a user selects text in the transcript. It is a small button with the text "Clean & Note" that hovers near the selected text.
Key Features:
- Visibility: It is only rendered when the
visibleprop istrue, which is controlled by theselectionstate inApp.tsx. - Positioning: Its position is dynamically calculated based on the
DOMRectof the user's text selection. - Action: Clicking the button triggers the
onAnalyzecallback, which initiates the process of cleaning the selected text and creating a note.
NoteCard.tsx
The NoteCard component is responsible for displaying a single note within the "Notes" tab of the SmartBoard. Each card represents a summary generated from a transcript selection.
| Prop | Type | Description |
|---|---|---|
note | Note | The note object containing text, timestamp, etc. |
onDelete | (id: string) => void | Callback to delete the note. |
onJumpToTime | (time: number) => void | Callback to seek the video player to the note's timestamp. |
The card displays the cleaned text, the timestamp (which is also a button to seek the video), and action buttons for copying the note text and deleting the note. These actions become visible on hover.
Sources: components/NoteCard.tsx:8-79
ThreadModal.tsx
This modal component is used to display the full content of a generated Twitter thread.
Functionality:
- It is controlled by the
isOpenprop. - It displays each tweet in a numbered list.
- It provides a button to copy each individual tweet.
- It includes a "Copy Full Thread" button in the footer to copy all tweets, formatted for easy pasting into Twitter.
- It shows a character count for each tweet, highlighting if it exceeds the recommended limit.
Sources: components/ThreadModal.tsx:9-101
Data Display and Layout Components
These components are primarily concerned with displaying data and structuring content.
TranscriptColumn.tsx
This component displays the video transcript as a scrollable list of segments.
Key Features:
- Segment Rendering: Each transcript segment is rendered by a memoized
TranscriptSegmentItemcomponent. - Active Segment Highlighting: The segment corresponding to the video's
currentTimeis highlighted. - Seeking: Clicking on any transcript segment seeks the video to that segment's
startTime. - Text Selection: It listens for
mouseupandkeyupevents to detect when the user has selected text. When a selection is made, it calls theonSelectionprop with the selected text, its start time, and its position on the screen. - Search: A search input allows users to filter the transcript segments. Matched text within segments is highlighted.
Sources: components/TranscriptColumn.tsx:12-169
Settings Modal
The settings modal, defined within Header.tsx, allows users to configure their Gemini API key.
Functionality:
- It opens when the settings icon in the header is clicked.
- It provides an input field for the API key.
- It includes a "Test Key" button that calls
validateApiKeyto verify the key's validity. - The "Save Changes" button persists the key to local storage using
setApiKey. - Visual feedback is provided for valid or invalid keys.
Sources: components/Header.tsx:73-181