The relay's ack path is drawn under the stroke when the key's version nibble is >= 2 (ADR-0014's ordered turning chain decodes to the stroke itself); a v1 key's blob stays hidden. Safe to ship ahead of the relay: nothing shows until the relay encodes v2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
72674afe05
commit
12e9fcd609
+17
-5
@@ -12,10 +12,11 @@
|
|||||||
//
|
//
|
||||||
// When a relay URL is given, the widget also speaks the redoal-relay
|
// When a relay URL is given, the widget also speaks the redoal-relay
|
||||||
// protocol (ADR-0013 in the redoal repo): announce the stroke, receive
|
// protocol (ADR-0013 in the redoal repo): announce the stroke, receive
|
||||||
// an ack carrying the stroke's gesture key (the decoded path it also
|
// an ack carrying the stroke's gesture key plus the key's own decoded
|
||||||
// carries is ignored: decode_key's sketch is too rough to show), and
|
// path - "what the network heard", drawn as a ghost under the stroke
|
||||||
// receive echoes of similar strokes other visitors drew, shown as
|
// when the key is v2 or later (ADR-0014's ordered turning chain; a v1
|
||||||
// thumbnails.
|
// key's histogram decode is a blob and stays hidden) - and receive
|
||||||
|
// echoes of similar strokes other visitors drew, shown as thumbnails.
|
||||||
// Everything network is best-effort: no relay, refused connection, or
|
// Everything network is best-effort: no relay, refused connection, or
|
||||||
// a dropped socket all degrade to a plain offline drawing input.
|
// a dropped socket all degrade to a plain offline drawing input.
|
||||||
//
|
//
|
||||||
@@ -28,10 +29,12 @@ const THEMES = {
|
|||||||
dark: {
|
dark: {
|
||||||
stroke: '#8ec2c0',
|
stroke: '#8ec2c0',
|
||||||
echo: '#8ec2c0',
|
echo: '#8ec2c0',
|
||||||
|
ghost: 'rgba(255, 255, 255, 0.28)',
|
||||||
},
|
},
|
||||||
light: {
|
light: {
|
||||||
stroke: '#47807e',
|
stroke: '#47807e',
|
||||||
echo: '#47807e',
|
echo: '#47807e',
|
||||||
|
ghost: 'rgba(29, 29, 27, 0.30)',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,6 +48,7 @@ class GestureWidget {
|
|||||||
this.container = container;
|
this.container = container;
|
||||||
this.hidden = hidden || null;
|
this.hidden = hidden || null;
|
||||||
this.relayUrl = relayUrl || '';
|
this.relayUrl = relayUrl || '';
|
||||||
|
this.ghost = null;
|
||||||
this.points = [];
|
this.points = [];
|
||||||
this.drawing = false;
|
this.drawing = false;
|
||||||
this.stopped = false;
|
this.stopped = false;
|
||||||
@@ -109,8 +113,9 @@ class GestureWidget {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.canvas.setPointerCapture(e.pointerId);
|
this.canvas.setPointerCapture(e.pointerId);
|
||||||
// One stroke only - a new pointerdown replaces the old drawing
|
// One stroke only - a new pointerdown replaces the old drawing
|
||||||
// (and any ambient trails from the previous round).
|
// (and any ghost from the previous round).
|
||||||
this.drawing = true;
|
this.drawing = true;
|
||||||
|
this.ghost = null;
|
||||||
this.points = [this.pos(e)];
|
this.points = [this.pos(e)];
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
@@ -212,6 +217,10 @@ class GestureWidget {
|
|||||||
if (this.points.length >= 2) {
|
if (this.points.length >= 2) {
|
||||||
this.setValue({ points: this.normalized(), key: msg.key });
|
this.setValue({ points: this.normalized(), key: msg.key });
|
||||||
}
|
}
|
||||||
|
// Version nibble is the key's first hex digit.
|
||||||
|
const version = parseInt((msg.key || '0')[0], 16);
|
||||||
|
this.ghost = version >= 2 && Array.isArray(msg.path) ? msg.path : null;
|
||||||
|
this.render();
|
||||||
} else if (msg.type === 'echo') {
|
} else if (msg.type === 'echo') {
|
||||||
this.addEchoThumbnail(msg);
|
this.addEchoThumbnail(msg);
|
||||||
}
|
}
|
||||||
@@ -268,6 +277,9 @@ class GestureWidget {
|
|||||||
if (!this.ctx) return;
|
if (!this.ctx) return;
|
||||||
const t = this.theme();
|
const t = this.theme();
|
||||||
this.ctx.clearRect(0, 0, this.cssWidth, this.cssHeight);
|
this.ctx.clearRect(0, 0, this.cssWidth, this.cssHeight);
|
||||||
|
if (this.ghost) {
|
||||||
|
this.drawPath(this.ctx, this.ghost, this.cssWidth, this.cssHeight, t.ghost, 2, 0.2);
|
||||||
|
}
|
||||||
if (this.points.length >= 1) {
|
if (this.points.length >= 1) {
|
||||||
this.ctx.strokeStyle = t.stroke;
|
this.ctx.strokeStyle = t.stroke;
|
||||||
this.ctx.lineWidth = 2;
|
this.ctx.lineWidth = 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user