@bivy/bivy 0.18.3 → 0.18.4-staging.1
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.
- package/dist/apps/preview-shell.js +11 -9
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ iframe { width:100%; height:100%; border:0; background:var(--bg); }
|
|
|
22
22
|
#dock > * { pointer-events:auto; }
|
|
23
23
|
/* The hint sits over the app; a tap on it is meant for the app underneath. */
|
|
24
24
|
#dock > #pointing { pointer-events:none; }
|
|
25
|
-
nav, #draw-bar { display:flex; align-items:center; gap:var(--space-1); max-width:100%; padding:var(--space-1); background:var(--surface); border:thin solid var(--line); border-radius:var(--radius-
|
|
25
|
+
nav, #draw-bar { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:var(--space-1); max-width:100%; padding:var(--space-1); background:var(--surface); border:thin solid var(--line); border-radius:var(--radius-xl); box-shadow:var(--shadow-lg); }
|
|
26
26
|
nav .btn, #draw-bar .btn { flex-shrink:0; border-radius:var(--radius-full); }
|
|
27
27
|
nav .btn[aria-pressed="true"] { background:var(--accent-soft); color:var(--accent); }
|
|
28
28
|
#name { display:flex; flex-direction:column; min-width:0; padding:0 var(--space-2); }
|
|
@@ -46,7 +46,7 @@ nav .btn[aria-pressed="true"] { background:var(--accent-soft); color:var(--accen
|
|
|
46
46
|
#draft-row { display:flex; align-items:flex-start; gap:var(--space-2); }
|
|
47
47
|
#draft-row #draft-text { flex:1; min-width:0; }
|
|
48
48
|
/* Hold to talk: a phone-sized target that never selects text or opens a callout. */
|
|
49
|
-
#mic { flex:none; inline-size:
|
|
49
|
+
#mic { flex:none; inline-size:var(--space-7); block-size:var(--space-7); padding:0; border-radius:var(--radius-full); touch-action:none; user-select:none; -webkit-user-select:none; -webkit-touch-callout:none; }
|
|
50
50
|
#mic[aria-pressed="true"] { background:var(--accent); border-color:var(--accent); color:var(--accent-contrast); }
|
|
51
51
|
#voice-status { font-size:var(--text-xs); margin:var(--space-2) 0 0; }
|
|
52
52
|
#voice-status:empty { display:none; }
|
|
@@ -58,14 +58,15 @@ nav .btn[aria-pressed="true"] { background:var(--accent-soft); color:var(--accen
|
|
|
58
58
|
/* Draw: marks over the frozen app (or Compare's "after" shot). The layer takes
|
|
59
59
|
every touch, so nothing reaches the app; two fingers scroll the page. */
|
|
60
60
|
#ink { position:fixed; z-index:var(--z-sticky); touch-action:none; cursor:crosshair; user-select:none; -webkit-user-select:none; -webkit-touch-callout:none; }
|
|
61
|
+
/* An HTML hit surface owns gestures even where the SVG has no painted marks. */
|
|
62
|
+
#ink svg { display:block; width:100%; height:100%; pointer-events:none; }
|
|
61
63
|
#ink.frozen { pointer-events:none; cursor:default; }
|
|
62
64
|
#ink .halo { fill:none; stroke:var(--annotate-halo); stroke-width:7; stroke-linecap:round; stroke-linejoin:round; }
|
|
63
65
|
#ink .mark { fill:none; stroke:var(--annotate); stroke-width:4; stroke-linecap:round; stroke-linejoin:round; }
|
|
64
66
|
#dock > #drawing { pointer-events:none; }
|
|
65
67
|
/* Hints float over the app, whose page may be any colour: back them solidly. */
|
|
66
68
|
#dock > .banner.inline[data-tone="accent"] { background:color-mix(in srgb, var(--accent) 14%, var(--surface)); box-shadow:var(--shadow-sm); }
|
|
67
|
-
#
|
|
68
|
-
#draw-bar .seg-btn { min-block-size:36px; min-inline-size:48px; }
|
|
69
|
+
#dock .btn, #dock .seg-btn, #show, #down .btn { min-block-size:var(--space-7); min-inline-size:var(--space-7); font-size:var(--text-sm); }
|
|
69
70
|
#draw-bar .segmented { flex-shrink:0; }
|
|
70
71
|
#compare-draw { margin-top:var(--space-2); }
|
|
71
72
|
/* Marking a Compare shot: make it big enough to draw on with a thumb. */
|
|
@@ -78,7 +79,7 @@ nav .btn[aria-pressed="true"] { background:var(--accent-soft); color:var(--accen
|
|
|
78
79
|
<div class="banner" data-tone="warn" id="down" hidden><span class="banner-text" id="down-text" role="status"></span><span class="banner-actions"><button class="btn sm" id="ask" hidden>Ask agent to fix</button></span></div>
|
|
79
80
|
<p id="status" role="status">Opening app…</p>
|
|
80
81
|
<div id="stage" data-lens="full"><iframe id="app" title="App preview" hidden sandbox="allow-scripts allow-same-origin allow-forms allow-downloads allow-popups" referrerpolicy="no-referrer"></iframe></div>
|
|
81
|
-
<
|
|
82
|
+
<div id="ink" hidden aria-hidden="true"><svg id="ink-marks"></svg></div>
|
|
82
83
|
<div id="dock">
|
|
83
84
|
<section class="panel" id="console" hidden aria-labelledby="console-title">
|
|
84
85
|
<h2><span id="console-title">Console</span><button class="btn sm ghost" id="clear">Clear</button></h2>
|
|
@@ -270,7 +271,7 @@ function picked(d){
|
|
|
270
271
|
// with that context; Add to chat hands them to the Bivy client, which gets a
|
|
271
272
|
// picture from the machine. Nothing about them goes through this origin's
|
|
272
273
|
// network. Compare's "after" shot can be marked the same way.
|
|
273
|
-
const ink=$('ink'),SVG='http://www.w3.org/2000/svg';
|
|
274
|
+
const ink=$('ink'),inkMarks=$('ink-marks'),SVG='http://www.w3.org/2000/svg';
|
|
274
275
|
let draw=null,marks=null,drawOk=false,nextStroke=0;
|
|
275
276
|
const pos=v=>({x:Number(v?.x)||0,y:Number(v?.y)||0});
|
|
276
277
|
function startDraw(target){
|
|
@@ -292,6 +293,7 @@ function startDraw(target){
|
|
|
292
293
|
current.waiting=d=>{current.waiting=null;current.scroll=pos(d.scroll);current.state={viewport:{width:Math.round(Number(d.viewport?.width))||current.state.viewport.width,height:Math.round(Number(d.viewport?.height))||current.state.viewport.height},dpr:Number(d.dpr)||devicePixelRatio,theme:d.theme==='dark'?'dark':'light',path:safePath(d.path),signals:Object.fromEntries(Object.entries(d.signals||{}).map(([k,v])=>[k,v===true]))};renderInk();};
|
|
293
294
|
frame.contentWindow?.postMessage({type:'bivy:draw'},metadata.origin);
|
|
294
295
|
}
|
|
296
|
+
for(const b of $('draw-bar').querySelectorAll('[data-tool]'))b.setAttribute('aria-checked',String(b.dataset.tool===draw.tool));
|
|
295
297
|
$('draw-bar').querySelector('[aria-checked="true"]').focus();
|
|
296
298
|
updateDrawBar();renderInk();
|
|
297
299
|
}
|
|
@@ -299,7 +301,7 @@ function startDraw(target){
|
|
|
299
301
|
function placeInk(target){
|
|
300
302
|
const r=(target==='compare'?$('compare-after'):frame).getBoundingClientRect();
|
|
301
303
|
Object.assign(ink.style,{left:r.left+'px',top:r.top+'px',width:r.width+'px',height:r.height+'px'});
|
|
302
|
-
|
|
304
|
+
inkMarks.setAttribute('viewBox','0 0 '+r.width+' '+r.height);
|
|
303
305
|
return {left:r.left,top:r.top,width:r.width,height:r.height};
|
|
304
306
|
}
|
|
305
307
|
// A rotation or a keyboard moves things: keep the layer on them. (Marks on
|
|
@@ -308,7 +310,7 @@ addEventListener('resize',()=>{if(draw&&!draw.done)draw.rect=Object.assign(place
|
|
|
308
310
|
function endDraw(){
|
|
309
311
|
if(!draw)return;
|
|
310
312
|
delete $('compare').dataset.drawing;
|
|
311
|
-
draw=null;marks=null;ink.toggleAttribute('hidden',true);
|
|
313
|
+
draw=null;marks=null;ink.toggleAttribute('hidden',true);inkMarks.replaceChildren();
|
|
312
314
|
$('drawing').hidden=true;$('draw-bar').hidden=true;document.querySelector('nav').hidden=false;
|
|
313
315
|
}
|
|
314
316
|
function updateDrawBar(){const has=Boolean(draw?.strokes.length);for(const id of ['draw-undo','draw-clear','draw-done'])$(id).disabled=!has;}
|
|
@@ -321,7 +323,7 @@ function shape(stroke){
|
|
|
321
323
|
function renderInk(){
|
|
322
324
|
if(!draw)return;
|
|
323
325
|
const all=[...draw.strokes,...(draw.current?[draw.current]:[])];
|
|
324
|
-
|
|
326
|
+
inkMarks.replaceChildren(...all.flatMap(s=>['halo','mark'].map(c=>{const el=shape(s);el.setAttribute('class',c);return el;})));
|
|
325
327
|
}
|
|
326
328
|
function local(e){const x=e.clientX-draw.rect.left,y=e.clientY-draw.rect.top;return draw.target==='frame'?[Math.round(x+draw.scroll.x),Math.round(y+draw.scroll.y)]:[Math.round(x),Math.round(y)];}
|
|
327
329
|
let scrollAsk=null;
|