Repository navigation
Conversation
|
@ottob is attempting to deploy a commit to the Nuclear Pasta Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
LunatiqueCoder
left a comment
There was a problem hiding this comment.
🤖 posted by [drax] Reviewer, Ovidiu's review bot
thanks ottob, this fixes a real bug, and it's worse than the description says. one thing to sort out before merging.
repro on main (iOS): after a native drop in a standalone SortableContainer, stableData never updates, because the rawData effect sees the echoed order and returns early. I saw:
renderItemindexes and the built-in "Item N of M" a11y label stay stale (the top row reads "Item 2 of 6")- a later parent update that keeps the same key order is silently dropped (the parent has
D1, the list keeps showingD0) - on the next drag,
onReorderhands back the old item objects, so that edit is lost
with this PR all three are fixed: indexes and labels are right, the edit shows up immediately, and it survives the next reorder. worth adding the dropped-update and data-loss cases to the description, since they're a stronger reason than hit-testing.
the blocker: the setTimeout(0) reopens the race the web comment warns about. if a new drag starts after onReorder and before the flush fires, flushVisualOrder swaps stableData and clears committedOrderRef under the active drag, so pendingOrderRef points into the old array. I reproduced it: expected F E C D B A, got F E D B C A. the window is small, but main didn't have it on native. could native use the same synchronous flush as web? React batches the parent's setData with setStableData there. or at least skip or re-defer the flush while a drag is active.
optional hardening: if the parent doesn't store onReorder data, the flush sets stableData to the same reference, so the shift-clearing effect never runs while the committed refs do get cleared. the next drag then jumps. web already behaves this way; this extends it to native.
how I tested: yarn typecheck and yarn lint pass, and there are no unit tests yet. touch injection wasn't working on the simulator I had, so instead of finger drags I drove the real finalizeDrag path (the function this PR changes) from the debugger, on a temporary screen with a FlatList SortableContainer. the gesture, hover and animation code wasn't exercised, so a quick real-finger pass (two fast drags in a row, plus the cross-list screen) would still be good.
| // races when the user grabbed another item before it fired. | ||
| sortable._internal.flushVisualOrder(); | ||
| } else { | ||
| setTimeout(() => { |
There was a problem hiding this comment.
🤖 posted by [drax] Reviewer, Ovidiu's review bot
deferring with setTimeout(0) reopens the race described in the web comment above: a drag that starts after onReorder but before this fires gets stableData swapped and committedOrderRef cleared underneath it, and the drop scrambles the order (reproduced: expected F E C D B A, got F E D B C A). could native share the synchronous web path, or skip/re-defer while draggedItem.value !== -1?
| sortable._internal.flushVisualOrder(); | ||
| } else { | ||
| setTimeout(() => { | ||
| sortable._internal.flushVisualOrder(); |
There was a problem hiding this comment.
🤖 posted by [drax] Reviewer, Ovidiu's review bot
non-blocking: if the parent ignores onReorder, setStableData gets the same reference, so React bails out and the shift-clearing layout effect never runs, but the committed refs are cleared. the view keeps the dragged order while the hook thinks it's identity, and the next drag jumps. maybe guard for that in flushVisualOrder (useSortableList.ts:557).
Summary
sortable._internal.flushVisualOrder()is also called on native (iOS/Android) after a standaloneSortableContainer(DraxList) reorder completes.finalizeDragonly calledflushVisualOrder()whenboardContextwas present (setTimeout(..., 300)) or whenPlatform.OS === 'web'.stableDatawas never synced torawDataafter a reorder, leaving items permanently shifted viatranslateY/translateXtransforms rather than updating their actual layout order (which breaks native touch hit-testing on shifted child controls such asDraxHandleor buttons).