Files

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:

  1. Token {video.gameTitle} — resolves in description blocks, allowing game name to appear in descriptions automatically.
  2. Canva search link — when Team.showCanvaLink is enabled in team settings, the video editor shows a "Search Canva" link that opens https://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/sync enqueues a youtube-sync BullMQ job. The processor renders description, checks hash, calls YouTube API, updates lastSyncedHash and renderedDescription.
  • hasPendingChanges: Computed in findAll by comparing hashMetadata(currentFields) against lastSyncedHash. If lastSyncedHash is null, falls back to comparing against YouTube baseline using youtubeDescription.
  • 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) and videos/[id]/page.tsx (editor)
  • Table component: VideoTable.tsx uses TanStack Table v8
  • URL state: Tab, page, sort, and search are persisted in URL params
  • Column layout persistence: Saved to User.preferences via PATCH /users/me/preferences using keys videoEditLeftCol and videoEditRightCol
  • 02 - Description Engine
  • 03 - Metadata Linting
  • 02 - Videos API