BDYDB
ClipBot
The team clip platform. Built for esports orgs, open to everyone.
Sign In
Team members sign in with Twitch. Individual accounts welcome — no team required.
or enter your username
Powered by bdydb-clips.pages.dev
Loading...
\s*(\d+):(\d+):(\d+)[,\.](\d+)/) if(!tm)continue; const start=parseInt(tm[1])*3600+parseInt(tm[2])*60+parseInt(tm[3])+parseInt(tm[4])/1000; const end=parseInt(tm[5])*3600+parseInt(tm[6])*60+parseInt(tm[7])+parseInt(tm[8])/1000; const text=lines.slice(2).join(" ").replace(/<[^>]+>/g,"").trim(); if(text)captions.push({start,end,text}); } return captions; } function generateCaptionsFromText(text, duration) { const words=text.split(/\s+/); const captions=[]; const wordsPerCap=6; const capDuration=2.5; for(let i=0;i{startCanvasLoop();bindEditorControls();},100); } function deleteCaption(i){ EDITOR_CAPTIONS.splice(i,1); selectedCaption=-1; renderPage(); setTimeout(()=>{startCanvasLoop();bindEditorControls();},100); } function addTextLayer(){ const text=document.getElementById("new-text-inp")?.value||"TEXT"; const size=parseInt(document.getElementById("text-size")?.value||"32"); const color=document.getElementById("text-color")?.value||"#ffffff"; const [W,H]=getCanvasSize(); EDITOR_TEXT_LAYERS.push({text,size,color,x:W/2,y:H*0.4,isEmoji:false}); toast("Text added to canvas"); renderPage(); setTimeout(()=>{startCanvasLoop();bindEditorControls();},100); } function addSticker(emoji){ const [W,H]=getCanvasSize(); EDITOR_TEXT_LAYERS.push({text:emoji,size:48,color:"#fff",x:W/2+(Math.random()-0.5)*100,y:H/3+(Math.random()-0.5)*100,isEmoji:true}); toast("Sticker added"); renderPage(); setTimeout(()=>{startCanvasLoop();bindEditorControls();},100); } function addLogoLayer(text, color){ const [W,H]=getCanvasSize(); EDITOR_TEXT_LAYERS.push({text,size:36,color,x:W/2,y:H*0.08,isEmoji:false}); toast("Logo added"); renderPage(); setTimeout(()=>{startCanvasLoop();bindEditorControls();},100); } // ── TOAST + LOG ─────────────────────────────────────────────── function toast(msg,type="success"){const tc=document.getElementById("toast-c");if(!tc)return;const el=document.createElement("div");el.className="toast t"+type[0];el.textContent=msg;tc.appendChild(el);setTimeout(()=>el.remove(),3400);} function addLog(msg){LOGS.unshift({id:Date.now(),time:new Date().toLocaleTimeString(),msg});if(LOGS.length>60)LOGS.pop();} function setProc(v){const el=document.getElementById("tb-proc");if(el)el.style.display=v?"flex":"none";} function setApiStatus(ok){const dot=document.getElementById("api-dot"),lbl=document.getElementById("api-lbl");if(dot)dot.style.background=ok?"var(--green)":"var(--muted)";if(lbl)lbl.textContent=ok?"Worker Live":"Demo";} function showSpin(v,msg){const el=document.getElementById("screen-spin");if(el)el.style.display=v?"flex":"none";const m=document.getElementById("spin-msg");if(m&&msg)m.textContent=msg;} function showErr(msg){const el=document.getElementById("lerr");if(el){el.textContent=msg;el.style.display="";}} function showScreen(name){["login","pick","request","app"].forEach(s=>{const el=s==="app"?document.getElementById("shell"):document.getElementById("screen-"+s);if(el)el.style.display=s===name?"flex":"none";});showSpin(false);} function updateBadges(){ const myC=CLIPS.filter(c=>c.login===ME?.login).length,teamC=CLIPS.length,appC=CLIPS.filter(c=>c.approved).length; const bm=document.getElementById("b-mine");if(bm){bm.textContent=myC;bm.style.display=myC?"":"none";} const bt=document.getElementById("b-team");if(bt){bt.textContent=teamC;bt.style.display=teamC?"":"none";} const bs=document.getElementById("b-sched");if(bs){bs.textContent=appC;bs.style.display=appC?"":"none";} const bv=document.getElementById("b-vods");if(bv){bv.textContent=VODS.length;bv.style.display=VODS.length?"":"none";} } function updateVodBadge(){const b=document.getElementById("b-vods");if(b){b.textContent=VODS.length;b.style.display=VODS.length?"":"none";}} function buildSidebar(){ if(!ME)return; const isTeam=!!CUR_TEAM,isAdmin=MY_ROLE==="admin"||MY_ROLE==="superAdmin",isSA=MY_ROLE==="superAdmin"; const sdot=document.getElementById("s-dot"),sname=document.getElementById("s-team-name"); if(sdot)sdot.style.background=CUR_TEAM?CUR_TEAM.col:"#9b5de5"; if(sname)sname.textContent=CUR_TEAM?CUR_TEAM.name:"Individual"; document.getElementById("n-team").style.display=isTeam?"":"none"; document.getElementById("n-tadmin").style.display=isAdmin&&isTeam?"":"none"; document.getElementById("n-sadmin").style.display=isSA?"":"none"; const bReq=document.getElementById("b-req");if(bReq&&CUR_TEAM){const n=CUR_TEAM.pendingRequests.length;bReq.textContent=n;bReq.style.display=n?"":"none";} document.getElementById("u-name").textContent=ME.display; document.getElementById("u-role-disp").innerHTML=`${MY_ROLE}`; document.getElementById("u-ava").innerHTML=ava(ME,34,"var(--red)"); document.getElementById("btn-switch").style.display=MY_TEAMS.length>1?"":"none"; const ctxLbl=document.getElementById("tb-ctx-lbl"),ctxDot=document.getElementById("tb-ctx-dot"); if(ctxLbl)ctxLbl.textContent=CUR_TEAM?CUR_TEAM.name:"Individual"; if(ctxDot)ctxDot.style.background=CUR_TEAM?CUR_TEAM.col:"#9b5de5"; const rSec=document.getElementById("s-roster-sec"),tl=document.getElementById("team-list"); if(rSec)rSec.style.display=isTeam?"":"none"; if(tl&&isTeam&&CUR_TEAM){tl.innerHTML=CUR_TEAM.members.map(m=>{const u=USERS[m.login]||{display:m.login,ini:m.login.slice(0,2).toUpperCase()};const isMe=m.login===ME.login;return`
${ava(u,26,teamColor(m.login))}
${u.display}${isMe?" ★":""}
${CLIPS.filter(c=>c.login===m.login).length} clips
`;}).join("");tl.querySelectorAll(".trow").forEach(row=>row.addEventListener("click",()=>{if(isAdmin)openPersonModal(row.dataset.login);else filterMember(row.dataset.login);}));} else if(tl)tl.innerHTML=""; } function buildPicker(){ const el=document.getElementById("picker-grid");if(!el)return; const spaces=[...MY_TEAMS.map(t=>({type:"team",team:t})),{type:"individual"}]; el.innerHTML=spaces.map(s=>{if(s.type==="individual")return`
Individual
Personal Space
Your private clip queue
`;const t=s.team,r=t.members.find(m=>m.login===ME.login)?.role||"member";return`
${t.name}
${r}
${t.members.length} members
`;}).join(""); el.querySelectorAll(".tpc").forEach(card=>{card.addEventListener("click",()=>{const pick=card.dataset.pick;if(pick==="individual")enterIndividual();else{const t=TEAMS.find(x=>x.id===pick);if(t)enterTeam(t);}});}); } function populatePublicTeams(){ const el=document.getElementById("public-teams-list");if(!el)return; const pub=TEAMS.filter(t=>t.public&&!t.members.some(m=>m.login===ME.login)); el.innerHTML=pub.length?pub.map(t=>`
${t.tag.slice(0,2)}
${t.name}
${t.members.length} members
`).join(""):`
No public teams available.
`; el.querySelectorAll("[data-rtid]").forEach(btn=>btn.addEventListener("click",()=>requestTeam(btn.dataset.rtid))); document.getElementById("btn-use-code")?.addEventListener("click",()=>{const code=(document.getElementById("team-code-inp")?.value||"").trim();const e=document.getElementById("req-err");if(!code){e.textContent="Enter a code.";e.style.display="";return;}useInviteCode(code,null);}); } function showTeamPicker(){MY_TEAMS=TEAMS.filter(t=>t.members.some(m=>m.login===ME.login));showScreen("pick");buildPicker();} // ── INIT ───────────────────────────────────────────────────── document.getElementById("btn-twitch").addEventListener("click",()=>window.location.href=AUTH_URL); document.getElementById("btn-dev").addEventListener("click",()=>devLogin(document.getElementById("dev-user").value)); document.getElementById("dev-user").addEventListener("keydown",e=>{if(e.key==="Enter")devLogin(document.getElementById("dev-user").value);}); document.getElementById("btn-go-individual").addEventListener("click",()=>enterIndividual()); document.getElementById("btn-out").addEventListener("click",signOut); document.getElementById("btn-out-pick").addEventListener("click",signOut); document.getElementById("btn-out-req").addEventListener("click",signOut); document.getElementById("btn-switch").addEventListener("click",showTeamPicker); document.querySelectorAll(".nitem[data-p]").forEach(el=>el.addEventListener("click",()=>nav(el.dataset.p))); ["m1-ov","m2-ov","m3-ov"].forEach(id=>{document.getElementById(id)?.addEventListener("click",e=>{if(e.target===e.currentTarget)document.getElementById(id).classList.remove("open");});}); function signOut(){ME=null;TOKEN=null;CUR_TEAM=null;MY_ROLE=null;MY_TEAMS=[];CLIPS=[];VODS=[];LOGS=[];API_OK=false;EDITOR_CLIP=null;stopCanvasLoop();if(REFRESH_INT)clearInterval(REFRESH_INT);showScreen("login");setApiStatus(false);document.getElementById("dev-user").value="";} if(checkOAuth()){loginWithToken(TOKEN);}