livedesk 0.1.656 → 0.1.657

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/hub/src/remote-hub.js +47 -24
  2. package/hub/src/server.js +200 -13
  3. package/hub/src/shared-wall-profile-contract.mjs +40 -0
  4. package/hub/src/shared-wall-profile-contract.test.mjs +38 -0
  5. package/package.json +1 -1
  6. package/web/dist/app.html +3 -3
  7. package/web/dist/app.webmanifest +1 -1
  8. package/web/dist/assets/{AgentSettingsTab-D0271Ynp.js → AgentSettingsTab-CU3kHssT.js} +1 -1
  9. package/web/dist/assets/{AgentsPage-DEdUBoe0.js → AgentsPage-DcUy7xPU.js} +1 -1
  10. package/web/dist/assets/{App-DK9GZcvU.js → App-ARrqCA9B.js} +3 -3
  11. package/web/dist/assets/{CaptureGallery-C0xqFLap.js → CaptureGallery-BPKKxPej.js} +1 -1
  12. package/web/dist/assets/{DesktopUpdatePanel-uMaTnBsl.js → DesktopUpdatePanel-C5wDB5zf.js} +1 -1
  13. package/web/dist/assets/{SettingsPage-BoFLQBfH.js → SettingsPage-ChNfBaQo.js} +1 -1
  14. package/web/dist/assets/{SettingsTabs-D0zQN-Mo.js → SettingsTabs-B-uMhvwn.js} +1 -1
  15. package/web/dist/assets/{ShareFilesPage-BiCS0Nyd.js → ShareFilesPage-C9vhKzGp.js} +1 -1
  16. package/web/dist/assets/{SupportPage-D241Vkb1.js → SupportPage-C-uQ-RTX.js} +1 -1
  17. package/web/dist/assets/{VuvoDeskApp-36bRXXS2.js → VuvoDeskApp-BeeOb_MQ.js} +1 -1
  18. package/web/dist/assets/{app-hMd5uyvT.js → app-DhbXrOFp.js} +1 -1
  19. package/web/dist/assets/{main-DT492iHt.js → main-BTb7f--C.js} +2 -2
  20. package/web/dist/assets/styles-eZ2IzXEL.js +16 -0
  21. package/web/dist/index.html +2 -2
  22. package/web/dist/sw.js +2 -2
  23. package/web/dist/vuvodesk-build-evidence.json +51 -51
  24. package/web/dist/assets/styles-Ba1tPFHg.js +0 -16
