Skip to content

fix: prevent item jump on long-press and after reorder#115

Open
lumenwire wants to merge 4 commits intofivecar:mainfrom
lumenwire:fix/drag-jump-bugs
Open

fix: prevent item jump on long-press and after reorder#115
lumenwire wants to merge 4 commits intofivecar:mainfrom
lumenwire:fix/drag-jump-bugs

Conversation

@lumenwire
Copy link
Copy Markdown

Summary

  • Fix snap on release at original position: when a drag was released without moving to a new index, pan was still at its translated value when reset() switched the cell back to the anim value, causing a visible snap. Fix: call pan.setValue(0) before reset().
  • Fix stale pan inherited by next drag: after a successful reorder, reset() was not called in the finally block, leaving activeDataRef non-null and pan in a stale state. A quick subsequent press could inherit the leftover translation. Fix: call pan.setValue(0) and reset() synchronously in the finally block and also in onDragStart.
  • Fix item jump on long-press without drag movement: the isPanGranted guard in CellRendererComponent's slide animation useEffect was ineffective because it was backed by a useRef passed through context — refs don't trigger re-renders, so the guard never fired. Fix: track isPanGranted as React state so context consumers re-render correctly.
  • Fix unnecessary re-renders on reorder-only data changes: dataGen was being bumped even when a reorder produced identical data, causing unnecessary animation resets. Fix: skip the bump when the new data is a reorder of the same items.

Test plan

  • Long-press an item without dragging — no jump should occur
  • Drag an item and release at its original position — no snap
  • Drag an item to a new position — reorder completes cleanly, immediately pressing another item does not jump
  • Reorder an item and verify no unnecessary re-renders of surrounding cells

When onReordered causes the parent to update the data prop with the
same items in a new order, detect the pure-reorder case (same key set,
same count) and skip bumping dataGenRef. This preserves cell keys so
FlatList does not remount them mid-animation, eliminating the visual
jump after a drag completes. Because FlatList now reuses row components
across reorders, also resolve the active item's index by key lookup in
onDragStart to avoid acting on a stale info.index from the prior render.
When the user drags an item but drops it back at its starting position
(no reorder), the active cell was still at translateY(pan) at the
moment reset() switched it to translateY(anim). Zeroing pan before
calling reset() ensures both values are 0 at the transition point,
eliminating the visible snap.
Introduce isPanGranted through DragListContext so CellRendererComponent
can distinguish a long-press touch (pan responder not yet granted) from
a real drag. Guard the slide animation useEffect to return early when
pan is not granted, preventing all cells from resetting their translateY
to 0 on press-only interactions and causing a visible jump.
Two related jump bugs are fixed:

1. Long-press without drag movement caused other items to slide
   unexpectedly. The guard introduced in the previous commit used
   panGrantedRef (a ref) to pass isPanGranted through context. Refs don't
   trigger re-renders, so CellRendererComponent never reacted to the grant
   status change and the slide animation useEffect guard never fired.
   Fix: track isPanGranted as React state so context consumers re-render
   and the guard works correctly.

2. After a successful reorder, reset() was never called in the finally
   block, leaving activeDataRef non-null and pan in a stale state. A quick
   subsequent press could then inherit leftover translation and jump.
   Fix: call pan.setValue(0) and reset() synchronously in the finally
   block, and also in onDragStart to clear any leftover pan before a new
   drag begins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant