3.9 KiB
3.9 KiB
Video Management
User Perspective
The Videos page (/videos) is the main workspace. It displays the team's full video library in a paginated, sortable table. Users can filter by status, search by title, switch between predefined tabs, and click any video to open the editor.
Video List Features
- Tabs: All Content, Published, Private, Scheduled, Conflicts, Push Pending, Lint Issues, Deleted (conditionally shown)
- Columns: YouTube ID, Title, Privacy Status, Published Date, Lint Status, Playlists, Sync Status
- Sorting: Click column headers
- Pagination: Page size selector + prev/next
- Search: Title search via URL param
search= - Middle-click: Opens video in background tab (native anchor overlay)
- Lint status badges: OK (no badge), WARNING (amber), ERROR (pink/red)
- Sync status badges: In sync (green), Push pending (amber), Conflict (red)
Video Editor Features
The video editor (/videos/[id]) provides:
- Combined header: thumbnail, YouTube/Studio links, meta info (ID, date, privacy, sync status), lint badge, action buttons
- Sortable two-column layout: sections (Basic Info, Language, Audience & Content, Playlists, Description) can be dragged between columns. Layout persists to user preferences.
- Basic Info: title, tags (chip input), privacy status, category, scheduled publish date, recording date, game title
- Language: title/description language, video language
- Audience & Content: Made for Kids toggle, Allow Embedding toggle, License selector
- Playlists: add/remove from channel playlists via search dropdown
- Description: description block config editor (see 02 - Description Engine)
- Actions: Apply Template, Refresh from YouTube, Push to YouTube, Save Changes
- Diff view: "See what changed" shows field-level diff against last synced YouTube state
Game Title Field
gameTitle is a custom metadata field — it is not a YouTube API field and is never populated during channel import. Users enter it manually in the video editor's Basic Info section.
It serves two purposes:
- Token
{video.gameTitle}— resolves in description blocks, allowing game name to appear in descriptions automatically. - Canva search link — when
Team.showCanvaLinkis enabled in team settings, the video editor shows a "Search Canva" link that openshttps://www.canva.com/search?q={gameTitle}, helping creators find thumbnail templates for their game.
It can also be set as a template default via Template.videoFields.gameTitle, so assigning a template pre-fills the game name.
Developer Perspective
Backend
- Module:
backend/src/modules/videos/ - Key service methods:
findAll(query, teamId),findOne(id),update(id, dto),syncVideo(id),refreshFromYouTube(id),renderDescription(id) - Sync flow:
POST /videos/:id/syncenqueues ayoutube-syncBullMQ job. The processor renders description, checks hash, calls YouTube API, updateslastSyncedHashandrenderedDescription. hasPendingChanges: Computed infindAllby comparinghashMetadata(currentFields)againstlastSyncedHash. IflastSyncedHashis null, falls back to comparing against YouTube baseline usingyoutubeDescription.- Filters (
GET /videos):search,lintStatus,privacyStatus,scheduled,notScheduled,remoteConflict,pendingSync,deletedOnYouTube,hasLintIssues(matches ERROR or WARNING)
Frontend
- Pages:
frontend/src/app/(dashboard)/videos/page.tsx(list) andvideos/[id]/page.tsx(editor) - Table component:
VideoTable.tsxuses TanStack Table v8 - URL state: Tab, page, sort, and search are persisted in URL params
- Column layout persistence: Saved to
User.preferencesviaPATCH /users/me/preferencesusing keysvideoEditLeftColandvideoEditRightCol
Related
- 02 - Description Engine
- 03 - Metadata Linting
- 02 - Videos API