Add live drag-reorder preview to dash grid with spatial fold/reorder - #108
Add live drag-reorder preview to dash grid with spatial fold/reorder#108RobinJ1995 wants to merge 3 commits into
Conversation
Dragging apps to reorder the dash under the custom sort order previously had no live feedback: the icons stayed put and only jumped into place on drop, and fold-vs-reorder was distinguished by a dwell timer. This makes the dash mirror the launcher bar's reorder preview. The dragged loose app or whole folder now becomes an empty placeholder cell (GridAdapter.setHiddenKey, keyed by DashItem.stableKey) and the distinction between reordering and foldering is spatial, like LauncherDragListener: over a cell's centre (the 0.3-0.7 horizontal band) rings it for a folder create/add and freezes the gap; over a cell's edge or the space between cells opens a reorder gap there (custom order only). The other icons flow around the gap as the finger moves — the listener reorders the adapter's items live as a preview over the untouched model and animates each cell from its old slot to its new one with a pre-draw translate, so they slide rather than jump. The drop commits the previewed order through DashLayoutRepository.moveItem. Folder-member extraction keeps its simpler pause-to-fold gesture. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D594DCEMgKkkceo5McSkKU
The GeoGrid test harness dereferenced its own `gridAdapter` field from getChildCount()/getChildAt()/pointToPosition() overrides, but the GridView super-constructor invokes those before the subclass field is initialised, so every GeoGrid-based test threw an NPE at construction. Route the overrides through the null-safe getAdapter() instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D594DCEMgKkkceo5McSkKU
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7e3a1a24e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (position == AdapterView.INVALID_POSITION) { | ||
| // Past the last icon / empty area: preview an append (custom order only). | ||
| this.setFold(grid, null) | ||
| if (custom) { | ||
| this.previewInsertAt(grid, this.baseItems.size) |
There was a problem hiding this comment.
Avoid appending from the title padding
When custom ordering is enabled, this treats every INVALID_POSITION as the empty area after the last icon, but the dash grid also reserves the overlaid profile title by adding top padding in ProfilePagerAdapter.onBindViewHolder. Dragging or dropping in that top/title padding has no child under the pointer, so pointToPosition is invalid and the preview moves the item to the end even though the user is above the first row, accidentally corrupting the manual order. Please only append for invalid positions below the last laid-out cell (or otherwise exclude the top padding).
Useful? React with 👍 / 👎.
A dash reorder treated every INVALID_POSITION under the pointer as the empty area after the last icon and moved the item to the end. But the dash grid reserves the overlaid profile title as top padding, so dragging or dropping in that padding above the first row also has no cell under the pointer — which wrongly appended the item and corrupted the manual order. Restrict the append to points genuinely below the last laid-out cell. Reported by Codex review on the PR. Adds tests for both the append and the padding-guard cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D594DCEMgKkkceo5McSkKU
Summary
Replaces the pause-to-fold gesture for loose apps and folders with a spatial, live-preview reorder system that mirrors the launcher bar's behavior. Dragging over a cell's centre rings it for folding; dragging over an edge opens a reorder gap. The dragged item becomes an invisible placeholder that flows through the grid as the finger moves, with a smooth reflow animation when the gap position changes.
Key Changes
setHiddenKey()to mark the dragged cell as invisible andsetItems()to update the display order during previewGeoGridwith deterministic cell geometry instead of mockingpointToPosition, enabling precise targeting of cell centres vs edgesImplementation Details
draggedKey,draggedItem,baseItems(order without dragged item),previewIndex(current gap position), andfoldTargetKey(ringed target or null)resolveAndPreview()determines fold vs reorder based onhorizontalFraction()within the cell and updates the preview viapreviewInsertAt()animateReflow()usesViewTreeObserver.OnPreDrawListenerto capture old positions, update the adapter, then animate each icon's translation to its new positionACTION_DRAG_ENDEDto restore visibility and model order if the drag was cancelledhttps://claude.ai/code/session_01D594DCEMgKkkceo5McSkKU