Stage 17 (#3,#5,#10): hover-hold drag zoom, always-editable profile, drag-back + double-tap recall
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 27s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 56s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 27s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 56s
- Board drag now auto-zooms toward a cell after holding the tile over it ~1s (#3). - Profile is inline-editable: drop the Edit/Cancel toggle, form is always shown for durable accounts; hint balance stays read-only; re-populate after link/merge (#5). - A pending tile recalls by double-tap (same cell) or by dragging it back onto the rack (unzoomed board); a single tap no longer recalls (#10). - e2e: lock double-tap recall + single-tap no-op; drop the removed Edit-profile click.
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
focus,
|
||||
oncell,
|
||||
ontogglezoom,
|
||||
onrecall,
|
||||
onpenddown,
|
||||
}: {
|
||||
board: (BoardCell | null)[][];
|
||||
premium: Premium[][];
|
||||
@@ -34,6 +36,10 @@
|
||||
focus: { row: number; col: number } | null;
|
||||
oncell: (row: number, col: number) => void;
|
||||
ontogglezoom: (row: number, col: number) => void;
|
||||
/** Recall the pending tile at (row, col) — fired on a double-tap of a pending cell. */
|
||||
onrecall: (row: number, col: number) => void;
|
||||
/** Pointer-down on a pending cell, to start dragging that tile back to the rack. */
|
||||
onpenddown: (e: PointerEvent, row: number, col: number) => void;
|
||||
} = $props();
|
||||
|
||||
const Z = 1.85;
|
||||
@@ -60,16 +66,26 @@
|
||||
return () => cancelAnimationFrame(raf);
|
||||
});
|
||||
|
||||
// Double-tap toggles zoom (pinch was dropped — it conflicts with native scroll).
|
||||
// Double-tap a pending tile recalls it; double-tap any other cell toggles zoom toward
|
||||
// it. A single tap places a selected rack tile (handled by oncell). Drag also auto-zooms
|
||||
// toward a cell the held tile hovers over (handled in Game), so the one-finger native
|
||||
// scroll of the zoomed board is never hijacked by a pinch gesture.
|
||||
let lastTap = 0;
|
||||
let lastCell = '';
|
||||
function onTap(row: number, col: number) {
|
||||
const now = Date.now();
|
||||
if (now - lastTap < 300) {
|
||||
ontogglezoom(row, col); // zoom toward the double-tapped cell, not the top-left
|
||||
const k = key(row, col);
|
||||
// A double-tap counts only when it lands twice on the same cell, so quick taps across
|
||||
// different cells don't coalesce into a stray recall/zoom.
|
||||
if (k === lastCell && now - lastTap < 300) {
|
||||
lastTap = 0;
|
||||
lastCell = '';
|
||||
if (pending.has(k)) onrecall(row, col);
|
||||
else ontogglezoom(row, col);
|
||||
return;
|
||||
}
|
||||
lastTap = now;
|
||||
lastCell = k;
|
||||
oncell(row, col);
|
||||
}
|
||||
|
||||
@@ -95,6 +111,7 @@
|
||||
data-row={r}
|
||||
data-col={c}
|
||||
onclick={() => onTap(r, c)}
|
||||
onpointerdown={(e) => { if (!!p && !cell) onpenddown(e, r, c); }}
|
||||
>
|
||||
{#if letter}
|
||||
<span class="letter">{letter}</span>
|
||||
|
||||
Reference in New Issue
Block a user