27
import type {Lanes, Lane} from './ReactFiberLane';
28
import type {HookFlags} from './ReactHookEffectTags';
29
import type {Flags} from './ReactFiberFlags';
30
-import type {TransitionStatus} from './ReactFiberConfig';
30
+import type {TransitionStatus, GestureTimeline} from './ReactFiberConfig';
31
import type {ScheduledGesture} from './ReactFiberGestureScheduler';
32
33
import {
3981
type SwipeTransitionUpdateQueue = {
3982
pending: null | SwipeTransitionGestureUpdate,
3983
dispatch: StartGesture,
3984
+ initialDirection: boolean,
3985
};
3986
3987
function startGesture(
3997
// Noop.
3998
};
3999
}
3999
- const scheduledGesture = scheduleGesture(root, gestureProvider);
4000
+ const gestureTimeline: GestureTimeline = gestureProvider;
4001
+ const scheduledGesture = scheduleGesture(
4002
+ root,
4003
+ gestureTimeline,
4004
+ queue.initialDirection,
4005
+ );
4006
// Add this particular instance to the queue.
4001
- // We add multiple of the same provider even if they get batched so
4007
+ // We add multiple of the same timeline even if they get batched so
4008
// that if we cancel one but not the other we can keep track of this.
4009
// Order doesn't matter but we insert in the beginning to avoid two fields.
4010
const update: SwipeTransitionGestureUpdate = {
4047
const queue: SwipeTransitionUpdateQueue = {
4048
pending: null,
4049
dispatch: (null: any),
4050
+ initialDirection: previous === current,
4051
};
4052
const startGestureOnHook: StartGesture = (queue.dispatch = (startGesture.bind(
4053
null,
4069
const startGestureOnHook: StartGesture = queue.dispatch;
4070
const rootRenderLanes = getWorkInProgressRootRenderLanes();
4071
let value = current;
4065
- if (isGestureRender(rootRenderLanes)) {
4066
- // We're inside a gesture render. We'll traverse the queue to see if
4067
- // this specific Hook is part of this gesture and, if so, which
4068
- // direction to render.
4069
- const root: FiberRoot | null = getWorkInProgressRoot();
4070
- if (root === null) {
4071
- throw new Error(
4072
- 'Expected a work-in-progress root. This is a bug in React. Please file an issue.',
4073
- );
4074
- }
4075
- // We assume that the currently rendering gesture is the one first in the queue.
4076
- const rootRenderGesture = root.gestures;
4077
- let update = queue.pending;
4078
- while (update !== null) {
4079
- if (rootRenderGesture === update.gesture) {
4080
- // We had a match, meaning we're currently rendering a direction of this
4081
- // hook for this gesture.
4082
- // TODO: Determine which direction this gesture is currently rendering.
4083
- value = previous;
4084
- break;
4072
+ if (queue.pending !== null) {
4073
+ if (isGestureRender(rootRenderLanes)) {
4074
+ // We're inside a gesture render. We'll traverse the queue to see if
4075
+ // this specific Hook is part of this gesture and, if so, which
4076
+ // direction to render.
4077
+ const root: FiberRoot | null = getWorkInProgressRoot();
4078
+ if (root === null) {
4079
+ throw new Error(
4080
+ 'Expected a work-in-progress root. This is a bug in React. Please file an issue.',
4081
+ );
4082
}
4086
- update = update.next;
4083
+ // We assume that the currently rendering gesture is the one first in the queue.
4084
+ const rootRenderGesture = root.gestures;
4085
+ if (rootRenderGesture !== null) {
4086
+ let update = queue.pending;
4087
+ while (update !== null) {
4088
+ if (rootRenderGesture === update.gesture) {
4089
+ // We had a match, meaning we're currently rendering a direction of this
4090
+ // hook for this gesture.
4091
+ value = rootRenderGesture.direction ? next : previous;
4092
+ break;
4093
+ }
4094
+ update = update.next;
4095
+ }
4096
+ }
4097
+ // This lane cannot be cleared as long as we have active gestures.
4098
+ markWorkInProgressReceivedUpdate();
4099
}
4088
- }
4089
- if (queue.pending !== null) {
4100
// As long as there are any active gestures we need to leave the lane on
4101
// in case we need to render it later. Since a gesture render doesn't commit
4102
// the only time it really fully gets cleared is if something else rerenders
4106
GestureLane,
4107
);
4108
}
4109
+ // By default, we don't know which direction we should start until a movement
4110
+ // has happened. However, if one direction has the same value as current we
4111
+ // know that it's probably not that direction since it won't do anything anyway.
4112
+ // TODO: Add an explicit option to provide this.
4113
+ queue.initialDirection = previous === current;
4114
return [value, startGestureOnHook];
4115
}
4116