app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
← Commit history
Dashboard 1.0.119: the recording is an inline thumbnail with a play button under Play the demo; native controls, fullscreen via Hydrogen
2 files changed
+25−49
dashboard/ui/index.html+24−48@@ -321,15 +321,13 @@ main a:hover{border-bottom-color:var(--accent)} .note{font-size:12.5px;color:var(--text-2);margin:-6px 0 12px} .wins{font:12.5px 'JetBrains Mono',monospace;color:var(--text-2)} -/* ── recorded tour lightbox (John, 2026-09-05) ─────────────────────────── */-.anp-video{margin-left:8px;}-#vidBox{display:none;position:fixed;inset:0;z-index:9000;background:rgba(6,9,14,.94);flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:16px;}-#vidBox .vb-bar{display:flex;align-items:center;gap:10px;width:min(96vw,1400px);color:#c9d3df;font-size:14px;}-#vidBox .vb-sp{flex:1;}-#vidBox .vb-bar button{background:#161b22;color:#e6edf3;border:1px solid #2a3341;border-radius:8px;padding:6px 10px;cursor:pointer;font-size:13px;}-#vidBox .vb-bar button:hover{border-color:#2dd4bf;}-#vidBox video{width:min(96vw,1400px);max-height:calc(100vh - 80px);background:#000;border-radius:10px;outline:none;}-#vidBox:fullscreen{padding:24px;} #vidBox:fullscreen video{width:min(96vw,1800px);max-height:calc(100vh - 90px);}+/* ── inline demo recording (John, 2026-09-05) ─────────────────────────── */+.demo-clip{position:relative;margin-top:10px;width:min(100%,360px);border-radius:10px;overflow:hidden;background:#000;border:1px solid #2a3341;}+.demo-clip video{display:block;width:100%;aspect-ratio:16/9;background:#000;}+.demo-clip .clip-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:56px;height:56px;border-radius:50%;border:0;background:rgba(45,212,191,.92);color:#04121a;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 18px rgba(0,0,0,.45);}+.demo-clip .clip-play:hover{background:#2dd4bf;transform:translate(-50%,-50%) scale(1.06);}+.demo-clip .clip-cap{position:absolute;left:0;right:0;bottom:0;padding:22px 10px 8px;font-size:12px;color:#e6edf3;background:linear-gradient(transparent,rgba(0,0,0,.75));pointer-events:none;}+.demo-clip.playing .clip-play,.demo-clip.playing .clip-cap{display:none;} </style> </head> <body>@@ -643,48 +641,26 @@ function doMount(phrases){ }); mountVideo(); }-// ── the recorded tour, right in the newbie panel (John, 2026-09-05) ─────────-// The recording starts at the Play click (the viewer is already in this-// dashboard, so no dock-bar or dashboard explanation). Plays in a lightbox that-// fills this webview; the fullscreen button asks the host for real fullscreen,-// which works when the hosting iframe allows it and otherwise keeps the lightbox.+// ── the recorded tour, inline in the newbie panel (John, 2026-09-05) ───────+// A small thumbnail with a play button under the demo button; it plays right+// there, and the player's own fullscreen control hands off to Hydrogen, whose+// WebView2 grows the webview to 90% of the window on the standard Fullscreen API. const DEMO_VIDEO_URL='https://wiki.adom.inc/api/pages/adom/kicad-bridge/files/docs/videos/kicad-demo-tour.mp4';+const DEMO_VIDEO_POSTER='https://wiki.adom.inc/api/pages/adom/kicad-bridge/files/docs/videos/kicad-demo-tour-poster.jpg'; function mountVideo(){- const demoBtn=document.querySelector('#newbie .anp-demo'); if(!demoBtn||document.getElementById('btnVideo'))return;- const b=document.createElement('button'); b.type='button'; b.id='btnVideo'; b.className='anp-demo anp-video';- b.innerHTML='<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M10 9l5 3-5 3z"/></svg><span>Watch the recording</span>';- b.title='The same six views, recorded on a real desktop (2 min 50 s)';- b.addEventListener('click',openVideo);- demoBtn.insertAdjacentElement('afterend',b);+ const demoBtn=document.querySelector('#newbie .anp-demo'); if(!demoBtn||document.getElementById('demoClip'))return;+ const col=demoBtn.parentElement;+ const wrap=document.createElement('div'); wrap.id='demoClip'; wrap.className='demo-clip';+ wrap.innerHTML='<video id="demoVideo" poster="'+DEMO_VIDEO_POSTER+'" preload="none" playsinline controls controlslist="nodownload"></video>'++ '<button type="button" class="clip-play" aria-label="Play the recording"><svg viewBox="0 0 24 24" width="28" height="28" fill="currentColor"><path d="M8 5v14l11-7z"/></svg></button>'++ '<div class="clip-cap">The demo, recorded (2:51)</div>';+ col.appendChild(wrap);+ const v=wrap.querySelector('video'), play=wrap.querySelector('.clip-play');+ play.addEventListener('click',()=>{ if(!v.src){ v.src=DEMO_VIDEO_URL; } wrap.classList.add('playing'); v.play().catch(()=>{}); });+ v.addEventListener('pause',()=>{ if(!document.fullscreenElement) wrap.classList.remove('playing'); });+ v.addEventListener('play',()=>wrap.classList.add('playing'));+ v.addEventListener('ended',()=>{ wrap.classList.remove('playing'); }); }-function openVideo(){- // Hydrogen Desktop's WebView2 implements the standard Fullscreen API by growing- // the webview to 90% of the HD window (the shotlog lightbox relies on it). The- // request must run straight from the click (no await before it) or the gesture- // is lost; the fixed overlay is the fallback when the host refuses.- let box=document.getElementById('vidBox');- if(!box){- box=document.createElement('div'); box.id='vidBox';- box.innerHTML='<div class="vb-bar"><span>KiCad Bridge demo, recorded</span><span class="vb-sp"></span>'+- '<button type="button" id="vbFull" title="Fullscreen">⛶ Fullscreen</button><button type="button" id="vbClose" title="Close">✕</button></div>'+- '<video id="vbVideo" controls autoplay playsinline preload="metadata"></video>';- document.body.appendChild(box);- box.querySelector('#vbClose').addEventListener('click',closeVideo);- box.addEventListener('click',e=>{ if(e.target===box) closeVideo(); });- box.querySelector('#vbFull').addEventListener('click',()=>{ goFull(box); });- document.addEventListener('keydown',e=>{ if(e.key==='Escape'&&box.style.display!=='none'&&!document.fullscreenElement) closeVideo(); });- document.addEventListener('fullscreenchange',()=>{ if(!document.fullscreenElement&&box.dataset.wasFull==='1'){ box.dataset.wasFull=''; closeVideo(); } });- }- const v=box.querySelector('#vbVideo'); v.src=DEMO_VIDEO_URL; box.style.display='flex';- goFull(box);- v.play().catch(()=>{});-}-function goFull(box){- try{- if(box.requestFullscreen){ box.dataset.wasFull='1'; box.requestFullscreen().catch(()=>{ box.dataset.wasFull=''; }); }- }catch(e){ box.dataset.wasFull=''; }-}-function closeVideo(){ const box=document.getElementById('vidBox'); if(!box)return; const v=box.querySelector('#vbVideo'); v.pause(); v.removeAttribute('src'); v.load(); box.style.display='none'; } // Guided demo with a REAL progress bar + the stepShot stream (one screenshot per finished beat). async function startDemo(){ toast(demoMuted()?'starting the guided demo MUTED (narration off): click the speaker on the pill or the remote to unmute':'starting the guided demo');
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "kicad-bridge",- "version": "1.0.118",+ "version": "1.0.119", "type": "app", "description": "Skills for your container so your AI knows how to drive the KiCad bridge. The bridge runtime itself is the release zip; Adom Bridge loads that.", "tags": [