ba9625d45d
CI / test (push) Has been cancelled
Subscribe per-device with a Symfony Mercure hub: server publishes a fresh device payload after every poll (200/304/204), every PATCH, and every lock/unlock. The frontend opens one EventSource per device topic and splats inbound JSON straight into the devices store — same shape as GET /api/devices, so no envelope handling. Topic: https://pictureframe.edholm.me/devices/{id} Stack mirrors aqua-iq: - symfony/mercure-bundle + config/packages/mercure.yaml - App\Service\MercurePublisher (errors swallowed + logged; a flaky hub must not break a poll response) - App\Service\DeviceSerializer extracted as the single source of truth for the wire shape (REST + Mercure share it) - Frontend useDeviceMercure() composable: opens/closes EventSources to match the device list reactively, reconnects on hub-side closes - SpaController exposes MERCURE_PUBLIC_URL via window.__PF_MERCURE_URL__ Production compose adds a dunglas/mercure container with Traefik labels for pictureframe.edholm.me/.well-known/mercure (handled separately on the host since the file isn't in this repo). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 line
1.7 KiB
JavaScript
1 line
1.7 KiB
JavaScript
import{K as e,d as t,dt as n,ft as r,j as i,k as a,m as o,p as s,pt as c,s as l,t as u,u as d,v as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,r as m,t as h}from"./index-CJkFKvc-.js";var g={class:`settings`},_={class:`settings__section`},v={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},y=[`aria-checked`,`aria-label`,`onClick`],b={class:`theme-swatch__label`},x={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},S={class:`settings__section`},C={class:`settings__row`},w={class:`settings__row-value`},T=u(f({__name:`SettingsView`,setup(u){let f=m(),{saveTheme:T}=p(),E=d(()=>f.user?.theme??`warm-craft`);function D(e){T(e)}return(u,d)=>(a(),o(`main`,g,[d[5]||=t(`h1`,{class:`settings__title`},`Settings`,-1),t(`section`,_,[d[1]||=t(`h2`,{class:`settings__section-title`},`Theme`,-1),t(`div`,v,[(a(!0),o(l,null,i(e(h),e=>(a(),o(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":E.value===e.id,"aria-label":e.label,class:n([`theme-swatch`,{"theme-swatch--active":E.value===e.id}]),style:r({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>D(e.id)},[d[0]||=t(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[t(`span`,{class:`theme-swatch__bar`}),t(`span`,{class:`theme-swatch__dot`})],-1),t(`span`,b,c(e.label),1),E.value===e.id?(a(),o(`span`,x,`✓`)):s(``,!0)],14,y))),128))])]),t(`section`,S,[d[3]||=t(`h2`,{class:`settings__section-title`},`Account`,-1),t(`div`,C,[d[2]||=t(`span`,{class:`settings__row-label`},`Signed in as`,-1),t(`span`,w,c(e(f).user?.email),1)]),d[4]||=t(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)])]))}}),[[`__scopeId`,`data-v-76ec3881`]]);export{T as default}; |