diff --git a/server/public/assets/index-dT4ud4zG.js b/server/public/assets/index-Di-AJuYD.js similarity index 99% rename from server/public/assets/index-dT4ud4zG.js rename to server/public/assets/index-Di-AJuYD.js index 8a6d54f9..3ea32650 100644 --- a/server/public/assets/index-dT4ud4zG.js +++ b/server/public/assets/index-Di-AJuYD.js @@ -116,4 +116,4 @@ wine wok yeast yogurt -`;function IA(a){return a?a.charAt(0).toUpperCase()+a.slice(1):""}function PA(){const a=String(WA).split(/\r?\n/).map(i=>i.trim()).filter(Boolean);return a.length?(a[Math.floor(Math.random()*a.length)]||"").trim():""}function uf(){const{setNickname:a}=De(),{value:s,status:i,save:r}=ct("profile",{nickname:""}),f=g.useRef(!1);g.useEffect(()=>{if(i!=="ready"||f.current||(s.nickname||"").trim())return;f.current=!0;const p=IA(PA()).slice(0,32);if(!p)return;(async()=>{try{await a(p)}catch{}finally{r({nickname:p})}})()},[r,a,i,s.nickname])}const cu=1e4,uu=28,ej=14;function ff({layout:a="desktop",className:s=""}){const{session:i}=De(),r=i?.communityGoal?.text?String(i.communityGoal.text).trim():"",f=a==="mobile-portrait"||a==="mobile-landscape"||a==="mobile",[d,p]=g.useState(!1),[m,y]=g.useState(uu),[v,S]=g.useState(0),b=g.useRef(null),M=g.useRef(null),j=g.useRef(null);g.useEffect(()=>{if(!r){p(!1);return}if(p(!0),!f)return;const A=Date.now();S(cu);const E=setTimeout(()=>p(!1),cu),w=setInterval(()=>{const O=Date.now()-A;S(Math.max(0,cu-O))},250);return()=>{clearTimeout(E),clearInterval(w)}},[r,f]),g.useEffect(()=>{if(!r)return;y(uu);let A=0;const E=()=>{const O=j.current,J=M.current;if(!O||!J)return;const Q=O.clientWidth;if(!Q)return;const H=J.scrollWidth;if(!H)return;const B=Math.min(1,Q/H),F=Math.max(ej,Math.floor(uu*B));y(F)};A=window.requestAnimationFrame(E);const w=new ResizeObserver(()=>{window.cancelAnimationFrame(A),A=window.requestAnimationFrame(E)});return b.current&&w.observe(b.current),()=>{window.cancelAnimationFrame(A),w.disconnect()}},[r]);const N=g.useMemo(()=>["panel-section flex w-full items-center justify-center",f?"rounded-none":"rounded","px-1 py-1 text-center font-semibold tracking-tight",s].filter(Boolean).join(" "),[s,f]);if(!r||!d)return null;const T=f?Math.ceil(v/1e3):null;return c.jsx("div",{ref:b,className:N,style:{fontSize:`${m}px`,lineHeight:1.1},onClick:()=>p(!1),role:"button",tabIndex:0,children:c.jsxs("span",{className:"flex w-full items-stretch gap-0.5 whitespace-nowrap",children:[c.jsxs("span",{className:"flex flex-col justify-center border-r border-slate-700/60 px-0.5 text-[0.55em] font-semibold leading-tight text-slate-400",children:[c.jsx("span",{children:"Community"}),c.jsx("span",{children:"Goal"})]}),c.jsx("span",{ref:j,className:"flex-1 overflow-hidden text-slate-100",children:c.jsx("span",{ref:M,className:"block",children:r})}),f?c.jsxs("span",{className:"flex items-center border-l border-slate-700/60 px-0.5 text-[0.55em] font-semibold uppercase tracking-wide text-slate-400",children:[T,"s"]}):null]})})}function tj(){const[a,s]=g.useState(()=>typeof window>"u"||window.innerWidth>=1024?"desktop":window.innerWidth>window.innerHeight?"mobile-landscape":"mobile-portrait");return g.useEffect(()=>{function i(){if(typeof window>"u")return;const{innerWidth:r,innerHeight:f}=window;r>=1024?s("desktop"):r>f?s("mobile-landscape"):s("mobile-portrait")}return i(),window.addEventListener("resize",i),()=>window.removeEventListener("resize",i)},[]),a}function nj({layout:a,onOpenHelpOverlay:s}){return c.jsxs("div",{className:"flex h-full gap-0.5 overflow-hidden",children:[c.jsxs("div",{className:"flex min-w-0 flex-[1.8] flex-col gap-0.5 overflow-y-auto pr-0.5",children:[c.jsx(tf,{}),c.jsxs("div",{className:"grid h-52 grid-cols-2 gap-0.5",children:[c.jsx("div",{className:"h-full min-h-0",children:c.jsx(cf,{fillHeight:!0})}),c.jsx("div",{className:"h-full min-h-0",children:c.jsx(Ds,{fillHeight:!0})})]}),c.jsx(Fu,{})]}),c.jsxs("div",{className:"flex min-w-0 flex-1 flex-col gap-0.5 overflow-y-auto",children:[c.jsx(ff,{layout:a}),c.jsx(kA,{layout:a,onOpenHelpOverlay:s})]})]})}function bg({layout:a,onOpenHelpOverlay:s,roomPanelId:i,showTelemetry:r=!0}){return c.jsx("section",{className:"panel text-base",children:c.jsxs(sf,{defaultTab:"chat",children:[c.jsxs(rf,{children:[c.jsx(Jt,{id:"chat",children:"Chat"}),c.jsx(Jt,{id:"roomcontrols",children:"Room Controls"}),c.jsx(Jt,{id:"help",children:"Help"}),c.jsx(Jt,{id:"settings",children:"Settings"})]}),c.jsxs(of,{children:[c.jsx(Ft,{id:"chat",children:c.jsxs("div",{className:"space-y-0.5",children:[c.jsx(Ds,{}),c.jsx(cf,{})]})}),c.jsx(Ft,{id:"roomcontrols",children:c.jsxs("div",{className:"space-y-0.5",children:[c.jsx(og,{}),c.jsx(Ju,{panelId:i})]})}),c.jsx(Ft,{id:"help",children:c.jsx(gg,{layout:a,onOpenOverlay:s})}),c.jsx(Ft,{id:"settings",children:c.jsxs("div",{className:"space-y-0.5",children:[c.jsx(hg,{}),c.jsx(Fu,{})]})})]})]})})}function aj({onOpenHelpOverlay:a}){return c.jsxs("div",{className:"flex flex-col gap-0.5",children:[c.jsx(tf,{layoutFormat:"mobile-portrait"}),c.jsx(zS,{}),c.jsxs("div",{className:"grid gap-0.5 grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]",children:[c.jsx(Ku,{panelId:"replay-sources-mobile-portrait"}),c.jsx($u,{})]}),c.jsx(bg,{layout:"mobile-portrait",onOpenHelpOverlay:a,roomPanelId:"mobile-portrait-room"})]})}function lj({onOpenHelpOverlay:a}){return c.jsxs("div",{className:"flex flex-col gap-0.5",children:[c.jsxs("section",{className:"grid min-h-screen grid-cols-[minmax(0,0.7fr)_minmax(0,2.1fr)_minmax(0,0.7fr)] gap-0.5",children:[c.jsx(OS,{}),c.jsxs("div",{children:[c.jsx(tf,{layoutFormat:"mobile-landscape"}),c.jsxs("div",{className:"grid gap-0.5 grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]",children:[c.jsx(Ku,{panelId:"replay-sources-mobile-landscape"}),c.jsx($u,{})]})]}),c.jsx(DS,{})]}),c.jsx("div",{className:"flex flex-col gap-0.5 pb-0.5",children:c.jsx(bg,{layout:"mobile-landscape",onOpenHelpOverlay:a,roomPanelId:"mobile-landscape-room",showTelemetry:!1})})]})}function sj(){const a=tj(),s=a==="desktop",i=JA(a);return c.jsx("div",{className:`bg-black text-slate-100 ${s?"h-screen overflow-hidden":"min-h-screen"}`,children:c.jsx(Hu,{children:c.jsx(ij,{layout:a,isDesktop:s,fullscreen:i})})})}function ij({layout:a,isDesktop:s,fullscreen:i}){uf();const{visible:r,mode:f,enterFullscreen:d,dismiss:p}=i,{value:m,status:y,save:v}=ct("help",{showOnLoad:!0}),[S,b]=g.useState(!1);g.useEffect(()=>{y==="ready"&&b(m?.showOnLoad!==!1)},[y,m?.showOnLoad]);const M=g.useCallback(()=>b(!0),[]),j=g.useCallback(()=>b(!1),[]),N=g.useCallback(A=>{const E=!!A;v(w=>({...w??{},showOnLoad:E})),E||b(!1)},[v]),T=g.useMemo(()=>s?c.jsx(nj,{layout:a,onOpenHelpOverlay:M}):a==="mobile-landscape"?c.jsx(lj,{onOpenHelpOverlay:M}):c.jsx(aj,{onOpenHelpOverlay:M}),[s,a,M]);return c.jsxs(X1,{children:[c.jsx(eS,{}),c.jsx(tS,{}),c.jsxs("main",{className:`flex w-full flex-col gap-0.5 text-base ${s?"h-full overflow-hidden":""}`,children:[s?null:c.jsx(ff,{layout:a}),T]}),c.jsx(Zu,{}),c.jsx(YA,{}),c.jsx(UA,{}),c.jsx(FA,{visible:S,layout:a,onClose:j,showOnLoad:m?.showOnLoad!==!1,onToggleShowOnLoad:N}),c.jsx(QA,{visible:r,mode:f,onEnterFullscreen:d,onDismiss:p})]})}function Sg(){const{session:a,setRole:s,subscribeAll:i,connected:r}=De(),[f,d]=g.useState(!1);return g.useEffect(()=>{let p=!1;async function m(){if(a?.mode==="lockdown"){d(!1);return}try{a?.role!=="spectator"&&await s("spectator"),await i(),p||d(!0)}catch(y){console.error("Failed to enter spectator mode",y),p||d(!1)}}return m(),()=>{p=!0}},[r,a?.mode,a?.role,s,i]),f}function rj({roverId:a,session:s}){const i=s?.activeDrivers?.[a]||null,f=(s?.users||[]).find(y=>y.socketId===i)?.nickname||(i?i.slice(0,6):"No driver"),d=s?.mode,p=s?.turnQueues?.[a];return d==="turns"&&p?.current?`${f} (turns)`:f}function oj({rover:a,frame:s,snapshotFeed:i,audioInfo:r,session:f}){const d=rj({roverId:a.id,session:f});return c.jsx("article",{className:"min-h-[16rem] rounded bg-zinc-900 p-0.5 sm:min-h-[18rem]",children:c.jsx("div",{className:"min-h-0 overflow-hidden rounded bg-black/20",children:c.jsx(ef,{sessionInfo:null,videoMode:"snapshot",snapshotFeed:i,audioSessionInfo:r,label:a.name,telemetryFrame:s,batteryConfig:a.battery,hudVariant:"spectator",driverLabel:d,hudForceMap:!0,hudMapPosition:"bottom-left"})})})}function cj({roster:a,frames:s,snapshotFeeds:i,audioSources:r,session:f}){return a.length===0?c.jsx("p",{className:"col-span-full text-slate-400",children:"No rovers registered."}):c.jsx("section",{className:"grid grid-cols-1 gap-0.5 md:grid-cols-2",children:a.map(d=>c.jsx(oj,{rover:d,frame:s[d.id],snapshotFeed:i[d.id],audioInfo:r[`${d.id}-audio`],session:f,showHudMap:!0,hudMapPosition:"bottom-left"},d.id))})}function uj(){return c.jsx("section",{className:"min-h-0",children:c.jsx("div",{className:"surface min-h-[14rem] overflow-hidden",children:c.jsx(Ju,{defaultOrientation:"horizontal",hideLayoutToggle:!0,hideHeader:!0,panelId:"spectator-secondary"})})})}function fj({className:a=""}){return c.jsx("div",{className:`panel ${a}`,children:c.jsx(Fu,{})})}function dj(){const{session:a}=De(),s=a?.mode==="lockdown";uf(),Sg();const i=Lu(),r=a?.roster??[],f=Iu(r.map(m=>m.id),{enabled:!s,version:a?.mode}),d=r.flatMap(m=>m.media?.audioPublishUrl?[{type:"rover",id:`${m.id}-audio`,key:`${m.id}-audio`}]:[]),p=Wu(d,{enabled:!s,version:a?.mode});return s?c.jsx("div",{className:"flex min-h-screen items-center justify-center bg-black text-slate-200",children:c.jsxs("div",{className:"surface max-w-md space-y-0.5 p-1 text-center text-sm",children:[c.jsx("p",{className:"text-lg font-semibold text-white",children:"Spectate disabled during lockdown."}),c.jsx("p",{className:"text-slate-300",children:"Please wait until the server leaves lockdown to view streams."})]})}):c.jsxs("div",{className:"min-h-screen bg-black text-slate-100 md:h-screen md:overflow-hidden",children:[c.jsxs("main",{className:"grid min-h-screen grid-cols-1 gap-0.5 p-0.5 md:h-full md:min-h-0 md:grid-cols-[minmax(0,1fr)_18rem] lg:grid-cols-[minmax(0,1fr)_20rem]",children:[c.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col gap-0.5 md:overflow-y-auto",children:[c.jsx(cj,{roster:r,frames:i,snapshotFeeds:f,audioSources:p,session:a}),c.jsx(uj,{})]}),c.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col gap-0.5 md:h-full",children:[c.jsx(ff,{layout:"desktop"}),c.jsx("div",{className:"panel",children:c.jsx(Xu,{roster:r,title:"Rovers",emptyText:"No rovers registered."})}),c.jsx("div",{className:"min-h-0 min-w-0 flex-1 overflow-hidden",children:c.jsx(cf,{hideNicknameForm:!0,hideHeader:!0,fillHeight:!0,className:"h-full"})}),c.jsx("div",{className:"min-h-0 min-w-0 flex-[1.1] overflow-hidden",children:c.jsx(Ds,{hideInput:!0,hideSpectatorNotice:!0,fillHeight:!0})}),c.jsx("div",{className:"min-h-0 min-w-0",children:c.jsx(fj,{className:"h-40 overflow-hidden"})})]})]}),c.jsx(Zu,{})]})}function hj(){return c.jsx(Hu,{children:c.jsx(dj,{})})}const mj=2e4,pj=10800*1e3;function gj({roverId:a,session:s}){const i=s?.activeDrivers?.[a]||null,f=(s?.users||[]).find(m=>m.socketId===i)?.nickname||(i?i.slice(0,6):"No driver"),d=s?.mode,p=s?.turnQueues?.[a];return d==="turns"&&p?.current?`${f} (turns)`:f}function yj(){const{session:a}=De(),s=Sg();uf();const i=a?.mode==="lockdown",r=Lu(),f=a?.roster??[],[d,p]=g.useState(0),m=a?.activeDrivers||{},y=g.useMemo(()=>f.filter(Q=>m[Q.id]),[f,m]),v=Iu(y.map(Q=>Q.id),{enabled:!i,version:a?.mode}),S=g.useMemo(()=>y.flatMap(Q=>{if(!Q?.id||!Q.media?.audioPublishUrl)return[];const H=String(Q.id);return[{type:"rover",id:`${H}-audio`,key:`${H}-audio`}]}),[y]),b=Wu(S,{enabled:!i,version:a?.mode}),M=g.useMemo(()=>{if(!y.length)return[];const Q=y.filter(H=>v[H.id]?.objectUrl);return Q.length?Q:y},[y,v]),j=g.useMemo(()=>M.map(Q=>({type:"rover",rover:Q})),[M]),N=g.useMemo(()=>j.map(Q=>`r:${Q.rover.id}`).join("|"),[j]);g.useEffect(()=>{p(0)},[N]),g.useEffect(()=>{if(!j.length)return;const Q=setInterval(()=>{p(H=>(H+1)%j.length)},mj);return()=>clearInterval(Q)},[j.length,N]);const T=j.length?j[d%j.length]:null,A=T?.type==="rover"?T.rover:null,E=A&&v[A.id]||null,w=A&&b[`${A.id}-audio`]||null,O=A&&r[A.id]||null,J=A?gj({roverId:A.id,session:a}):null;return i?c.jsx("div",{className:"relative flex h-screen w-screen items-center justify-center bg-black text-slate-200",children:c.jsxs("div",{className:"surface max-w-sm space-y-0.5 p-1 text-center text-sm",children:[c.jsx("p",{className:"text-lg font-semibold text-white",children:"Mini spectator is disabled in lockdown."}),c.jsx("p",{className:"text-slate-300",children:"It will automatically resume once lockdown ends."})]})}):c.jsxs("div",{className:"relative h-screen w-screen overflow-hidden bg-black p-0.5 text-slate-100 flex flex-col gap-0.5",children:[c.jsx(xj,{}),c.jsx("section",{className:"panel relative flex min-h-0 flex-1 overflow-hidden",children:s?A?c.jsx(bj,{children:c.jsx(ef,{sessionInfo:null,videoMode:"snapshot",snapshotFeed:E,audioSessionInfo:w,label:A.name||A.id,telemetryFrame:O,batteryConfig:A.battery,layoutFormat:"mobile",hudVariant:"spectator",driverLabel:J,hudLabelScale:3,hudForceMap:!0,hudMapPosition:"bottom-left",fitParent:!0})}):c.jsx("div",{className:"flex h-full w-full items-center justify-center text-sm text-slate-500",children:y.length?"No sources available.":"No active drivers."}):c.jsx("div",{className:"flex h-full w-full items-center justify-center text-sm text-slate-500",children:"Switching to spectator…"})})]})}function vj(){return g.useEffect(()=>{if(typeof window>"u")return;const a=setTimeout(()=>{const s=new URL(window.location.href);s.searchParams.set("refresh",Date.now().toString()),window.location.replace(s.toString())},pj);return()=>clearTimeout(a)},[]),c.jsx(Hu,{children:c.jsxs(c.Fragment,{children:[c.jsx(yj,{}),c.jsx(Zu,{scale:3})]})})}function xj(){return c.jsx("div",{className:"pointer-events-none absolute left-1/2 top-1 z-30",style:{transform:"translate(-50%, 0) scale(0.7)",transformOrigin:"top center"},children:c.jsx("div",{className:"pointer-events-none overflow-hidden rounded-md",style:{width:"50vw",minWidth:"16rem",maxWidth:"24rem",opacity:.55,maxHeight:"12rem"},children:c.jsx(Ds,{hideInput:!0,hideSpectatorNotice:!0})})})}function bj({children:a}){return c.jsx("div",{className:"flex h-full w-full items-center justify-center overflow-hidden bg-black",children:c.jsx("div",{className:"relative flex items-center justify-center overflow-hidden bg-black",style:{width:"min(100%, calc(100vh * 16 / 9))",height:"min(100%, calc(100vw * 9 / 16))",maxWidth:"100%",maxHeight:"100%",aspectRatio:"16 / 9"},children:c.jsx("div",{className:"flex h-full w-full items-center justify-center overflow-hidden",children:a})})})}Fv.createRoot(document.getElementById("root")).render(c.jsx(g.StrictMode,{children:c.jsx(x1,{children:c.jsx(S1,{children:c.jsx(A1,{children:c.jsx($1,{children:c.jsx(fb,{children:c.jsxs(Yx,{children:[c.jsx(rr,{path:"/",element:c.jsx(sj,{})}),c.jsx(rr,{path:"/spectate",element:c.jsx(hj,{})}),c.jsx(rr,{path:"/mini",element:c.jsx(vj,{})})]})})})})})})})); +`;function IA(a){return a?a.charAt(0).toUpperCase()+a.slice(1):""}function PA(){const a=String(WA).split(/\r?\n/).map(i=>i.trim()).filter(Boolean);return a.length?(a[Math.floor(Math.random()*a.length)]||"").trim():""}function uf(){const{setNickname:a}=De(),{value:s,status:i,save:r}=ct("profile",{nickname:""}),f=g.useRef(!1);g.useEffect(()=>{if(i!=="ready"||f.current||(s.nickname||"").trim())return;f.current=!0;const p=IA(PA()).slice(0,32);if(!p)return;(async()=>{try{await a(p)}catch{}finally{r({nickname:p})}})()},[r,a,i,s.nickname])}const cu=1e4,uu=28,ej=14;function ff({layout:a="desktop",className:s=""}){const{session:i}=De(),r=i?.communityGoal?.text?String(i.communityGoal.text).trim():"",f=a==="mobile-portrait"||a==="mobile-landscape"||a==="mobile",[d,p]=g.useState(!1),[m,y]=g.useState(uu),[v,S]=g.useState(0),b=g.useRef(null),M=g.useRef(null),j=g.useRef(null);g.useEffect(()=>{if(!r){p(!1);return}if(p(!0),!f)return;const A=Date.now();S(cu);const E=setTimeout(()=>p(!1),cu),w=setInterval(()=>{const O=Date.now()-A;S(Math.max(0,cu-O))},250);return()=>{clearTimeout(E),clearInterval(w)}},[r,f]),g.useEffect(()=>{if(!r)return;y(uu);let A=0;const E=()=>{const O=j.current,J=M.current;if(!O||!J)return;const Q=O.clientWidth;if(!Q)return;const H=J.scrollWidth;if(!H)return;const B=Math.min(1,Q/H),F=Math.max(ej,Math.floor(uu*B));y(F)};A=window.requestAnimationFrame(E);const w=new ResizeObserver(()=>{window.cancelAnimationFrame(A),A=window.requestAnimationFrame(E)});return b.current&&w.observe(b.current),()=>{window.cancelAnimationFrame(A),w.disconnect()}},[r]);const N=g.useMemo(()=>["panel-section flex w-full items-center justify-center",f?"rounded-none":"rounded","px-1 py-1 text-center font-semibold tracking-tight",s].filter(Boolean).join(" "),[s,f]);if(!r||!d)return null;const T=f?Math.ceil(v/1e3):null;return c.jsx("div",{ref:b,className:N,style:{fontSize:`${m}px`,lineHeight:1.1},onClick:()=>p(!1),role:"button",tabIndex:0,children:c.jsxs("span",{className:"flex w-full items-stretch gap-0.5 whitespace-nowrap",children:[c.jsxs("span",{className:"flex flex-col justify-center border-r border-slate-700/60 px-0.5 text-[0.55em] font-semibold leading-tight text-slate-400",children:[c.jsx("span",{children:"Community"}),c.jsx("span",{children:"Goal"})]}),c.jsx("span",{ref:j,className:"flex-1 overflow-hidden text-slate-100",children:c.jsx("span",{ref:M,className:"block",children:r})}),f?c.jsxs("span",{className:"flex items-center border-l border-slate-700/60 px-0.5 text-[0.55em] font-semibold uppercase tracking-wide text-slate-400",children:[T,"s"]}):null]})})}function tj(){const[a,s]=g.useState(()=>typeof window>"u"||window.innerWidth>=1024?"desktop":window.innerWidth>window.innerHeight?"mobile-landscape":"mobile-portrait");return g.useEffect(()=>{function i(){if(typeof window>"u")return;const{innerWidth:r,innerHeight:f}=window;r>=1024?s("desktop"):r>f?s("mobile-landscape"):s("mobile-portrait")}return i(),window.addEventListener("resize",i),()=>window.removeEventListener("resize",i)},[]),a}function nj({layout:a,onOpenHelpOverlay:s}){return c.jsxs("div",{className:"flex h-full gap-0.5 overflow-hidden",children:[c.jsxs("div",{className:"flex min-w-0 flex-[1.8] flex-col gap-0.5 overflow-y-auto pr-0.5",children:[c.jsx(tf,{}),c.jsxs("div",{className:"grid h-52 grid-cols-2 gap-0.5",children:[c.jsx("div",{className:"h-full min-h-0",children:c.jsx(cf,{fillHeight:!0})}),c.jsx("div",{className:"h-full min-h-0",children:c.jsx(Ds,{fillHeight:!0})})]}),c.jsx(Fu,{})]}),c.jsxs("div",{className:"flex min-w-0 flex-1 flex-col gap-0.5 overflow-y-auto",children:[c.jsx(ff,{layout:a}),c.jsx(kA,{layout:a,onOpenHelpOverlay:s})]})]})}function bg({layout:a,onOpenHelpOverlay:s,roomPanelId:i,showTelemetry:r=!0}){return c.jsx("section",{className:"panel text-base",children:c.jsxs(sf,{defaultTab:"chat",children:[c.jsxs(rf,{children:[c.jsx(Jt,{id:"chat",children:"Chat"}),c.jsx(Jt,{id:"roomcontrols",children:"Room Controls"}),c.jsx(Jt,{id:"help",children:"Help"}),c.jsx(Jt,{id:"settings",children:"Settings"})]}),c.jsxs(of,{children:[c.jsx(Ft,{id:"chat",children:c.jsxs("div",{className:"space-y-0.5",children:[c.jsx(Ds,{}),c.jsx(cf,{})]})}),c.jsx(Ft,{id:"roomcontrols",children:c.jsxs("div",{className:"space-y-0.5",children:[c.jsx(og,{}),c.jsx(Ju,{panelId:i})]})}),c.jsx(Ft,{id:"help",children:c.jsx(gg,{layout:a,onOpenOverlay:s})}),c.jsx(Ft,{id:"settings",children:c.jsxs("div",{className:"space-y-0.5",children:[c.jsx(hg,{}),c.jsx(Fu,{})]})})]})]})})}function aj({onOpenHelpOverlay:a}){return c.jsxs("div",{className:"flex flex-col gap-0.5",children:[c.jsx(tf,{layoutFormat:"mobile-portrait"}),c.jsx(zS,{}),c.jsxs("div",{className:"grid gap-0.5 grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]",children:[c.jsx(Ku,{panelId:"replay-sources-mobile-portrait"}),c.jsx($u,{})]}),c.jsx(bg,{layout:"mobile-portrait",onOpenHelpOverlay:a,roomPanelId:"mobile-portrait-room"})]})}function lj({onOpenHelpOverlay:a}){return c.jsxs("div",{className:"flex flex-col gap-0.5",children:[c.jsxs("section",{className:"grid min-h-screen grid-cols-[minmax(0,0.7fr)_minmax(0,2.1fr)_minmax(0,0.7fr)] gap-0.5",children:[c.jsx(OS,{}),c.jsxs("div",{children:[c.jsx(tf,{layoutFormat:"mobile-landscape"}),c.jsxs("div",{className:"grid gap-0.5 grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]",children:[c.jsx(Ku,{panelId:"replay-sources-mobile-landscape"}),c.jsx($u,{})]})]}),c.jsx(DS,{})]}),c.jsx("div",{className:"flex flex-col gap-0.5 pb-0.5",children:c.jsx(bg,{layout:"mobile-landscape",onOpenHelpOverlay:a,roomPanelId:"mobile-landscape-room",showTelemetry:!1})})]})}function sj(){const a=tj(),s=a==="desktop",i=JA(a);return c.jsx("div",{className:`bg-black text-slate-100 ${s?"h-screen overflow-hidden":"min-h-screen"}`,children:c.jsx(Hu,{children:c.jsx(ij,{layout:a,isDesktop:s,fullscreen:i})})})}function ij({layout:a,isDesktop:s,fullscreen:i}){uf();const{visible:r,mode:f,enterFullscreen:d,dismiss:p}=i,{value:m,status:y,save:v}=ct("help",{showOnLoad:!0}),[S,b]=g.useState(!1);g.useEffect(()=>{y==="ready"&&b(m?.showOnLoad!==!1)},[y,m?.showOnLoad]);const M=g.useCallback(()=>b(!0),[]),j=g.useCallback(()=>b(!1),[]),N=g.useCallback(A=>{const E=!!A;v(w=>({...w??{},showOnLoad:E})),E||b(!1)},[v]),T=g.useMemo(()=>s?c.jsx(nj,{layout:a,onOpenHelpOverlay:M}):a==="mobile-landscape"?c.jsx(lj,{onOpenHelpOverlay:M}):c.jsx(aj,{onOpenHelpOverlay:M}),[s,a,M]);return c.jsxs(X1,{children:[c.jsx(eS,{}),c.jsx(tS,{}),c.jsxs("main",{className:`flex w-full flex-col gap-0.5 text-base ${s?"h-full overflow-hidden":""}`,children:[s?null:c.jsx(ff,{layout:a}),T]}),c.jsx(Zu,{}),c.jsx(YA,{}),c.jsx(UA,{}),c.jsx(FA,{visible:S,layout:a,onClose:j,showOnLoad:m?.showOnLoad!==!1,onToggleShowOnLoad:N}),c.jsx(QA,{visible:r,mode:f,onEnterFullscreen:d,onDismiss:p})]})}function Sg(){const{session:a,setRole:s,subscribeAll:i,connected:r}=De(),[f,d]=g.useState(!1);return g.useEffect(()=>{let p=!1;async function m(){if(a?.mode==="lockdown"){d(!1);return}try{a?.role!=="spectator"&&await s("spectator"),await i(),p||d(!0)}catch(y){console.error("Failed to enter spectator mode",y),p||d(!1)}}return m(),()=>{p=!0}},[r,a?.mode,a?.role,s,i]),f}function rj({roverId:a,session:s}){const i=s?.activeDrivers?.[a]||null,f=(s?.users||[]).find(y=>y.socketId===i)?.nickname||(i?i.slice(0,6):"No driver"),d=s?.mode,p=s?.turnQueues?.[a];return d==="turns"&&p?.current?`${f} (turns)`:f}function oj({rover:a,frame:s,snapshotFeed:i,audioInfo:r,session:f}){const d=rj({roverId:a.id,session:f});return c.jsx("article",{className:"min-h-[16rem] rounded bg-zinc-900 p-0.5 sm:min-h-[18rem]",children:c.jsx("div",{className:"min-h-0 overflow-hidden rounded bg-black/20",children:c.jsx(ef,{sessionInfo:null,videoMode:"snapshot",snapshotFeed:i,audioSessionInfo:r,label:a.name,telemetryFrame:s,batteryConfig:a.battery,hudVariant:"spectator",driverLabel:d,hudForceMap:!0,hudMapPosition:"bottom-left"})})})}function cj({roster:a,frames:s,snapshotFeeds:i,audioSources:r,session:f}){return a.length===0?c.jsx("p",{className:"col-span-full text-slate-400",children:"No rovers registered."}):c.jsx("section",{className:"grid grid-cols-1 gap-0.5 md:grid-cols-2",children:a.map(d=>c.jsx(oj,{rover:d,frame:s[d.id],snapshotFeed:i[d.id],audioInfo:r[`${d.id}-audio`],session:f,showHudMap:!0,hudMapPosition:"bottom-left"},d.id))})}function uj(){return c.jsx("section",{className:"min-h-0",children:c.jsx("div",{className:"surface min-h-[14rem] overflow-hidden",children:c.jsx(Ju,{defaultOrientation:"horizontal",hideLayoutToggle:!0,hideHeader:!0,panelId:"spectator-secondary"})})})}function fj({className:a=""}){return c.jsx("div",{className:`panel ${a}`,children:c.jsx(Fu,{})})}function dj(){const{session:a}=De(),s=a?.mode==="lockdown";uf(),Sg();const i=Lu(),r=a?.roster??[],f=Iu(r.map(m=>m.id),{enabled:!s,version:a?.mode}),d=r.flatMap(m=>m.media?.audioPublishUrl?[{type:"rover",id:`${m.id}-audio`,key:`${m.id}-audio`}]:[]),p=Wu(d,{enabled:!s,version:a?.mode});return s?c.jsx("div",{className:"flex min-h-screen items-center justify-center bg-black text-slate-200",children:c.jsxs("div",{className:"surface max-w-md space-y-0.5 p-1 text-center text-sm",children:[c.jsx("p",{className:"text-lg font-semibold text-white",children:"Spectate disabled during lockdown."}),c.jsx("p",{className:"text-slate-300",children:"Please wait until the server leaves lockdown to view streams."})]})}):c.jsxs("div",{className:"min-h-screen bg-black text-slate-100 md:h-screen md:overflow-hidden",children:[c.jsxs("main",{className:"grid min-h-screen grid-cols-1 gap-0.5 p-0.5 md:h-full md:min-h-0 md:grid-cols-[minmax(0,1fr)_18rem] lg:grid-cols-[minmax(0,1fr)_20rem]",children:[c.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col gap-0.5 md:overflow-y-auto",children:[c.jsx(cj,{roster:r,frames:i,snapshotFeeds:f,audioSources:p,session:a}),c.jsx(uj,{})]}),c.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col gap-0.5 md:h-full",children:[c.jsx(ff,{layout:"desktop"}),c.jsx("div",{className:"panel",children:c.jsx(Xu,{roster:r,title:"Rovers",emptyText:"No rovers registered."})}),c.jsx("div",{className:"min-h-0 min-w-0 flex-1 overflow-hidden",children:c.jsx(cf,{hideNicknameForm:!0,hideHeader:!0,fillHeight:!0,className:"h-full"})}),c.jsx("div",{className:"min-h-0 min-w-0 flex-[1.1] overflow-hidden",children:c.jsx(Ds,{hideInput:!0,hideSpectatorNotice:!0,fillHeight:!0})}),c.jsx("div",{className:"min-h-0 min-w-0",children:c.jsx(fj,{className:"h-40 overflow-hidden"})})]})]}),c.jsx(Zu,{})]})}function hj(){return c.jsx(Hu,{children:c.jsx(dj,{})})}const mj=2e4,pj=10800*1e3;function gj({roverId:a,session:s}){const i=s?.activeDrivers?.[a]||null,f=(s?.users||[]).find(m=>m.socketId===i)?.nickname||(i?i.slice(0,6):"No driver"),d=s?.mode,p=s?.turnQueues?.[a];return d==="turns"&&p?.current?`${f} (turns)`:f}function yj(){const{session:a}=De(),s=Sg();uf();const i=a?.mode==="lockdown",r=Lu(),f=a?.roster??[],[d,p]=g.useState(0),m=a?.activeDrivers||{},y=g.useMemo(()=>f.filter(Q=>m[Q.id]),[f,m]),v=Iu(y.map(Q=>Q.id),{enabled:!i,version:a?.mode}),S=g.useMemo(()=>y.flatMap(Q=>{if(!Q?.id||!Q.media?.audioPublishUrl)return[];const H=String(Q.id);return[{type:"rover",id:`${H}-audio`,key:`${H}-audio`}]}),[y]),b=Wu(S,{enabled:!i,version:a?.mode}),M=g.useMemo(()=>{if(!y.length)return[];const Q=y.filter(H=>v[H.id]?.objectUrl);return Q.length?Q:y},[y,v]),j=g.useMemo(()=>M.map(Q=>({type:"rover",rover:Q})),[M]),N=g.useMemo(()=>j.map(Q=>`r:${Q.rover.id}`).join("|"),[j]);g.useEffect(()=>{p(0)},[N]),g.useEffect(()=>{if(!j.length)return;const Q=setInterval(()=>{p(H=>(H+1)%j.length)},mj);return()=>clearInterval(Q)},[j.length,N]);const T=j.length?j[d%j.length]:null,A=T?.type==="rover"?T.rover:null,E=A&&v[A.id]||null,w=A&&b[`${A.id}-audio`]||null,O=A&&r[A.id]||null,J=A?gj({roverId:A.id,session:a}):null;return i?c.jsx("div",{className:"relative flex h-screen w-screen items-center justify-center bg-black text-slate-200",children:c.jsxs("div",{className:"surface max-w-sm space-y-0.5 p-1 text-center text-sm",children:[c.jsx("p",{className:"text-lg font-semibold text-white",children:"Mini spectator is disabled in lockdown."}),c.jsx("p",{className:"text-slate-300",children:"It will automatically resume once lockdown ends."})]})}):c.jsxs("div",{className:"relative h-screen w-screen overflow-hidden bg-black p-0.5 text-slate-100 flex flex-col gap-0.5",children:[c.jsx(xj,{}),c.jsx("section",{className:"panel relative flex min-h-0 flex-1 overflow-hidden",children:s?A?c.jsx(bj,{children:c.jsx(ef,{sessionInfo:null,videoMode:"snapshot",snapshotFeed:E,audioSessionInfo:w,label:A.name||A.id,telemetryFrame:O,batteryConfig:A.battery,layoutFormat:"mobile",hudVariant:"spectator",driverLabel:J,hudLabelScale:5,hudForceMap:!0,hudMapPosition:"bottom-left",fitParent:!0})}):c.jsx("div",{className:"flex h-full w-full items-center justify-center text-sm text-slate-500",children:y.length?"No sources available.":"No active drivers."}):c.jsx("div",{className:"flex h-full w-full items-center justify-center text-sm text-slate-500",children:"Switching to spectator…"})})]})}function vj(){return g.useEffect(()=>{if(typeof window>"u")return;const a=setTimeout(()=>{const s=new URL(window.location.href);s.searchParams.set("refresh",Date.now().toString()),window.location.replace(s.toString())},pj);return()=>clearTimeout(a)},[]),c.jsx(Hu,{children:c.jsxs(c.Fragment,{children:[c.jsx(yj,{}),c.jsx(Zu,{scale:5})]})})}function xj(){return c.jsx("div",{className:"pointer-events-none absolute left-1/2 top-1 z-30",style:{transform:"translate(-50%, 0) scale(0.7)",transformOrigin:"top center"},children:c.jsx("div",{className:"pointer-events-none overflow-hidden rounded-md",style:{width:"50vw",minWidth:"16rem",maxWidth:"24rem",opacity:.55,maxHeight:"12rem"},children:c.jsx(Ds,{hideInput:!0,hideSpectatorNotice:!0})})})}function bj({children:a}){return c.jsx("div",{className:"flex h-full w-full items-center justify-center overflow-hidden bg-black",children:c.jsx("div",{className:"relative flex items-center justify-center overflow-hidden bg-black",style:{width:"min(100%, calc(100vh * 16 / 9))",height:"min(100%, calc(100vw * 9 / 16))",maxWidth:"100%",maxHeight:"100%",aspectRatio:"16 / 9"},children:c.jsx("div",{className:"flex h-full w-full items-center justify-center overflow-hidden",children:a})})})}Fv.createRoot(document.getElementById("root")).render(c.jsx(g.StrictMode,{children:c.jsx(x1,{children:c.jsx(S1,{children:c.jsx(A1,{children:c.jsx($1,{children:c.jsx(fb,{children:c.jsxs(Yx,{children:[c.jsx(rr,{path:"/",element:c.jsx(sj,{})}),c.jsx(rr,{path:"/spectate",element:c.jsx(hj,{})}),c.jsx(rr,{path:"/mini",element:c.jsx(vj,{})})]})})})})})})})); diff --git a/server/public/index.html b/server/public/index.html index 4d4472c5..c2c38380 100644 --- a/server/public/index.html +++ b/server/public/index.html @@ -11,7 +11,7 @@