Stage 17 round 6 (#3): drag-reorder rack tiles with a visual gap
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 30s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m7s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 30s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m7s
Dragging a rack tile and dropping it back on the rack reorders it: the dragged tile is lifted out (the drag ghost stands in) and the tiles at/after the pointer's drop slot slide right to open a gap there, so the drop position is visible. On drop the rack and its stable ids are permuted (reorderIndices, unit-tested). Reorder applies only with no pending tiles, so it stays a clean permutation; dropping on a board cell still places as before. Server persistence of the order follows (#4).
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
rackView,
|
||||
recallAt,
|
||||
recallIndex,
|
||||
reorderIndices,
|
||||
reset,
|
||||
toSubmit,
|
||||
} from './placement';
|
||||
@@ -122,3 +123,12 @@ describe('placementFromHint', () => {
|
||||
expect(p.pending.map((t) => t.letter)).toEqual(['A']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reorderIndices', () => {
|
||||
it('lifts an element and drops it at the given slot among the others', () => {
|
||||
expect(reorderIndices(4, 0, 2)).toEqual([1, 2, 0, 3]);
|
||||
expect(reorderIndices(4, 3, 0)).toEqual([3, 0, 1, 2]);
|
||||
expect(reorderIndices(4, 1, 1)).toEqual([0, 1, 2, 3]); // back to identity
|
||||
expect(reorderIndices(3, 0, 99)).toEqual([1, 2, 0]); // slot clamped to the end
|
||||
});
|
||||
});
|
||||
|
||||
@@ -106,6 +106,19 @@ export function reset(p: Placement): Placement {
|
||||
return { ...p, pending: [] };
|
||||
}
|
||||
|
||||
/**
|
||||
* reorderIndices returns the permutation of [0, n) that lifts the element at `from` and
|
||||
* drops it at slot `toSlot` among the remaining elements (clamped to a valid slot). It is
|
||||
* applied in parallel to the rack letters and their stable ids when a tile is dragged to a
|
||||
* new rack position.
|
||||
*/
|
||||
export function reorderIndices(n: number, from: number, toSlot: number): number[] {
|
||||
const order: number[] = [];
|
||||
for (let i = 0; i < n; i++) if (i !== from) order.push(i);
|
||||
order.splice(Math.max(0, Math.min(toSlot, order.length)), 0, from);
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
* direction infers the play orientation from the pending tiles: H if they share a row,
|
||||
* V if they share a column, null if a single tile (ambiguous) or non-linear (invalid).
|
||||
|
||||
Reference in New Issue
Block a user