Saltar al contenido principal

Clips — Referencia técnica

← Volver a Clips

Dónde vive esto

Backend

Un clip no es un modelo distinto — es un Post con type: 'clip', asignado al momento de crearlo cuando el post tiene exactamente un video adjunto y ninguna imagen. No existe un tipo de GraphQL "Clip" separado; clips devuelve objetos Post normales.

Frontend

  • apps/frontend-nextjs/src/page-components/ClipsPage.tsx — el feed vertical a pantalla completa para usuarios autenticados; consulta clips, y reutiliza las mismas mutations de "me gusta"/guardar/republicar que usa PostCard.tsx (hasUserLikedPost/likePost, isPostSaved/savePost, hasUserReposted/repostPost/undoRepost)
  • apps/frontend-nextjs/src/page-components/PublicClipsPage.tsx — vista sin sesión iniciada: una cuadrícula de desplazamiento infinito con clips públicos (consulta clips, apoyándose en el filtrado publicOnly del resolver); tocar una miniatura abre PublicPostViewer, y las interacciones redirigen a /login
  • apps/frontend-nextjs/src/components/public/BrowseGate.tsx — elige entre ClipsPage y PublicClipsPage según useAuth().isAuthenticated
  • apps/frontend-nextjs/src/app/clips/page.tsx — ruta /clips; renderiza BrowseGate con ClipsPage/PublicClipsPage
  • apps/frontend-nextjs/src/components/Navigation.tsx — enlace a Clips en la barra lateral de escritorio (ClipIcon), ubicado justo después de Explorar; también es el elemento central de la barra inferior en móvil
  • apps/frontend-nextjs/src/components/PostModal.tsx — se abre desde ClipsPage.tsx para manejar los comentarios de un clip, el mismo modal que usa el feed normal
  • apps/frontend-nextjs/src/components/stories/CreateClipModal.tsx — un compositor funcional centrado en video ya construido (selector de archivos o captura vía getUserMedia/MediaRecorder, leyenda, selector de audiencia, llama a createPost). Corregido en esta sesión: antes solo lo importaba una historia de Storybook (StoriesFeature.stories.tsx), inaccesible desde cualquier página real (un botón flotante "+" anterior en ClipsPage.tsx que lo abría había sido eliminado, commit 835c2de6, "drop redundant Clips upload FAB", en favor de crear clips a través del compositor de posts normal). ClipsPage.tsx ahora lo importa directamente y lo renderiza detrás de un flag de estado showCreateClip, abierto mediante un botón flotante "Crear clip" (arriba a la derecha, ícono Plus, visible solo cuando authUser está definido)

Checklist de implementación técnica

  • Query clips — conectado de punta a punta; ClipsPage.tsx (con sesión iniciada) y PublicClipsPage.tsx (sin sesión iniciada, solo contenido público)
  • Dar / quitar "me gusta" — conectado; comparte las mutations hasUserLikedPost/likePost de PostCard.tsx
  • Guardar / quitar de guardados — conectado; comparte las mutations isPostSaved/savePost
  • Republicar / deshacer republicación — conectado; comparte las mutations hasUserReposted/repostPost/undoRepost
  • Comentar — conectado vía el PostModal.tsx compartido
  • Interfaz dedicada para crear Clips (flujo de grabación/subida con cámara) — Corregido en esta sesión: CreateClipModal.tsx está completamente construido y ahora montado en ClipsPage.tsx detrás de un botón flotante "Crear clip"; los clips también se pueden seguir produciendo con el compositor de posts normal (CreatePostModal.tsx) cuando se adjunta un solo video

Query del feed

query GetClips($limit: Int, $offset: Int) {
clips(limit: $limit, offset: $offset) {
id
text
userId
createdAt
user { id username profilePicture }
media { id mediaUrl mediaType width height }
}
}

ClipsPage.tsx sigue el mismo patrón de alternancia optimista que PostCard.tsx para "me gusta"/guardar/republicar — consulta el estado actual (hasUserLikedPost, isPostSaved, hasUserReposted) por cada clip visible y actualiza el estado local de inmediato al tocar, antes de que la mutation se resuelva.