Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions packages/react-reconciler/src/ReactFiberGestureScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,19 @@ import type {FiberRoot} from './ReactInternalTypes';
import type {GestureOptions} from 'shared/ReactTypes';
import type {GestureTimeline, RunningViewTransition} from './ReactFiberConfig';
import type {TransitionTypes} from 'react/src/ReactTransitionType';
import type {Lane} from './ReactFiberLane';

import {GestureLane, markRootFinished, NoLane, NoLanes} from './ReactFiberLane';
import {ensureRootIsScheduled} from './ReactFiberRootScheduler';
import {
GestureLane,
markRootEntangled,
markRootFinished,
NoLane,
NoLanes,
} from './ReactFiberLane';
import {
ensureRootIsScheduled,
requestTransitionLane,
} from './ReactFiberRootScheduler';
import {getCurrentGestureOffset, stopViewTransition} from './ReactFiberConfig';
import {pingGestureRoot, restartGestureRoot} from './ReactFiberWorkLoop';

Expand All @@ -26,6 +36,7 @@ export type ScheduledGesture = {
types: null | TransitionTypes, // Any addTransitionType call made during startGestureTransition.
running: null | RunningViewTransition, // Used to cancel the running transition after we're done.
committing: boolean, // If the gesture was released in a committed state and should actually commit.
revertLane: Lane, // The Lane that we'll use to schedule the revert.
prev: null | ScheduledGesture, // The previous scheduled gesture in the queue for this root.
next: null | ScheduledGesture, // The next scheduled gesture in the queue for this root.
};
Expand Down Expand Up @@ -54,6 +65,7 @@ export function scheduleGesture(
types: null,
running: null,
committing: false,
revertLane: NoLane, // Starts uninitialized.
prev: prev,
next: null,
};
Expand Down Expand Up @@ -119,6 +131,13 @@ export function cancelScheduledGesture(
root: FiberRoot,
gesture: ScheduledGesture,
): void {
// Entangle any Transitions started in this event with the revertLane of the gesture
// so that we commit them all together.
if (gesture.revertLane !== NoLane) {
const entangledLanes = gesture.revertLane | requestTransitionLane(null);
markRootEntangled(root, entangledLanes);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that's a bit strange with this one is that the revert lane isn't actually scheduled at this point yet because it's not pending until we actually commit the gesture lane which is the one that leaves the work behind. Ideally this should probably be done somewhere in the commit phase instead.

}

gesture.count--;
if (gesture.count === 0) {
// If the end state is closer to the end than the beginning then we commit into the
Expand Down
9 changes: 8 additions & 1 deletion packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -3792,7 +3792,14 @@ function dispatchOptimisticSetState<S, A>(
if (provider !== null) {
// If this was a gesture, ensure we have a scheduled gesture and that
// we associate this update with this specific gesture instance.
update.gesture = scheduleGesture(root, provider);
const gesture = (update.gesture = scheduleGesture(root, provider));
// Ensure the gesture always uses the same revert lane. This can happen for
// two startGestureTransition calls to the same provider in different events.
if (gesture.revertLane === NoLane) {
gesture.revertLane = update.revertLane;
} else {
update.revertLane = gesture.revertLane;
}
}
}
}
Expand Down
Loading