mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
feat(tiles): move tiles by hand, and detach a tile into its own window
Gesture control now moves tiles: with the tile grid open, pinch anywhere on a tile and carry it onto another tile (they swap) or an empty cell (it moves there); a session tab carried onto the grid joins it there. The overlay asks tile-grid.js what is under the hand (tileAtPoint, tileDropTargetAt) and drops through the mouse drag's own paths (dropSessionOnTile / dropSessionOnSlot, so _reorderTiles stays the one move path). Detach Tiles (App Settings > Appearance, per device, OFF by default, desktop only): - a tile's header let go outside the browser window opens the session as a pop-out (detachSession, which now takes an optional size and screen position), the tile's size, near the drop point, after a 120 ms settle; - dropped on another Codeman window's tiles it moves there: that window docks it through the target's own drop and posts 'tile-adopted' on the window channel, and only the window it was dragged from lets go of its copy (a last tile goes to the welcome screen, never onto that session); - a pop-out's title drags back onto any grid: the session is taken back, the pop-out is asked to close and is released (stops answering roll-calls; one a script cannot close says where the session went), and its stale 'detached' answers are ignored for 2 s; - a tile's menu offers "Open in a new window", and a hand that lets a tile go outside the grid pops it out too. With the setting off nothing changes. No server change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
3d59e59e37
commit
2c55fe907e
16 files changed
+1469
-39
No files matched your search
@@ -213,6 +213,8 @@ export const bySelector = new Map<string, FakeEl>();
|
||||
export const body = new FakeEl();
|
||||
/** The context's `fetch`; a test sets what it answers. */
|
||||
export const fetchSpy = vi.fn(async (..._args: unknown[]) => ({ ok: true, json: async () => ({}) }));
|
||||
/** What `document.elementFromPoint` answers (the gesture overlay's hit test); a test sets it. */
|
||||
export const pointHits: { at: ((x: number, y: number) => FakeEl | null) | null } = { at: null };
|
||||
/** `document.addEventListener`, so a test can find a listener the app installed. */
|
||||
export const documentAddEventListener = vi.fn();
|
||||
export const documentRemoveEventListener = vi.fn();
|
||||
@@ -280,6 +282,7 @@ const context = vm.createContext({
|
||||
return focusedEl;
|
||||
},
|
||||
getElementById: (id: string) => (id === 'tileGrid' ? section : (bySelector.get(`#${id}`) ?? null)),
|
||||
elementFromPoint: (x: number, y: number) => pointHits.at?.(x, y) ?? null,
|
||||
body,
|
||||
querySelector: (sel: string) =>
|
||||
bySelector.get(sel) ?? (sel === '.main' ? main : sel === '.terminal-wrap' ? wrap : null),
|
||||
@@ -389,4 +392,5 @@ export function resetGridHarness() {
|
||||
main.appendChild(section);
|
||||
bySelector.clear();
|
||||
body.children = [];
|
||||
pointHits.at = null;
|
||||
}
|
||||
Reference in new issue
Block a user