StreamOverlayPage-Ck7DNYWg.js 15 KB

1
  1. import{i as e}from"./chunk-aKtaBQYM.js";import{C as t,D as n,S as r,a as i,t as a,w as o}from"./client-DnySrlFv.js";import{n as s}from"./QueryClientProvider-Ce8_sN3w.js";import{t as c}from"./useQuery-BBCjCezC.js";import{t as l}from"./box-DAdKb9s5.js";import{t as u}from"./timer-GUTR9dAu.js";import{c as d,o as f}from"./date-G9KUauqz.js";import{Jt as ee,Lt as p,On as m,Un as h,Wn as g,bn as _,cn as te}from"./index-CovRLYqQ.js";import{t as v}from"./printerModel-DrNvERGQ.js";import{a as y,n as b,o as x,s as S,t as C}from"./OverlayFrame-fLmufrTC.js";var w=e(n(),1),T=t();function E(e,t){let[n,r]=(0,w.useState)(null);return(0,w.useLayoutEffect)(()=>{let n=e.current;if(!t||!n)return;let i=()=>{let e=n.clientWidth,t=n.clientHeight;e>0&&t>0&&r(n=>n&&n.width===e&&n.height===t?n:{width:e,height:t})};if(i(),typeof ResizeObserver>`u`)return window.addEventListener(`resize`,i),()=>window.removeEventListener(`resize`,i);let a=new ResizeObserver(i);return a.observe(n),()=>a.disconnect()},[e,t]),t?n:null}function D(e){let[t,n]=(0,w.useState)(()=>window.matchMedia(`(orientation: portrait)`).matches);return(0,w.useEffect)(()=>{if(e)return;let t=window.matchMedia(`(orientation: portrait)`),r=e=>n(e.matches);return n(t.matches),t.addEventListener(`change`,r),()=>t.removeEventListener(`change`,r)},[e]),e??(t?`portrait`:`landscape`)}function O(e){let{t}=o(),n=1-(e.backgroundTransparency??0)/100,r={"--overlay-background-alpha":n,"--overlay-identity-alpha":n*.9,"--overlay-panel-alpha":n*.88};(0,w.useLayoutEffect)(()=>{if(n===1)return;let e=document.body.style.backgroundColor;return document.body.style.backgroundColor=`transparent`,()=>{document.body.style.backgroundColor=e}},[n]);let i=D(e.layout),{camera:a,name:s,model:c,filename:l,status:d,state:f,progress:p,layers:h,remaining:g,eta:_,temperatures:v}=e,y=x(e.progressBackground),b=l||d||p!=null||h||g||_||v.length>0,S=a?.rotation??0,C=Math.abs(S%180)===90,O=(0,w.useRef)(null),k=E(O,C&&a!=null),A=[{key:`layers`,icon:(0,T.jsx)(te,{}),label:t(`streamOverlay.layer`),value:h},{key:`remaining`,icon:(0,T.jsx)(u,{}),label:t(`streamOverlay.remaining`),value:g},{key:`eta`,icon:(0,T.jsx)(m,{}),label:t(`streamOverlay.eta`),value:_}].filter(e=>e.value!=null);return(0,T.jsxs)(`div`,{className:`updated-overlay`,"data-size":e.size,"data-layout":i,"data-state":f,style:r,children:[(0,T.jsxs)(`header`,{className:`updated-overlay__header`,children:[(s||c)&&(0,T.jsxs)(`div`,{className:`updated-overlay__identity`,children:[(0,T.jsx)(ee,{"aria-hidden":`true`}),(0,T.jsxs)(`div`,{children:[s&&(0,T.jsx)(`strong`,{children:s}),c&&(0,T.jsx)(`span`,{children:c})]})]}),(0,T.jsxs)(`div`,{className:`updated-overlay__logo flex flex-col items-end`,children:[e.customLogo,(0,T.jsx)(`a`,{href:`https://github.com/maziggy/bambuddy`,target:`_blank`,rel:`noopener noreferrer`,children:(0,T.jsx)(`img`,{src:`/img/bambuddy_logo_powered_by.png`,alt:`Bambuddy`})})]})]}),a&&(0,T.jsx)(`div`,{className:`updated-overlay__camera`,ref:O,children:(0,T.jsx)(`img`,{src:a.url,alt:t(`streamOverlay.cameraStream`),style:{transform:`translate(-50%, -50%) rotate(${S}deg)`,...C&&k?{width:k.height,height:k.width}:{}},onError:a.onError},a.url)}),b&&(0,T.jsxs)(`section`,{className:`updated-overlay__panel`,children:[(l||d)&&(0,T.jsxs)(`div`,{className:`updated-overlay__summary`,children:[l&&(0,T.jsx)(`h1`,{children:l}),d&&(0,T.jsxs)(`div`,{className:`updated-overlay__status`,children:[(0,T.jsx)(`span`,{"aria-hidden":`true`}),d]})]}),p!=null&&(0,T.jsxs)(`div`,{className:`updated-overlay__progress`,children:[(0,T.jsx)(`span`,{style:y,children:t(`streamOverlay.progress`)}),(0,T.jsx)(`div`,{role:`progressbar`,"aria-label":t(`streamOverlay.progress`),"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":p,children:(0,T.jsx)(`div`,{style:{width:`${p}%`,background:e.progressBackground}})}),(0,T.jsxs)(`strong`,{style:y,children:[Math.round(p),`%`]})]}),(A.length>0||v.length>0)&&(0,T.jsxs)(`div`,{className:`updated-overlay__readings`,children:[A.length>0&&(0,T.jsx)(`div`,{className:`updated-overlay__stats`,children:A.map(e=>(0,T.jsxs)(`div`,{className:`updated-overlay__reading`,children:[e.icon,(0,T.jsxs)(`div`,{children:[(0,T.jsx)(`span`,{children:e.label}),(0,T.jsx)(`strong`,{children:e.value})]})]},e.key))}),v.length>0&&(0,T.jsx)(`div`,{className:`updated-overlay__temperatures`,children:v.map(e=>(0,T.jsxs)(`div`,{className:`updated-overlay__reading`,children:[e.icon,(0,T.jsxs)(`div`,{children:[(0,T.jsx)(`span`,{children:e.label}),(0,T.jsxs)(`strong`,{children:[Math.round(e.current),`°C`,e.target!=null&&e.target>0&&Math.round(e.target)!==Math.round(e.current)&&(0,T.jsxs)(`small`,{children:[` / `,Math.round(e.target),`°C`]})]})]})]},e.key))})]})]})]})}var k=6e4,A=3e3;function ne(e){let[t,n]=(0,w.useState)(Date.now),r=(0,w.useRef)(null),i=(0,w.useCallback)(()=>{r.current!==null&&(clearTimeout(r.current),r.current=null),n(e=>e+1)},[]);return(0,w.useEffect)(()=>{if(!e)return;let t=setTimeout(i,k);return()=>{clearTimeout(t),r.current!==null&&(clearTimeout(r.current),r.current=null)}},[e,t,i]),{imageKey:t,handleStreamError:(0,w.useCallback)(()=>{!e||r.current!==null||(r.current=setTimeout(i,A))},[e,i])}}function j(e,t,n){if(!e)return``;if(!t)return e;let r=t.match(/plate_(\d+)\.gcode/);return r&&parseInt(r[1],10)>1?`${e} — ${n(`printers.plateNumber`,`Plate {{number}}`,{number:r[1]})}`:e}function re(e){let t=e.get(`show`)?.split(`,`)||[`progress`,`layers`,`eta`,`filename`,`status`],n=parseInt(e.get(`fps`)||`15`,10),r=Math.min(Math.max(isNaN(n)?15:n,1),30),i=e.get(`camera`),a=i!==`false`&&i!==`0`,o=Number(e.get(`backgroundTransparency`)),s=Number.isFinite(o)?Math.min(100,Math.max(0,o)):0,c=e.get(`layout`);return{layout:c===`portrait`||c===`landscape`?c:null,backgroundTransparency:s,size:e.get(`size`)||`medium`,fps:r,updatedArtwork:e.get(`artwork`)===`2`,showCamera:a,showProgress:t.includes(`progress`),showLayers:t.includes(`layers`),showEta:t.includes(`eta`),showFilename:t.includes(`filename`),showStatus:t.includes(`status`),showPrinter:t.includes(`printer`),showModel:t.includes(`model`),showNozzle:t.includes(`nozzle`),showBed:t.includes(`bed`),showChamber:t.includes(`chamber`)}}function M(e,t){if(e.stg_cur_name)return e.stg_cur_name;switch(e.state){case`RUNNING`:return t(`streamOverlay.status.printing`);case`PAUSE`:return t(`streamOverlay.status.paused`);case`FINISH`:return t(`streamOverlay.status.finished`);case`FAILED`:return t(`streamOverlay.status.failed`);case`IDLE`:return t(`streamOverlay.status.idle`);default:return e.state||t(`streamOverlay.status.unknown`)}}function N(e,t){let n=e[t];return typeof n==`number`?n:null}function ie({icon:e,label:t,current:n,target:r,sizes:i}){let a=r!=null&&r>0&&Math.round(r)!==Math.round(n);return(0,T.jsxs)(`div`,{className:`flex items-center ${i.gap} text-white/70`,children:[e,(0,T.jsxs)(`span`,{className:`classic-overlay__text ${i.text}`,children:[(0,T.jsx)(`span`,{className:`mr-1`,children:t}),(0,T.jsxs)(`span`,{className:`text-white`,children:[Math.round(n),`°C`]}),a&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`span`,{className:`mx-1`,children:`/`}),(0,T.jsxs)(`span`,{children:[Math.round(r),`°C`]})]})]})]})}function ae(e){switch(e){case`small`:return{container:`p-3`,text:`text-sm`,textLarge:`text-lg`,progressHeight:`h-2`,icon:`w-3 h-3`,gap:`gap-2`,logoHeight:`h-12`};case`large`:return{container:`p-6`,text:`text-xl`,textLarge:`text-3xl`,progressHeight:`h-4`,icon:`w-6 h-6`,gap:`gap-4`,logoHeight:`h-24`};default:return{container:`p-4`,text:`text-base`,textLarge:`text-xl`,progressHeight:`h-3`,icon:`w-4 h-4`,gap:`gap-3`,logoHeight:`h-16`}}}function P(){let{printerId:e}=h(),[t]=g(),{t:n}=o(),E=s(),D=parseInt(e||`0`,10),k=(0,w.useMemo)(()=>re(t),[t]),A=ae(k.size),P=t.get(`token`),F=P!=null&&P!==``,I=S(t.get(`logo`)===`1`,P),L=y(t.get(`progressFrom`),t.get(`progressTo`)),R=x(L),z=I?(0,T.jsx)(`img`,{src:I,alt:n(`streamOverlay.branding.logo`),className:`mb-2 object-contain`,style:{maxHeight:k.layout?b[k.layout].height*.14:`14vh`,maxWidth:k.layout?b[k.layout].width*.2:`20vw`}}):null,{data:B}=c({queryKey:[`overlayStatus`,D,P],queryFn:()=>i.getOverlayStatus(D,P??void 0),enabled:D>0&&F,refetchInterval:2e3}),{data:V}=c({queryKey:[`printer`,D],queryFn:()=>i.getPrinter(D),enabled:D>0&&!F}),{data:oe}=c({queryKey:[`printerStatus`,D],queryFn:()=>i.getPrinterStatus(D),enabled:D>0&&!F,refetchInterval:2e3}),{data:se}=c({queryKey:[`settings`],queryFn:i.getSettings,enabled:!F}),H=(0,w.useMemo)(()=>F?B&&{name:B.name,model:B.model,camera_rotation:B.camera_rotation}:V,[F,B,V]),U=[k.showPrinter?H?.name:null,k.showModel?v(H?.model??null):null].filter(Boolean).join(` · `),W=F?B:oe,{imageKey:G,handleStreamError:K}=ne(D>0&&k.showCamera&&W!=null),q=(F?B?.time_format:se?.time_format)||`system`;if((0,w.useEffect)(()=>{if(!D||F)return;let e=null,t=!1;return(async()=>{let n;try{n=(await i.getWebSocketToken()).token}catch(e){let t=e instanceof a?e.status:0;if(t===401||t===403)return}if(t)return;let r=window.location.protocol===`https:`?`wss:`:`ws:`,o=n?`?token=${encodeURIComponent(n)}`:``,s=`${r}//${window.location.host}/api/v1/ws${o}`;e=new WebSocket(s),e.onmessage=e=>{try{let t=JSON.parse(e.data);t.type===`printer_status`&&t.printer_id===D&&E.setQueryData([`printerStatus`,D],t.status)}catch{}},e.onerror=()=>{}})(),()=>{t=!0,e&&e.close()}},[D,F,E]),(0,w.useEffect)(()=>(document.title=H?`${H.name} - ${n(`streamOverlay.title`)}`:n(`streamOverlay.title`),()=>{document.title=`Bambuddy`}),[H,n]),!D)return(0,T.jsx)(`div`,{className:`min-h-screen bg-black flex items-center justify-center`,children:(0,T.jsx)(`p`,{className:`text-white`,children:n(`streamOverlay.invalidPrinterId`)})});if(!W)return(0,T.jsx)(`div`,{className:`min-h-screen bg-black flex items-center justify-center`,children:(0,T.jsx)(`p`,{className:`text-gray-400`,children:n(`common.loading`)})});let J=W.connected&&(W.state===`RUNNING`||W.state===`PAUSE`),Y=W.progress||0,X=W.temperatures??{},Z=[];if(k.showNozzle){let e=N(X,`nozzle`),t=N(X,`nozzle_2`);e!=null&&Z.push({key:`nozzle`,icon:(0,T.jsx)(_,{className:`classic-overlay__icon ${A.icon}`}),label:n(`printers.heaterHistory.nozzle`,`Nozzle`),current:e,target:N(X,`nozzle_target`)}),t!=null&&Z.push({key:`nozzle_2`,icon:(0,T.jsx)(_,{className:`classic-overlay__icon ${A.icon}`}),label:n(`printers.heaterHistory.nozzle2`,`Nozzle 2`),current:t,target:N(X,`nozzle_2_target`)})}if(k.showBed){let e=N(X,`bed`);e!=null&&Z.push({key:`bed`,icon:(0,T.jsx)(p,{className:`classic-overlay__icon ${A.icon}`}),label:n(`printers.heaterHistory.bed`,`Bed`),current:e,target:N(X,`bed_target`)})}if(k.showChamber){let e=N(X,`chamber`);e!=null&&Z.push({key:`chamber`,icon:(0,T.jsx)(l,{className:`classic-overlay__icon ${A.icon}`}),label:n(`printers.heaterHistory.chamber`,`Chamber`),current:e,target:N(X,`chamber_target`)})}let ce=`/api/v1/printers/${D}/camera/stream?fps=${k.fps}&t=${G}`,le=F&&P?`${ce}&token=${encodeURIComponent(P)}`:r(ce);if(k.updatedArtwork){let e=W.connected&&J,t=W.remaining_time,r=e&&k.showEta&&t!=null&&t>0,i=(0,T.jsx)(O,{layout:k.layout??void 0,backgroundTransparency:k.backgroundTransparency,customLogo:z,progressBackground:L,size:k.size,camera:k.showCamera?{url:le,rotation:H?.camera_rotation??0,onError:K}:null,name:k.showPrinter?H?.name??null:null,model:k.showModel&&v(H?.model??null)||null,filename:k.showFilename&&W.current_print?j(W.current_print.replace(/\.gcode\.3mf$|\.3mf$|\.gcode$/i,``),W.gcode_file,n):null,status:k.showStatus?W.connected?M(W,n):n(`streamOverlay.printerOffline`):null,state:W.connected?W.state:null,progress:e&&k.showProgress?Math.min(100,Math.max(0,Number.isFinite(Y)?Y:0)):null,layers:e&&k.showLayers&&W.layer_num!=null&&W.total_layers!=null&&W.total_layers>0?`${W.layer_num} / ${W.total_layers}`:null,remaining:r?f(t*60):null,eta:r?d(t,q,n):null,temperatures:W.connected?Z:[]});return k.layout?(0,T.jsx)(C,{layout:k.layout,children:i}):i}let Q=k.layout?b[k.layout]:null,$=H?.camera_rotation??0,ue=Math.abs($%180)===90,de=(0,T.jsxs)(`div`,{className:`classic-overlay min-h-screen bg-black relative overflow-hidden`,"data-layout":k.layout??void 0,"data-size":k.size,children:[k.showCamera&&(0,T.jsx)(`img`,{src:le,alt:n(`streamOverlay.cameraStream`),className:`absolute inset-0 w-full h-full object-contain`,style:Q?{left:`50%`,top:`50%`,maxWidth:`none`,width:ue?Q.height:Q.width,height:ue?Q.width:Q.height,transform:`translate(-50%, -50%) rotate(${$}deg)`}:$?{transform:`rotate(${$}deg)`}:void 0,onError:K},G),(0,T.jsxs)(`div`,{className:`absolute top-4 right-4 z-10 flex flex-col items-end`,children:[z,(0,T.jsx)(`a`,{href:`https://github.com/maziggy/bambuddy`,target:`_blank`,rel:`noopener noreferrer`,children:(0,T.jsx)(`img`,{src:`/img/bambuddy_logo_dark_transparent.png`,alt:`Bambuddy`,className:`classic-overlay__logo ${A.logoHeight} object-contain drop-shadow-lg hover:scale-105 transition-transform`})})]}),(0,T.jsx)(`div`,{className:`absolute bottom-0 left-0 right-0 z-10 bg-gradient-to-t from-black/80 via-black/60 to-transparent`,children:(0,T.jsxs)(`div`,{className:`classic-overlay__panel ${A.container}`,children:[U&&(0,T.jsxs)(`div`,{className:`flex items-center ${A.gap} mb-2`,children:[(0,T.jsx)(ee,{className:`classic-overlay__icon ${A.icon} shrink-0 text-white/70`}),(0,T.jsx)(`span`,{className:`classic-overlay__text ${A.text} min-w-0 truncate text-white font-medium`,children:U})]}),k.showFilename&&W.current_print&&(0,T.jsx)(`div`,{className:`classic-overlay__filename ${A.textLarge} text-white font-semibold mb-2 truncate drop-shadow-md`,children:j(W.current_print.replace(/\.gcode\.3mf$|\.3mf$|\.gcode$/i,``),W.gcode_file,n)}),k.showStatus&&(0,T.jsx)(`div`,{className:`classic-overlay__text ${A.text} text-white/70 mb-2`,children:W.connected?M(W,n):n(`streamOverlay.printerOffline`)}),k.showProgress&&J&&(0,T.jsxs)(`div`,{className:`mb-3`,children:[(0,T.jsxs)(`div`,{className:`flex items-center justify-between mb-1 classic-overlay__text ${A.text}`,children:[(0,T.jsx)(`span`,{className:`text-white/70`,style:R,children:n(`streamOverlay.progress`)}),(0,T.jsxs)(`span`,{className:`text-white font-bold`,style:R,children:[Math.round(Y),`%`]})]}),(0,T.jsx)(`div`,{className:`w-full bg-white/20 rounded-full ${A.progressHeight}`,children:(0,T.jsx)(`div`,{className:`bg-bambu-green ${A.progressHeight} rounded-full transition-all duration-500`,style:{width:`${Y}%`,background:L}})})]}),J&&(k.showLayers||k.showEta)&&(0,T.jsxs)(`div`,{className:`flex items-center ${A.gap} flex-wrap`,children:[k.showLayers&&W.layer_num!=null&&W.total_layers!=null&&W.total_layers>0&&(0,T.jsxs)(`div`,{className:`flex items-center ${A.gap} text-white/70`,children:[(0,T.jsx)(te,{className:`classic-overlay__icon ${A.icon}`}),(0,T.jsxs)(`span`,{className:`classic-overlay__text ${A.text}`,children:[(0,T.jsx)(`span`,{className:`text-white`,children:W.layer_num}),(0,T.jsx)(`span`,{className:`mx-1`,children:`/`}),(0,T.jsx)(`span`,{children:W.total_layers})]})]}),k.showEta&&W.remaining_time!=null&&W.remaining_time>0&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsxs)(`div`,{className:`flex items-center ${A.gap} text-white/70`,children:[(0,T.jsx)(u,{className:`classic-overlay__icon ${A.icon}`}),(0,T.jsx)(`span`,{className:`classic-overlay__text ${A.text} text-white`,children:f(W.remaining_time*60)})]}),(0,T.jsxs)(`div`,{className:`flex items-center ${A.gap} text-white/70`,children:[(0,T.jsx)(m,{className:`classic-overlay__icon ${A.icon}`}),(0,T.jsxs)(`span`,{className:`classic-overlay__text ${A.text} text-white`,children:[n(`streamOverlay.eta`),` `,d(W.remaining_time,q,n)]})]})]})]}),Z.length>0&&W.connected&&(0,T.jsx)(`div`,{className:`flex items-center ${A.gap} flex-wrap mt-2`,children:Z.map(e=>(0,T.jsx)(ie,{icon:e.icon,label:e.label,current:e.current,target:e.target,sizes:A},e.key))})]})})]});return k.layout?(0,T.jsx)(C,{layout:k.layout,children:de}):de}export{P as StreamOverlayPage};