@@ -1 +1 @@
1
- import{j as e}from"./styles-Ba1tPFHg.js";import{a as r,Y as p,a8 as j,D as u,a9 as g,a1 as f}from"./icons-CacEbnZu.js";import{l as b,c as d,d as y}from"./App-DK9GZcvU.js";import"./react-Cfedt3N5.js";import"./supabase-C7qjtLN3.js";import"./frame-lifecycle-esOdP-EY.js";function D({hubUrl:t,onToast:i}){const[o,m]=r.useState([]),[h,c]=r.useState(!0),n=r.useCallback(async()=>{c(!0);try{m((await b(t)).captures||[])}catch(a){i(a instanceof Error?a.message:String(a))}finally{c(!1)}},[t,i]);r.useEffect(()=>{n()},[n]);const x=async a=>{const s=d(a.id,t);if(navigator.share)try{await navigator.share({title:a.fileName,url:s});return}catch{}window.open(s,"_blank","noopener,noreferrer")};return e.jsxs("section",{className:"capture-gallery",children:[e.jsxs("header",{children:[e.jsxs("div",{children:[e.jsx("span",{className:"settings-eyebrow",children:"Capture Gallery"}),e.jsx("h2",{children:"Saved captures"})]}),e.jsxs("button",{className:"text-button",onClick:()=>{n()},type:"button",children:[e.jsx(p,{size:15})," Refresh"]})]}),h?e.jsx("p",{className:"settings-help",children:"Loading captures..."}):o.length===0?e.jsx("p",{className:"settings-help",children:"No captures saved yet."}):e.jsx("div",{className:"capture-gallery-grid",children:o.map(a=>{const s=d(a.id,t);return e.jsxs("article",{className:"capture-gallery-card",children:[a.mimeType.startsWith("image/")?e.jsx("img",{src:s,alt:a.target.label}):e.jsx("video",{src:s,controls:!0,preload:"metadata"}),e.jsxs("div",{className:"capture-gallery-card-body",children:[e.jsx("strong",{children:a.fileName}),e.jsxs("small",{children:[a.target.label," · ",new Date(a.createdAt).toLocaleString()," · ",Math.ceil(a.sizeBytes/1024)," KB"]}),e.jsxs("div",{children:[e.jsx("button",{className:"icon-button",title:"Open","aria-label":"Open",onClick:()=>window.open(s,"_blank","noopener,noreferrer"),type:"button",children:e.jsx(j,{size:15})}),e.jsx("a",{className:"icon-button",title:"Download","aria-label":"Download",href:`${s}?download=1`,download:a.fileName,children:e.jsx(u,{size:15})}),e.jsx("button",{className:"icon-button",title:"Share","aria-label":"Share",onClick:()=>{x(a)},type:"button",children:e.jsx(g,{size:15})}),e.jsx("button",{className:"icon-button danger",title:"Delete","aria-label":"Delete",onClick:()=>{window.confirm(`Delete ${a.fileName}?`)&&y(a.id,t).then(()=>n()).catch(l=>i(l instanceof Error?l.message:String(l)))},type:"button",children:e.jsx(f,{size:15})})]})]})]},a.id)})})]})}export{D as CaptureGallery};
1
+ import{j as e}from"./styles-eZ2IzXEL.js";import{a as r,Y as p,a8 as j,D as u,a9 as g,a1 as f}from"./icons-CacEbnZu.js";import{l as b,c as d,d as y}from"./App-ARrqCA9B.js";import"./react-Cfedt3N5.js";import"./supabase-C7qjtLN3.js";import"./frame-lifecycle-esOdP-EY.js";function D({hubUrl:t,onToast:i}){const[o,m]=r.useState([]),[h,c]=r.useState(!0),n=r.useCallback(async()=>{c(!0);try{m((await b(t)).captures||[])}catch(a){i(a instanceof Error?a.message:String(a))}finally{c(!1)}},[t,i]);r.useEffect(()=>{n()},[n]);const x=async a=>{const s=d(a.id,t);if(navigator.share)try{await navigator.share({title:a.fileName,url:s});return}catch{}window.open(s,"_blank","noopener,noreferrer")};return e.jsxs("section",{className:"capture-gallery",children:[e.jsxs("header",{children:[e.jsxs("div",{children:[e.jsx("span",{className:"settings-eyebrow",children:"Capture Gallery"}),e.jsx("h2",{children:"Saved captures"})]}),e.jsxs("button",{className:"text-button",onClick:()=>{n()},type:"button",children:[e.jsx(p,{size:15})," Refresh"]})]}),h?e.jsx("p",{className:"settings-help",children:"Loading captures..."}):o.length===0?e.jsx("p",{className:"settings-help",children:"No captures saved yet."}):e.jsx("div",{className:"capture-gallery-grid",children:o.map(a=>{const s=d(a.id,t);return e.jsxs("article",{className:"capture-gallery-card",children:[a.mimeType.startsWith("image/")?e.jsx("img",{src:s,alt:a.target.label}):e.jsx("video",{src:s,controls:!0,preload:"metadata"}),e.jsxs("div",{className:"capture-gallery-card-body",children:[e.jsx("strong",{children:a.fileName}),e.jsxs("small",{children:[a.target.label," · ",new Date(a.createdAt).toLocaleString()," · ",Math.ceil(a.sizeBytes/1024)," KB"]}),e.jsxs("div",{children:[e.jsx("button",{className:"icon-button",title:"Open","aria-label":"Open",onClick:()=>window.open(s,"_blank","noopener,noreferrer"),type:"button",children:e.jsx(j,{size:15})}),e.jsx("a",{className:"icon-button",title:"Download","aria-label":"Download",href:`${s}?download=1`,download:a.fileName,children:e.jsx(u,{size:15})}),e.jsx("button",{className:"icon-button",title:"Share","aria-label":"Share",onClick:()=>{x(a)},type:"button",children:e.jsx(g,{size:15})}),e.jsx("button",{className:"icon-button danger",title:"Delete","aria-label":"Delete",onClick:()=>{window.confirm(`Delete ${a.fileName}?`)&&y(a.id,t).then(()=>n()).catch(l=>i(l instanceof Error?l.message:String(l)))},type:"button",children:e.jsx(f,{size:15})})]})]})]},a.id)})})]})}export{D as CaptureGallery};
@@ -1 +1 @@
1
- import{j as e}from"./styles-Ba1tPFHg.js";import{a as r,D as y,a4 as j,Y as b}from"./icons-CacEbnZu.js";import"./react-Cfedt3N5.js";function D(t){if(!t)return"Reading the installed version...";const n=String(t.errorCode||t.error||"");switch(t.state){case"checking":return"Checking for a newer VuvoDesk version...";case"available":return`Version ${t.availableVersion||""} is available.`;case"downloading":return`Downloading version ${t.availableVersion||""} (${Math.round(t.progress||0)}%).`;case"downloaded":return`Version ${t.availableVersion||""} is ready. Restart to install it.`;case"installing":return"Closing VuvoDesk safely and starting the update...";case"current":return"This computer has the latest VuvoDesk version.";case"error":return/runtime-recovery-failed/i.test(n)?"The local VuvoDesk service could not restart. Quit VuvoDesk completely and reopen it.":/owner-cleanup-stuck|owner-reset-failed/i.test(n)?"The Windows update service could not reset. Quit VuvoDesk completely, reopen it, and check again.":/installer-launch-failed/i.test(n)?"The installer could not start. VuvoDesk restored its local service so you can retry.":/version-mismatch/i.test(n)?"The downloaded update did not match the expected version. VuvoDesk will retry safely.":/stalled|timed-out/i.test(n)?"The update connection stopped responding. VuvoDesk will retry automatically.":"The update server could not be reached. VuvoDesk will retry automatically.";case"development":return"Desktop updates are available in an installed VuvoDesk build.";case"unavailable":return"Updates are not available for this desktop build.";default:return"VuvoDesk checks once when the desktop app starts."}}function C(){const t=window.liveDesk?.updates,n=window.liveDesk?.app,[s,i]=r.useState(null),[f,u]=r.useState(!1),[o,p]=r.useState(null),[g,h]=r.useState(!1);if(r.useEffect(()=>{if(!t)return;let a=!0;t.getStatus?.().then(c=>{a&&i(c)});const d=t.onStatus?.(c=>{a&&i(c)});return()=>{a=!1,d?.()}},[t]),r.useEffect(()=>{if(!n?.getAutoStart)return;let a=!0;return n.getAutoStart().then(d=>{a&&p(d)}),()=>{a=!1}},[n]),!t)return null;const v=s?.state==="downloaded"||s?.downloaded===!0,k=!!s?.reopenRequired||/runtime-recovery-failed|owner-cleanup-stuck|owner-reset-failed/i.test(String(s?.errorCode||"")),l=f||s?.state==="checking"||s?.state==="downloading"||s?.state==="installing",m=s?.channel==="dev"?"Development":s?.channel==="stable"?"Stable":s?.channel||"Unknown",x=async()=>{u(!0);try{const a=v?await t.install?.():await t.check?.();a&&i(a)}finally{u(!1)}},w=async a=>{if(n?.setAutoStart){h(!0);try{p(await n.setAutoStart(a))}finally{h(!1)}}};return e.jsxs("section",{className:"settings-section-card desktop-update-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Desktop app"}),e.jsx("h3",{children:"VuvoDesk updates"})]}),e.jsx(y,{size:20})]}),e.jsx("p",{className:"settings-help","aria-live":"polite",children:D(s)}),e.jsxs("div",{className:"desktop-update-meta",children:[e.jsx("span",{children:"Installed"}),e.jsx("strong",{children:s?.currentVersion||"Unknown"}),e.jsx("span",{children:"Channel"}),e.jsx("strong",{children:m}),s?.availableVersion&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"Available"}),e.jsx("strong",{children:s.availableVersion})]})]}),n?.getAutoStart&&e.jsxs("div",{className:"desktop-auto-start-setting",children:[e.jsxs("div",{className:"desktop-auto-start-copy",children:[e.jsx(j,{size:18}),e.jsxs("span",{children:[e.jsx("strong",{children:"Start automatically after sign-in"}),e.jsx("small",{children:"Reconnect this computer quietly after Windows, macOS, or Linux sign-in."})]})]}),e.jsxs("label",{className:"settings-toggle desktop-auto-start-toggle",children:[e.jsx("input",{type:"checkbox",checked:o?.enabled??!0,onChange:a=>{w(a.target.checked)},disabled:!o?.supported||g}),e.jsx("span",{children:o?.enabled===!1?"Off":"On"})]}),o?.error&&e.jsx("p",{className:"desktop-auto-start-error",role:"alert",children:"Automatic start could not be updated. VuvoDesk will retry next time it opens."})]}),e.jsxs("button",{className:"settings-reset desktop-update-action",onClick:()=>{x()},disabled:l||k,type:"button",children:[e.jsx(b,{size:15,className:l?"desktop-update-spin":""}),k?"Reopen VuvoDesk":v?"Restart and update":l?"Updating...":"Check for updates"]})]})}export{C as DesktopUpdatePanel};
1
+ import{j as e}from"./styles-eZ2IzXEL.js";import{a as r,D as y,a4 as j,Y as b}from"./icons-CacEbnZu.js";import"./react-Cfedt3N5.js";function D(t){if(!t)return"Reading the installed version...";const n=String(t.errorCode||t.error||"");switch(t.state){case"checking":return"Checking for a newer VuvoDesk version...";case"available":return`Version ${t.availableVersion||""} is available.`;case"downloading":return`Downloading version ${t.availableVersion||""} (${Math.round(t.progress||0)}%).`;case"downloaded":return`Version ${t.availableVersion||""} is ready. Restart to install it.`;case"installing":return"Closing VuvoDesk safely and starting the update...";case"current":return"This computer has the latest VuvoDesk version.";case"error":return/runtime-recovery-failed/i.test(n)?"The local VuvoDesk service could not restart. Quit VuvoDesk completely and reopen it.":/owner-cleanup-stuck|owner-reset-failed/i.test(n)?"The Windows update service could not reset. Quit VuvoDesk completely, reopen it, and check again.":/installer-launch-failed/i.test(n)?"The installer could not start. VuvoDesk restored its local service so you can retry.":/version-mismatch/i.test(n)?"The downloaded update did not match the expected version. VuvoDesk will retry safely.":/stalled|timed-out/i.test(n)?"The update connection stopped responding. VuvoDesk will retry automatically.":"The update server could not be reached. VuvoDesk will retry automatically.";case"development":return"Desktop updates are available in an installed VuvoDesk build.";case"unavailable":return"Updates are not available for this desktop build.";default:return"VuvoDesk checks once when the desktop app starts."}}function C(){const t=window.liveDesk?.updates,n=window.liveDesk?.app,[s,i]=r.useState(null),[f,u]=r.useState(!1),[o,p]=r.useState(null),[g,h]=r.useState(!1);if(r.useEffect(()=>{if(!t)return;let a=!0;t.getStatus?.().then(c=>{a&&i(c)});const d=t.onStatus?.(c=>{a&&i(c)});return()=>{a=!1,d?.()}},[t]),r.useEffect(()=>{if(!n?.getAutoStart)return;let a=!0;return n.getAutoStart().then(d=>{a&&p(d)}),()=>{a=!1}},[n]),!t)return null;const v=s?.state==="downloaded"||s?.downloaded===!0,k=!!s?.reopenRequired||/runtime-recovery-failed|owner-cleanup-stuck|owner-reset-failed/i.test(String(s?.errorCode||"")),l=f||s?.state==="checking"||s?.state==="downloading"||s?.state==="installing",m=s?.channel==="dev"?"Development":s?.channel==="stable"?"Stable":s?.channel||"Unknown",x=async()=>{u(!0);try{const a=v?await t.install?.():await t.check?.();a&&i(a)}finally{u(!1)}},w=async a=>{if(n?.setAutoStart){h(!0);try{p(await n.setAutoStart(a))}finally{h(!1)}}};return e.jsxs("section",{className:"settings-section-card desktop-update-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Desktop app"}),e.jsx("h3",{children:"VuvoDesk updates"})]}),e.jsx(y,{size:20})]}),e.jsx("p",{className:"settings-help","aria-live":"polite",children:D(s)}),e.jsxs("div",{className:"desktop-update-meta",children:[e.jsx("span",{children:"Installed"}),e.jsx("strong",{children:s?.currentVersion||"Unknown"}),e.jsx("span",{children:"Channel"}),e.jsx("strong",{children:m}),s?.availableVersion&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"Available"}),e.jsx("strong",{children:s.availableVersion})]})]}),n?.getAutoStart&&e.jsxs("div",{className:"desktop-auto-start-setting",children:[e.jsxs("div",{className:"desktop-auto-start-copy",children:[e.jsx(j,{size:18}),e.jsxs("span",{children:[e.jsx("strong",{children:"Start automatically after sign-in"}),e.jsx("small",{children:"Reconnect this computer quietly after Windows, macOS, or Linux sign-in."})]})]}),e.jsxs("label",{className:"settings-toggle desktop-auto-start-toggle",children:[e.jsx("input",{type:"checkbox",checked:o?.enabled??!0,onChange:a=>{w(a.target.checked)},disabled:!o?.supported||g}),e.jsx("span",{children:o?.enabled===!1?"Off":"On"})]}),o?.error&&e.jsx("p",{className:"desktop-auto-start-error",role:"alert",children:"Automatic start could not be updated. VuvoDesk will retry next time it opens."})]}),e.jsxs("button",{className:"settings-reset desktop-update-action",onClick:()=>{x()},disabled:l||k,type:"button",children:[e.jsx(b,{size:15,className:l?"desktop-update-spin":""}),k?"Reopen VuvoDesk":v?"Restart and update":l?"Updating...":"Check for updates"]})]})}export{C as DesktopUpdatePanel};
@@ -1 +1 @@
1
- import{h as C,j as e,w as je,n as ve}from"./styles-Ba1tPFHg.js";import{a as i,W as be,k as ee,a3 as O,S as we,c as F,F as Re,Z as Se,a4 as ye,J as $}from"./icons-CacEbnZu.js";import"./react-Cfedt3N5.js";const x={revision:0,settings:{connection:{showThisComputer:!1},security:{accessMode:"trusted-only"},control:{allowKeyboardMouse:!0,allowRemoteRestart:!1},filesAudio:{allowFileTransfer:!0,allowRemoteAudio:!0,rollingBufferEnabled:!1,recordingQuality:"standard",timelapseIntervalSeconds:10,includeRemoteCursor:!0}}},Y=[{id:"connection",label:"Connection",icon:be},{id:"remote-access",label:"Remote Access",icon:ee},{id:"capture-audio",label:"Capture & Audio",icon:O},{id:"agent",label:"Agent",icon:we}];function A(t,n){return t?.settings?.[n]||x.settings[n]||{}}function _(t,n){return{...t,settings:{...t.settings,[n.section]:{...A(t,n.section),[n.key]:n.value}}}}function J(t){return{revision:Number(t.revision||0),updatedAt:t.updatedAt,settings:t.settings}}function g({icon:t,title:n,description:d,children:m,recommended:a=!1}){return e.jsxs("div",{className:"product-setting-row",children:[e.jsx("div",{className:"product-setting-control",children:m}),t&&e.jsx("span",{className:"product-setting-icon",children:e.jsx(t,{size:17})}),e.jsxs("div",{className:"product-setting-copy",children:[e.jsx("strong",{children:n}),a&&e.jsx("em",{children:"Recommended"}),e.jsx("small",{children:d})]})]})}function R({checked:t,onChange:n,label:d}){return e.jsxs("label",{className:"product-switch",children:[e.jsx("input",{"aria-label":d,type:"checkbox",checked:t,onChange:m=>n(m.target.checked)}),e.jsx("span",{})]})}function U({value:t,onChange:n,options:d,label:m}){return e.jsx("select",{"aria-label":m,value:String(t),onChange:a=>n(a.target.value),children:d.map(([a,M])=>e.jsx("option",{value:a,children:M},a))})}function ke({hubUrl:t="",mobileLayout:n=!1,runtimeRole:d="hub",runtimeDeviceId:m="",sessionAccessToken:a="",showThisComputerSetting:M=!0,onShowThisComputerChange:D,initialTab:Q="connection",pin:te,agent:se,captureGallery:ne,desktopUpdate:ie}){const[r,q]=i.useState(()=>n&&Q==="connection"?"remote-access":Q),[j,k]=i.useState(null),[oe,v]=i.useState("loading"),[G,T]=i.useState(""),[K,E]=i.useState("idle"),[V,z]=i.useState(""),b=i.useRef(null),u=i.useRef(null),p=i.useRef([]),B=i.useRef(Promise.resolve()),re=i.useRef(0),f=i.useRef(0);i.useEffect(()=>{const s=++f.current;let l=!0;return p.current=[],u.current=null,b.current=null,B.current=Promise.resolve(),v("loading"),C("/api/settings",void 0,t).then(o=>{if(!l||s!==f.current)return;const c=J(o);u.current=c,b.current=c,k(c),v("saved")}).catch(o=>{!l||s!==f.current||(T(o instanceof Error?o.message:String(o)),u.current=x,b.current=x,k(x),v("failed"))}),()=>{l=!1}},[t]);const ce=async(s,l,o)=>{const c={id:++re.current,section:s,key:l,value:o},H=f.current;p.current.push(c);const L=_(b.current||u.current||x,c);b.current=L,k(L),v("saving"),T(""),B.current=B.current.then(async()=>{if(H!==f.current)return;let S=null,y=null;for(let N=0;N<2&&!S;N+=1){const xe=u.current||x;try{const w=await C("/api/settings",{method:"PATCH",body:JSON.stringify({revision:xe.revision,[c.section]:{[c.key]:c.value}})},t);S=J(w)}catch(w){if(y=w,N!==0||!String(w instanceof Error?w.message:w).startsWith("409 "))break;try{const W=await C("/api/settings",void 0,t);if(H!==f.current)return;u.current=J(W)}catch(W){y=W;break}}}if(H!==f.current)return;p.current=p.current.filter(N=>N.id!==c.id),S&&(u.current=S);const fe=u.current||x,X=p.current.reduce(_,fe);b.current=X,k(X),S?(T(""),v(p.current.length>0?"saving":"saved")):(v(p.current.length>0?"saving":"failed"),T(y instanceof Error?y.message:String(y||"Settings could not be saved.")))}),await B.current},h=(s,l)=>o=>{ce(s,l,o)},ae=async()=>{if(d!=="hub"||!m||!a){E("failed"),z("Sign in to this Hub before changing its runtime role.");return}E("changing"),z("");try{const s=await C("/api/runtime/status",void 0,t);await C("/api/runtime/role",{method:"POST",headers:{Authorization:`Bearer ${a}`},body:JSON.stringify({role:"client"})},t),E("accepted"),await je({baseUrl:t,targetRole:"client",previousRuntimePid:Number(s.runtimePid||0),allowedStates:["running","waiting-auth"]}),ve(5179)}catch(s){E("failed"),z(s instanceof Error?s.message:String(s))}},le=A(j,"security"),Z=A(j,"control"),P=A(j,"filesAudio"),I=A(j,"connection"),de=`settings-panel-${r}`,ue=n?Y.filter(s=>s.id!=="connection"):Y;i.useEffect(()=>{n&&r==="connection"&&q("remote-access")},[r,n]),i.useEffect(()=>{j&&D?.(!!I.showThisComputer)},[I.showThisComputer,D,j]);const he=e.jsxs("div",{className:"settings-tab-content product-settings-content",children:[te,ie,M&&e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Hub computer list"}),e.jsx("h3",{children:"This computer"})]}),e.jsx(F,{size:20})]}),e.jsx(g,{icon:F,title:"Show this computer",description:"Show this Hub computer in its own Wall and computer lists. It stays available from other computers and the mobile app when hidden.",children:e.jsx(R,{checked:!!I.showThisComputer,onChange:h("connection","showThisComputer"),label:"Show this computer"})})]}),e.jsxs("section",{className:"settings-section-card runtime-role-settings",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Runtime role"}),e.jsx("h3",{children:"Use this computer as a Client"})]}),e.jsx(Re,{size:20})]}),e.jsx("p",{className:"settings-help",children:"Stop hosting from this computer and reconnect it to the selected Hub."}),K==="accepted"?e.jsx("p",{className:"settings-help runtime-role-success",children:"VuvoDesk is restarting as Client."}):V?e.jsx("p",{className:"settings-help runtime-role-error",role:"alert",children:V}):null,e.jsx("button",{className:"settings-reset",onClick:()=>{ae()},disabled:K==="changing"||d!=="hub",type:"button",children:K==="changing"?"Switching role...":"Switch this computer to Client"})]})]}),ge=e.jsxs("div",{className:"settings-tab-content product-settings-content",children:[e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Remote access"}),e.jsx("h3",{children:"Who may connect?"})]}),e.jsx(Se,{size:20})]}),e.jsx(g,{icon:ee,title:"Access mode",description:"Choose the default permission boundary for remote sessions.",recommended:!0,children:e.jsx(U,{value:String(le.accessMode),onChange:h("security","accessMode"),label:"Access mode",options:[["trusted-only","Trusted devices only"],["block-remote-access","Block remote access"]]})})]}),e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Session permissions"}),e.jsx("h3",{children:"What may remote users do?"})]}),e.jsx(F,{size:20})]}),e.jsx(g,{icon:F,title:"Keyboard and mouse control",description:"Allow Control to send keyboard and pointer input.",recommended:!0,children:e.jsx(R,{checked:!!Z.allowKeyboardMouse,onChange:h("control","allowKeyboardMouse"),label:"Keyboard and mouse control"})}),e.jsx(g,{icon:ye,title:"Power actions",description:"Allow confirmed sleep, restart, and shut down commands from the Hub.",children:e.jsx(R,{checked:!!Z.allowRemoteRestart,onChange:h("control","allowRemoteRestart"),label:"Power actions"})}),e.jsx(g,{icon:O,title:"File transfer",description:"Allow files to be delivered to connected computers.",children:e.jsx(R,{checked:!!P.allowFileTransfer,onChange:h("filesAudio","allowFileTransfer"),label:"File transfer"})}),e.jsx(g,{icon:$,title:"Remote audio",description:"Allow sound capture from connected computers.",children:e.jsx(R,{checked:!!P.allowRemoteAudio,onChange:h("filesAudio","allowRemoteAudio"),label:"Remote audio"})})]})]}),me=e.jsxs("div",{className:"settings-tab-content product-settings-content",children:[e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Capture"}),e.jsx("h3",{children:"Recording defaults"})]}),e.jsx(O,{size:20})]}),e.jsx(g,{icon:$,title:"Keep a Last 30s buffer",description:"Keep recent video in memory until you explicitly save it.",children:e.jsx(R,{checked:!!P.rollingBufferEnabled,onChange:h("filesAudio","rollingBufferEnabled"),label:"Keep a Last 30s buffer"})}),e.jsx(g,{icon:$,title:"Timelapse interval",description:"Choose how often a timelapse frame is captured.",children:e.jsx(U,{value:Number(P.timelapseIntervalSeconds),onChange:s=>h("filesAudio","timelapseIntervalSeconds")(Number(s)),label:"Timelapse interval",options:[["5","5 seconds"],["10","10 seconds"],["30","30 seconds"],["60","60 seconds"]]})})]}),ne]}),pe=r==="connection"?he:r==="remote-access"?ge:r==="capture-audio"?me:se;return e.jsxs("section",{className:"settings-page",children:[e.jsx("div",{className:"settings-page-tabs",role:"tablist","aria-label":"VuvoDesk settings",children:ue.map(({id:s,label:l,icon:o})=>e.jsxs("button",{className:r===s?"active":"",id:`settings-tab-${s}`,role:"tab","aria-selected":r===s,"aria-controls":`settings-panel-${s}`,tabIndex:r===s?0:-1,onClick:()=>q(s),type:"button",children:[e.jsx(o,{size:16}),l]},s))}),oe==="saving"&&e.jsx("div",{className:"product-save-state",role:"status",children:"Saving settings..."}),G&&e.jsx("div",{className:"agent-settings-alert error",role:"alert",children:G}),e.jsx("section",{className:"settings-page-panel",id:de,role:"tabpanel","aria-labelledby":`settings-tab-${r}`,tabIndex:0,children:pe})]})}export{ke as SettingsPage};
1
+ import{h as C,j as e,w as je,n as ve}from"./styles-eZ2IzXEL.js";import{a as i,W as be,k as ee,a3 as O,S as we,c as F,F as Re,Z as Se,a4 as ye,J as $}from"./icons-CacEbnZu.js";import"./react-Cfedt3N5.js";const x={revision:0,settings:{connection:{showThisComputer:!1},security:{accessMode:"trusted-only"},control:{allowKeyboardMouse:!0,allowRemoteRestart:!1},filesAudio:{allowFileTransfer:!0,allowRemoteAudio:!0,rollingBufferEnabled:!1,recordingQuality:"standard",timelapseIntervalSeconds:10,includeRemoteCursor:!0}}},Y=[{id:"connection",label:"Connection",icon:be},{id:"remote-access",label:"Remote Access",icon:ee},{id:"capture-audio",label:"Capture & Audio",icon:O},{id:"agent",label:"Agent",icon:we}];function A(t,n){return t?.settings?.[n]||x.settings[n]||{}}function _(t,n){return{...t,settings:{...t.settings,[n.section]:{...A(t,n.section),[n.key]:n.value}}}}function J(t){return{revision:Number(t.revision||0),updatedAt:t.updatedAt,settings:t.settings}}function g({icon:t,title:n,description:d,children:m,recommended:a=!1}){return e.jsxs("div",{className:"product-setting-row",children:[e.jsx("div",{className:"product-setting-control",children:m}),t&&e.jsx("span",{className:"product-setting-icon",children:e.jsx(t,{size:17})}),e.jsxs("div",{className:"product-setting-copy",children:[e.jsx("strong",{children:n}),a&&e.jsx("em",{children:"Recommended"}),e.jsx("small",{children:d})]})]})}function R({checked:t,onChange:n,label:d}){return e.jsxs("label",{className:"product-switch",children:[e.jsx("input",{"aria-label":d,type:"checkbox",checked:t,onChange:m=>n(m.target.checked)}),e.jsx("span",{})]})}function U({value:t,onChange:n,options:d,label:m}){return e.jsx("select",{"aria-label":m,value:String(t),onChange:a=>n(a.target.value),children:d.map(([a,M])=>e.jsx("option",{value:a,children:M},a))})}function ke({hubUrl:t="",mobileLayout:n=!1,runtimeRole:d="hub",runtimeDeviceId:m="",sessionAccessToken:a="",showThisComputerSetting:M=!0,onShowThisComputerChange:D,initialTab:Q="connection",pin:te,agent:se,captureGallery:ne,desktopUpdate:ie}){const[r,q]=i.useState(()=>n&&Q==="connection"?"remote-access":Q),[j,k]=i.useState(null),[oe,v]=i.useState("loading"),[G,T]=i.useState(""),[K,E]=i.useState("idle"),[V,z]=i.useState(""),b=i.useRef(null),u=i.useRef(null),p=i.useRef([]),B=i.useRef(Promise.resolve()),re=i.useRef(0),f=i.useRef(0);i.useEffect(()=>{const s=++f.current;let l=!0;return p.current=[],u.current=null,b.current=null,B.current=Promise.resolve(),v("loading"),C("/api/settings",void 0,t).then(o=>{if(!l||s!==f.current)return;const c=J(o);u.current=c,b.current=c,k(c),v("saved")}).catch(o=>{!l||s!==f.current||(T(o instanceof Error?o.message:String(o)),u.current=x,b.current=x,k(x),v("failed"))}),()=>{l=!1}},[t]);const ce=async(s,l,o)=>{const c={id:++re.current,section:s,key:l,value:o},H=f.current;p.current.push(c);const L=_(b.current||u.current||x,c);b.current=L,k(L),v("saving"),T(""),B.current=B.current.then(async()=>{if(H!==f.current)return;let S=null,y=null;for(let N=0;N<2&&!S;N+=1){const xe=u.current||x;try{const w=await C("/api/settings",{method:"PATCH",body:JSON.stringify({revision:xe.revision,[c.section]:{[c.key]:c.value}})},t);S=J(w)}catch(w){if(y=w,N!==0||!String(w instanceof Error?w.message:w).startsWith("409 "))break;try{const W=await C("/api/settings",void 0,t);if(H!==f.current)return;u.current=J(W)}catch(W){y=W;break}}}if(H!==f.current)return;p.current=p.current.filter(N=>N.id!==c.id),S&&(u.current=S);const fe=u.current||x,X=p.current.reduce(_,fe);b.current=X,k(X),S?(T(""),v(p.current.length>0?"saving":"saved")):(v(p.current.length>0?"saving":"failed"),T(y instanceof Error?y.message:String(y||"Settings could not be saved.")))}),await B.current},h=(s,l)=>o=>{ce(s,l,o)},ae=async()=>{if(d!=="hub"||!m||!a){E("failed"),z("Sign in to this Hub before changing its runtime role.");return}E("changing"),z("");try{const s=await C("/api/runtime/status",void 0,t);await C("/api/runtime/role",{method:"POST",headers:{Authorization:`Bearer ${a}`},body:JSON.stringify({role:"client"})},t),E("accepted"),await je({baseUrl:t,targetRole:"client",previousRuntimePid:Number(s.runtimePid||0),allowedStates:["running","waiting-auth"]}),ve(5179)}catch(s){E("failed"),z(s instanceof Error?s.message:String(s))}},le=A(j,"security"),Z=A(j,"control"),P=A(j,"filesAudio"),I=A(j,"connection"),de=`settings-panel-${r}`,ue=n?Y.filter(s=>s.id!=="connection"):Y;i.useEffect(()=>{n&&r==="connection"&&q("remote-access")},[r,n]),i.useEffect(()=>{j&&D?.(!!I.showThisComputer)},[I.showThisComputer,D,j]);const he=e.jsxs("div",{className:"settings-tab-content product-settings-content",children:[te,ie,M&&e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Hub computer list"}),e.jsx("h3",{children:"This computer"})]}),e.jsx(F,{size:20})]}),e.jsx(g,{icon:F,title:"Show this computer",description:"Show this Hub computer in its own Wall and computer lists. It stays available from other computers and the mobile app when hidden.",children:e.jsx(R,{checked:!!I.showThisComputer,onChange:h("connection","showThisComputer"),label:"Show this computer"})})]}),e.jsxs("section",{className:"settings-section-card runtime-role-settings",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Runtime role"}),e.jsx("h3",{children:"Use this computer as a Client"})]}),e.jsx(Re,{size:20})]}),e.jsx("p",{className:"settings-help",children:"Stop hosting from this computer and reconnect it to the selected Hub."}),K==="accepted"?e.jsx("p",{className:"settings-help runtime-role-success",children:"VuvoDesk is restarting as Client."}):V?e.jsx("p",{className:"settings-help runtime-role-error",role:"alert",children:V}):null,e.jsx("button",{className:"settings-reset",onClick:()=>{ae()},disabled:K==="changing"||d!=="hub",type:"button",children:K==="changing"?"Switching role...":"Switch this computer to Client"})]})]}),ge=e.jsxs("div",{className:"settings-tab-content product-settings-content",children:[e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Remote access"}),e.jsx("h3",{children:"Who may connect?"})]}),e.jsx(Se,{size:20})]}),e.jsx(g,{icon:ee,title:"Access mode",description:"Choose the default permission boundary for remote sessions.",recommended:!0,children:e.jsx(U,{value:String(le.accessMode),onChange:h("security","accessMode"),label:"Access mode",options:[["trusted-only","Trusted devices only"],["block-remote-access","Block remote access"]]})})]}),e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Session permissions"}),e.jsx("h3",{children:"What may remote users do?"})]}),e.jsx(F,{size:20})]}),e.jsx(g,{icon:F,title:"Keyboard and mouse control",description:"Allow Control to send keyboard and pointer input.",recommended:!0,children:e.jsx(R,{checked:!!Z.allowKeyboardMouse,onChange:h("control","allowKeyboardMouse"),label:"Keyboard and mouse control"})}),e.jsx(g,{icon:ye,title:"Power actions",description:"Allow confirmed sleep, restart, and shut down commands from the Hub.",children:e.jsx(R,{checked:!!Z.allowRemoteRestart,onChange:h("control","allowRemoteRestart"),label:"Power actions"})}),e.jsx(g,{icon:O,title:"File transfer",description:"Allow files to be delivered to connected computers.",children:e.jsx(R,{checked:!!P.allowFileTransfer,onChange:h("filesAudio","allowFileTransfer"),label:"File transfer"})}),e.jsx(g,{icon:$,title:"Remote audio",description:"Allow sound capture from connected computers.",children:e.jsx(R,{checked:!!P.allowRemoteAudio,onChange:h("filesAudio","allowRemoteAudio"),label:"Remote audio"})})]})]}),me=e.jsxs("div",{className:"settings-tab-content product-settings-content",children:[e.jsxs("section",{className:"settings-section-card",children:[e.jsxs("div",{className:"settings-section-heading",children:[e.jsxs("div",{children:[e.jsx("span",{children:"Capture"}),e.jsx("h3",{children:"Recording defaults"})]}),e.jsx(O,{size:20})]}),e.jsx(g,{icon:$,title:"Keep a Last 30s buffer",description:"Keep recent video in memory until you explicitly save it.",children:e.jsx(R,{checked:!!P.rollingBufferEnabled,onChange:h("filesAudio","rollingBufferEnabled"),label:"Keep a Last 30s buffer"})}),e.jsx(g,{icon:$,title:"Timelapse interval",description:"Choose how often a timelapse frame is captured.",children:e.jsx(U,{value:Number(P.timelapseIntervalSeconds),onChange:s=>h("filesAudio","timelapseIntervalSeconds")(Number(s)),label:"Timelapse interval",options:[["5","5 seconds"],["10","10 seconds"],["30","30 seconds"],["60","60 seconds"]]})})]}),ne]}),pe=r==="connection"?he:r==="remote-access"?ge:r==="capture-audio"?me:se;return e.jsxs("section",{className:"settings-page",children:[e.jsx("div",{className:"settings-page-tabs",role:"tablist","aria-label":"VuvoDesk settings",children:ue.map(({id:s,label:l,icon:o})=>e.jsxs("button",{className:r===s?"active":"",id:`settings-tab-${s}`,role:"tab","aria-selected":r===s,"aria-controls":`settings-panel-${s}`,tabIndex:r===s?0:-1,onClick:()=>q(s),type:"button",children:[e.jsx(o,{size:16}),l]},s))}),oe==="saving"&&e.jsx("div",{className:"product-save-state",role:"status",children:"Saving settings..."}),G&&e.jsx("div",{className:"agent-settings-alert error",role:"alert",children:G}),e.jsx("section",{className:"settings-page-panel",id:de,role:"tabpanel","aria-labelledby":`settings-tab-${r}`,tabIndex:0,children:pe})]})}export{ke as SettingsPage};
@@ -1 +1 @@
1
- import{j as i}from"./styles-Ba1tPFHg.js";import"./icons-CacEbnZu.js";import"./react-Cfedt3N5.js";function r({children:t}){return i.jsx("div",{className:"settings-tab-content",children:t})}export{r as PinSettingsTab};
1
+ import{j as i}from"./styles-eZ2IzXEL.js";import"./icons-CacEbnZu.js";import"./react-Cfedt3N5.js";function r({children:t}){return i.jsx("div",{className:"settings-tab-content",children:t})}export{r as PinSettingsTab};