PageSourceSearch

https://trybrain.io/assets/_authenticated.composition-OPbJPm1N.js

js trybrain.io collected 2026-09-24 15:05:46 UTC 10,478 bytes, 1 lines download raw bytes

1import{au as E,e as c,c0 as A,c1 as I,c2 as V,c3 as W,c4 as H,r as b,f as k,K as C,t as x,s as J,j as e,B as p,N as q,k as L,I as G,ay as X,aN as Y,P as Z,c5 as ee,av as se,c6 as te,aF as ae,am as K,an as M,ao as Q,ap as O,as as $,c7 as ne,ab as R,ac as P,ad as T,ae as U,af as B}from"./index-DHwBXtP2.js";import{U as le}from"./upload-D6q4E55j.js";function re(s){return new Promise(o=>{const r=URL.createObjectURL(s),i=document.createElement("video");i.preload="metadata",i.onloadedmetadata=()=>{URL.revokeObjectURL(r),o(Number.isFinite(i.duration)?Number(i.duration.toFixed(2)):null)},i.onerror=()=>{URL.revokeObjectURL(r),o(null)},i.src=r})}function ie({workspaceId:s}){const o=E(),r=c(A),i=c(I),N=c(V),u=c(W),v=c(H),h=b.useRef(null),[n,w]=b.useState({}),y=["composition-broll",s],{data:_,isLoading:S}=k({queryKey:y,queryFn:()=>r({data:{workspaceId:s}})}),d=()=>o.invalidateQueries({queryKey:y}),g=C({mutationFn:async t=>{for(const l of t){const a=await re(l),{path:m,token:z}=await i({data:{workspaceId:s,filename:l.name}}),{error:D}=await J.storage.from("composition-broll").uploadToSignedUrl(m,z,l);if(D)throw new Error(D.message);await N({data:{workspaceId:s,name:l.name.replace(/\.[^.]+$/,""),storagePath:m,durationSeconds:a}})}},onSuccess:()=>{x.success("B-roll uploaded"),d()},onError:t=>x.error(t.message)}),j=C({mutationFn:t=>u({data:{workspaceId:s,...t}}),onSuccess:d,onError:t=>x.error(t.message)}),F=C({mutationFn:t=>v({data:{workspaceId:s,id:t}}),onSuccess:()=>{x.success("Clip removed"),d()},onError:t=>x.error(t.message)}),f=_?.clips??[];return e.jsxs("section",{className:"rounded-lg border bg-card",children:[e.jsxs("header",{className:"flex flex-wrap items-center justify-between gap-3 border-b p-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"B-roll library"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Short muted clips cut over the talking head every few seconds — hides avatar jitter and keeps the frame moving. Tags are matched against the script so relevant clips get picked first."})]}),e.jsxs("div",{children:[e.jsx("input",{ref:h,type:"file",accept:"video/*",multiple:!0,className:"hidden",onChange:t=>{const l=Array.from(t.target.files??[]);l.length&&g.mutate(l),t.target.value=""}}),e.jsxs(p,{size:"sm",onClick:()=>h.current?.click(),disabled:g.isPending,children:[e.jsx(le,{className:"mr-2 h-4 w-4"}),g.isPending?"Uploading…":"Upload clips"]})]})]}),S?e.jsx("div",{className:"p-4",children:e.jsx(q,{className:"h-24 w-full"})}):f.length===0?e.jsx("p",{className:"p-6 text-center text-sm text-muted-foreground",children:"No b-roll yet. Upload 5–10 short clips (2–4s each) to start cutting away."}):e.jsx("ul",{className:"divide-y",children:f.map(t=>e.jsxs("li",{className:"flex flex-wrap items-center gap-3 p-3",children:[e.jsxs("div",{className:"min-w-40 flex-1",children:[e.jsx("p",{className:"text-sm font-medium",children:t.name}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t.duration_seconds?`${t.duration_seconds}s`:"duration unknown"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[(t.tags??[]).map(l=>e.jsxs(L,{variant:"secondary",className:"cursor-pointer",onClick:()=>j.mutate({id:t.id,tags:(t.tags??[]).filter(a=>a!==l)}),title:"Remove tag",children:[l," ×"]},l)),e.jsx(G,{value:n[t.id]??"",placeholder:"add tag",className:"h-7 w-28 text-xs",onChange:l=>w(a=>({...a,[t.id]:l.target.value})),onKeyDown:l=>{if(l.key!=="Enter")return;const a=(n[t.id]??"").trim();a&&(j.mutate({id:t.id,tags:Array.from(new Set([...t.tags??[],a]))}),w(m=>({...m,[t.id]:""})))}})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(X,{checked:t.is_active,onCheckedChange:l=>j.mutate({id:t.id,isActive:l})}),e.jsx("span",{className:"text-xs text-muted-foreground",children:t.is_active?"In rotation":"Paused"}),e.jsx(p,{size:"icon",variant:"ghost",onClick:()=>F.mutate(t.id),"aria-label":`Delete ${t.name}`,children:e.jsx(Y,{className:"h-4 w-4"})})]})]},t.id))})]})}function xe(){const s=c(Z),{data:o}=k({queryKey:["workspaces"],queryFn:()=>s({})}),r=o?.[0];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold tracking-tight",children:"Composition queue"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Shotstack composition — captions, hook overlay, music, end card. Every organic render runs through this stage when composition is enabled in Settings."})]}
1),r?.id?e.jsxs(e.Fragment,{children:[e.jsx(ie,{workspaceId:r.id}),e.jsx(oe,{workspaceId:r.id})]}):e.jsx(q,{className:"h-96 w-full"})]})}function oe({workspaceId:s}){const o=E(),r=c(ee),i=c(se),N=c(te),u=c(ae),{data:v,isLoading:h}=k({queryKey:["composition-jobs",s],queryFn:()=>r({data:{workspaceId:s}}),refetchInterval:8e3}),{data:n}=k({queryKey:["composition-templates",s],queryFn:()=>i({data:{workspaceId:s}})}),{data:w}=k({queryKey:["composition-music",s],queryFn:()=>N({data:{workspaceId:s}})}),y=C({mutationFn:a=>u({data:{workspaceId:s,jobId:a}}),onSuccess:()=>{x.success("Queued for re-render"),o.invalidateQueries({queryKey:["composition-jobs",s]})},onError:a=>x.error(a.message)}),[_,S]=b.useState(null),[d,g]=b.useState(null);if(h)return e.jsx(q,{className:"h-96 w-full"});const j=v?.jobs??[],F=n?.templates??[],f=w?.tracks??[],t=a=>a?F.find(m=>m.id===a)?.name??"—":"—",l=a=>a?f.find(m=>m.id===a)?.name??"—":f.find(m=>m.is_default)?.name??"default";return e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"border-b bg-muted/30 text-xs uppercase text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"p-3 text-left",children:"Lane"}),e.jsx("th",{className:"p-3 text-left",children:"Template"}),e.jsx("th",{className:"p-3 text-left",children:"Music"}),e.jsx("th",{className:"p-3 text-left",children:"Status"}),e.jsx("th",{className:"p-3 text-left",children:"Preview"}),e.jsx("th",{className:"p-3 text-left",children:"Created"}),e.jsx("th",{className:"p-3 text-right",children:"Actions"})]})}),e.jsx("tbody",{children:j.length===0?e.jsx("tr",{children:e.jsxs("td",{colSpan:7,className:"p-8 text-center text-muted-foreground",children:["No composition jobs yet. Enable composition in"," ",e.jsx("a",{href:"/settings/organic-video",className:"underline underline-offset-2",children:"Settings → Organic video providers"})," ","to start."]})}):j.map(a=>e.jsxs("tr",{className:"border-b",children:[e.jsx("td",{className:"p-3",children:e.jsx(L,{variant:"outline",className:"text-[10px]",children:a.lane})}),e.jsx("td",{className:"p-3",children:t(a.template_id)}),e.jsx("td",{className:"p-3",children:l(a.music_track_id)}),e.jsxs("td",{className:"p-3",children:[e.jsx(ce,{status:a.status}),a.status==="failed"&&a.error_message?e.jsx("div",{className:"mt-1 max-w-xs text-xs text-red-600",children:a.error_message}):null]}),e.jsx("td",{className:"p-3",children:a.composed_url?e.jsx(p,{size:"sm",variant:"outline",onClick:()=>g(a),children:"Preview"}):e.jsx("span",{className:"text-xs text-muted-foreground",children:"—"})}),e.jsx("td",{className:"p-3 text-xs text-muted-foreground",children:new Date(a.created_at).toLocaleString()}),e.jsx("td",{className:"p-3 text-right",children:e.jsxs("div",{className:"flex justify-end gap-2",children:[a.status==="failed"?e.jsx(p,{size:"sm",variant:"outline",disabled:y.isPending,onClick:()=>y.mutate(a.id),children:"Retry"}):null,e.jsx(p,{size:"sm",variant:"ghost",onClick:()=>S(a),children:"Recompose"})]})})]},a.id))})]}),e.jsx(de,{workspaceId:s,job:_,templates:F,tracks:f,onClose:()=>S(null),onDone:()=>o.invalidateQueries({queryKey:["composition-jobs",s]})}),e.jsx(K,{open:!!d,onOpenChange:a=>a?null:g(null),children:e.jsxs(M,{className:"max-w-md p-4 sm:max-w-lg",children:[e.jsx(Q,{children:e.jsx(O,{children:"Composed video preview"})}),d?.composed_url?e.jsx("div",{className:"flex justify-center",children:e.jsx("video",{src:d.composed_url,controls:!0,autoPlay:!0,playsInline:!0,className:"max-h-[70vh] w-auto rounded-md border bg-black"},d.id)}):null,e.jsx($,{children:d?.composed_url?e.jsx("a",{href:d.composed_url,target:"_blank",rel:"noreferrer",className:"text-xs text-muted-foreground underline underline-offset-2",children:"Open in new tab"}):null})]})})]})}function ce({status:s}){const r={queued:{label:"Queued",className:"bg-muted text-muted-foreground"},submitting:{label:"Submitting",className:"bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300"},rendering:{label:"Rendering",className:"bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-300"},succeeded:{label:"Succeeded",className:"bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-300"},failed:{label:"Failed",className:"bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-300"}}[s];return e.jsx("span",{className:`inline-flex rounded px-2 py-0.5 text-[10px] font-medium ${r.className}`,children:r.label})}function de(s){const o=c(ne),r=s.tracks.find(n=>n.is_default),[i,N]=b.useState(""),[u,v]=b.useState(""),h=C({mutationFn:async()=>
1{if(s.job)return o({data:{workspaceId:s.workspaceId,jobId:s.job.id,templateId:i||null,musicTrackId:u||(u===""?null:u)}})},onSuccess:()=>{x.success("Recomposition queued"),s.onDone(),s.onClose()},onError:n=>x.error(n.message)});return e.jsx(K,{open:!!s.job,onOpenChange:n=>n?null:s.onClose(),children:e.jsxs(M,{children:[e.jsx(Q,{children:e.jsx(O,{children:"Recompose with different template"})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"text-xs font-medium",children:"Template"}),e.jsxs(R,{value:i,onValueChange:N,children:[e.jsx(P,{children:e.jsx(T,{placeholder:"Lane default"})}),e.jsx(U,{children:s.templates.map(n=>e.jsxs(B,{value:n.id,children:[n.name," ",n.lane?`(${n.lane})`:""]},n.id))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"text-xs font-medium",children:"Music track"}),e.jsxs(R,{value:u,onValueChange:v,children:[e.jsx(P,{children:e.jsx(T,{placeholder:r?`Default: ${r.name}`:"No music"})}),e.jsx(U,{children:s.tracks.map(n=>e.jsxs(B,{value:n.id,children:[n.name," ",n.is_default?"(default)":""]},n.id))})]})]})]}),e.jsxs($,{children:[e.jsx(p,{variant:"ghost",onClick:s.onClose,children:"Cancel"}),e.jsx(p,{onClick:()=>h.mutate(),disabled:h.isPending,children:h.isPending?"Queuing…":"Recompose"})]})]})})}export{xe as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.