Public: anyone can read this; the crew can change it.
A card can be moved with a thumb: touch dragging, and a fallback that picks a position #46
Check · Review · Land · Live done — Landed and live in production.
A card can now be moved with a thumb: a long-press touch path sits beside the existing mouse drag, and both end in the same `commitMove()` so exactly one path ever posts a move.
shipped production is serving it deploy fc047f8
Merged main in and pushed. The only real conflict was in the README's Dependencies section (both sides had added a sentence about their own new test file); I combined them so happy-dom's role is credited to drag.test.ts, touch.test.ts, theme.test.ts, and boards.test.ts together. src/pages/board.ts merged automatically — the Top/Bottom move control and the guest-boards-list feature from main don't overlap.
Merging main also brought in boards.test.ts and tty.test.ts, which, combined with touch.test.ts's own board creation, pushed the whole suite's cumulative use of the shared boardCreationBucket token bucket over its 30/minute budget again. I fixed this the same way server.test.ts already does (per its own comment): building touch.test.ts's board straight from db.createBoard() instead of POST /boards, so it no longer draws from that shared limiter at all. bun test is green (101 pass) across repeated runs.
A card can now be moved with a thumb: a long-press touch path sits beside the existing mouse drag, and both end in the same
commitMove()so exactly one path ever posts a move.What changed
static/board.<newhash>.js:pointerdown/pointermove/pointerup(bound topointerType !== "mouse") drives a 300ms long press that picks a card up with the same.dragging/.drop-targetfeedback the mouse shows; before the press threshold a touch still scrolls the board, and a tap still focuses the title input. Holding a card within 48px of the board strip's edge auto-scrolls it into view.src/pages/board.ts: the move form's hiddenindex=999999is now a visible Top/Bottom choice — the no-JS/screen-reader path can reorder within a column, not just append..card .rowcontrols (Move dropdowns, buttons) grow to a 32px minimum touch target, and.boardgetsmax-width: 100%so the board's horizontal scroll stays inside the strip instead of the document.BOARD_JSpoints at the new script's content hash.src/touch.test.ts(new, shaped likedrag.test.ts): a long press then a move commits exactly once, a short swipe commits nothing, a mouse pointer sequence is left untouched for the existing drag path, and the Top/Bottom form postsindex=0versus the end of the column.README.md: documents the touch gesture and the new test file.What I left out: nothing from the issue's "done" list — auto-scroll landed cleanly, so it's included rather than deferred.
Worth noting:
src/touch.test.tsshares one board across its five tests instead of creating one per test. The board-creation route spends from a single, process-wide token bucket (limits.ts) that's shared by every test file in the samebun testprocess — the existing suite (db,drag,limits,live-refresh,server,theme,who) was already close to its 30/minute budget, and a naive one-board-per-test touch suite tipped it over, failing tests unrelated to touch itself. Sharing a board fixed that without touching other test files or the production rate limit.To try it:
bun run src/server.ts, open a board on a phone (or Chrome DevTools' touch emulation), create a couple of cards, and press-hold one for ~300ms to drag it between columns; a quick swipe should just scroll. With JavaScript off, each card's move form now offers Top/Bottom instead of only appending.Closes #21