@legendapp/list 3.0.0-beta.4 → 3.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.DS_Store +0 -0
- package/CHANGELOG.md +19 -0
- package/README.md +9 -2
- package/animated.d.ts +620 -5
- package/animated.js +2 -2
- package/animated.mjs +1 -1
- package/index.d.ts +1227 -11
- package/index.js +2594 -1023
- package/index.mjs +2593 -1024
- package/index.native.js +2347 -961
- package/index.native.mjs +2327 -943
- package/keyboard-test.d.ts +206 -0
- package/keyboard-test.js +34 -0
- package/keyboard-test.mjs +13 -0
- package/keyboard.d.ts +206 -8
- package/keyboard.js +340 -32
- package/keyboard.mjs +343 -34
- package/package.json +62 -1
- package/{types-JPHClxiw.d.mts → react-native.d.ts} +436 -158
- package/react-native.js +4942 -0
- package/react-native.mjs +4911 -0
- package/{types-JPHClxiw.d.ts → react-native.web.d.ts} +493 -158
- package/react-native.web.js +5357 -0
- package/react-native.web.mjs +5326 -0
- package/{types-YNdphn_A.d.mts → react.d.ts} +493 -158
- package/react.js +5357 -0
- package/react.mjs +5326 -0
- package/reanimated.d.ts +631 -7
- package/reanimated.js +156 -30
- package/reanimated.mjs +155 -29
- package/section-list.d.ts +620 -5
- package/section-list.js +38 -3679
- package/section-list.mjs +34 -3676
- package/animated.d.mts +0 -9
- package/index.d.mts +0 -23
- package/index.native.d.mts +0 -23
- package/index.native.d.ts +0 -23
- package/keyboard-controller.d.mts +0 -12
- package/keyboard-controller.d.ts +0 -12
- package/keyboard-controller.js +0 -69
- package/keyboard-controller.mjs +0 -48
- package/keyboard.d.mts +0 -13
- package/reanimated.d.mts +0 -18
- package/section-list.d.mts +0 -113
- package/section-list.native.d.mts +0 -113
- package/section-list.native.d.ts +0 -113
- package/section-list.native.js +0 -3700
- package/section-list.native.mjs +0 -3679
- package/types-YNdphn_A.d.ts +0 -670
package/index.native.mjs
CHANGED
|
@@ -1,36 +1,69 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle,
|
|
3
|
-
import
|
|
2
|
+
import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, useContext } from 'react';
|
|
3
|
+
import * as ReactNative from 'react-native';
|
|
4
|
+
import { Animated, View as View$1, Text as Text$1, Platform, StyleSheet as StyleSheet$1, RefreshControl, Dimensions } from 'react-native';
|
|
4
5
|
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
5
6
|
|
|
6
7
|
// src/components/LegendList.tsx
|
|
7
8
|
Animated.View;
|
|
8
9
|
var View = View$1;
|
|
9
10
|
var Text = Text$1;
|
|
11
|
+
|
|
12
|
+
// src/state/getContentInsetEnd.ts
|
|
13
|
+
function getContentInsetEnd(state) {
|
|
14
|
+
var _a3;
|
|
15
|
+
const { props } = state;
|
|
16
|
+
const horizontal = props.horizontal;
|
|
17
|
+
const contentInset = props.contentInset;
|
|
18
|
+
const baseInset = contentInset != null ? contentInset : state.nativeContentInset;
|
|
19
|
+
const overrideInset = (_a3 = state.contentInsetOverride) != null ? _a3 : void 0;
|
|
20
|
+
if (overrideInset) {
|
|
21
|
+
const mergedInset = { bottom: 0, right: 0, ...baseInset, ...overrideInset };
|
|
22
|
+
return (horizontal ? mergedInset.right : mergedInset.bottom) || 0;
|
|
23
|
+
}
|
|
24
|
+
if (baseInset) {
|
|
25
|
+
return (horizontal ? baseInset.right : baseInset.bottom) || 0;
|
|
26
|
+
}
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/state/getContentSize.ts
|
|
31
|
+
function getContentSize(ctx) {
|
|
32
|
+
var _a3;
|
|
33
|
+
const { values, state } = ctx;
|
|
34
|
+
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
35
|
+
const stylePaddingBottom = state.props.stylePaddingBottom || 0;
|
|
36
|
+
const headerSize = values.get("headerSize") || 0;
|
|
37
|
+
const footerSize = values.get("footerSize") || 0;
|
|
38
|
+
const contentInsetBottom = getContentInsetEnd(state);
|
|
39
|
+
const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
|
|
40
|
+
return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
|
|
41
|
+
}
|
|
10
42
|
var createAnimatedValue = (value) => new Animated.Value(value);
|
|
11
43
|
|
|
12
44
|
// src/state/state.tsx
|
|
13
45
|
var ContextState = React2.createContext(null);
|
|
46
|
+
var contextNum = 0;
|
|
14
47
|
function StateProvider({ children }) {
|
|
15
48
|
const [value] = React2.useState(() => ({
|
|
16
49
|
animatedScrollY: createAnimatedValue(0),
|
|
17
50
|
columnWrapperStyle: void 0,
|
|
18
|
-
|
|
51
|
+
contextNum: contextNum++,
|
|
19
52
|
listeners: /* @__PURE__ */ new Map(),
|
|
20
53
|
mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
|
|
21
54
|
mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
|
|
22
55
|
mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
|
|
23
56
|
mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
|
|
24
57
|
mapViewabilityValues: /* @__PURE__ */ new Map(),
|
|
58
|
+
positionListeners: /* @__PURE__ */ new Map(),
|
|
59
|
+
state: void 0,
|
|
25
60
|
values: /* @__PURE__ */ new Map([
|
|
26
|
-
["alignItemsPaddingTop", 0],
|
|
27
61
|
["stylePaddingTop", 0],
|
|
28
62
|
["headerSize", 0],
|
|
29
63
|
["numContainers", 0],
|
|
30
|
-
["activeStickyIndex",
|
|
64
|
+
["activeStickyIndex", -1],
|
|
31
65
|
["totalSize", 0],
|
|
32
|
-
["scrollAdjustPending", 0]
|
|
33
|
-
["scrollingTo", void 0]
|
|
66
|
+
["scrollAdjustPending", 0]
|
|
34
67
|
]),
|
|
35
68
|
viewRefs: /* @__PURE__ */ new Map()
|
|
36
69
|
}));
|
|
@@ -98,15 +131,24 @@ function set$(ctx, signalName, value) {
|
|
|
98
131
|
}
|
|
99
132
|
}
|
|
100
133
|
}
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return
|
|
134
|
+
function listenPosition$(ctx, key, cb) {
|
|
135
|
+
const { positionListeners } = ctx;
|
|
136
|
+
let setListeners = positionListeners.get(key);
|
|
137
|
+
if (!setListeners) {
|
|
138
|
+
setListeners = /* @__PURE__ */ new Set();
|
|
139
|
+
positionListeners.set(key, setListeners);
|
|
140
|
+
}
|
|
141
|
+
setListeners.add(cb);
|
|
142
|
+
return () => setListeners.delete(cb);
|
|
143
|
+
}
|
|
144
|
+
function notifyPosition$(ctx, key, value) {
|
|
145
|
+
const { positionListeners } = ctx;
|
|
146
|
+
const setListeners = positionListeners.get(key);
|
|
147
|
+
if (setListeners) {
|
|
148
|
+
for (const listener of setListeners) {
|
|
149
|
+
listener(value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
110
152
|
}
|
|
111
153
|
function useArr$(signalNames) {
|
|
112
154
|
const ctx = React2.useContext(ContextState);
|
|
@@ -125,7 +167,7 @@ function useSelector$(signalName, selector) {
|
|
|
125
167
|
var DebugRow = ({ children }) => {
|
|
126
168
|
return /* @__PURE__ */ React2.createElement(View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
|
|
127
169
|
};
|
|
128
|
-
|
|
170
|
+
React2.memo(function DebugView2({ state }) {
|
|
129
171
|
const ctx = useStateContext();
|
|
130
172
|
const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
|
|
131
173
|
"totalSize",
|
|
@@ -177,7 +219,7 @@ var _a;
|
|
|
177
219
|
var envMode = typeof process !== "undefined" && typeof process.env === "object" && process.env ? (_a = process.env.NODE_ENV) != null ? _a : process.env.MODE : void 0;
|
|
178
220
|
var processDev = typeof envMode === "string" ? envMode.toLowerCase() !== "production" : void 0;
|
|
179
221
|
var _a2;
|
|
180
|
-
var IS_DEV = (_a2 =
|
|
222
|
+
var IS_DEV = (_a2 = processDev != null ? processDev : metroDev) != null ? _a2 : false;
|
|
181
223
|
|
|
182
224
|
// src/constants.ts
|
|
183
225
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
@@ -185,7 +227,8 @@ var ENABLE_DEVMODE = IS_DEV && false;
|
|
|
185
227
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
186
228
|
|
|
187
229
|
// src/constants-platform.native.ts
|
|
188
|
-
var
|
|
230
|
+
var f = global.nativeFabricUIManager;
|
|
231
|
+
var IsNewArchitecture = f !== void 0 && f != null;
|
|
189
232
|
var useAnimatedValue = (initialValue) => {
|
|
190
233
|
const [animAnimatedValue] = useState(() => new Animated.Value(initialValue));
|
|
191
234
|
return animAnimatedValue;
|
|
@@ -222,6 +265,11 @@ function extractPadding(style, contentContainerStyle, type) {
|
|
|
222
265
|
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
223
266
|
}
|
|
224
267
|
function findContainerId(ctx, key) {
|
|
268
|
+
var _a3, _b;
|
|
269
|
+
const directMatch = (_b = (_a3 = ctx.state) == null ? void 0 : _a3.containerItemKeys) == null ? void 0 : _b.get(key);
|
|
270
|
+
if (directMatch !== void 0) {
|
|
271
|
+
return directMatch;
|
|
272
|
+
}
|
|
225
273
|
const numContainers = peek$(ctx, "numContainers");
|
|
226
274
|
for (let i = 0; i < numContainers; i++) {
|
|
227
275
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
@@ -244,7 +292,7 @@ function useValue$(key, params) {
|
|
|
244
292
|
useMemo(() => {
|
|
245
293
|
let prevValue;
|
|
246
294
|
let didQueueTask = false;
|
|
247
|
-
listen$(ctx, key, (
|
|
295
|
+
listen$(ctx, key, () => {
|
|
248
296
|
const newValue = getNewValue();
|
|
249
297
|
if (delay !== void 0) {
|
|
250
298
|
const fn = () => {
|
|
@@ -273,11 +321,19 @@ function useValue$(key, params) {
|
|
|
273
321
|
}, []);
|
|
274
322
|
return animValue;
|
|
275
323
|
}
|
|
276
|
-
var
|
|
277
|
-
var
|
|
324
|
+
var typedMemo = React2.memo;
|
|
325
|
+
var getComponent = (Component) => {
|
|
326
|
+
if (React2.isValidElement(Component)) {
|
|
327
|
+
return Component;
|
|
328
|
+
}
|
|
329
|
+
if (Component) {
|
|
330
|
+
return /* @__PURE__ */ React2.createElement(Component, null);
|
|
331
|
+
}
|
|
332
|
+
return null;
|
|
333
|
+
};
|
|
278
334
|
|
|
279
335
|
// src/components/PositionView.native.tsx
|
|
280
|
-
var PositionViewState = typedMemo(function
|
|
336
|
+
var PositionViewState = typedMemo(function PositionViewState2({
|
|
281
337
|
id,
|
|
282
338
|
horizontal,
|
|
283
339
|
style,
|
|
@@ -297,7 +353,7 @@ var PositionViewState = typedMemo(function PositionView({
|
|
|
297
353
|
}
|
|
298
354
|
);
|
|
299
355
|
});
|
|
300
|
-
var PositionViewAnimated = typedMemo(function
|
|
356
|
+
var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
|
|
301
357
|
id,
|
|
302
358
|
horizontal,
|
|
303
359
|
style,
|
|
@@ -321,74 +377,120 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
321
377
|
style,
|
|
322
378
|
refView,
|
|
323
379
|
animatedScrollY,
|
|
324
|
-
stickyOffset,
|
|
325
380
|
index,
|
|
381
|
+
stickyHeaderConfig,
|
|
382
|
+
children,
|
|
326
383
|
...rest
|
|
327
384
|
}) {
|
|
328
|
-
const [position = POSITION_OUT_OF_VIEW, headerSize] = useArr$([
|
|
385
|
+
const [position = POSITION_OUT_OF_VIEW, headerSize = 0, stylePaddingTop = 0] = useArr$([
|
|
386
|
+
`containerPosition${id}`,
|
|
387
|
+
"headerSize",
|
|
388
|
+
"stylePaddingTop"
|
|
389
|
+
]);
|
|
329
390
|
const transform = React2.useMemo(() => {
|
|
330
|
-
|
|
391
|
+
var _a3;
|
|
392
|
+
if (animatedScrollY) {
|
|
393
|
+
const stickyConfigOffset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
|
|
394
|
+
const stickyStart = position + headerSize + stylePaddingTop - stickyConfigOffset;
|
|
331
395
|
const stickyPosition = animatedScrollY.interpolate({
|
|
332
396
|
extrapolateLeft: "clamp",
|
|
333
397
|
extrapolateRight: "extend",
|
|
334
|
-
inputRange: [
|
|
398
|
+
inputRange: [stickyStart, stickyStart + 5e3],
|
|
335
399
|
outputRange: [position, position + 5e3]
|
|
336
400
|
});
|
|
337
401
|
return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
|
|
338
402
|
}
|
|
339
|
-
}, [animatedScrollY, headerSize, horizontal,
|
|
403
|
+
}, [animatedScrollY, headerSize, horizontal, position, stylePaddingTop, stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset]);
|
|
340
404
|
const viewStyle = React2.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
|
|
341
|
-
|
|
405
|
+
const renderStickyHeaderBackdrop = React2.useMemo(() => {
|
|
406
|
+
if (!(stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent)) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
return /* @__PURE__ */ React2.createElement(
|
|
410
|
+
View$1,
|
|
411
|
+
{
|
|
412
|
+
style: {
|
|
413
|
+
inset: 0,
|
|
414
|
+
pointerEvents: "none",
|
|
415
|
+
position: "absolute"
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
getComponent(stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent)
|
|
419
|
+
);
|
|
420
|
+
}, [stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent]);
|
|
421
|
+
return /* @__PURE__ */ React2.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest }, renderStickyHeaderBackdrop, children);
|
|
342
422
|
});
|
|
343
|
-
var
|
|
423
|
+
var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
|
|
344
424
|
function useInit(cb) {
|
|
345
425
|
useState(() => cb());
|
|
346
426
|
}
|
|
347
427
|
|
|
348
428
|
// src/state/ContextContainer.ts
|
|
349
429
|
var ContextContainer = createContext(null);
|
|
430
|
+
function useContextContainer() {
|
|
431
|
+
return useContext(ContextContainer);
|
|
432
|
+
}
|
|
350
433
|
function useViewability(callback, configId) {
|
|
351
434
|
const ctx = useStateContext();
|
|
352
|
-
const
|
|
353
|
-
const key = containerId + (configId != null ? configId : "");
|
|
435
|
+
const containerContext = useContextContainer();
|
|
354
436
|
useInit(() => {
|
|
437
|
+
if (!containerContext) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const { containerId } = containerContext;
|
|
441
|
+
const key = containerId + (configId != null ? configId : "");
|
|
355
442
|
const value = ctx.mapViewabilityValues.get(key);
|
|
356
443
|
if (value) {
|
|
357
444
|
callback(value);
|
|
358
445
|
}
|
|
359
446
|
});
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
447
|
+
useEffect(() => {
|
|
448
|
+
if (!containerContext) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
const { containerId } = containerContext;
|
|
452
|
+
const key = containerId + (configId != null ? configId : "");
|
|
453
|
+
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
454
|
+
return () => {
|
|
363
455
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
);
|
|
456
|
+
};
|
|
457
|
+
}, [ctx, callback, configId, containerContext]);
|
|
367
458
|
}
|
|
368
459
|
function useViewabilityAmount(callback) {
|
|
369
460
|
const ctx = useStateContext();
|
|
370
|
-
const
|
|
461
|
+
const containerContext = useContextContainer();
|
|
371
462
|
useInit(() => {
|
|
463
|
+
if (!containerContext) {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
const { containerId } = containerContext;
|
|
372
467
|
const value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
373
468
|
if (value) {
|
|
374
469
|
callback(value);
|
|
375
470
|
}
|
|
376
471
|
});
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
472
|
+
useEffect(() => {
|
|
473
|
+
if (!containerContext) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const { containerId } = containerContext;
|
|
477
|
+
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
478
|
+
return () => {
|
|
380
479
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
);
|
|
480
|
+
};
|
|
481
|
+
}, [ctx, callback, containerContext]);
|
|
384
482
|
}
|
|
385
483
|
function useRecyclingEffect(effect) {
|
|
386
|
-
const
|
|
484
|
+
const containerContext = useContextContainer();
|
|
387
485
|
const prevValues = useRef({
|
|
388
486
|
prevIndex: void 0,
|
|
389
487
|
prevItem: void 0
|
|
390
488
|
});
|
|
391
489
|
useEffect(() => {
|
|
490
|
+
if (!containerContext) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const { index, value } = containerContext;
|
|
392
494
|
let ret;
|
|
393
495
|
if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
|
|
394
496
|
ret = effect({
|
|
@@ -403,38 +505,58 @@ function useRecyclingEffect(effect) {
|
|
|
403
505
|
prevItem: value
|
|
404
506
|
};
|
|
405
507
|
return ret;
|
|
406
|
-
}, [
|
|
508
|
+
}, [effect, containerContext]);
|
|
407
509
|
}
|
|
408
510
|
function useRecyclingState(valueOrFun) {
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
511
|
+
var _a3, _b;
|
|
512
|
+
const containerContext = useContextContainer();
|
|
513
|
+
const computeValue = (ctx) => {
|
|
514
|
+
if (isFunction(valueOrFun)) {
|
|
515
|
+
const initializer = valueOrFun;
|
|
516
|
+
return ctx ? initializer({
|
|
517
|
+
index: ctx.index,
|
|
518
|
+
item: ctx.value,
|
|
519
|
+
prevIndex: void 0,
|
|
520
|
+
prevItem: void 0
|
|
521
|
+
}) : initializer();
|
|
522
|
+
}
|
|
523
|
+
return valueOrFun;
|
|
524
|
+
};
|
|
525
|
+
const [stateValue, setStateValue] = useState(() => {
|
|
526
|
+
return computeValue(containerContext);
|
|
413
527
|
});
|
|
414
|
-
const
|
|
415
|
-
const
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
index,
|
|
420
|
-
item: value,
|
|
421
|
-
prevIndex: void 0,
|
|
422
|
-
prevItem: void 0
|
|
423
|
-
}) : valueOrFun;
|
|
528
|
+
const prevItemKeyRef = useRef((_a3 = containerContext == null ? void 0 : containerContext.itemKey) != null ? _a3 : null);
|
|
529
|
+
const currentItemKey = (_b = containerContext == null ? void 0 : containerContext.itemKey) != null ? _b : null;
|
|
530
|
+
if (currentItemKey !== null && prevItemKeyRef.current !== currentItemKey) {
|
|
531
|
+
prevItemKeyRef.current = currentItemKey;
|
|
532
|
+
setStateValue(computeValue(containerContext));
|
|
424
533
|
}
|
|
534
|
+
const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
|
|
425
535
|
const setState = useCallback(
|
|
426
536
|
(newState) => {
|
|
427
|
-
|
|
428
|
-
|
|
537
|
+
if (!triggerLayout) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
setStateValue((prevValue) => {
|
|
541
|
+
return isFunction(newState) ? newState(prevValue) : newState;
|
|
542
|
+
});
|
|
429
543
|
triggerLayout();
|
|
430
544
|
},
|
|
431
|
-
[triggerLayout
|
|
545
|
+
[triggerLayout]
|
|
432
546
|
);
|
|
433
|
-
return [
|
|
547
|
+
return [stateValue, setState];
|
|
434
548
|
}
|
|
435
549
|
function useIsLastItem() {
|
|
436
|
-
const
|
|
437
|
-
const isLast = useSelector$("lastItemKeys", (lastItemKeys) =>
|
|
550
|
+
const containerContext = useContextContainer();
|
|
551
|
+
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
|
|
552
|
+
if (containerContext) {
|
|
553
|
+
const { itemKey } = containerContext;
|
|
554
|
+
if (!isNullOrUndefined(itemKey)) {
|
|
555
|
+
return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return false;
|
|
559
|
+
});
|
|
438
560
|
return isLast;
|
|
439
561
|
}
|
|
440
562
|
function useListScrollSize() {
|
|
@@ -444,8 +566,9 @@ function useListScrollSize() {
|
|
|
444
566
|
var noop = () => {
|
|
445
567
|
};
|
|
446
568
|
function useSyncLayout() {
|
|
447
|
-
|
|
448
|
-
|
|
569
|
+
const containerContext = useContextContainer();
|
|
570
|
+
if (IsNewArchitecture && containerContext) {
|
|
571
|
+
const { triggerLayout: syncLayout } = containerContext;
|
|
449
572
|
return syncLayout;
|
|
450
573
|
} else {
|
|
451
574
|
return noop;
|
|
@@ -488,30 +611,44 @@ function useOnLayoutSync({
|
|
|
488
611
|
}
|
|
489
612
|
return { onLayout };
|
|
490
613
|
}
|
|
614
|
+
var Platform2 = Platform;
|
|
615
|
+
var PlatformAdjustBreaksScroll = Platform2.OS === "android";
|
|
616
|
+
var typedForwardRef = React2.forwardRef;
|
|
617
|
+
var typedMemo2 = React2.memo;
|
|
618
|
+
|
|
619
|
+
// src/utils/isInMVCPActiveMode.native.ts
|
|
620
|
+
function isInMVCPActiveMode(state) {
|
|
621
|
+
return state.dataChangeNeedsScrollUpdate;
|
|
622
|
+
}
|
|
491
623
|
|
|
492
624
|
// src/components/Container.tsx
|
|
493
|
-
var Container =
|
|
625
|
+
var Container = typedMemo2(function Container2({
|
|
494
626
|
id,
|
|
495
627
|
recycleItems,
|
|
496
628
|
horizontal,
|
|
497
629
|
getRenderedItem: getRenderedItem2,
|
|
498
630
|
updateItemSize: updateItemSize2,
|
|
499
|
-
ItemSeparatorComponent
|
|
631
|
+
ItemSeparatorComponent,
|
|
632
|
+
stickyHeaderConfig
|
|
500
633
|
}) {
|
|
501
634
|
const ctx = useStateContext();
|
|
502
635
|
const { columnWrapperStyle, animatedScrollY } = ctx;
|
|
503
|
-
const
|
|
636
|
+
const positionComponentInternal = ctx.state.props.positionComponentInternal;
|
|
637
|
+
const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
|
|
638
|
+
const [column = 0, span = 1, data, itemKey, numColumns = 1, extraData, isSticky] = useArr$([
|
|
504
639
|
`containerColumn${id}`,
|
|
640
|
+
`containerSpan${id}`,
|
|
505
641
|
`containerItemData${id}`,
|
|
506
642
|
`containerItemKey${id}`,
|
|
507
643
|
"numColumns",
|
|
508
644
|
"extraData",
|
|
509
|
-
`containerSticky${id}
|
|
510
|
-
`containerStickyOffset${id}`
|
|
645
|
+
`containerSticky${id}`
|
|
511
646
|
]);
|
|
512
647
|
const itemLayoutRef = useRef({
|
|
648
|
+
didLayout: false,
|
|
513
649
|
horizontal,
|
|
514
650
|
itemKey,
|
|
651
|
+
pendingShrinkToken: 0,
|
|
515
652
|
updateItemSize: updateItemSize2
|
|
516
653
|
});
|
|
517
654
|
itemLayoutRef.current.horizontal = horizontal;
|
|
@@ -519,9 +656,10 @@ var Container = typedMemo(function Container2({
|
|
|
519
656
|
itemLayoutRef.current.updateItemSize = updateItemSize2;
|
|
520
657
|
const ref = useRef(null);
|
|
521
658
|
const [layoutRenderCount, forceLayoutRender] = useState(0);
|
|
522
|
-
const
|
|
523
|
-
const
|
|
524
|
-
const
|
|
659
|
+
const resolvedColumn = column > 0 ? column : 1;
|
|
660
|
+
const resolvedSpan = Math.min(Math.max(span || 1, 1), numColumns);
|
|
661
|
+
const otherAxisPos = numColumns > 1 ? `${(resolvedColumn - 1) / numColumns * 100}%` : 0;
|
|
662
|
+
const otherAxisSize = numColumns > 1 ? `${resolvedSpan / numColumns * 100}%` : void 0;
|
|
525
663
|
const style = useMemo(() => {
|
|
526
664
|
let paddingStyles;
|
|
527
665
|
if (columnWrapperStyle) {
|
|
@@ -576,19 +714,41 @@ var Container = typedMemo(function Container2({
|
|
|
576
714
|
const {
|
|
577
715
|
horizontal: currentHorizontal,
|
|
578
716
|
itemKey: currentItemKey,
|
|
579
|
-
updateItemSize: updateItemSizeFn
|
|
717
|
+
updateItemSize: updateItemSizeFn,
|
|
718
|
+
lastSize,
|
|
719
|
+
pendingShrinkToken
|
|
580
720
|
} = itemLayoutRef.current;
|
|
581
721
|
if (isNullOrUndefined(currentItemKey)) {
|
|
582
722
|
return;
|
|
583
723
|
}
|
|
584
|
-
|
|
724
|
+
itemLayoutRef.current.didLayout = true;
|
|
585
725
|
let layout = rectangle;
|
|
586
|
-
const
|
|
726
|
+
const axis = currentHorizontal ? "width" : "height";
|
|
727
|
+
const size = roundSize(rectangle[axis]);
|
|
728
|
+
const prevSize = lastSize ? roundSize(lastSize[axis]) : void 0;
|
|
587
729
|
const doUpdate = () => {
|
|
588
|
-
itemLayoutRef.current.lastSize =
|
|
730
|
+
itemLayoutRef.current.lastSize = layout;
|
|
589
731
|
updateItemSizeFn(currentItemKey, layout);
|
|
590
|
-
|
|
732
|
+
itemLayoutRef.current.didLayout = true;
|
|
591
733
|
};
|
|
734
|
+
const shouldDeferWebShrinkLayoutUpdate = Platform2.OS === "web" && !isInMVCPActiveMode(ctx.state) && prevSize !== void 0 && size + 1 < prevSize;
|
|
735
|
+
if (shouldDeferWebShrinkLayoutUpdate) {
|
|
736
|
+
const token = pendingShrinkToken + 1;
|
|
737
|
+
itemLayoutRef.current.pendingShrinkToken = token;
|
|
738
|
+
requestAnimationFrame(() => {
|
|
739
|
+
var _a4;
|
|
740
|
+
if (itemLayoutRef.current.pendingShrinkToken !== token) {
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
const element = ref.current;
|
|
744
|
+
const rect = (_a4 = element == null ? void 0 : element.getBoundingClientRect) == null ? void 0 : _a4.call(element);
|
|
745
|
+
if (rect) {
|
|
746
|
+
layout = { height: rect.height, width: rect.width };
|
|
747
|
+
}
|
|
748
|
+
doUpdate();
|
|
749
|
+
});
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
592
752
|
if (IsNewArchitecture || size > 0) {
|
|
593
753
|
doUpdate();
|
|
594
754
|
} else {
|
|
@@ -601,16 +761,15 @@ var Container = typedMemo(function Container2({
|
|
|
601
761
|
const { onLayout } = useOnLayoutSync(
|
|
602
762
|
{
|
|
603
763
|
onLayoutChange,
|
|
604
|
-
ref
|
|
605
|
-
},
|
|
764
|
+
ref},
|
|
606
765
|
[itemKey, layoutRenderCount]
|
|
607
766
|
);
|
|
608
767
|
if (!IsNewArchitecture) {
|
|
609
768
|
useEffect(() => {
|
|
610
769
|
if (!isNullOrUndefined(itemKey)) {
|
|
611
|
-
|
|
770
|
+
itemLayoutRef.current.didLayout = false;
|
|
612
771
|
const timeout = setTimeout(() => {
|
|
613
|
-
if (!
|
|
772
|
+
if (!itemLayoutRef.current.didLayout) {
|
|
614
773
|
const {
|
|
615
774
|
itemKey: currentItemKey,
|
|
616
775
|
lastSize,
|
|
@@ -618,7 +777,7 @@ var Container = typedMemo(function Container2({
|
|
|
618
777
|
} = itemLayoutRef.current;
|
|
619
778
|
if (lastSize && !isNullOrUndefined(currentItemKey)) {
|
|
620
779
|
updateItemSizeFn(currentItemKey, lastSize);
|
|
621
|
-
|
|
780
|
+
itemLayoutRef.current.didLayout = true;
|
|
622
781
|
}
|
|
623
782
|
}
|
|
624
783
|
}, 16);
|
|
@@ -628,7 +787,7 @@ var Container = typedMemo(function Container2({
|
|
|
628
787
|
}
|
|
629
788
|
}, [itemKey]);
|
|
630
789
|
}
|
|
631
|
-
const PositionComponent = isSticky ? PositionViewSticky :
|
|
790
|
+
const PositionComponent = isSticky ? stickyPositionComponentInternal ? stickyPositionComponentInternal : PositionViewSticky : positionComponentInternal ? positionComponentInternal : PositionView;
|
|
632
791
|
return /* @__PURE__ */ React2.createElement(
|
|
633
792
|
PositionComponent,
|
|
634
793
|
{
|
|
@@ -639,7 +798,7 @@ var Container = typedMemo(function Container2({
|
|
|
639
798
|
key: recycleItems ? void 0 : itemKey,
|
|
640
799
|
onLayout,
|
|
641
800
|
refView: ref,
|
|
642
|
-
|
|
801
|
+
stickyHeaderConfig,
|
|
643
802
|
style
|
|
644
803
|
},
|
|
645
804
|
/* @__PURE__ */ React2.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React2.createElement(Separator, { ItemSeparatorComponent, leadingItem: renderedItemInfo.item }))
|
|
@@ -652,6 +811,7 @@ var Containers = typedMemo(function Containers2({
|
|
|
652
811
|
recycleItems,
|
|
653
812
|
ItemSeparatorComponent,
|
|
654
813
|
waitForInitialLayout,
|
|
814
|
+
stickyHeaderConfig,
|
|
655
815
|
updateItemSize: updateItemSize2,
|
|
656
816
|
getRenderedItem: getRenderedItem2
|
|
657
817
|
}) {
|
|
@@ -663,10 +823,10 @@ var Containers = typedMemo(function Containers2({
|
|
|
663
823
|
// If this is the initial scroll, we don't want to delay because we want to update the size immediately
|
|
664
824
|
delay: (value, prevValue) => {
|
|
665
825
|
var _a3;
|
|
666
|
-
return !((_a3 = ctx.
|
|
826
|
+
return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
|
|
667
827
|
}
|
|
668
828
|
});
|
|
669
|
-
const animOpacity = waitForInitialLayout
|
|
829
|
+
const animOpacity = waitForInitialLayout ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
|
|
670
830
|
const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
|
|
671
831
|
const containers = [];
|
|
672
832
|
for (let i = 0; i < numContainers; i++) {
|
|
@@ -680,25 +840,26 @@ var Containers = typedMemo(function Containers2({
|
|
|
680
840
|
id: i,
|
|
681
841
|
key: i,
|
|
682
842
|
recycleItems,
|
|
843
|
+
stickyHeaderConfig,
|
|
683
844
|
updateItemSize: updateItemSize2
|
|
684
845
|
}
|
|
685
846
|
)
|
|
686
847
|
);
|
|
687
848
|
}
|
|
688
849
|
const style = horizontal ? { minHeight: otherAxisSize, opacity: animOpacity, width: animSize } : { height: animSize, minWidth: otherAxisSize, opacity: animOpacity };
|
|
689
|
-
if (columnWrapperStyle
|
|
850
|
+
if (columnWrapperStyle) {
|
|
690
851
|
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
691
852
|
const gapX = columnGap || gap || 0;
|
|
692
853
|
const gapY = rowGap || gap || 0;
|
|
693
854
|
if (horizontal) {
|
|
694
|
-
if (gapY) {
|
|
855
|
+
if (gapY && numColumns > 1) {
|
|
695
856
|
style.marginVertical = -gapY / 2;
|
|
696
857
|
}
|
|
697
858
|
if (gapX) {
|
|
698
859
|
style.marginRight = -gapX;
|
|
699
860
|
}
|
|
700
861
|
} else {
|
|
701
|
-
if (gapX) {
|
|
862
|
+
if (gapX && numColumns > 1) {
|
|
702
863
|
style.marginHorizontal = -gapX;
|
|
703
864
|
}
|
|
704
865
|
if (gapY) {
|
|
@@ -708,45 +869,7 @@ var Containers = typedMemo(function Containers2({
|
|
|
708
869
|
}
|
|
709
870
|
return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
|
|
710
871
|
});
|
|
711
|
-
function DevNumbers() {
|
|
712
|
-
return IS_DEV && React2.memo(function DevNumbers2() {
|
|
713
|
-
return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2.createElement(
|
|
714
|
-
View$1,
|
|
715
|
-
{
|
|
716
|
-
key: index,
|
|
717
|
-
style: {
|
|
718
|
-
height: 100,
|
|
719
|
-
pointerEvents: "none",
|
|
720
|
-
position: "absolute",
|
|
721
|
-
top: index * 100,
|
|
722
|
-
width: "100%"
|
|
723
|
-
}
|
|
724
|
-
},
|
|
725
|
-
/* @__PURE__ */ React2.createElement(Text$1, { style: { color: "red" } }, index * 100)
|
|
726
|
-
));
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
872
|
var ListComponentScrollView = Animated.ScrollView;
|
|
730
|
-
function Padding() {
|
|
731
|
-
const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
|
|
732
|
-
return /* @__PURE__ */ React2.createElement(Animated.View, { style: { paddingTop: animPaddingTop } });
|
|
733
|
-
}
|
|
734
|
-
function PaddingDevMode() {
|
|
735
|
-
const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
|
|
736
|
-
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React2.createElement(
|
|
737
|
-
Animated.View,
|
|
738
|
-
{
|
|
739
|
-
style: {
|
|
740
|
-
backgroundColor: "green",
|
|
741
|
-
height: animPaddingTop,
|
|
742
|
-
left: 0,
|
|
743
|
-
position: "absolute",
|
|
744
|
-
right: 0,
|
|
745
|
-
top: 0
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
));
|
|
749
|
-
}
|
|
750
873
|
function ScrollAdjust() {
|
|
751
874
|
const bias = 1e7;
|
|
752
875
|
const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
|
|
@@ -769,22 +892,13 @@ function SnapWrapper({ ScrollComponent, ...props }) {
|
|
|
769
892
|
return /* @__PURE__ */ React2.createElement(ScrollComponent, { ...props, snapToOffsets });
|
|
770
893
|
}
|
|
771
894
|
var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
|
|
772
|
-
const ref = refView != null ? refView : useRef();
|
|
895
|
+
const ref = refView != null ? refView : useRef(null);
|
|
773
896
|
const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
|
|
774
897
|
return /* @__PURE__ */ React2.createElement(View$1, { ...rest, onLayout, ref });
|
|
775
898
|
};
|
|
776
899
|
|
|
777
900
|
// src/components/ListComponent.tsx
|
|
778
|
-
var
|
|
779
|
-
if (React2.isValidElement(Component)) {
|
|
780
|
-
return Component;
|
|
781
|
-
}
|
|
782
|
-
if (Component) {
|
|
783
|
-
return /* @__PURE__ */ React2.createElement(Component, null);
|
|
784
|
-
}
|
|
785
|
-
return null;
|
|
786
|
-
};
|
|
787
|
-
var ListComponent = typedMemo(function ListComponent2({
|
|
901
|
+
var ListComponent = typedMemo2(function ListComponent2({
|
|
788
902
|
canRender,
|
|
789
903
|
style,
|
|
790
904
|
contentContainerStyle,
|
|
@@ -792,7 +906,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
792
906
|
initialContentOffset,
|
|
793
907
|
recycleItems,
|
|
794
908
|
ItemSeparatorComponent,
|
|
795
|
-
alignItemsAtEnd,
|
|
909
|
+
alignItemsAtEnd: _alignItemsAtEnd,
|
|
796
910
|
waitForInitialLayout,
|
|
797
911
|
onScroll: onScroll2,
|
|
798
912
|
onLayout,
|
|
@@ -804,31 +918,52 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
804
918
|
getRenderedItem: getRenderedItem2,
|
|
805
919
|
updateItemSize: updateItemSize2,
|
|
806
920
|
refScrollView,
|
|
807
|
-
maintainVisibleContentPosition,
|
|
808
921
|
renderScrollComponent,
|
|
922
|
+
onLayoutFooter,
|
|
809
923
|
scrollAdjustHandler,
|
|
810
|
-
onLayoutHeader,
|
|
811
924
|
snapToIndices,
|
|
925
|
+
stickyHeaderConfig,
|
|
812
926
|
stickyHeaderIndices,
|
|
927
|
+
useWindowScroll = false,
|
|
813
928
|
...rest
|
|
814
929
|
}) {
|
|
815
930
|
const ctx = useStateContext();
|
|
931
|
+
const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
|
|
816
932
|
const ScrollComponent = renderScrollComponent ? useMemo(
|
|
817
|
-
() => React2.forwardRef(
|
|
933
|
+
() => React2.forwardRef(
|
|
934
|
+
(props, ref) => renderScrollComponent({ ...props, ref })
|
|
935
|
+
),
|
|
818
936
|
[renderScrollComponent]
|
|
819
937
|
) : ListComponentScrollView;
|
|
820
|
-
React2.useEffect(() => {
|
|
821
|
-
if (canRender) {
|
|
822
|
-
setTimeout(() => {
|
|
823
|
-
scrollAdjustHandler.setMounted();
|
|
824
|
-
}, 0);
|
|
825
|
-
}
|
|
826
|
-
}, [canRender]);
|
|
827
938
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
939
|
+
useLayoutEffect(() => {
|
|
940
|
+
if (!ListHeaderComponent) {
|
|
941
|
+
set$(ctx, "headerSize", 0);
|
|
942
|
+
}
|
|
943
|
+
if (!ListFooterComponent) {
|
|
944
|
+
set$(ctx, "footerSize", 0);
|
|
945
|
+
}
|
|
946
|
+
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
947
|
+
const onLayoutHeader = useCallback(
|
|
948
|
+
(rect) => {
|
|
949
|
+
const size = rect[horizontal ? "width" : "height"];
|
|
950
|
+
set$(ctx, "headerSize", size);
|
|
951
|
+
},
|
|
952
|
+
[ctx, horizontal]
|
|
953
|
+
);
|
|
954
|
+
const onLayoutFooterInternal = useCallback(
|
|
955
|
+
(rect, fromLayoutEffect) => {
|
|
956
|
+
const size = rect[horizontal ? "width" : "height"];
|
|
957
|
+
set$(ctx, "footerSize", size);
|
|
958
|
+
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
959
|
+
},
|
|
960
|
+
[ctx, horizontal, onLayoutFooter]
|
|
961
|
+
);
|
|
828
962
|
return /* @__PURE__ */ React2.createElement(
|
|
829
963
|
SnapOrScroll,
|
|
830
964
|
{
|
|
831
965
|
...rest,
|
|
966
|
+
...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
|
|
832
967
|
contentContainerStyle: [
|
|
833
968
|
contentContainerStyle,
|
|
834
969
|
horizontal ? {
|
|
@@ -837,7 +972,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
837
972
|
],
|
|
838
973
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
839
974
|
horizontal,
|
|
840
|
-
maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
|
|
975
|
+
maintainVisibleContentPosition: maintainVisibleContentPosition.size || maintainVisibleContentPosition.data ? { minIndexForVisible: 0 } : void 0,
|
|
841
976
|
onLayout,
|
|
842
977
|
onScroll: onScroll2,
|
|
843
978
|
ref: refScrollView,
|
|
@@ -845,7 +980,6 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
845
980
|
style
|
|
846
981
|
},
|
|
847
982
|
/* @__PURE__ */ React2.createElement(ScrollAdjust, null),
|
|
848
|
-
ENABLE_DEVMODE ? /* @__PURE__ */ React2.createElement(PaddingDevMode, null) : /* @__PURE__ */ React2.createElement(Padding, null),
|
|
849
983
|
ListHeaderComponent && /* @__PURE__ */ React2.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
850
984
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
851
985
|
canRender && !ListEmptyComponent && /* @__PURE__ */ React2.createElement(
|
|
@@ -855,25 +989,27 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
855
989
|
horizontal,
|
|
856
990
|
ItemSeparatorComponent,
|
|
857
991
|
recycleItems,
|
|
992
|
+
stickyHeaderConfig,
|
|
858
993
|
updateItemSize: updateItemSize2,
|
|
859
994
|
waitForInitialLayout
|
|
860
995
|
}
|
|
861
996
|
),
|
|
862
|
-
ListFooterComponent && /* @__PURE__ */ React2.createElement(
|
|
863
|
-
|
|
864
|
-
{
|
|
865
|
-
onLayoutChange: (layout) => {
|
|
866
|
-
const size = layout[horizontal ? "width" : "height"];
|
|
867
|
-
set$(ctx, "footerSize", size);
|
|
868
|
-
},
|
|
869
|
-
style: ListFooterComponentStyle
|
|
870
|
-
},
|
|
871
|
-
getComponent(ListFooterComponent)
|
|
872
|
-
),
|
|
873
|
-
IS_DEV && ENABLE_DEVMODE && /* @__PURE__ */ React2.createElement(DevNumbers, null)
|
|
997
|
+
ListFooterComponent && /* @__PURE__ */ React2.createElement(LayoutView, { onLayoutChange: onLayoutFooterInternal, style: ListFooterComponentStyle }, getComponent(ListFooterComponent)),
|
|
998
|
+
IS_DEV && ENABLE_DEVMODE
|
|
874
999
|
);
|
|
875
1000
|
});
|
|
876
1001
|
|
|
1002
|
+
// src/core/calculateOffsetForIndex.ts
|
|
1003
|
+
function calculateOffsetForIndex(ctx, index) {
|
|
1004
|
+
const state = ctx.state;
|
|
1005
|
+
return index !== void 0 ? state.positions[index] || 0 : 0;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// src/core/getTopOffsetAdjustment.ts
|
|
1009
|
+
function getTopOffsetAdjustment(ctx) {
|
|
1010
|
+
return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
877
1013
|
// src/utils/getId.ts
|
|
878
1014
|
function getId(state, index) {
|
|
879
1015
|
const { data, keyExtractor } = state.props;
|
|
@@ -886,61 +1022,9 @@ function getId(state, index) {
|
|
|
886
1022
|
return id;
|
|
887
1023
|
}
|
|
888
1024
|
|
|
889
|
-
// src/core/calculateOffsetForIndex.ts
|
|
890
|
-
function calculateOffsetForIndex(ctx, state, index) {
|
|
891
|
-
let position = 0;
|
|
892
|
-
if (index !== void 0) {
|
|
893
|
-
position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
|
|
894
|
-
const paddingTop = peek$(ctx, "stylePaddingTop");
|
|
895
|
-
if (paddingTop) {
|
|
896
|
-
position += paddingTop;
|
|
897
|
-
}
|
|
898
|
-
const headerSize = peek$(ctx, "headerSize");
|
|
899
|
-
if (headerSize) {
|
|
900
|
-
position += headerSize;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
return position;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// src/utils/setPaddingTop.ts
|
|
907
|
-
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
908
|
-
if (stylePaddingTop !== void 0) {
|
|
909
|
-
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
910
|
-
if (stylePaddingTop < prevStylePaddingTop) {
|
|
911
|
-
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
912
|
-
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
913
|
-
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
914
|
-
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
915
|
-
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
916
|
-
}, 16);
|
|
917
|
-
}
|
|
918
|
-
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
919
|
-
}
|
|
920
|
-
if (alignItemsPaddingTop !== void 0) {
|
|
921
|
-
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
// src/utils/updateAlignItemsPaddingTop.ts
|
|
926
|
-
function updateAlignItemsPaddingTop(ctx, state) {
|
|
927
|
-
const {
|
|
928
|
-
scrollLength,
|
|
929
|
-
props: { alignItemsAtEnd, data }
|
|
930
|
-
} = state;
|
|
931
|
-
if (alignItemsAtEnd) {
|
|
932
|
-
let alignItemsPaddingTop = 0;
|
|
933
|
-
if ((data == null ? void 0 : data.length) > 0) {
|
|
934
|
-
const contentSize = getContentSize(ctx);
|
|
935
|
-
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
936
|
-
}
|
|
937
|
-
setPaddingTop(ctx, state, { alignItemsPaddingTop });
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
|
|
941
1025
|
// src/core/addTotalSize.ts
|
|
942
|
-
function addTotalSize(ctx,
|
|
943
|
-
const
|
|
1026
|
+
function addTotalSize(ctx, key, add) {
|
|
1027
|
+
const state = ctx.state;
|
|
944
1028
|
const prevTotalSize = state.totalSize;
|
|
945
1029
|
let totalSize = state.totalSize;
|
|
946
1030
|
if (key === null) {
|
|
@@ -959,48 +1043,47 @@ function addTotalSize(ctx, state, key, add) {
|
|
|
959
1043
|
state.pendingTotalSize = void 0;
|
|
960
1044
|
state.totalSize = totalSize;
|
|
961
1045
|
set$(ctx, "totalSize", totalSize);
|
|
962
|
-
if (alignItemsAtEnd) {
|
|
963
|
-
updateAlignItemsPaddingTop(ctx, state);
|
|
964
|
-
}
|
|
965
1046
|
}
|
|
966
1047
|
}
|
|
967
1048
|
}
|
|
968
1049
|
|
|
969
1050
|
// src/core/setSize.ts
|
|
970
|
-
function setSize(ctx,
|
|
1051
|
+
function setSize(ctx, itemKey, size) {
|
|
1052
|
+
const state = ctx.state;
|
|
971
1053
|
const { sizes } = state;
|
|
972
1054
|
const previousSize = sizes.get(itemKey);
|
|
973
1055
|
const diff = previousSize !== void 0 ? size - previousSize : size;
|
|
974
1056
|
if (diff !== 0) {
|
|
975
|
-
addTotalSize(ctx,
|
|
1057
|
+
addTotalSize(ctx, itemKey, diff);
|
|
976
1058
|
}
|
|
977
1059
|
sizes.set(itemKey, size);
|
|
978
1060
|
}
|
|
979
1061
|
|
|
980
1062
|
// src/utils/getItemSize.ts
|
|
981
|
-
function getItemSize(ctx,
|
|
1063
|
+
function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
|
|
982
1064
|
var _a3, _b;
|
|
1065
|
+
const state = ctx.state;
|
|
983
1066
|
const {
|
|
984
1067
|
sizesKnown,
|
|
985
1068
|
sizes,
|
|
986
1069
|
averageSizes,
|
|
987
|
-
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
1070
|
+
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
|
|
1071
|
+
scrollingTo
|
|
988
1072
|
} = state;
|
|
989
1073
|
const sizeKnown = sizesKnown.get(key);
|
|
990
1074
|
if (sizeKnown !== void 0) {
|
|
991
1075
|
return sizeKnown;
|
|
992
1076
|
}
|
|
993
1077
|
let size;
|
|
994
|
-
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
995
|
-
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
996
1078
|
if (preferCachedSize) {
|
|
997
1079
|
const cachedSize = sizes.get(key);
|
|
998
1080
|
if (cachedSize !== void 0) {
|
|
999
1081
|
return cachedSize;
|
|
1000
1082
|
}
|
|
1001
1083
|
}
|
|
1084
|
+
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1002
1085
|
if (getFixedItemSize) {
|
|
1003
|
-
size = getFixedItemSize(
|
|
1086
|
+
size = getFixedItemSize(data, index, itemType);
|
|
1004
1087
|
if (size !== void 0) {
|
|
1005
1088
|
sizesKnown.set(key, size);
|
|
1006
1089
|
}
|
|
@@ -1018,96 +1101,68 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
|
|
|
1018
1101
|
}
|
|
1019
1102
|
}
|
|
1020
1103
|
if (size === void 0) {
|
|
1021
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(
|
|
1104
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(data, index, itemType) : estimatedItemSize;
|
|
1022
1105
|
}
|
|
1023
|
-
setSize(ctx,
|
|
1106
|
+
setSize(ctx, key, size);
|
|
1024
1107
|
return size;
|
|
1025
1108
|
}
|
|
1026
1109
|
|
|
1027
1110
|
// src/core/calculateOffsetWithOffsetPosition.ts
|
|
1028
|
-
function calculateOffsetWithOffsetPosition(ctx,
|
|
1111
|
+
function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
1112
|
+
var _a3;
|
|
1113
|
+
const state = ctx.state;
|
|
1029
1114
|
const { index, viewOffset, viewPosition } = params;
|
|
1030
1115
|
let offset = offsetParam;
|
|
1031
1116
|
if (viewOffset) {
|
|
1032
1117
|
offset -= viewOffset;
|
|
1033
1118
|
}
|
|
1034
|
-
if (
|
|
1035
|
-
|
|
1119
|
+
if (index !== void 0) {
|
|
1120
|
+
const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
|
|
1121
|
+
if (topOffsetAdjustment) {
|
|
1122
|
+
offset += topOffsetAdjustment;
|
|
1123
|
+
}
|
|
1036
1124
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
function finishScrollTo(ctx, state) {
|
|
1042
|
-
var _a3, _b;
|
|
1043
|
-
if (state) {
|
|
1044
|
-
state.scrollHistory.length = 0;
|
|
1045
|
-
state.initialScroll = void 0;
|
|
1046
|
-
state.initialAnchor = void 0;
|
|
1047
|
-
set$(ctx, "scrollingTo", void 0);
|
|
1048
|
-
if (state.pendingTotalSize !== void 0) {
|
|
1049
|
-
addTotalSize(ctx, state, null, state.pendingTotalSize);
|
|
1125
|
+
if (viewPosition !== void 0 && index !== void 0) {
|
|
1126
|
+
const dataLength = state.props.data.length;
|
|
1127
|
+
if (dataLength === 0) {
|
|
1128
|
+
return offset;
|
|
1050
1129
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1130
|
+
const isOutOfBounds = index < 0 || index >= dataLength;
|
|
1131
|
+
const fallbackEstimatedSize = (_a3 = state.props.estimatedItemSize) != null ? _a3 : 0;
|
|
1132
|
+
const itemSize = isOutOfBounds ? fallbackEstimatedSize : getItemSize(ctx, getId(state, index), index, state.props.data[index]);
|
|
1133
|
+
const trailingInset = getContentInsetEnd(state);
|
|
1134
|
+
offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
|
|
1135
|
+
if (!isOutOfBounds && index === state.props.data.length - 1) {
|
|
1136
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
1137
|
+
offset += footerSize;
|
|
1053
1138
|
}
|
|
1054
1139
|
}
|
|
1140
|
+
return offset;
|
|
1055
1141
|
}
|
|
1056
|
-
var Platform2 = Platform;
|
|
1057
1142
|
|
|
1058
|
-
// src/core/
|
|
1059
|
-
function
|
|
1060
|
-
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
state.scrollHistory.length = 0;
|
|
1073
|
-
if (!noScrollingTo) {
|
|
1074
|
-
set$(ctx, "scrollingTo", scrollTarget);
|
|
1075
|
-
}
|
|
1076
|
-
state.scrollPending = offset;
|
|
1077
|
-
if (!isInitialScroll || Platform2.OS === "android") {
|
|
1078
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
1079
|
-
animated: !!animated,
|
|
1080
|
-
x: horizontal ? offset : 0,
|
|
1081
|
-
y: horizontal ? 0 : offset
|
|
1082
|
-
});
|
|
1083
|
-
}
|
|
1084
|
-
if (!animated) {
|
|
1085
|
-
state.scroll = offset;
|
|
1086
|
-
if (Platform2.OS === "web") {
|
|
1087
|
-
const unlisten = listen$(ctx, "containersDidLayout", (value) => {
|
|
1088
|
-
if (value && peek$(ctx, "scrollingTo")) {
|
|
1089
|
-
finishScrollTo(ctx, state);
|
|
1090
|
-
unlisten();
|
|
1091
|
-
}
|
|
1092
|
-
});
|
|
1093
|
-
} else {
|
|
1094
|
-
setTimeout(() => finishScrollTo(ctx, state), 100);
|
|
1095
|
-
}
|
|
1096
|
-
if (isInitialScroll) {
|
|
1097
|
-
setTimeout(() => {
|
|
1098
|
-
state.initialScroll = void 0;
|
|
1099
|
-
}, 500);
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1143
|
+
// src/core/clampScrollOffset.ts
|
|
1144
|
+
function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
1145
|
+
const state = ctx.state;
|
|
1146
|
+
const contentSize = getContentSize(ctx);
|
|
1147
|
+
let clampedOffset = offset;
|
|
1148
|
+
if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength) && (Platform2.OS !== "android" || state.lastLayout)) {
|
|
1149
|
+
const baseMaxOffset = Math.max(0, contentSize - state.scrollLength);
|
|
1150
|
+
const viewOffset = scrollTarget == null ? void 0 : scrollTarget.viewOffset;
|
|
1151
|
+
const extraEndOffset = typeof viewOffset === "number" && viewOffset < 0 ? -viewOffset : 0;
|
|
1152
|
+
const maxOffset = baseMaxOffset + extraEndOffset;
|
|
1153
|
+
clampedOffset = Math.min(offset, maxOffset);
|
|
1154
|
+
}
|
|
1155
|
+
clampedOffset = Math.max(0, clampedOffset);
|
|
1156
|
+
return clampedOffset;
|
|
1102
1157
|
}
|
|
1103
1158
|
|
|
1104
1159
|
// src/utils/checkThreshold.ts
|
|
1105
1160
|
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1106
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
1161
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1107
1162
|
const absDistance = Math.abs(distance);
|
|
1108
1163
|
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1109
1164
|
const updateSnapshot = () => {
|
|
1110
|
-
setSnapshot
|
|
1165
|
+
setSnapshot({
|
|
1111
1166
|
atThreshold,
|
|
1112
1167
|
contentSize: context.contentSize,
|
|
1113
1168
|
dataLength: context.dataLength,
|
|
@@ -1118,19 +1173,21 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
|
|
|
1118
1173
|
if (!within) {
|
|
1119
1174
|
return false;
|
|
1120
1175
|
}
|
|
1121
|
-
onReached
|
|
1176
|
+
onReached(distance);
|
|
1122
1177
|
updateSnapshot();
|
|
1123
1178
|
return true;
|
|
1124
1179
|
}
|
|
1125
1180
|
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1126
1181
|
if (reset) {
|
|
1127
|
-
setSnapshot
|
|
1182
|
+
setSnapshot(void 0);
|
|
1128
1183
|
return false;
|
|
1129
1184
|
}
|
|
1130
1185
|
if (within) {
|
|
1131
1186
|
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1132
1187
|
if (changed) {
|
|
1133
|
-
|
|
1188
|
+
if (allowReentryOnChange) {
|
|
1189
|
+
onReached(distance);
|
|
1190
|
+
}
|
|
1134
1191
|
updateSnapshot();
|
|
1135
1192
|
}
|
|
1136
1193
|
}
|
|
@@ -1138,9 +1195,10 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
|
|
|
1138
1195
|
};
|
|
1139
1196
|
|
|
1140
1197
|
// src/utils/checkAtBottom.ts
|
|
1141
|
-
function checkAtBottom(ctx
|
|
1198
|
+
function checkAtBottom(ctx) {
|
|
1142
1199
|
var _a3;
|
|
1143
|
-
|
|
1200
|
+
const state = ctx.state;
|
|
1201
|
+
if (!state || state.initialScroll) {
|
|
1144
1202
|
return;
|
|
1145
1203
|
}
|
|
1146
1204
|
const {
|
|
@@ -1150,9 +1208,13 @@ function checkAtBottom(ctx, state) {
|
|
|
1150
1208
|
maintainingScrollAtEnd,
|
|
1151
1209
|
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1152
1210
|
} = state;
|
|
1211
|
+
if (state.initialScroll) {
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1153
1214
|
const contentSize = getContentSize(ctx);
|
|
1154
1215
|
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1155
|
-
const
|
|
1216
|
+
const insetEnd = getContentInsetEnd(state);
|
|
1217
|
+
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1156
1218
|
const isContentLess = contentSize < scrollLength;
|
|
1157
1219
|
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1158
1220
|
state.isEndReached = checkThreshold(
|
|
@@ -1172,95 +1234,659 @@ function checkAtBottom(ctx, state) {
|
|
|
1172
1234
|
},
|
|
1173
1235
|
(snapshot) => {
|
|
1174
1236
|
state.endReachedSnapshot = snapshot;
|
|
1175
|
-
}
|
|
1237
|
+
},
|
|
1238
|
+
true
|
|
1176
1239
|
);
|
|
1177
1240
|
}
|
|
1178
1241
|
}
|
|
1179
1242
|
|
|
1180
1243
|
// src/utils/checkAtTop.ts
|
|
1181
|
-
function checkAtTop(
|
|
1182
|
-
|
|
1183
|
-
if (!state) {
|
|
1244
|
+
function checkAtTop(ctx) {
|
|
1245
|
+
const state = ctx == null ? void 0 : ctx.state;
|
|
1246
|
+
if (!state || state.initialScroll || state.scrollingTo) {
|
|
1184
1247
|
return;
|
|
1185
1248
|
}
|
|
1186
1249
|
const {
|
|
1187
|
-
|
|
1250
|
+
dataChangeEpoch,
|
|
1251
|
+
isStartReached,
|
|
1252
|
+
props: { data, onStartReachedThreshold },
|
|
1188
1253
|
scroll,
|
|
1189
|
-
|
|
1254
|
+
scrollLength,
|
|
1255
|
+
startReachedSnapshot,
|
|
1256
|
+
startReachedSnapshotDataChangeEpoch,
|
|
1257
|
+
totalSize
|
|
1190
1258
|
} = state;
|
|
1191
|
-
const
|
|
1192
|
-
|
|
1259
|
+
const dataLength = data.length;
|
|
1260
|
+
const threshold = onStartReachedThreshold * scrollLength;
|
|
1261
|
+
const dataChanged = startReachedSnapshotDataChangeEpoch !== dataChangeEpoch;
|
|
1262
|
+
const withinThreshold = threshold > 0 && Math.abs(scroll) <= threshold;
|
|
1263
|
+
const allowReentryOnDataChange = !!isStartReached && withinThreshold && !!dataChanged && !isInMVCPActiveMode(state);
|
|
1264
|
+
if (isStartReached && threshold > 0 && scroll > threshold && startReachedSnapshot && (dataChanged || startReachedSnapshot.contentSize !== totalSize || startReachedSnapshot.dataLength !== dataLength)) {
|
|
1265
|
+
state.isStartReached = false;
|
|
1266
|
+
state.startReachedSnapshot = void 0;
|
|
1267
|
+
state.startReachedSnapshotDataChangeEpoch = void 0;
|
|
1268
|
+
}
|
|
1269
|
+
state.isAtStart = scroll <= 0;
|
|
1270
|
+
if (isStartReached && withinThreshold && dataChanged && !allowReentryOnDataChange) {
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1193
1273
|
state.isStartReached = checkThreshold(
|
|
1194
|
-
|
|
1274
|
+
scroll,
|
|
1195
1275
|
false,
|
|
1196
|
-
|
|
1276
|
+
threshold,
|
|
1197
1277
|
state.isStartReached,
|
|
1198
|
-
|
|
1278
|
+
allowReentryOnDataChange ? void 0 : startReachedSnapshot,
|
|
1199
1279
|
{
|
|
1200
|
-
contentSize:
|
|
1201
|
-
dataLength
|
|
1280
|
+
contentSize: totalSize,
|
|
1281
|
+
dataLength,
|
|
1202
1282
|
scrollPosition: scroll
|
|
1203
1283
|
},
|
|
1204
1284
|
(distance) => {
|
|
1205
|
-
var
|
|
1206
|
-
return (_b = (
|
|
1285
|
+
var _a3, _b;
|
|
1286
|
+
return (_b = (_a3 = state.props).onStartReached) == null ? void 0 : _b.call(_a3, { distanceFromStart: distance });
|
|
1207
1287
|
},
|
|
1208
1288
|
(snapshot) => {
|
|
1209
1289
|
state.startReachedSnapshot = snapshot;
|
|
1210
|
-
|
|
1290
|
+
state.startReachedSnapshotDataChangeEpoch = snapshot ? dataChangeEpoch : void 0;
|
|
1291
|
+
},
|
|
1292
|
+
allowReentryOnDataChange
|
|
1211
1293
|
);
|
|
1212
1294
|
}
|
|
1213
1295
|
|
|
1214
|
-
// src/
|
|
1215
|
-
function
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1296
|
+
// src/utils/checkThresholds.ts
|
|
1297
|
+
function checkThresholds(ctx) {
|
|
1298
|
+
checkAtBottom(ctx);
|
|
1299
|
+
checkAtTop(ctx);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// src/utils/setInitialRenderState.ts
|
|
1303
|
+
function setInitialRenderState(ctx, {
|
|
1304
|
+
didLayout,
|
|
1305
|
+
didInitialScroll
|
|
1306
|
+
}) {
|
|
1307
|
+
const { state } = ctx;
|
|
1308
|
+
const {
|
|
1309
|
+
loadStartTime,
|
|
1310
|
+
props: { onLoad }
|
|
1311
|
+
} = state;
|
|
1312
|
+
if (didLayout) {
|
|
1313
|
+
state.didContainersLayout = true;
|
|
1226
1314
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
if (!adjustChanged) {
|
|
1230
|
-
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1231
|
-
}
|
|
1315
|
+
if (didInitialScroll) {
|
|
1316
|
+
state.didFinishInitialScroll = true;
|
|
1232
1317
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1318
|
+
const isReadyToRender = Boolean(state.didContainersLayout && state.didFinishInitialScroll);
|
|
1319
|
+
if (isReadyToRender && !peek$(ctx, "readyToRender")) {
|
|
1320
|
+
set$(ctx, "readyToRender", true);
|
|
1321
|
+
if (onLoad) {
|
|
1322
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1323
|
+
}
|
|
1235
1324
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
// src/core/finishScrollTo.ts
|
|
1328
|
+
function finishScrollTo(ctx) {
|
|
1329
|
+
var _a3, _b;
|
|
1330
|
+
const state = ctx.state;
|
|
1331
|
+
if (state == null ? void 0 : state.scrollingTo) {
|
|
1332
|
+
const resolvePendingScroll = state.pendingScrollResolve;
|
|
1333
|
+
state.pendingScrollResolve = void 0;
|
|
1334
|
+
const scrollingTo = state.scrollingTo;
|
|
1335
|
+
state.scrollHistory.length = 0;
|
|
1336
|
+
state.initialScroll = void 0;
|
|
1337
|
+
state.initialScrollUsesOffset = false;
|
|
1338
|
+
state.initialAnchor = void 0;
|
|
1339
|
+
state.initialNativeScrollWatchdog = void 0;
|
|
1340
|
+
state.scrollingTo = void 0;
|
|
1341
|
+
if (state.pendingTotalSize !== void 0) {
|
|
1342
|
+
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1343
|
+
}
|
|
1344
|
+
if ((_a3 = state.props) == null ? void 0 : _a3.data) {
|
|
1345
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
1346
|
+
}
|
|
1347
|
+
if (PlatformAdjustBreaksScroll) {
|
|
1348
|
+
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1349
|
+
}
|
|
1350
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1351
|
+
checkThresholds(ctx);
|
|
1352
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// src/core/checkFinishedScroll.ts
|
|
1357
|
+
var INITIAL_SCROLL_MIN_TARGET_OFFSET = 1;
|
|
1358
|
+
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
1359
|
+
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
1360
|
+
function checkFinishedScroll(ctx) {
|
|
1361
|
+
ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
|
|
1362
|
+
}
|
|
1363
|
+
function checkFinishedScrollFrame(ctx) {
|
|
1364
|
+
var _a3;
|
|
1365
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
1366
|
+
if (scrollingTo) {
|
|
1367
|
+
const { state } = ctx;
|
|
1368
|
+
state.animFrameCheckFinishedScroll = void 0;
|
|
1369
|
+
const scroll = state.scrollPending;
|
|
1370
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
1371
|
+
const clampedTargetOffset = (_a3 = scrollingTo.targetOffset) != null ? _a3 : clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0), scrollingTo);
|
|
1372
|
+
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
1373
|
+
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
1374
|
+
const diff2 = Math.abs(diff1 - adjust);
|
|
1375
|
+
const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
|
|
1376
|
+
const isAtTarget = diff1 < 1 || !scrollingTo.animated && diff2 < 1;
|
|
1377
|
+
if (isNotOverscrolled && isAtTarget) {
|
|
1378
|
+
finishScrollTo(ctx);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
function checkFinishedScrollFallback(ctx) {
|
|
1383
|
+
const state = ctx.state;
|
|
1384
|
+
const scrollingTo = state.scrollingTo;
|
|
1385
|
+
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
1386
|
+
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget || !state.didContainersLayout;
|
|
1387
|
+
state.timeoutCheckFinishedScrollFallback = setTimeout(
|
|
1388
|
+
() => {
|
|
1389
|
+
let numChecks = 0;
|
|
1390
|
+
const checkHasScrolled = () => {
|
|
1391
|
+
var _a3, _b;
|
|
1392
|
+
state.timeoutCheckFinishedScrollFallback = void 0;
|
|
1393
|
+
const isStillScrollingTo = state.scrollingTo;
|
|
1394
|
+
if (isStillScrollingTo) {
|
|
1395
|
+
numChecks++;
|
|
1396
|
+
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
1397
|
+
const maxChecks = isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
1398
|
+
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
1399
|
+
if (shouldFinishZeroTarget || state.hasScrolled || numChecks > maxChecks) {
|
|
1400
|
+
finishScrollTo(ctx);
|
|
1401
|
+
} else if (isNativeInitialPending && numChecks <= maxChecks) {
|
|
1402
|
+
const targetOffset = (_b = (_a3 = state.initialNativeScrollWatchdog) == null ? void 0 : _a3.targetOffset) != null ? _b : state.scrollPending;
|
|
1403
|
+
const scroller = state.refScroller.current;
|
|
1404
|
+
if (scroller) {
|
|
1405
|
+
scroller.scrollTo({
|
|
1406
|
+
animated: false,
|
|
1407
|
+
x: state.props.horizontal ? targetOffset : 0,
|
|
1408
|
+
y: state.props.horizontal ? 0 : targetOffset
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
|
|
1412
|
+
} else {
|
|
1413
|
+
state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
checkHasScrolled();
|
|
1418
|
+
},
|
|
1419
|
+
slowTimeout ? 500 : 100
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
function isNativeInitialNonZeroTarget(state) {
|
|
1423
|
+
return !state.didFinishInitialScroll && !!state.initialNativeScrollWatchdog && state.initialNativeScrollWatchdog.targetOffset > INITIAL_SCROLL_MIN_TARGET_OFFSET;
|
|
1424
|
+
}
|
|
1425
|
+
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
1426
|
+
var _a3;
|
|
1427
|
+
const { state } = ctx;
|
|
1428
|
+
return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
// src/core/doScrollTo.native.ts
|
|
1432
|
+
function doScrollTo(ctx, params) {
|
|
1433
|
+
const state = ctx.state;
|
|
1434
|
+
const { animated, horizontal, offset } = params;
|
|
1435
|
+
const isAnimated = !!animated;
|
|
1436
|
+
const { refScroller } = state;
|
|
1437
|
+
const scroller = refScroller.current;
|
|
1438
|
+
if (!scroller) {
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
scroller.scrollTo({
|
|
1442
|
+
animated: isAnimated,
|
|
1443
|
+
x: horizontal ? offset : 0,
|
|
1444
|
+
y: horizontal ? 0 : offset
|
|
1445
|
+
});
|
|
1446
|
+
if (!isAnimated) {
|
|
1447
|
+
state.scroll = offset;
|
|
1448
|
+
checkFinishedScrollFallback(ctx);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
// src/core/scrollTo.ts
|
|
1453
|
+
var WATCHDOG_OFFSET_EPSILON = 1;
|
|
1454
|
+
function scrollTo(ctx, params) {
|
|
1455
|
+
var _a3, _b;
|
|
1456
|
+
const state = ctx.state;
|
|
1457
|
+
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
1458
|
+
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
1459
|
+
const {
|
|
1460
|
+
props: { horizontal }
|
|
1461
|
+
} = state;
|
|
1462
|
+
if (state.animFrameCheckFinishedScroll) {
|
|
1463
|
+
cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
|
|
1464
|
+
}
|
|
1465
|
+
if (state.timeoutCheckFinishedScrollFallback) {
|
|
1466
|
+
clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
|
|
1467
|
+
}
|
|
1468
|
+
let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
|
|
1469
|
+
offset = clampScrollOffset(ctx, offset, scrollTarget);
|
|
1470
|
+
state.scrollHistory.length = 0;
|
|
1471
|
+
if (!noScrollingTo) {
|
|
1472
|
+
state.scrollingTo = {
|
|
1473
|
+
...scrollTarget,
|
|
1474
|
+
targetOffset: offset
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
state.scrollPending = offset;
|
|
1478
|
+
const shouldWatchInitialNativeScroll = !state.didFinishInitialScroll && (isInitialScroll || !!state.initialNativeScrollWatchdog) && offset > WATCHDOG_OFFSET_EPSILON;
|
|
1479
|
+
const shouldClearInitialNativeScrollWatchdog = !state.didFinishInitialScroll && !!state.initialNativeScrollWatchdog && offset <= WATCHDOG_OFFSET_EPSILON;
|
|
1480
|
+
if (shouldWatchInitialNativeScroll) {
|
|
1481
|
+
state.hasScrolled = false;
|
|
1482
|
+
state.initialNativeScrollWatchdog = {
|
|
1483
|
+
startScroll: (_b = (_a3 = state.initialNativeScrollWatchdog) == null ? void 0 : _a3.startScroll) != null ? _b : state.scroll,
|
|
1484
|
+
targetOffset: offset
|
|
1485
|
+
};
|
|
1486
|
+
} else if (shouldClearInitialNativeScrollWatchdog) {
|
|
1487
|
+
state.initialNativeScrollWatchdog = void 0;
|
|
1488
|
+
}
|
|
1489
|
+
if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
|
|
1490
|
+
doScrollTo(ctx, { animated, horizontal, offset });
|
|
1491
|
+
} else {
|
|
1492
|
+
state.scroll = offset;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1497
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1498
|
+
const state = ctx.state;
|
|
1499
|
+
const {
|
|
1500
|
+
didContainersLayout,
|
|
1501
|
+
isAtEnd,
|
|
1502
|
+
pendingNativeMVCPAdjust,
|
|
1503
|
+
refScroller,
|
|
1504
|
+
props: { maintainScrollAtEnd }
|
|
1505
|
+
} = state;
|
|
1506
|
+
const shouldMaintainScrollAtEnd = !!(isAtEnd && maintainScrollAtEnd && didContainersLayout);
|
|
1507
|
+
if (pendingNativeMVCPAdjust) {
|
|
1508
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1509
|
+
return false;
|
|
1510
|
+
}
|
|
1511
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1512
|
+
if (shouldMaintainScrollAtEnd) {
|
|
1513
|
+
const contentSize = getContentSize(ctx);
|
|
1514
|
+
if (contentSize < state.scrollLength) {
|
|
1515
|
+
state.scroll = 0;
|
|
1516
|
+
}
|
|
1517
|
+
requestAnimationFrame(() => {
|
|
1518
|
+
var _a3;
|
|
1519
|
+
if (state.isAtEnd) {
|
|
1520
|
+
state.maintainingScrollAtEnd = true;
|
|
1521
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
1522
|
+
animated: maintainScrollAtEnd.animated
|
|
1523
|
+
});
|
|
1524
|
+
setTimeout(
|
|
1525
|
+
() => {
|
|
1526
|
+
state.maintainingScrollAtEnd = false;
|
|
1527
|
+
},
|
|
1528
|
+
maintainScrollAtEnd.animated ? 500 : 0
|
|
1529
|
+
);
|
|
1530
|
+
}
|
|
1531
|
+
});
|
|
1532
|
+
return true;
|
|
1533
|
+
}
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
// src/core/mvcp.ts
|
|
1538
|
+
var MVCP_POSITION_EPSILON = 0.1;
|
|
1539
|
+
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
1540
|
+
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
1541
|
+
var NATIVE_END_CLAMP_EPSILON = 1;
|
|
1542
|
+
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
1543
|
+
if (!enableMVCPAnchorLock) {
|
|
1544
|
+
state.mvcpAnchorLock = void 0;
|
|
1545
|
+
return void 0;
|
|
1546
|
+
}
|
|
1547
|
+
const lock = state.mvcpAnchorLock;
|
|
1548
|
+
if (!lock) {
|
|
1549
|
+
return void 0;
|
|
1550
|
+
}
|
|
1551
|
+
const isExpired = now > lock.expiresAt;
|
|
1552
|
+
const isMissing = state.indexByKey.get(lock.id) === void 0;
|
|
1553
|
+
if (isExpired || isMissing || !mvcpData) {
|
|
1554
|
+
state.mvcpAnchorLock = void 0;
|
|
1555
|
+
return void 0;
|
|
1556
|
+
}
|
|
1557
|
+
return lock;
|
|
1558
|
+
}
|
|
1559
|
+
function updateAnchorLock(state, params) {
|
|
1560
|
+
if (Platform2.OS === "web") {
|
|
1561
|
+
const { anchorId, anchorPosition, dataChanged, now, positionDiff } = params;
|
|
1562
|
+
const enableMVCPAnchorLock = !!dataChanged || !!state.mvcpAnchorLock;
|
|
1563
|
+
const mvcpData = state.props.maintainVisibleContentPosition.data;
|
|
1564
|
+
if (!enableMVCPAnchorLock || !mvcpData || state.scrollingTo || !anchorId || anchorPosition === void 0) {
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
const existingLock = state.mvcpAnchorLock;
|
|
1568
|
+
const quietPasses = !dataChanged && Math.abs(positionDiff) <= MVCP_POSITION_EPSILON && (existingLock == null ? void 0 : existingLock.id) === anchorId ? existingLock.quietPasses + 1 : 0;
|
|
1569
|
+
if (!dataChanged && quietPasses >= MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE) {
|
|
1570
|
+
state.mvcpAnchorLock = void 0;
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
state.mvcpAnchorLock = {
|
|
1574
|
+
expiresAt: now + MVCP_ANCHOR_LOCK_TTL_MS,
|
|
1575
|
+
id: anchorId,
|
|
1576
|
+
position: anchorPosition,
|
|
1577
|
+
quietPasses
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
function shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget) {
|
|
1582
|
+
if (!dataChanged || Platform2.OS === "web" || !state.props.maintainVisibleContentPosition.data || scrollTarget !== void 0 || positionDiff >= -MVCP_POSITION_EPSILON) {
|
|
1583
|
+
return false;
|
|
1584
|
+
}
|
|
1585
|
+
const distanceFromEnd = prevTotalSize - prevScroll - state.scrollLength;
|
|
1586
|
+
return distanceFromEnd < Math.abs(positionDiff) - MVCP_POSITION_EPSILON;
|
|
1587
|
+
}
|
|
1588
|
+
function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
|
|
1589
|
+
if (Math.abs(unresolvedAmount) <= MVCP_POSITION_EPSILON) {
|
|
1590
|
+
return 0;
|
|
1591
|
+
}
|
|
1592
|
+
const maxScroll = Math.max(0, totalSize - state.scrollLength);
|
|
1593
|
+
const clampDelta = maxScroll - state.scroll;
|
|
1594
|
+
if (unresolvedAmount < 0) {
|
|
1595
|
+
return Math.max(unresolvedAmount, Math.min(0, clampDelta));
|
|
1596
|
+
}
|
|
1597
|
+
if (unresolvedAmount > 0) {
|
|
1598
|
+
return Math.min(unresolvedAmount, Math.max(0, clampDelta));
|
|
1599
|
+
}
|
|
1600
|
+
return 0;
|
|
1601
|
+
}
|
|
1602
|
+
function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
1603
|
+
const state = ctx.state;
|
|
1604
|
+
const pending = state.pendingNativeMVCPAdjust;
|
|
1605
|
+
if (!pending || Math.abs(pending.manualApplied) > MVCP_POSITION_EPSILON) {
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
const totalSize = getContentSize(ctx);
|
|
1609
|
+
const predictedNativeClamp = getPredictedNativeClamp(state, pending.amount, totalSize);
|
|
1610
|
+
if (Math.abs(predictedNativeClamp) <= MVCP_POSITION_EPSILON) {
|
|
1611
|
+
return;
|
|
1612
|
+
}
|
|
1613
|
+
const manualDesired = pending.amount - predictedNativeClamp;
|
|
1614
|
+
if (Math.abs(manualDesired) <= MVCP_POSITION_EPSILON) {
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1617
|
+
pending.manualApplied = manualDesired;
|
|
1618
|
+
requestAdjust(ctx, manualDesired, true);
|
|
1619
|
+
}
|
|
1620
|
+
function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
1621
|
+
const state = ctx.state;
|
|
1622
|
+
const pending = state.pendingNativeMVCPAdjust;
|
|
1623
|
+
if (!pending) {
|
|
1624
|
+
return false;
|
|
1625
|
+
}
|
|
1626
|
+
const remainingAfterManual = pending.amount - pending.manualApplied;
|
|
1627
|
+
const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
|
|
1628
|
+
const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
|
|
1629
|
+
if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
|
|
1630
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1631
|
+
return true;
|
|
1632
|
+
}
|
|
1633
|
+
if (isWrongDirection) {
|
|
1634
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1635
|
+
return false;
|
|
1636
|
+
}
|
|
1637
|
+
const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
1638
|
+
const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
|
|
1639
|
+
const didApproachClamp = distanceToClamp < pending.closestDistanceToClamp - MVCP_POSITION_EPSILON;
|
|
1640
|
+
const didMoveAwayAfterApproach = pending.hasApproachedClamp && distanceToClamp > pending.closestDistanceToClamp + MVCP_POSITION_EPSILON;
|
|
1641
|
+
if (didApproachClamp) {
|
|
1642
|
+
pending.closestDistanceToClamp = distanceToClamp;
|
|
1643
|
+
pending.hasApproachedClamp = true;
|
|
1644
|
+
} else if (didMoveAwayAfterApproach) {
|
|
1645
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1646
|
+
return false;
|
|
1647
|
+
}
|
|
1648
|
+
const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
|
|
1649
|
+
if (!isAtExpectedNativeClamp) {
|
|
1650
|
+
return false;
|
|
1651
|
+
}
|
|
1652
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1653
|
+
const remaining = remainingAfterManual - nativeDelta;
|
|
1654
|
+
if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
|
|
1655
|
+
requestAdjust(ctx, remaining, true);
|
|
1656
|
+
}
|
|
1657
|
+
return true;
|
|
1658
|
+
}
|
|
1659
|
+
function prepareMVCP(ctx, dataChanged) {
|
|
1660
|
+
const state = ctx.state;
|
|
1661
|
+
const { idsInView, positions, props } = state;
|
|
1662
|
+
const {
|
|
1663
|
+
maintainVisibleContentPosition: { data: mvcpData, size: mvcpScroll, shouldRestorePosition }
|
|
1664
|
+
} = props;
|
|
1665
|
+
const isWeb = Platform2.OS === "web";
|
|
1666
|
+
const now = Date.now();
|
|
1667
|
+
const enableMVCPAnchorLock = isWeb && (!!dataChanged || !!state.mvcpAnchorLock);
|
|
1668
|
+
const scrollingTo = state.scrollingTo;
|
|
1669
|
+
const anchorLock = isWeb ? resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) : void 0;
|
|
1670
|
+
let prevPosition;
|
|
1671
|
+
let targetId;
|
|
1672
|
+
const idsInViewWithPositions = [];
|
|
1673
|
+
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
1674
|
+
const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
|
|
1675
|
+
const isEndAnchoredScrollTarget = scrollTarget !== void 0 && state.props.data.length > 0 && scrollTarget >= state.props.data.length - 1 && (scrollingToViewPosition != null ? scrollingToViewPosition : 0) > 0;
|
|
1676
|
+
const shouldMVCP = dataChanged ? mvcpData : mvcpScroll;
|
|
1677
|
+
const indexByKey = state.indexByKey;
|
|
1678
|
+
const prevScroll = state.scroll;
|
|
1679
|
+
const prevTotalSize = getContentSize(ctx);
|
|
1680
|
+
if (shouldMVCP) {
|
|
1681
|
+
if (!isWeb && state.pendingNativeMVCPAdjust && scrollTarget === void 0) {
|
|
1682
|
+
maybeApplyPredictedNativeMVCPAdjust(ctx);
|
|
1683
|
+
return void 0;
|
|
1684
|
+
}
|
|
1685
|
+
if (anchorLock && scrollTarget === void 0) {
|
|
1686
|
+
targetId = anchorLock.id;
|
|
1687
|
+
prevPosition = anchorLock.position;
|
|
1688
|
+
} else if (scrollTarget !== void 0) {
|
|
1689
|
+
if (!IsNewArchitecture && (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll)) {
|
|
1690
|
+
return void 0;
|
|
1691
|
+
}
|
|
1692
|
+
targetId = getId(state, scrollTarget);
|
|
1693
|
+
} else if (idsInView.length > 0 && state.didContainersLayout && !dataChanged) {
|
|
1694
|
+
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1695
|
+
}
|
|
1696
|
+
if (dataChanged && idsInView.length > 0 && state.didContainersLayout) {
|
|
1697
|
+
for (let i = 0; i < idsInView.length; i++) {
|
|
1698
|
+
const id = idsInView[i];
|
|
1699
|
+
const index = indexByKey.get(id);
|
|
1700
|
+
if (index !== void 0) {
|
|
1701
|
+
const position = positions[index];
|
|
1702
|
+
if (position !== void 0) {
|
|
1703
|
+
idsInViewWithPositions.push({ id, position });
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
if (targetId !== void 0 && prevPosition === void 0) {
|
|
1709
|
+
const targetIndex = indexByKey.get(targetId);
|
|
1710
|
+
if (targetIndex !== void 0) {
|
|
1711
|
+
prevPosition = positions[targetIndex];
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
return () => {
|
|
1715
|
+
let positionDiff = 0;
|
|
1716
|
+
let anchorIdForLock = anchorLock == null ? void 0 : anchorLock.id;
|
|
1717
|
+
let anchorPositionForLock;
|
|
1718
|
+
let skipTargetAnchor = false;
|
|
1719
|
+
const data = state.props.data;
|
|
1720
|
+
const shouldValidateLockedAnchor = isWeb && dataChanged && mvcpData && scrollTarget === void 0 && targetId !== void 0 && (anchorLock == null ? void 0 : anchorLock.id) === targetId && shouldRestorePosition !== void 0;
|
|
1721
|
+
if (shouldValidateLockedAnchor && targetId !== void 0) {
|
|
1722
|
+
const index = indexByKey.get(targetId);
|
|
1723
|
+
if (index !== void 0) {
|
|
1724
|
+
const item = data[index];
|
|
1725
|
+
skipTargetAnchor = item === void 0 || !shouldRestorePosition(item, index, data);
|
|
1726
|
+
if (skipTargetAnchor && (anchorLock == null ? void 0 : anchorLock.id) === targetId) {
|
|
1727
|
+
state.mvcpAnchorLock = void 0;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
const shouldUseFallbackVisibleAnchor = dataChanged && mvcpData && scrollTarget === void 0 && (() => {
|
|
1732
|
+
if (targetId === void 0 || skipTargetAnchor) {
|
|
1733
|
+
return true;
|
|
1734
|
+
}
|
|
1735
|
+
const targetIndex = indexByKey.get(targetId);
|
|
1736
|
+
return targetIndex === void 0 || positions[targetIndex] === void 0;
|
|
1737
|
+
})();
|
|
1738
|
+
if (shouldUseFallbackVisibleAnchor) {
|
|
1739
|
+
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1740
|
+
const { id, position } = idsInViewWithPositions[i];
|
|
1741
|
+
const index = indexByKey.get(id);
|
|
1742
|
+
if (index !== void 0 && shouldRestorePosition) {
|
|
1743
|
+
const item = data[index];
|
|
1744
|
+
if (item === void 0 || !shouldRestorePosition(item, index, data)) {
|
|
1745
|
+
continue;
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
const newPosition = index !== void 0 ? positions[index] : void 0;
|
|
1749
|
+
if (newPosition !== void 0) {
|
|
1750
|
+
positionDiff = newPosition - position;
|
|
1751
|
+
anchorIdForLock = id;
|
|
1752
|
+
anchorPositionForLock = newPosition;
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
if (!skipTargetAnchor && targetId !== void 0 && prevPosition !== void 0) {
|
|
1758
|
+
const targetIndex = indexByKey.get(targetId);
|
|
1759
|
+
const newPosition = targetIndex !== void 0 ? positions[targetIndex] : void 0;
|
|
1760
|
+
if (newPosition !== void 0) {
|
|
1761
|
+
const totalSize = getContentSize(ctx);
|
|
1762
|
+
let diff = newPosition - prevPosition;
|
|
1763
|
+
if (diff !== 0 && isEndAnchoredScrollTarget && state.scroll + state.scrollLength > totalSize) {
|
|
1764
|
+
if (diff > 0) {
|
|
1765
|
+
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
1766
|
+
} else {
|
|
1767
|
+
diff = 0;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
positionDiff = diff;
|
|
1771
|
+
anchorIdForLock = targetId;
|
|
1772
|
+
anchorPositionForLock = newPosition;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
if (scrollingToViewPosition && scrollingToViewPosition > 0) {
|
|
1776
|
+
const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
|
|
1777
|
+
const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
|
|
1778
|
+
if (newSize !== void 0 && prevSize !== void 0 && newSize !== prevSize) {
|
|
1779
|
+
const diff = newSize - prevSize;
|
|
1780
|
+
if (diff !== 0) {
|
|
1781
|
+
positionDiff += diff * scrollingToViewPosition;
|
|
1782
|
+
scrollingTo.itemSize = newSize;
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
updateAnchorLock(state, {
|
|
1787
|
+
anchorId: anchorIdForLock,
|
|
1788
|
+
anchorPosition: anchorPositionForLock,
|
|
1789
|
+
dataChanged,
|
|
1790
|
+
now,
|
|
1791
|
+
positionDiff
|
|
1792
|
+
});
|
|
1793
|
+
if (shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget)) {
|
|
1794
|
+
state.pendingNativeMVCPAdjust = {
|
|
1795
|
+
amount: positionDiff,
|
|
1796
|
+
closestDistanceToClamp: Math.abs(
|
|
1797
|
+
prevScroll - Math.max(0, getContentSize(ctx) - state.scrollLength)
|
|
1798
|
+
),
|
|
1799
|
+
hasApproachedClamp: false,
|
|
1800
|
+
manualApplied: 0,
|
|
1801
|
+
startScroll: prevScroll
|
|
1802
|
+
};
|
|
1803
|
+
maybeApplyPredictedNativeMVCPAdjust(ctx);
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
|
|
1807
|
+
requestAdjust(ctx, positionDiff, dataChanged && mvcpData);
|
|
1808
|
+
}
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
// src/platform/flushSync.native.ts
|
|
1814
|
+
var flushSync = (fn) => {
|
|
1815
|
+
fn();
|
|
1816
|
+
};
|
|
1817
|
+
|
|
1818
|
+
// src/core/updateScroll.ts
|
|
1819
|
+
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1820
|
+
var _a3;
|
|
1821
|
+
const state = ctx.state;
|
|
1822
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
1823
|
+
const prevScroll = state.scroll;
|
|
1824
|
+
state.hasScrolled = true;
|
|
1825
|
+
state.lastBatchingAction = Date.now();
|
|
1826
|
+
const currentTime = Date.now();
|
|
1827
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
1828
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
1829
|
+
if (adjustChanged) {
|
|
1830
|
+
scrollHistory.length = 0;
|
|
1831
|
+
}
|
|
1832
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
1833
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1834
|
+
if (!adjustChanged) {
|
|
1835
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
if (scrollHistory.length > 5) {
|
|
1839
|
+
scrollHistory.shift();
|
|
1840
|
+
}
|
|
1841
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1842
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1843
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1244
1844
|
state.ignoreScrollFromMVCPIgnored = true;
|
|
1245
1845
|
return;
|
|
1246
1846
|
}
|
|
1247
1847
|
}
|
|
1248
|
-
|
|
1848
|
+
state.scrollPrev = prevScroll;
|
|
1849
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1850
|
+
state.scroll = newScroll;
|
|
1851
|
+
state.scrollTime = currentTime;
|
|
1852
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1853
|
+
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1854
|
+
const scrollLength = state.scrollLength;
|
|
1855
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
1856
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1857
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1858
|
+
if (shouldUpdate) {
|
|
1859
|
+
state.scrollLastCalculate = state.scroll;
|
|
1249
1860
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1861
|
+
state.lastScrollDelta = scrollDelta;
|
|
1862
|
+
const runCalculateItems = () => {
|
|
1863
|
+
var _a4;
|
|
1864
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1865
|
+
checkThresholds(ctx);
|
|
1866
|
+
};
|
|
1867
|
+
if (Platform2.OS === "web" && scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
1868
|
+
flushSync(runCalculateItems);
|
|
1869
|
+
} else {
|
|
1870
|
+
runCalculateItems();
|
|
1871
|
+
}
|
|
1872
|
+
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
1873
|
+
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
1874
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1875
|
+
doMaintainScrollAtEnd(ctx);
|
|
1876
|
+
}
|
|
1253
1877
|
state.dataChangeNeedsScrollUpdate = false;
|
|
1878
|
+
state.lastScrollDelta = 0;
|
|
1254
1879
|
}
|
|
1255
1880
|
}
|
|
1256
1881
|
|
|
1257
1882
|
// src/utils/requestAdjust.ts
|
|
1258
|
-
function requestAdjust(ctx,
|
|
1883
|
+
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1884
|
+
const state = ctx.state;
|
|
1259
1885
|
if (Math.abs(positionDiff) > 0.1) {
|
|
1260
1886
|
const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
|
|
1261
1887
|
const doit = () => {
|
|
1262
1888
|
if (needsScrollWorkaround) {
|
|
1263
|
-
scrollTo(ctx,
|
|
1889
|
+
scrollTo(ctx, {
|
|
1264
1890
|
noScrollingTo: true,
|
|
1265
1891
|
offset: state.scroll
|
|
1266
1892
|
});
|
|
@@ -1273,8 +1899,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1273
1899
|
};
|
|
1274
1900
|
state.scroll += positionDiff;
|
|
1275
1901
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
1276
|
-
const
|
|
1277
|
-
if (
|
|
1902
|
+
const readyToRender = peek$(ctx, "readyToRender");
|
|
1903
|
+
if (readyToRender) {
|
|
1278
1904
|
doit();
|
|
1279
1905
|
if (Platform2.OS !== "web") {
|
|
1280
1906
|
const threshold = state.scroll - positionDiff / 2;
|
|
@@ -1296,7 +1922,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1296
1922
|
if (shouldForceUpdate) {
|
|
1297
1923
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
1298
1924
|
state.scrollPending = state.scroll;
|
|
1299
|
-
updateScroll(ctx, state
|
|
1925
|
+
updateScroll(ctx, state.scroll, true);
|
|
1300
1926
|
}
|
|
1301
1927
|
}, delay);
|
|
1302
1928
|
}
|
|
@@ -1311,30 +1937,33 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1311
1937
|
var INITIAL_ANCHOR_TOLERANCE = 0.5;
|
|
1312
1938
|
var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
|
|
1313
1939
|
var INITIAL_ANCHOR_SETTLED_TICKS = 2;
|
|
1314
|
-
function ensureInitialAnchor(ctx
|
|
1315
|
-
var _a3, _b, _c, _d, _e;
|
|
1316
|
-
const
|
|
1940
|
+
function ensureInitialAnchor(ctx) {
|
|
1941
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
1942
|
+
const state = ctx.state;
|
|
1943
|
+
const { initialAnchor, didContainersLayout, scroll, scrollLength } = state;
|
|
1944
|
+
const anchor = initialAnchor;
|
|
1945
|
+
if (state.initialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll)) {
|
|
1946
|
+
return;
|
|
1947
|
+
}
|
|
1317
1948
|
const item = state.props.data[anchor.index];
|
|
1318
|
-
|
|
1319
|
-
if (!containersDidLayout) {
|
|
1949
|
+
if (!didContainersLayout) {
|
|
1320
1950
|
return;
|
|
1321
1951
|
}
|
|
1322
1952
|
const id = getId(state, anchor.index);
|
|
1323
|
-
if (state.positions.
|
|
1953
|
+
if (state.positions[anchor.index] === void 0) {
|
|
1324
1954
|
return;
|
|
1325
1955
|
}
|
|
1326
|
-
const size = getItemSize(ctx,
|
|
1956
|
+
const size = getItemSize(ctx, id, anchor.index, item, true, true);
|
|
1327
1957
|
if (size === void 0) {
|
|
1328
1958
|
return;
|
|
1329
1959
|
}
|
|
1330
|
-
const availableSpace = Math.max(0,
|
|
1331
|
-
const
|
|
1332
|
-
const
|
|
1333
|
-
const
|
|
1334
|
-
const
|
|
1335
|
-
const delta = clampedDesiredOffset - state.scroll;
|
|
1960
|
+
const availableSpace = Math.max(0, scrollLength - size);
|
|
1961
|
+
const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
|
|
1962
|
+
const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) + topOffsetAdjustment - ((_b = anchor.viewOffset) != null ? _b : 0) - ((_c = anchor.viewPosition) != null ? _c : 0) * availableSpace;
|
|
1963
|
+
const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset, anchor);
|
|
1964
|
+
const delta = clampedDesiredOffset - scroll;
|
|
1336
1965
|
if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
|
|
1337
|
-
const settledTicks = ((
|
|
1966
|
+
const settledTicks = ((_d = anchor.settledTicks) != null ? _d : 0) + 1;
|
|
1338
1967
|
if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
|
|
1339
1968
|
state.initialAnchor = void 0;
|
|
1340
1969
|
} else {
|
|
@@ -1342,7 +1971,7 @@ function ensureInitialAnchor(ctx, state) {
|
|
|
1342
1971
|
}
|
|
1343
1972
|
return;
|
|
1344
1973
|
}
|
|
1345
|
-
if (((
|
|
1974
|
+
if (((_e = anchor.attempts) != null ? _e : 0) >= INITIAL_ANCHOR_MAX_ATTEMPTS) {
|
|
1346
1975
|
state.initialAnchor = void 0;
|
|
1347
1976
|
return;
|
|
1348
1977
|
}
|
|
@@ -1352,98 +1981,30 @@ function ensureInitialAnchor(ctx, state) {
|
|
|
1352
1981
|
return;
|
|
1353
1982
|
}
|
|
1354
1983
|
Object.assign(anchor, {
|
|
1355
|
-
attempts: ((
|
|
1984
|
+
attempts: ((_f = anchor.attempts) != null ? _f : 0) + 1,
|
|
1356
1985
|
lastDelta: delta,
|
|
1357
1986
|
settledTicks: 0
|
|
1358
1987
|
});
|
|
1359
|
-
requestAdjust(ctx,
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
// src/core/mvcp.ts
|
|
1363
|
-
function prepareMVCP(ctx, state, dataChanged) {
|
|
1364
|
-
const { idsInView, positions, props } = state;
|
|
1365
|
-
const { maintainVisibleContentPosition } = props;
|
|
1366
|
-
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1367
|
-
let prevPosition;
|
|
1368
|
-
let targetId;
|
|
1369
|
-
const idsInViewWithPositions = [];
|
|
1370
|
-
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
1371
|
-
const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
|
|
1372
|
-
const indexByKey = state.indexByKey;
|
|
1373
|
-
if (shouldMVCP) {
|
|
1374
|
-
if (scrollTarget !== void 0) {
|
|
1375
|
-
if (!IsNewArchitecture && (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll)) {
|
|
1376
|
-
return void 0;
|
|
1377
|
-
}
|
|
1378
|
-
targetId = getId(state, scrollTarget);
|
|
1379
|
-
} else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
|
|
1380
|
-
if (dataChanged) {
|
|
1381
|
-
for (let i = 0; i < idsInView.length; i++) {
|
|
1382
|
-
const id = idsInView[i];
|
|
1383
|
-
const index = indexByKey.get(id);
|
|
1384
|
-
if (index !== void 0) {
|
|
1385
|
-
idsInViewWithPositions.push({ id, position: positions.get(id) });
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
} else {
|
|
1389
|
-
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
if (targetId !== void 0) {
|
|
1393
|
-
prevPosition = positions.get(targetId);
|
|
1394
|
-
}
|
|
1395
|
-
return () => {
|
|
1396
|
-
let positionDiff;
|
|
1397
|
-
if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
|
|
1398
|
-
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
1399
|
-
const { id, position } = idsInViewWithPositions[i];
|
|
1400
|
-
const newPosition = positions.get(id);
|
|
1401
|
-
if (newPosition !== void 0) {
|
|
1402
|
-
positionDiff = newPosition - position;
|
|
1403
|
-
break;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
1408
|
-
const newPosition = positions.get(targetId);
|
|
1409
|
-
if (newPosition !== void 0) {
|
|
1410
|
-
const totalSize = getContentSize(ctx);
|
|
1411
|
-
let diff = newPosition - prevPosition;
|
|
1412
|
-
if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
|
|
1413
|
-
if (diff > 0) {
|
|
1414
|
-
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
1415
|
-
} else {
|
|
1416
|
-
diff = 0;
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
positionDiff = diff;
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
|
|
1423
|
-
requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
|
|
1424
|
-
}
|
|
1425
|
-
};
|
|
1426
|
-
}
|
|
1988
|
+
requestAdjust(ctx, delta);
|
|
1427
1989
|
}
|
|
1428
1990
|
|
|
1429
1991
|
// src/core/prepareColumnStartState.ts
|
|
1430
|
-
function prepareColumnStartState(ctx,
|
|
1992
|
+
function prepareColumnStartState(ctx, startIndex, useAverageSize) {
|
|
1431
1993
|
var _a3;
|
|
1994
|
+
const state = ctx.state;
|
|
1432
1995
|
const numColumns = peek$(ctx, "numColumns");
|
|
1433
1996
|
let rowStartIndex = startIndex;
|
|
1434
|
-
const columnAtStart = state.columns
|
|
1997
|
+
const columnAtStart = state.columns[startIndex];
|
|
1435
1998
|
if (columnAtStart !== 1) {
|
|
1436
1999
|
rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
|
|
1437
2000
|
}
|
|
1438
2001
|
let currentRowTop = 0;
|
|
1439
|
-
const
|
|
1440
|
-
const column = state.columns.get(curId);
|
|
2002
|
+
const column = state.columns[rowStartIndex];
|
|
1441
2003
|
if (rowStartIndex > 0) {
|
|
1442
2004
|
const prevIndex = rowStartIndex - 1;
|
|
1443
|
-
const
|
|
1444
|
-
const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
|
|
2005
|
+
const prevPosition = (_a3 = state.positions[prevIndex]) != null ? _a3 : 0;
|
|
1445
2006
|
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1446
|
-
const prevRowHeight = calculateRowMaxSize(ctx,
|
|
2007
|
+
const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
|
|
1447
2008
|
currentRowTop = prevPosition + prevRowHeight;
|
|
1448
2009
|
}
|
|
1449
2010
|
return {
|
|
@@ -1458,7 +2019,7 @@ function findRowStartIndex(state, numColumns, index) {
|
|
|
1458
2019
|
}
|
|
1459
2020
|
let rowStart = Math.max(0, index);
|
|
1460
2021
|
while (rowStart > 0) {
|
|
1461
|
-
const columnForIndex = state.columns
|
|
2022
|
+
const columnForIndex = state.columns[rowStart];
|
|
1462
2023
|
if (columnForIndex === 1) {
|
|
1463
2024
|
break;
|
|
1464
2025
|
}
|
|
@@ -1466,7 +2027,8 @@ function findRowStartIndex(state, numColumns, index) {
|
|
|
1466
2027
|
}
|
|
1467
2028
|
return rowStart;
|
|
1468
2029
|
}
|
|
1469
|
-
function calculateRowMaxSize(ctx,
|
|
2030
|
+
function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
|
|
2031
|
+
const state = ctx.state;
|
|
1470
2032
|
if (endIndex < startIndex) {
|
|
1471
2033
|
return 0;
|
|
1472
2034
|
}
|
|
@@ -1480,7 +2042,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
|
|
|
1480
2042
|
continue;
|
|
1481
2043
|
}
|
|
1482
2044
|
const id = state.idCache[i];
|
|
1483
|
-
const size = getItemSize(ctx,
|
|
2045
|
+
const size = getItemSize(ctx, id, i, data[i], useAverageSize);
|
|
1484
2046
|
if (size > maxSize) {
|
|
1485
2047
|
maxSize = size;
|
|
1486
2048
|
}
|
|
@@ -1489,22 +2051,44 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
|
|
|
1489
2051
|
}
|
|
1490
2052
|
|
|
1491
2053
|
// src/core/updateTotalSize.ts
|
|
1492
|
-
function updateTotalSize(ctx
|
|
2054
|
+
function updateTotalSize(ctx) {
|
|
2055
|
+
var _a3, _b;
|
|
2056
|
+
const state = ctx.state;
|
|
1493
2057
|
const {
|
|
1494
2058
|
positions,
|
|
1495
2059
|
props: { data }
|
|
1496
2060
|
} = state;
|
|
2061
|
+
const numColumns = (_a3 = peek$(ctx, "numColumns")) != null ? _a3 : 1;
|
|
1497
2062
|
if (data.length === 0) {
|
|
1498
|
-
addTotalSize(ctx,
|
|
2063
|
+
addTotalSize(ctx, null, 0);
|
|
1499
2064
|
} else {
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
2065
|
+
const lastIndex = data.length - 1;
|
|
2066
|
+
const lastId = getId(state, lastIndex);
|
|
2067
|
+
const lastPosition = positions[lastIndex];
|
|
2068
|
+
if (lastId !== void 0 && lastPosition !== void 0) {
|
|
2069
|
+
if (numColumns > 1) {
|
|
2070
|
+
let rowStart = lastIndex;
|
|
2071
|
+
while (rowStart > 0) {
|
|
2072
|
+
const column = state.columns[rowStart];
|
|
2073
|
+
if (column === 1 || column === void 0) {
|
|
2074
|
+
break;
|
|
2075
|
+
}
|
|
2076
|
+
rowStart -= 1;
|
|
2077
|
+
}
|
|
2078
|
+
let maxSize = 0;
|
|
2079
|
+
for (let i = rowStart; i <= lastIndex; i++) {
|
|
2080
|
+
const rowId = (_b = state.idCache[i]) != null ? _b : getId(state, i);
|
|
2081
|
+
const size = getItemSize(ctx, rowId, i, data[i]);
|
|
2082
|
+
if (size > maxSize) {
|
|
2083
|
+
maxSize = size;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
addTotalSize(ctx, null, lastPosition + maxSize);
|
|
2087
|
+
} else {
|
|
2088
|
+
const lastSize = getItemSize(ctx, lastId, lastIndex, data[lastIndex]);
|
|
1505
2089
|
if (lastSize !== void 0) {
|
|
1506
2090
|
const totalSize = lastPosition + lastSize;
|
|
1507
|
-
addTotalSize(ctx,
|
|
2091
|
+
addTotalSize(ctx, null, totalSize);
|
|
1508
2092
|
}
|
|
1509
2093
|
}
|
|
1510
2094
|
}
|
|
@@ -1514,90 +2098,107 @@ function updateTotalSize(ctx, state) {
|
|
|
1514
2098
|
// src/utils/getScrollVelocity.ts
|
|
1515
2099
|
var getScrollVelocity = (state) => {
|
|
1516
2100
|
const { scrollHistory } = state;
|
|
1517
|
-
|
|
1518
|
-
if (
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1530
|
-
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1531
|
-
start = i;
|
|
1532
|
-
break;
|
|
1533
|
-
}
|
|
1534
|
-
}
|
|
2101
|
+
const newestIndex = scrollHistory.length - 1;
|
|
2102
|
+
if (newestIndex < 1) {
|
|
2103
|
+
return 0;
|
|
2104
|
+
}
|
|
2105
|
+
const newest = scrollHistory[newestIndex];
|
|
2106
|
+
const now = Date.now();
|
|
2107
|
+
let direction = 0;
|
|
2108
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
2109
|
+
const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
|
|
2110
|
+
if (delta !== 0) {
|
|
2111
|
+
direction = Math.sign(delta);
|
|
2112
|
+
break;
|
|
1535
2113
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
2114
|
+
}
|
|
2115
|
+
if (direction === 0) {
|
|
2116
|
+
return 0;
|
|
2117
|
+
}
|
|
2118
|
+
let oldest = newest;
|
|
2119
|
+
for (let i = newestIndex - 1; i >= 0; i--) {
|
|
2120
|
+
const current = scrollHistory[i];
|
|
2121
|
+
const next = scrollHistory[i + 1];
|
|
2122
|
+
const delta = next.scroll - current.scroll;
|
|
2123
|
+
const deltaSign = Math.sign(delta);
|
|
2124
|
+
if (deltaSign !== 0 && deltaSign !== direction) {
|
|
2125
|
+
break;
|
|
1542
2126
|
}
|
|
1543
|
-
if (
|
|
1544
|
-
|
|
1545
|
-
const timeDiff = newest.time - oldest.time;
|
|
1546
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
2127
|
+
if (now - current.time > 1e3) {
|
|
2128
|
+
break;
|
|
1547
2129
|
}
|
|
2130
|
+
oldest = current;
|
|
1548
2131
|
}
|
|
1549
|
-
|
|
2132
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
2133
|
+
const timeDiff = newest.time - oldest.time;
|
|
2134
|
+
return timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1550
2135
|
};
|
|
1551
2136
|
|
|
1552
2137
|
// src/utils/updateSnapToOffsets.ts
|
|
1553
|
-
function updateSnapToOffsets(ctx
|
|
2138
|
+
function updateSnapToOffsets(ctx) {
|
|
2139
|
+
const state = ctx.state;
|
|
1554
2140
|
const {
|
|
1555
|
-
positions,
|
|
1556
2141
|
props: { snapToIndices }
|
|
1557
2142
|
} = state;
|
|
1558
2143
|
const snapToOffsets = Array(snapToIndices.length);
|
|
1559
2144
|
for (let i = 0; i < snapToIndices.length; i++) {
|
|
1560
2145
|
const idx = snapToIndices[i];
|
|
1561
|
-
|
|
1562
|
-
snapToOffsets[i] = positions
|
|
2146
|
+
getId(state, idx);
|
|
2147
|
+
snapToOffsets[i] = state.positions[idx];
|
|
1563
2148
|
}
|
|
1564
2149
|
set$(ctx, "snapToOffsets", snapToOffsets);
|
|
1565
2150
|
}
|
|
1566
2151
|
|
|
1567
2152
|
// src/core/updateItemPositions.ts
|
|
1568
|
-
function updateItemPositions(ctx,
|
|
2153
|
+
function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
|
|
1569
2154
|
doMVCP: false,
|
|
1570
2155
|
forceFullUpdate: false,
|
|
1571
2156
|
scrollBottomBuffered: -1,
|
|
1572
2157
|
startIndex: 0
|
|
1573
2158
|
}) {
|
|
1574
2159
|
var _a3, _b, _c, _d, _e;
|
|
2160
|
+
const state = ctx.state;
|
|
2161
|
+
const hasPositionListeners = ctx.positionListeners.size > 0;
|
|
1575
2162
|
const {
|
|
1576
2163
|
columns,
|
|
2164
|
+
columnSpans,
|
|
1577
2165
|
indexByKey,
|
|
1578
2166
|
positions,
|
|
1579
2167
|
idCache,
|
|
1580
2168
|
sizesKnown,
|
|
1581
|
-
props: { getEstimatedItemSize,
|
|
2169
|
+
props: { data, getEstimatedItemSize, overrideItemLayout, snapToIndices },
|
|
2170
|
+
scrollingTo
|
|
1582
2171
|
} = state;
|
|
1583
|
-
const data = state.props.data;
|
|
1584
2172
|
const dataLength = data.length;
|
|
1585
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
1586
|
-
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
2173
|
+
const numColumns = (_a3 = peek$(ctx, "numColumns")) != null ? _a3 : 1;
|
|
1587
2174
|
const hasColumns = numColumns > 1;
|
|
1588
2175
|
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
1589
|
-
const
|
|
2176
|
+
const extraData = peek$(ctx, "extraData");
|
|
2177
|
+
const layoutConfig = overrideItemLayout ? { span: 1 } : void 0;
|
|
2178
|
+
const lastScrollDelta = state.lastScrollDelta;
|
|
2179
|
+
const velocity = getScrollVelocity(state);
|
|
2180
|
+
const shouldOptimize = !forceFullUpdate && !dataChanged && (Math.abs(velocity) > 0 || Platform2.OS === "web" && state.scrollLength > 0 && lastScrollDelta > state.scrollLength);
|
|
1590
2181
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1591
|
-
const useAverageSize =
|
|
1592
|
-
const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((
|
|
2182
|
+
const useAverageSize = !getEstimatedItemSize;
|
|
2183
|
+
const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_b = peek$(ctx, "scrollAdjustPending")) != null ? _b : 0) !== 0;
|
|
1593
2184
|
let currentRowTop = 0;
|
|
1594
2185
|
let column = 1;
|
|
1595
2186
|
let maxSizeInRow = 0;
|
|
2187
|
+
if (dataChanged) {
|
|
2188
|
+
columnSpans.length = 0;
|
|
2189
|
+
}
|
|
2190
|
+
if (!hasColumns) {
|
|
2191
|
+
if (columns.length) {
|
|
2192
|
+
columns.length = 0;
|
|
2193
|
+
}
|
|
2194
|
+
if (columnSpans.length) {
|
|
2195
|
+
columnSpans.length = 0;
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
1596
2198
|
if (startIndex > 0) {
|
|
1597
2199
|
if (hasColumns) {
|
|
1598
2200
|
const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
|
|
1599
2201
|
ctx,
|
|
1600
|
-
state,
|
|
1601
2202
|
startIndex,
|
|
1602
2203
|
useAverageSize
|
|
1603
2204
|
);
|
|
@@ -1606,12 +2207,13 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1606
2207
|
} else if (startIndex < dataLength) {
|
|
1607
2208
|
const prevIndex = startIndex - 1;
|
|
1608
2209
|
const prevId = getId(state, prevIndex);
|
|
1609
|
-
const prevPosition = (
|
|
1610
|
-
const prevSize = (
|
|
2210
|
+
const prevPosition = (_c = positions[prevIndex]) != null ? _c : 0;
|
|
2211
|
+
const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
|
|
1611
2212
|
currentRowTop = prevPosition + prevSize;
|
|
1612
2213
|
}
|
|
1613
2214
|
}
|
|
1614
2215
|
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
2216
|
+
const canOverrideSpan = hasColumns && !!overrideItemLayout && !!layoutConfig;
|
|
1615
2217
|
let didBreakEarly = false;
|
|
1616
2218
|
let breakAt;
|
|
1617
2219
|
for (let i = startIndex; i < dataLength; i++) {
|
|
@@ -1623,8 +2225,23 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1623
2225
|
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1624
2226
|
breakAt = i + itemsPerRow + 10;
|
|
1625
2227
|
}
|
|
1626
|
-
const id = (
|
|
1627
|
-
|
|
2228
|
+
const id = (_e = idCache[i]) != null ? _e : getId(state, i);
|
|
2229
|
+
let span = 1;
|
|
2230
|
+
if (canOverrideSpan) {
|
|
2231
|
+
layoutConfig.span = 1;
|
|
2232
|
+
overrideItemLayout(layoutConfig, data[i], i, numColumns, extraData);
|
|
2233
|
+
const requestedSpan = layoutConfig.span;
|
|
2234
|
+
if (requestedSpan !== void 0 && Number.isFinite(requestedSpan)) {
|
|
2235
|
+
span = Math.max(1, Math.min(numColumns, Math.round(requestedSpan)));
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
if (hasColumns && column + span - 1 > numColumns) {
|
|
2239
|
+
currentRowTop += maxSizeInRow;
|
|
2240
|
+
column = 1;
|
|
2241
|
+
maxSizeInRow = 0;
|
|
2242
|
+
}
|
|
2243
|
+
const knownSize = sizesKnown.get(id);
|
|
2244
|
+
const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
|
|
1628
2245
|
if (IS_DEV && needsIndexByKey) {
|
|
1629
2246
|
if (indexByKeyForChecking.has(id)) {
|
|
1630
2247
|
console.error(
|
|
@@ -1633,30 +2250,36 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1633
2250
|
}
|
|
1634
2251
|
indexByKeyForChecking.set(id, i);
|
|
1635
2252
|
}
|
|
1636
|
-
|
|
2253
|
+
if (currentRowTop !== positions[i]) {
|
|
2254
|
+
positions[i] = currentRowTop;
|
|
2255
|
+
if (hasPositionListeners) {
|
|
2256
|
+
notifyPosition$(ctx, id, currentRowTop);
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
1637
2259
|
if (needsIndexByKey) {
|
|
1638
2260
|
indexByKey.set(id, i);
|
|
1639
2261
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
2262
|
+
if (!hasColumns) {
|
|
2263
|
+
currentRowTop += size;
|
|
2264
|
+
} else {
|
|
2265
|
+
columns[i] = column;
|
|
2266
|
+
columnSpans[i] = span;
|
|
1642
2267
|
if (size > maxSizeInRow) {
|
|
1643
2268
|
maxSizeInRow = size;
|
|
1644
2269
|
}
|
|
1645
|
-
column
|
|
2270
|
+
column += span;
|
|
1646
2271
|
if (column > numColumns) {
|
|
1647
2272
|
currentRowTop += maxSizeInRow;
|
|
1648
2273
|
column = 1;
|
|
1649
2274
|
maxSizeInRow = 0;
|
|
1650
2275
|
}
|
|
1651
|
-
} else {
|
|
1652
|
-
currentRowTop += size;
|
|
1653
2276
|
}
|
|
1654
2277
|
}
|
|
1655
2278
|
if (!didBreakEarly) {
|
|
1656
|
-
updateTotalSize(ctx
|
|
2279
|
+
updateTotalSize(ctx);
|
|
1657
2280
|
}
|
|
1658
2281
|
if (snapToIndices) {
|
|
1659
|
-
updateSnapToOffsets(ctx
|
|
2282
|
+
updateSnapToOffsets(ctx);
|
|
1660
2283
|
}
|
|
1661
2284
|
}
|
|
1662
2285
|
|
|
@@ -1734,7 +2357,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
|
|
|
1734
2357
|
if (previousViewableItems) {
|
|
1735
2358
|
for (const viewToken of previousViewableItems) {
|
|
1736
2359
|
const containerId = findContainerId(ctx, viewToken.key);
|
|
1737
|
-
if (!
|
|
2360
|
+
if (!checkIsViewable(
|
|
1738
2361
|
state,
|
|
1739
2362
|
ctx,
|
|
1740
2363
|
viewabilityConfig,
|
|
@@ -1755,7 +2378,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
|
|
|
1755
2378
|
if (item) {
|
|
1756
2379
|
const key = getId(state, i);
|
|
1757
2380
|
const containerId = findContainerId(ctx, key);
|
|
1758
|
-
if (
|
|
2381
|
+
if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
|
|
1759
2382
|
const viewToken = {
|
|
1760
2383
|
containerId,
|
|
1761
2384
|
index: i,
|
|
@@ -1801,25 +2424,49 @@ function shallowEqual(prev, next) {
|
|
|
1801
2424
|
return true;
|
|
1802
2425
|
}
|
|
1803
2426
|
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
1804
|
-
const { sizes,
|
|
2427
|
+
const { sizes, scroll: scrollState } = state;
|
|
1805
2428
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1806
2429
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
1807
2430
|
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
1808
2431
|
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
1809
2432
|
const scroll = scrollState - topPad;
|
|
1810
|
-
const
|
|
2433
|
+
const position = state.positions[index];
|
|
1811
2434
|
const size = sizes.get(key) || 0;
|
|
2435
|
+
if (position === void 0) {
|
|
2436
|
+
const value2 = {
|
|
2437
|
+
containerId,
|
|
2438
|
+
index,
|
|
2439
|
+
isViewable: false,
|
|
2440
|
+
item,
|
|
2441
|
+
key,
|
|
2442
|
+
percentOfScroller: 0,
|
|
2443
|
+
percentVisible: 0,
|
|
2444
|
+
scrollSize,
|
|
2445
|
+
size,
|
|
2446
|
+
sizeVisible: -1
|
|
2447
|
+
};
|
|
2448
|
+
const prev2 = ctx.mapViewabilityAmountValues.get(containerId);
|
|
2449
|
+
if (!shallowEqual(prev2, value2)) {
|
|
2450
|
+
ctx.mapViewabilityAmountValues.set(containerId, value2);
|
|
2451
|
+
const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
|
|
2452
|
+
if (cb) {
|
|
2453
|
+
cb(value2);
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
return value2;
|
|
2457
|
+
}
|
|
2458
|
+
const top = position - scroll;
|
|
1812
2459
|
const bottom = top + size;
|
|
1813
2460
|
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
1814
2461
|
const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
|
|
1815
2462
|
const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
|
|
1816
2463
|
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
1817
2464
|
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
1818
|
-
const
|
|
2465
|
+
const isViewable = percent >= viewablePercentThreshold;
|
|
1819
2466
|
const value = {
|
|
1820
2467
|
containerId,
|
|
1821
2468
|
index,
|
|
1822
|
-
isViewable
|
|
2469
|
+
isViewable,
|
|
1823
2470
|
item,
|
|
1824
2471
|
key,
|
|
1825
2472
|
percentOfScroller,
|
|
@@ -1838,8 +2485,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
|
|
|
1838
2485
|
}
|
|
1839
2486
|
return value;
|
|
1840
2487
|
}
|
|
1841
|
-
function
|
|
1842
|
-
|
|
2488
|
+
function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
2489
|
+
let value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
2490
|
+
if (!value || value.key !== key) {
|
|
2491
|
+
value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
2492
|
+
}
|
|
1843
2493
|
return value.isViewable;
|
|
1844
2494
|
}
|
|
1845
2495
|
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
@@ -1848,6 +2498,8 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
|
1848
2498
|
const cb = ctx.mapViewabilityCallbacks.get(key);
|
|
1849
2499
|
cb == null ? void 0 : cb(viewToken);
|
|
1850
2500
|
}
|
|
2501
|
+
var unstableBatchedUpdates = ReactNative.unstable_batchedUpdates;
|
|
2502
|
+
var batchedUpdates = typeof unstableBatchedUpdates === "function" ? unstableBatchedUpdates : (fn) => fn();
|
|
1851
2503
|
|
|
1852
2504
|
// src/utils/checkAllSizesKnown.ts
|
|
1853
2505
|
function isNullOrUndefined2(value) {
|
|
@@ -1867,8 +2519,9 @@ function checkAllSizesKnown(state) {
|
|
|
1867
2519
|
}
|
|
1868
2520
|
|
|
1869
2521
|
// src/utils/findAvailableContainers.ts
|
|
1870
|
-
function findAvailableContainers(ctx,
|
|
2522
|
+
function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
|
|
1871
2523
|
const numContainers = peek$(ctx, "numContainers");
|
|
2524
|
+
const state = ctx.state;
|
|
1872
2525
|
const { stickyContainerPool, containerItemTypes } = state;
|
|
1873
2526
|
const result = [];
|
|
1874
2527
|
const availableContainers = [];
|
|
@@ -1988,103 +2641,145 @@ function comparatorByDistance(a, b) {
|
|
|
1988
2641
|
}
|
|
1989
2642
|
|
|
1990
2643
|
// src/core/scrollToIndex.ts
|
|
1991
|
-
function scrollToIndex(ctx,
|
|
1992
|
-
|
|
1993
|
-
|
|
2644
|
+
function scrollToIndex(ctx, {
|
|
2645
|
+
index,
|
|
2646
|
+
viewOffset = 0,
|
|
2647
|
+
animated = true,
|
|
2648
|
+
forceScroll,
|
|
2649
|
+
isInitialScroll,
|
|
2650
|
+
viewPosition
|
|
2651
|
+
}) {
|
|
2652
|
+
const state = ctx.state;
|
|
2653
|
+
const { data } = state.props;
|
|
2654
|
+
if (index >= data.length) {
|
|
2655
|
+
index = data.length - 1;
|
|
1994
2656
|
} else if (index < 0) {
|
|
1995
2657
|
index = 0;
|
|
1996
2658
|
}
|
|
1997
|
-
const firstIndexOffset = calculateOffsetForIndex(ctx,
|
|
1998
|
-
const isLast = index ===
|
|
2659
|
+
const firstIndexOffset = calculateOffsetForIndex(ctx, index);
|
|
2660
|
+
const isLast = index === data.length - 1;
|
|
1999
2661
|
if (isLast && viewPosition === void 0) {
|
|
2000
2662
|
viewPosition = 1;
|
|
2001
2663
|
}
|
|
2002
2664
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2003
|
-
|
|
2665
|
+
const targetId = getId(state, index);
|
|
2666
|
+
const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
|
|
2667
|
+
scrollTo(ctx, {
|
|
2004
2668
|
animated,
|
|
2669
|
+
forceScroll,
|
|
2005
2670
|
index,
|
|
2671
|
+
isInitialScroll,
|
|
2672
|
+
itemSize,
|
|
2006
2673
|
offset: firstIndexOffset,
|
|
2007
2674
|
viewOffset,
|
|
2008
2675
|
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2009
2676
|
});
|
|
2010
2677
|
}
|
|
2011
2678
|
|
|
2679
|
+
// src/utils/performInitialScroll.ts
|
|
2680
|
+
function performInitialScroll(ctx, params) {
|
|
2681
|
+
var _a3;
|
|
2682
|
+
const { forceScroll, initialScrollUsesOffset, resolvedOffset, target } = params;
|
|
2683
|
+
if (initialScrollUsesOffset || resolvedOffset !== void 0) {
|
|
2684
|
+
scrollTo(ctx, {
|
|
2685
|
+
animated: false,
|
|
2686
|
+
forceScroll,
|
|
2687
|
+
index: initialScrollUsesOffset ? void 0 : target.index,
|
|
2688
|
+
isInitialScroll: true,
|
|
2689
|
+
offset: (_a3 = resolvedOffset != null ? resolvedOffset : target.contentOffset) != null ? _a3 : 0,
|
|
2690
|
+
precomputedWithViewOffset: resolvedOffset !== void 0
|
|
2691
|
+
});
|
|
2692
|
+
return;
|
|
2693
|
+
}
|
|
2694
|
+
if (target.index === void 0) {
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2697
|
+
scrollToIndex(ctx, {
|
|
2698
|
+
...target,
|
|
2699
|
+
animated: false,
|
|
2700
|
+
forceScroll,
|
|
2701
|
+
isInitialScroll: true
|
|
2702
|
+
});
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2012
2705
|
// src/utils/setDidLayout.ts
|
|
2013
|
-
function setDidLayout(ctx
|
|
2014
|
-
const
|
|
2015
|
-
|
|
2016
|
-
initialScroll,
|
|
2017
|
-
props: { onLoad }
|
|
2018
|
-
} = state;
|
|
2706
|
+
function setDidLayout(ctx) {
|
|
2707
|
+
const state = ctx.state;
|
|
2708
|
+
const { initialScroll } = state;
|
|
2019
2709
|
state.queuedInitialLayout = true;
|
|
2020
|
-
checkAtBottom(ctx
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2710
|
+
checkAtBottom(ctx);
|
|
2711
|
+
if (initialScroll) {
|
|
2712
|
+
const runScroll = () => {
|
|
2713
|
+
var _a3, _b;
|
|
2714
|
+
const target = state.initialScroll;
|
|
2715
|
+
if (!target) {
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
const activeInitialTargetOffset = ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) ? (_b = state.scrollingTo.targetOffset) != null ? _b : state.scrollingTo.offset : void 0;
|
|
2719
|
+
const desiredInitialTargetOffset = state.initialScrollUsesOffset ? target.contentOffset : activeInitialTargetOffset;
|
|
2720
|
+
const isAlreadyAtDesiredInitialTarget = desiredInitialTargetOffset !== void 0 && Math.abs(state.scroll - desiredInitialTargetOffset) <= 1 && Math.abs(state.scrollPending - desiredInitialTargetOffset) <= 1;
|
|
2721
|
+
if (!isAlreadyAtDesiredInitialTarget) {
|
|
2722
|
+
performInitialScroll(ctx, {
|
|
2723
|
+
forceScroll: true,
|
|
2724
|
+
initialScrollUsesOffset: state.initialScrollUsesOffset,
|
|
2725
|
+
// Offset-based initial scrolls do not need item lookup, so they can run even before data exists.
|
|
2726
|
+
// Re-run on the next frame to pick up measured viewport size without waiting for index resolution.
|
|
2727
|
+
target
|
|
2728
|
+
});
|
|
2729
|
+
}
|
|
2730
|
+
};
|
|
2731
|
+
runScroll();
|
|
2732
|
+
requestAnimationFrame(runScroll);
|
|
2040
2733
|
}
|
|
2734
|
+
setInitialRenderState(ctx, { didLayout: true });
|
|
2041
2735
|
}
|
|
2042
2736
|
|
|
2043
2737
|
// src/core/calculateItemsInView.ts
|
|
2044
2738
|
function findCurrentStickyIndex(stickyArray, scroll, state) {
|
|
2045
|
-
var _a3;
|
|
2046
|
-
const idCache = state.idCache;
|
|
2047
2739
|
const positions = state.positions;
|
|
2048
2740
|
for (let i = stickyArray.length - 1; i >= 0; i--) {
|
|
2049
2741
|
const stickyIndex = stickyArray[i];
|
|
2050
|
-
const
|
|
2051
|
-
const stickyPos = stickyId ? positions.get(stickyId) : void 0;
|
|
2742
|
+
const stickyPos = positions[stickyIndex];
|
|
2052
2743
|
if (stickyPos !== void 0 && scroll >= stickyPos) {
|
|
2053
2744
|
return i;
|
|
2054
2745
|
}
|
|
2055
2746
|
}
|
|
2056
2747
|
return -1;
|
|
2057
2748
|
}
|
|
2058
|
-
function getActiveStickyIndices(ctx,
|
|
2749
|
+
function getActiveStickyIndices(ctx, stickyHeaderIndices) {
|
|
2750
|
+
const state = ctx.state;
|
|
2059
2751
|
return new Set(
|
|
2060
2752
|
Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
|
|
2061
2753
|
);
|
|
2062
2754
|
}
|
|
2063
|
-
function handleStickyActivation(ctx,
|
|
2755
|
+
function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, needNewContainersSet, startBuffered, endBuffered) {
|
|
2064
2756
|
var _a3;
|
|
2065
|
-
const
|
|
2066
|
-
|
|
2757
|
+
const state = ctx.state;
|
|
2758
|
+
const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
|
|
2759
|
+
set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
|
|
2067
2760
|
for (let offset = 0; offset <= 1; offset++) {
|
|
2068
2761
|
const idx = currentStickyIdx - offset;
|
|
2069
2762
|
if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
|
|
2070
2763
|
const stickyIndex = stickyArray[idx];
|
|
2071
2764
|
const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
|
|
2072
|
-
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
|
|
2765
|
+
if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered) && !needNewContainersSet.has(stickyIndex)) {
|
|
2766
|
+
needNewContainersSet.add(stickyIndex);
|
|
2073
2767
|
needNewContainers.push(stickyIndex);
|
|
2074
2768
|
}
|
|
2075
2769
|
}
|
|
2076
2770
|
}
|
|
2077
|
-
function handleStickyRecycling(ctx,
|
|
2078
|
-
var _a3, _b
|
|
2771
|
+
function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval, alwaysRenderIndicesSet) {
|
|
2772
|
+
var _a3, _b;
|
|
2773
|
+
const state = ctx.state;
|
|
2079
2774
|
for (const containerIndex of state.stickyContainerPool) {
|
|
2080
2775
|
const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2081
2776
|
const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
|
|
2082
2777
|
if (itemIndex === void 0) continue;
|
|
2778
|
+
if (alwaysRenderIndicesSet.has(itemIndex)) continue;
|
|
2083
2779
|
const arrayIdx = stickyArray.indexOf(itemIndex);
|
|
2084
2780
|
if (arrayIdx === -1) {
|
|
2085
2781
|
state.stickyContainerPool.delete(containerIndex);
|
|
2086
2782
|
set$(ctx, `containerSticky${containerIndex}`, false);
|
|
2087
|
-
set$(ctx, `containerStickyOffset${containerIndex}`, void 0);
|
|
2088
2783
|
continue;
|
|
2089
2784
|
}
|
|
2090
2785
|
const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
|
|
@@ -2092,15 +2787,14 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2092
2787
|
const nextIndex = stickyArray[arrayIdx + 1];
|
|
2093
2788
|
let shouldRecycle = false;
|
|
2094
2789
|
if (nextIndex) {
|
|
2095
|
-
const
|
|
2096
|
-
|
|
2097
|
-
shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
|
|
2790
|
+
const nextPos = state.positions[nextIndex];
|
|
2791
|
+
shouldRecycle = nextPos !== void 0 && scroll > nextPos + drawDistance * 2;
|
|
2098
2792
|
} else {
|
|
2099
|
-
const currentId = (
|
|
2793
|
+
const currentId = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
|
|
2100
2794
|
if (currentId) {
|
|
2101
|
-
const currentPos = state.positions
|
|
2102
|
-
const currentSize = (
|
|
2103
|
-
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize +
|
|
2795
|
+
const currentPos = state.positions[itemIndex];
|
|
2796
|
+
const currentSize = (_b = state.sizes.get(currentId)) != null ? _b : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2797
|
+
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + drawDistance * 3;
|
|
2104
2798
|
}
|
|
2105
2799
|
}
|
|
2106
2800
|
if (shouldRecycle) {
|
|
@@ -2108,11 +2802,13 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2108
2802
|
}
|
|
2109
2803
|
}
|
|
2110
2804
|
}
|
|
2111
|
-
function calculateItemsInView(ctx,
|
|
2112
|
-
|
|
2113
|
-
|
|
2805
|
+
function calculateItemsInView(ctx, params = {}) {
|
|
2806
|
+
const state = ctx.state;
|
|
2807
|
+
batchedUpdates(() => {
|
|
2808
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
2114
2809
|
const {
|
|
2115
2810
|
columns,
|
|
2811
|
+
columnSpans,
|
|
2116
2812
|
containerItemKeys,
|
|
2117
2813
|
enableScrollForNextCalculateItemsInView,
|
|
2118
2814
|
idCache,
|
|
@@ -2120,7 +2816,15 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2120
2816
|
initialScroll,
|
|
2121
2817
|
minIndexSizeChanged,
|
|
2122
2818
|
positions,
|
|
2123
|
-
props: {
|
|
2819
|
+
props: {
|
|
2820
|
+
alwaysRenderIndicesArr,
|
|
2821
|
+
alwaysRenderIndicesSet,
|
|
2822
|
+
drawDistance,
|
|
2823
|
+
getItemType,
|
|
2824
|
+
itemsAreEqual,
|
|
2825
|
+
keyExtractor,
|
|
2826
|
+
onStickyHeaderChange
|
|
2827
|
+
},
|
|
2124
2828
|
scrollForNextCalculateItemsInView,
|
|
2125
2829
|
scrollLength,
|
|
2126
2830
|
sizes,
|
|
@@ -2130,79 +2834,84 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2130
2834
|
const { data } = state.props;
|
|
2131
2835
|
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
2132
2836
|
const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
|
|
2837
|
+
const alwaysRenderArr = alwaysRenderIndicesArr || [];
|
|
2838
|
+
const alwaysRenderSet = alwaysRenderIndicesSet || /* @__PURE__ */ new Set();
|
|
2839
|
+
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2133
2840
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
2134
2841
|
if (!data || scrollLength === 0 || !prevNumContainers) {
|
|
2135
|
-
if (state.initialAnchor) {
|
|
2136
|
-
ensureInitialAnchor(ctx
|
|
2842
|
+
if (!IsNewArchitecture && state.initialAnchor) {
|
|
2843
|
+
ensureInitialAnchor(ctx);
|
|
2137
2844
|
}
|
|
2138
2845
|
return;
|
|
2139
2846
|
}
|
|
2140
|
-
|
|
2847
|
+
let totalSize = getContentSize(ctx);
|
|
2141
2848
|
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
2142
2849
|
const numColumns = peek$(ctx, "numColumns");
|
|
2143
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2144
2850
|
const speed = getScrollVelocity(state);
|
|
2145
2851
|
const scrollExtra = 0;
|
|
2146
2852
|
const { queuedInitialLayout } = state;
|
|
2147
2853
|
let { scroll: scrollState } = state;
|
|
2148
2854
|
if (!queuedInitialLayout && initialScroll) {
|
|
2149
|
-
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
2855
|
+
const updatedOffset = state.initialScrollUsesOffset ? (_a3 = initialScroll.contentOffset) != null ? _a3 : 0 : calculateOffsetWithOffsetPosition(
|
|
2150
2856
|
ctx,
|
|
2151
|
-
|
|
2152
|
-
calculateOffsetForIndex(ctx, state, initialScroll.index),
|
|
2857
|
+
calculateOffsetForIndex(ctx, initialScroll.index),
|
|
2153
2858
|
initialScroll
|
|
2154
2859
|
);
|
|
2155
2860
|
scrollState = updatedOffset;
|
|
2156
2861
|
}
|
|
2157
|
-
const scrollAdjustPending = (
|
|
2862
|
+
const scrollAdjustPending = (_b = peek$(ctx, "scrollAdjustPending")) != null ? _b : 0;
|
|
2158
2863
|
const scrollAdjustPad = scrollAdjustPending - topPad;
|
|
2159
|
-
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
2864
|
+
let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
|
|
2160
2865
|
if (scroll + scrollLength > totalSize) {
|
|
2161
2866
|
scroll = Math.max(0, totalSize - scrollLength);
|
|
2162
2867
|
}
|
|
2163
|
-
|
|
2164
|
-
set$(ctx, "debugRawScroll", scrollState);
|
|
2165
|
-
set$(ctx, "debugComputedScroll", scroll);
|
|
2166
|
-
}
|
|
2167
|
-
const previousStickyIndex = state.activeStickyIndex;
|
|
2868
|
+
const previousStickyIndex = peek$(ctx, "activeStickyIndex");
|
|
2168
2869
|
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
2169
|
-
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] :
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
let
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2870
|
+
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
|
|
2871
|
+
if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
|
|
2872
|
+
set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
|
|
2873
|
+
}
|
|
2874
|
+
let scrollBufferTop = drawDistance;
|
|
2875
|
+
let scrollBufferBottom = drawDistance;
|
|
2876
|
+
if (speed > 0 || speed === 0 && scroll < Math.max(50, drawDistance)) {
|
|
2877
|
+
scrollBufferTop = drawDistance * 0.5;
|
|
2878
|
+
scrollBufferBottom = drawDistance * 1.5;
|
|
2177
2879
|
} else {
|
|
2178
|
-
scrollBufferTop =
|
|
2179
|
-
scrollBufferBottom =
|
|
2880
|
+
scrollBufferTop = drawDistance * 1.5;
|
|
2881
|
+
scrollBufferBottom = drawDistance * 0.5;
|
|
2180
2882
|
}
|
|
2181
2883
|
const scrollTopBuffered = scroll - scrollBufferTop;
|
|
2182
2884
|
const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
|
|
2183
2885
|
const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
|
|
2184
|
-
if (!dataChanged && scrollForNextCalculateItemsInView) {
|
|
2886
|
+
if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
|
|
2185
2887
|
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
2186
|
-
if (
|
|
2187
|
-
|
|
2188
|
-
|
|
2888
|
+
if (top === null && bottom === null) {
|
|
2889
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2890
|
+
} else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
|
|
2891
|
+
if (!IsNewArchitecture && state.initialAnchor) {
|
|
2892
|
+
ensureInitialAnchor(ctx);
|
|
2893
|
+
}
|
|
2894
|
+
if (Platform2.OS !== "web" || !isInMVCPActiveMode(state)) {
|
|
2895
|
+
return;
|
|
2189
2896
|
}
|
|
2190
|
-
return;
|
|
2191
2897
|
}
|
|
2192
2898
|
}
|
|
2193
|
-
const checkMVCP = doMVCP ? prepareMVCP(ctx,
|
|
2899
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
|
|
2194
2900
|
if (dataChanged) {
|
|
2195
2901
|
indexByKey.clear();
|
|
2196
2902
|
idCache.length = 0;
|
|
2197
|
-
positions.
|
|
2903
|
+
positions.length = 0;
|
|
2904
|
+
columns.length = 0;
|
|
2905
|
+
columnSpans.length = 0;
|
|
2198
2906
|
}
|
|
2199
|
-
const startIndex = dataChanged ? 0 : (
|
|
2200
|
-
updateItemPositions(ctx,
|
|
2907
|
+
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_c = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _c : 0;
|
|
2908
|
+
updateItemPositions(ctx, dataChanged, {
|
|
2201
2909
|
doMVCP,
|
|
2202
2910
|
forceFullUpdate: !!forceFullItemPositions,
|
|
2203
2911
|
scrollBottomBuffered,
|
|
2204
2912
|
startIndex
|
|
2205
2913
|
});
|
|
2914
|
+
totalSize = getContentSize(ctx);
|
|
2206
2915
|
if (minIndexSizeChanged !== void 0) {
|
|
2207
2916
|
state.minIndexSizeChanged = void 0;
|
|
2208
2917
|
}
|
|
@@ -2214,19 +2923,24 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2214
2923
|
let endBuffered = null;
|
|
2215
2924
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
2216
2925
|
for (let i = loopStart; i >= 0; i--) {
|
|
2217
|
-
const id = (
|
|
2218
|
-
const top = positions
|
|
2219
|
-
const size = (
|
|
2926
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
2927
|
+
const top = positions[i];
|
|
2928
|
+
const size = (_e = sizes.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i]);
|
|
2220
2929
|
const bottom = top + size;
|
|
2221
|
-
if (bottom > scroll -
|
|
2930
|
+
if (bottom > scroll - scrollBufferTop) {
|
|
2222
2931
|
loopStart = i;
|
|
2223
2932
|
} else {
|
|
2224
2933
|
break;
|
|
2225
2934
|
}
|
|
2226
2935
|
}
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2936
|
+
if (numColumns > 1) {
|
|
2937
|
+
while (loopStart > 0) {
|
|
2938
|
+
const loopColumn = columns[loopStart];
|
|
2939
|
+
if (loopColumn === 1 || loopColumn === void 0) {
|
|
2940
|
+
break;
|
|
2941
|
+
}
|
|
2942
|
+
loopStart -= 1;
|
|
2943
|
+
}
|
|
2230
2944
|
}
|
|
2231
2945
|
let foundEnd = false;
|
|
2232
2946
|
let nextTop;
|
|
@@ -2242,20 +2956,24 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2242
2956
|
let firstFullyOnScreenIndex;
|
|
2243
2957
|
const dataLength = data.length;
|
|
2244
2958
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
2245
|
-
const id = (
|
|
2246
|
-
const size = (
|
|
2247
|
-
const top = positions
|
|
2959
|
+
const id = (_f = idCache[i]) != null ? _f : getId(state, i);
|
|
2960
|
+
const size = (_g = sizes.get(id)) != null ? _g : getItemSize(ctx, id, i, data[i]);
|
|
2961
|
+
const top = positions[i];
|
|
2248
2962
|
if (!foundEnd) {
|
|
2249
2963
|
if (startNoBuffer === null && top + size > scroll) {
|
|
2250
2964
|
startNoBuffer = i;
|
|
2251
2965
|
}
|
|
2252
|
-
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
|
|
2966
|
+
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
|
|
2253
2967
|
firstFullyOnScreenIndex = i;
|
|
2254
2968
|
}
|
|
2255
2969
|
if (startBuffered === null && top + size > scrollTopBuffered) {
|
|
2256
2970
|
startBuffered = i;
|
|
2257
2971
|
startBufferedId = id;
|
|
2258
|
-
|
|
2972
|
+
if (scrollTopBuffered < 0) {
|
|
2973
|
+
nextTop = null;
|
|
2974
|
+
} else {
|
|
2975
|
+
nextTop = top;
|
|
2976
|
+
}
|
|
2259
2977
|
}
|
|
2260
2978
|
if (startNoBuffer !== null) {
|
|
2261
2979
|
if (top <= scrollBottom) {
|
|
@@ -2263,7 +2981,11 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2263
2981
|
}
|
|
2264
2982
|
if (top <= scrollBottomBuffered) {
|
|
2265
2983
|
endBuffered = i;
|
|
2266
|
-
|
|
2984
|
+
if (scrollBottomBuffered > totalSize) {
|
|
2985
|
+
nextBottom = null;
|
|
2986
|
+
} else {
|
|
2987
|
+
nextBottom = top + size;
|
|
2988
|
+
}
|
|
2267
2989
|
} else {
|
|
2268
2990
|
foundEnd = true;
|
|
2269
2991
|
}
|
|
@@ -2271,9 +2993,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2271
2993
|
}
|
|
2272
2994
|
}
|
|
2273
2995
|
const idsInView = [];
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2996
|
+
const firstVisibleAnchorIndex = firstFullyOnScreenIndex != null ? firstFullyOnScreenIndex : startNoBuffer;
|
|
2997
|
+
if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && endNoBuffer !== null) {
|
|
2998
|
+
for (let i = firstVisibleAnchorIndex; i <= endNoBuffer; i++) {
|
|
2999
|
+
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
3000
|
+
idsInView.push(id);
|
|
3001
|
+
}
|
|
2277
3002
|
}
|
|
2278
3003
|
Object.assign(state, {
|
|
2279
3004
|
endBuffered,
|
|
@@ -2285,12 +3010,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2285
3010
|
startNoBuffer
|
|
2286
3011
|
});
|
|
2287
3012
|
if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
|
|
2288
|
-
state.scrollForNextCalculateItemsInView = nextTop
|
|
3013
|
+
state.scrollForNextCalculateItemsInView = isNullOrUndefined(nextTop) && isNullOrUndefined(nextBottom) ? void 0 : {
|
|
2289
3014
|
bottom: nextBottom,
|
|
2290
3015
|
top: nextTop
|
|
2291
|
-
}
|
|
3016
|
+
};
|
|
2292
3017
|
}
|
|
2293
|
-
|
|
3018
|
+
let numContainers = prevNumContainers;
|
|
2294
3019
|
const pendingRemoval = [];
|
|
2295
3020
|
if (dataChanged) {
|
|
2296
3021
|
for (let i = 0; i < numContainers; i++) {
|
|
@@ -2301,37 +3026,46 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2301
3026
|
}
|
|
2302
3027
|
}
|
|
2303
3028
|
if (startBuffered !== null && endBuffered !== null) {
|
|
2304
|
-
let numContainers2 = prevNumContainers;
|
|
2305
3029
|
const needNewContainers = [];
|
|
3030
|
+
const needNewContainersSet = /* @__PURE__ */ new Set();
|
|
2306
3031
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
2307
|
-
const id = (
|
|
3032
|
+
const id = (_i = idCache[i]) != null ? _i : getId(state, i);
|
|
2308
3033
|
if (!containerItemKeys.has(id)) {
|
|
3034
|
+
needNewContainersSet.add(i);
|
|
2309
3035
|
needNewContainers.push(i);
|
|
2310
3036
|
}
|
|
2311
3037
|
}
|
|
3038
|
+
if (alwaysRenderArr.length > 0) {
|
|
3039
|
+
for (const index of alwaysRenderArr) {
|
|
3040
|
+
if (index < 0 || index >= dataLength) continue;
|
|
3041
|
+
const id = (_j = idCache[index]) != null ? _j : getId(state, index);
|
|
3042
|
+
if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
|
|
3043
|
+
needNewContainersSet.add(index);
|
|
3044
|
+
needNewContainers.push(index);
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
2312
3048
|
if (stickyIndicesArr.length > 0) {
|
|
2313
3049
|
handleStickyActivation(
|
|
2314
3050
|
ctx,
|
|
2315
|
-
state,
|
|
2316
3051
|
stickyIndicesSet,
|
|
2317
3052
|
stickyIndicesArr,
|
|
2318
3053
|
currentStickyIdx,
|
|
2319
3054
|
needNewContainers,
|
|
3055
|
+
needNewContainersSet,
|
|
2320
3056
|
startBuffered,
|
|
2321
3057
|
endBuffered
|
|
2322
3058
|
);
|
|
2323
|
-
} else {
|
|
2324
|
-
|
|
2325
|
-
set$(ctx, "activeStickyIndex", void 0);
|
|
3059
|
+
} else if (previousStickyIndex !== -1) {
|
|
3060
|
+
set$(ctx, "activeStickyIndex", -1);
|
|
2326
3061
|
}
|
|
2327
3062
|
if (needNewContainers.length > 0) {
|
|
2328
3063
|
const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
|
|
2329
3064
|
const itemType = getItemType(data[i], i);
|
|
2330
|
-
return itemType ? String(itemType) : "";
|
|
3065
|
+
return itemType !== void 0 ? String(itemType) : "";
|
|
2331
3066
|
}) : void 0;
|
|
2332
3067
|
const availableContainers = findAvailableContainers(
|
|
2333
3068
|
ctx,
|
|
2334
|
-
state,
|
|
2335
3069
|
needNewContainers.length,
|
|
2336
3070
|
startBuffered,
|
|
2337
3071
|
endBuffered,
|
|
@@ -2342,7 +3076,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2342
3076
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2343
3077
|
const i = needNewContainers[idx];
|
|
2344
3078
|
const containerIndex = availableContainers[idx];
|
|
2345
|
-
const id = (
|
|
3079
|
+
const id = (_k = idCache[i]) != null ? _k : getId(state, i);
|
|
2346
3080
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2347
3081
|
if (oldKey && oldKey !== id) {
|
|
2348
3082
|
containerItemKeys.delete(oldKey);
|
|
@@ -2352,30 +3086,55 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2352
3086
|
if (requiredItemTypes) {
|
|
2353
3087
|
state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
|
|
2354
3088
|
}
|
|
2355
|
-
containerItemKeys.
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
3089
|
+
containerItemKeys.set(id, containerIndex);
|
|
3090
|
+
const containerSticky = `containerSticky${containerIndex}`;
|
|
3091
|
+
const isSticky = stickyIndicesSet.has(i);
|
|
3092
|
+
const isAlwaysRender = alwaysRenderSet.has(i);
|
|
3093
|
+
if (isSticky) {
|
|
3094
|
+
set$(ctx, containerSticky, true);
|
|
2360
3095
|
state.stickyContainerPool.add(containerIndex);
|
|
2361
3096
|
} else {
|
|
2362
|
-
|
|
2363
|
-
|
|
3097
|
+
if (peek$(ctx, containerSticky)) {
|
|
3098
|
+
set$(ctx, containerSticky, false);
|
|
3099
|
+
}
|
|
3100
|
+
if (isAlwaysRender) {
|
|
3101
|
+
state.stickyContainerPool.add(containerIndex);
|
|
3102
|
+
} else if (state.stickyContainerPool.has(containerIndex)) {
|
|
3103
|
+
state.stickyContainerPool.delete(containerIndex);
|
|
3104
|
+
}
|
|
2364
3105
|
}
|
|
2365
|
-
if (containerIndex >=
|
|
2366
|
-
|
|
3106
|
+
if (containerIndex >= numContainers) {
|
|
3107
|
+
numContainers = containerIndex + 1;
|
|
2367
3108
|
}
|
|
2368
3109
|
}
|
|
2369
|
-
if (
|
|
2370
|
-
set$(ctx, "numContainers",
|
|
2371
|
-
if (
|
|
2372
|
-
set$(ctx, "numContainersPooled", Math.ceil(
|
|
3110
|
+
if (numContainers !== prevNumContainers) {
|
|
3111
|
+
set$(ctx, "numContainers", numContainers);
|
|
3112
|
+
if (numContainers > peek$(ctx, "numContainersPooled")) {
|
|
3113
|
+
set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
if (alwaysRenderArr.length > 0) {
|
|
3118
|
+
for (const index of alwaysRenderArr) {
|
|
3119
|
+
if (index < 0 || index >= dataLength) continue;
|
|
3120
|
+
const id = (_l = idCache[index]) != null ? _l : getId(state, index);
|
|
3121
|
+
const containerIndex = containerItemKeys.get(id);
|
|
3122
|
+
if (containerIndex !== void 0) {
|
|
3123
|
+
state.stickyContainerPool.add(containerIndex);
|
|
2373
3124
|
}
|
|
2374
3125
|
}
|
|
2375
3126
|
}
|
|
2376
3127
|
}
|
|
2377
|
-
if (
|
|
2378
|
-
handleStickyRecycling(
|
|
3128
|
+
if (state.stickyContainerPool.size > 0) {
|
|
3129
|
+
handleStickyRecycling(
|
|
3130
|
+
ctx,
|
|
3131
|
+
stickyIndicesArr,
|
|
3132
|
+
scroll,
|
|
3133
|
+
drawDistance,
|
|
3134
|
+
currentStickyIdx,
|
|
3135
|
+
pendingRemoval,
|
|
3136
|
+
alwaysRenderSet
|
|
3137
|
+
);
|
|
2379
3138
|
}
|
|
2380
3139
|
let didChangePositions = false;
|
|
2381
3140
|
for (let i = 0; i < numContainers; i++) {
|
|
@@ -2387,26 +3146,27 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2387
3146
|
state.containerItemTypes.delete(i);
|
|
2388
3147
|
if (state.stickyContainerPool.has(i)) {
|
|
2389
3148
|
set$(ctx, `containerSticky${i}`, false);
|
|
2390
|
-
set$(ctx, `containerStickyOffset${i}`, void 0);
|
|
2391
3149
|
state.stickyContainerPool.delete(i);
|
|
2392
3150
|
}
|
|
2393
3151
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
2394
3152
|
set$(ctx, `containerItemData${i}`, void 0);
|
|
2395
3153
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2396
3154
|
set$(ctx, `containerColumn${i}`, -1);
|
|
3155
|
+
set$(ctx, `containerSpan${i}`, 1);
|
|
2397
3156
|
} else {
|
|
2398
3157
|
const itemIndex = indexByKey.get(itemKey);
|
|
2399
3158
|
const item = data[itemIndex];
|
|
2400
3159
|
if (item !== void 0) {
|
|
2401
|
-
const
|
|
2402
|
-
const positionValue = positions.get(id);
|
|
3160
|
+
const positionValue = positions[itemIndex];
|
|
2403
3161
|
if (positionValue === void 0) {
|
|
2404
3162
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2405
3163
|
} else {
|
|
2406
3164
|
const position = (positionValue || 0) - scrollAdjustPending;
|
|
2407
|
-
const column = columns
|
|
3165
|
+
const column = columns[itemIndex] || 1;
|
|
3166
|
+
const span = columnSpans[itemIndex] || 1;
|
|
2408
3167
|
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
2409
3168
|
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
3169
|
+
const prevSpan = peek$(ctx, `containerSpan${i}`);
|
|
2410
3170
|
const prevData = peek$(ctx, `containerItemData${i}`);
|
|
2411
3171
|
if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
|
|
2412
3172
|
set$(ctx, `containerPosition${i}`, position);
|
|
@@ -2415,6 +3175,9 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2415
3175
|
if (column >= 0 && column !== prevColumn) {
|
|
2416
3176
|
set$(ctx, `containerColumn${i}`, column);
|
|
2417
3177
|
}
|
|
3178
|
+
if (span !== prevSpan) {
|
|
3179
|
+
set$(ctx, `containerSpan${i}`, span);
|
|
3180
|
+
}
|
|
2418
3181
|
if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
|
|
2419
3182
|
set$(ctx, `containerItemData${i}`, item);
|
|
2420
3183
|
}
|
|
@@ -2427,7 +3190,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2427
3190
|
}
|
|
2428
3191
|
if (!queuedInitialLayout && endBuffered !== null) {
|
|
2429
3192
|
if (checkAllSizesKnown(state)) {
|
|
2430
|
-
setDidLayout(ctx
|
|
3193
|
+
setDidLayout(ctx);
|
|
2431
3194
|
}
|
|
2432
3195
|
}
|
|
2433
3196
|
if (viewabilityConfigCallbackPairs) {
|
|
@@ -2440,8 +3203,8 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2440
3203
|
}
|
|
2441
3204
|
}
|
|
2442
3205
|
});
|
|
2443
|
-
if (state.initialAnchor) {
|
|
2444
|
-
ensureInitialAnchor(ctx
|
|
3206
|
+
if (!IsNewArchitecture && state.initialAnchor) {
|
|
3207
|
+
ensureInitialAnchor(ctx);
|
|
2445
3208
|
}
|
|
2446
3209
|
}
|
|
2447
3210
|
|
|
@@ -2465,37 +3228,6 @@ function checkActualChange(state, dataProp, previousData) {
|
|
|
2465
3228
|
return false;
|
|
2466
3229
|
}
|
|
2467
3230
|
|
|
2468
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
2469
|
-
function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
2470
|
-
const {
|
|
2471
|
-
refScroller,
|
|
2472
|
-
props: { maintainScrollAtEnd }
|
|
2473
|
-
} = state;
|
|
2474
|
-
if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
|
|
2475
|
-
const paddingTop = peek$(ctx, "alignItemsPaddingTop");
|
|
2476
|
-
if (paddingTop > 0) {
|
|
2477
|
-
state.scroll = 0;
|
|
2478
|
-
}
|
|
2479
|
-
requestAnimationFrame(() => {
|
|
2480
|
-
var _a3;
|
|
2481
|
-
if (state == null ? void 0 : state.isAtEnd) {
|
|
2482
|
-
state.maintainingScrollAtEnd = true;
|
|
2483
|
-
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
|
|
2484
|
-
animated
|
|
2485
|
-
});
|
|
2486
|
-
setTimeout(
|
|
2487
|
-
() => {
|
|
2488
|
-
state.maintainingScrollAtEnd = false;
|
|
2489
|
-
},
|
|
2490
|
-
0
|
|
2491
|
-
);
|
|
2492
|
-
}
|
|
2493
|
-
});
|
|
2494
|
-
return true;
|
|
2495
|
-
}
|
|
2496
|
-
return false;
|
|
2497
|
-
}
|
|
2498
|
-
|
|
2499
3231
|
// src/utils/updateAveragesOnDataChange.ts
|
|
2500
3232
|
function updateAveragesOnDataChange(state, oldData, newData) {
|
|
2501
3233
|
var _a3;
|
|
@@ -2549,36 +3281,37 @@ function updateAveragesOnDataChange(state, oldData, newData) {
|
|
|
2549
3281
|
}
|
|
2550
3282
|
|
|
2551
3283
|
// src/core/checkResetContainers.ts
|
|
2552
|
-
function checkResetContainers(ctx,
|
|
3284
|
+
function checkResetContainers(ctx, dataProp) {
|
|
3285
|
+
const state = ctx.state;
|
|
2553
3286
|
const { previousData } = state;
|
|
2554
3287
|
if (previousData) {
|
|
2555
3288
|
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2556
3289
|
}
|
|
2557
3290
|
const { maintainScrollAtEnd } = state.props;
|
|
2558
|
-
calculateItemsInView(ctx,
|
|
2559
|
-
const shouldMaintainScrollAtEnd = maintainScrollAtEnd
|
|
2560
|
-
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx
|
|
3291
|
+
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
3292
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onDataChange;
|
|
3293
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx);
|
|
2561
3294
|
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2562
3295
|
state.isEndReached = false;
|
|
2563
3296
|
}
|
|
2564
3297
|
if (!didMaintainScrollAtEnd) {
|
|
2565
|
-
|
|
2566
|
-
checkAtBottom(ctx, state);
|
|
3298
|
+
checkThresholds(ctx);
|
|
2567
3299
|
}
|
|
2568
3300
|
delete state.previousData;
|
|
2569
3301
|
}
|
|
2570
3302
|
|
|
2571
3303
|
// src/core/doInitialAllocateContainers.ts
|
|
2572
|
-
function doInitialAllocateContainers(ctx
|
|
3304
|
+
function doInitialAllocateContainers(ctx) {
|
|
2573
3305
|
var _a3, _b, _c;
|
|
3306
|
+
const state = ctx.state;
|
|
2574
3307
|
const {
|
|
2575
3308
|
scrollLength,
|
|
2576
3309
|
props: {
|
|
2577
3310
|
data,
|
|
3311
|
+
drawDistance,
|
|
2578
3312
|
getEstimatedItemSize,
|
|
2579
3313
|
getFixedItemSize,
|
|
2580
3314
|
getItemType,
|
|
2581
|
-
scrollBuffer,
|
|
2582
3315
|
numColumns,
|
|
2583
3316
|
estimatedItemSize
|
|
2584
3317
|
}
|
|
@@ -2591,40 +3324,58 @@ function doInitialAllocateContainers(ctx, state, dataChanged) {
|
|
|
2591
3324
|
const num = Math.min(20, data.length);
|
|
2592
3325
|
for (let i = 0; i < num; i++) {
|
|
2593
3326
|
const item = data[i];
|
|
2594
|
-
|
|
2595
|
-
|
|
3327
|
+
if (item !== void 0) {
|
|
3328
|
+
const itemType = (_a3 = getItemType == null ? void 0 : getItemType(item, i)) != null ? _a3 : "";
|
|
3329
|
+
totalSize += (_c = (_b = getFixedItemSize == null ? void 0 : getFixedItemSize(item, i, itemType)) != null ? _b : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(item, i, itemType)) != null ? _c : estimatedItemSize;
|
|
3330
|
+
}
|
|
2596
3331
|
}
|
|
2597
3332
|
averageItemSize = totalSize / num;
|
|
2598
3333
|
} else {
|
|
2599
3334
|
averageItemSize = estimatedItemSize;
|
|
2600
3335
|
}
|
|
2601
|
-
const numContainers = Math.ceil((scrollLength +
|
|
3336
|
+
const numContainers = Math.ceil((scrollLength + drawDistance * 2) / averageItemSize * numColumns);
|
|
2602
3337
|
for (let i = 0; i < numContainers; i++) {
|
|
2603
3338
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2604
3339
|
set$(ctx, `containerColumn${i}`, -1);
|
|
3340
|
+
set$(ctx, `containerSpan${i}`, 1);
|
|
2605
3341
|
}
|
|
2606
3342
|
set$(ctx, "numContainers", numContainers);
|
|
2607
3343
|
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
2608
3344
|
if (!IsNewArchitecture || state.lastLayout) {
|
|
2609
3345
|
if (state.initialScroll) {
|
|
2610
3346
|
requestAnimationFrame(() => {
|
|
2611
|
-
calculateItemsInView(ctx,
|
|
3347
|
+
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2612
3348
|
});
|
|
2613
3349
|
} else {
|
|
2614
|
-
calculateItemsInView(ctx,
|
|
3350
|
+
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
2615
3351
|
}
|
|
2616
3352
|
}
|
|
2617
3353
|
return true;
|
|
2618
3354
|
}
|
|
2619
3355
|
}
|
|
3356
|
+
function getWindowSize() {
|
|
3357
|
+
const screenSize = Dimensions.get("window");
|
|
3358
|
+
return {
|
|
3359
|
+
height: screenSize.height,
|
|
3360
|
+
width: screenSize.width
|
|
3361
|
+
};
|
|
3362
|
+
}
|
|
2620
3363
|
|
|
2621
3364
|
// src/core/handleLayout.ts
|
|
2622
|
-
function handleLayout(ctx,
|
|
2623
|
-
const
|
|
2624
|
-
const
|
|
3365
|
+
function handleLayout(ctx, layoutParam, setCanRender) {
|
|
3366
|
+
const state = ctx.state;
|
|
3367
|
+
const { maintainScrollAtEnd, useWindowScroll } = state.props;
|
|
3368
|
+
const scrollAxis = state.props.horizontal ? "width" : "height";
|
|
3369
|
+
const otherAxis = state.props.horizontal ? "height" : "width";
|
|
3370
|
+
let layout = layoutParam;
|
|
3371
|
+
if (useWindowScroll) {
|
|
3372
|
+
const windowScrollAxisLength = getWindowSize()[scrollAxis];
|
|
3373
|
+
layout = windowScrollAxisLength > 0 ? { ...layoutParam, [scrollAxis]: windowScrollAxisLength } : layoutParam;
|
|
3374
|
+
}
|
|
3375
|
+
const measuredLength = layout[scrollAxis];
|
|
2625
3376
|
const previousLength = state.scrollLength;
|
|
2626
3377
|
const scrollLength = measuredLength > 0 ? measuredLength : previousLength;
|
|
2627
|
-
const otherAxisSize = layout[
|
|
3378
|
+
const otherAxisSize = layout[otherAxis];
|
|
2628
3379
|
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
2629
3380
|
state.lastLayout = layout;
|
|
2630
3381
|
const prevOtherAxisSize = state.otherAxisSize;
|
|
@@ -2635,20 +3386,18 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2635
3386
|
state.lastBatchingAction = Date.now();
|
|
2636
3387
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2637
3388
|
if (scrollLength > 0) {
|
|
2638
|
-
doInitialAllocateContainers(ctx
|
|
3389
|
+
doInitialAllocateContainers(ctx);
|
|
2639
3390
|
}
|
|
2640
3391
|
if (needsCalculate) {
|
|
2641
|
-
calculateItemsInView(ctx,
|
|
3392
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
2642
3393
|
}
|
|
2643
3394
|
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
2644
3395
|
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
2645
3396
|
}
|
|
2646
|
-
if (maintainScrollAtEnd
|
|
2647
|
-
doMaintainScrollAtEnd(ctx
|
|
3397
|
+
if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onLayout) {
|
|
3398
|
+
doMaintainScrollAtEnd(ctx);
|
|
2648
3399
|
}
|
|
2649
|
-
|
|
2650
|
-
checkAtBottom(ctx, state);
|
|
2651
|
-
checkAtTop(state);
|
|
3400
|
+
checkThresholds(ctx);
|
|
2652
3401
|
if (state) {
|
|
2653
3402
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
2654
3403
|
}
|
|
@@ -2663,8 +3412,15 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2663
3412
|
}
|
|
2664
3413
|
|
|
2665
3414
|
// src/core/onScroll.ts
|
|
2666
|
-
|
|
2667
|
-
|
|
3415
|
+
var INITIAL_SCROLL_PROGRESS_EPSILON = 1;
|
|
3416
|
+
function didObserveInitialScrollProgress(newScroll, watchdog) {
|
|
3417
|
+
const previousDistance = Math.abs(watchdog.startScroll - watchdog.targetOffset);
|
|
3418
|
+
const nextDistance = Math.abs(newScroll - watchdog.targetOffset);
|
|
3419
|
+
return nextDistance <= INITIAL_SCROLL_PROGRESS_EPSILON || nextDistance + INITIAL_SCROLL_PROGRESS_EPSILON < previousDistance;
|
|
3420
|
+
}
|
|
3421
|
+
function onScroll(ctx, event) {
|
|
3422
|
+
var _a3, _b, _c, _d;
|
|
3423
|
+
const state = ctx.state;
|
|
2668
3424
|
const {
|
|
2669
3425
|
scrollProcessingEnabled,
|
|
2670
3426
|
props: { onScroll: onScrollProp }
|
|
@@ -2675,17 +3431,43 @@ function onScroll(ctx, state, event) {
|
|
|
2675
3431
|
if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
2676
3432
|
return;
|
|
2677
3433
|
}
|
|
3434
|
+
let insetChanged = false;
|
|
3435
|
+
if ((_d = event.nativeEvent) == null ? void 0 : _d.contentInset) {
|
|
3436
|
+
const { contentInset } = event.nativeEvent;
|
|
3437
|
+
const prevInset = state.nativeContentInset;
|
|
3438
|
+
if (!prevInset || prevInset.top !== contentInset.top || prevInset.bottom !== contentInset.bottom || prevInset.left !== contentInset.left || prevInset.right !== contentInset.right) {
|
|
3439
|
+
state.nativeContentInset = contentInset;
|
|
3440
|
+
insetChanged = true;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
2678
3443
|
let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
3444
|
+
if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
3445
|
+
const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
|
|
3446
|
+
if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
|
|
3447
|
+
newScroll = maxOffset;
|
|
3448
|
+
scrollTo(ctx, {
|
|
3449
|
+
forceScroll: true,
|
|
3450
|
+
isInitialScroll: true,
|
|
3451
|
+
noScrollingTo: true,
|
|
3452
|
+
offset: newScroll
|
|
3453
|
+
});
|
|
3454
|
+
return;
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
2679
3457
|
state.scrollPending = newScroll;
|
|
2680
|
-
const
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
3458
|
+
const initialNativeScrollWatchdog = state.initialNativeScrollWatchdog;
|
|
3459
|
+
const didInitialScrollProgress = !!initialNativeScrollWatchdog && didObserveInitialScrollProgress(newScroll, initialNativeScrollWatchdog);
|
|
3460
|
+
if (didInitialScrollProgress) {
|
|
3461
|
+
state.initialNativeScrollWatchdog = void 0;
|
|
3462
|
+
}
|
|
3463
|
+
updateScroll(ctx, newScroll, insetChanged);
|
|
3464
|
+
if (initialNativeScrollWatchdog && !didInitialScrollProgress) {
|
|
3465
|
+
state.hasScrolled = false;
|
|
3466
|
+
state.initialNativeScrollWatchdog = initialNativeScrollWatchdog;
|
|
3467
|
+
}
|
|
3468
|
+
if (state.scrollingTo) {
|
|
3469
|
+
checkFinishedScroll(ctx);
|
|
2687
3470
|
}
|
|
2688
|
-
updateScroll(ctx, state, newScroll);
|
|
2689
3471
|
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
2690
3472
|
}
|
|
2691
3473
|
|
|
@@ -2694,51 +3476,80 @@ var ScrollAdjustHandler = class {
|
|
|
2694
3476
|
constructor(ctx) {
|
|
2695
3477
|
this.appliedAdjust = 0;
|
|
2696
3478
|
this.pendingAdjust = 0;
|
|
2697
|
-
this.
|
|
2698
|
-
this.context = ctx;
|
|
2699
|
-
if (Platform2.OS === "web") {
|
|
2700
|
-
const commitPendingAdjust = () => {
|
|
2701
|
-
const state = this.context.internalState;
|
|
2702
|
-
const pending = this.pendingAdjust;
|
|
2703
|
-
if (pending !== 0) {
|
|
2704
|
-
this.pendingAdjust = 0;
|
|
2705
|
-
this.appliedAdjust += pending;
|
|
2706
|
-
state.scroll += pending;
|
|
2707
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2708
|
-
set$(this.context, "scrollAdjustPending", 0);
|
|
2709
|
-
set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
2710
|
-
calculateItemsInView(this.context, this.context.internalState);
|
|
2711
|
-
}
|
|
2712
|
-
};
|
|
2713
|
-
listen$(this.context, "scrollingTo", (value) => {
|
|
2714
|
-
if (value === void 0) {
|
|
2715
|
-
commitPendingAdjust();
|
|
2716
|
-
}
|
|
2717
|
-
});
|
|
2718
|
-
}
|
|
3479
|
+
this.ctx = ctx;
|
|
2719
3480
|
}
|
|
2720
3481
|
requestAdjust(add) {
|
|
2721
|
-
const scrollingTo =
|
|
2722
|
-
if (
|
|
3482
|
+
const scrollingTo = this.ctx.state.scrollingTo;
|
|
3483
|
+
if (PlatformAdjustBreaksScroll && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
|
|
2723
3484
|
this.pendingAdjust += add;
|
|
2724
|
-
set$(this.
|
|
3485
|
+
set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
|
|
2725
3486
|
} else {
|
|
2726
3487
|
this.appliedAdjust += add;
|
|
2727
|
-
set$(this.
|
|
3488
|
+
set$(this.ctx, "scrollAdjust", this.appliedAdjust);
|
|
3489
|
+
}
|
|
3490
|
+
if (this.ctx.state.scrollingTo) {
|
|
3491
|
+
checkFinishedScroll(this.ctx);
|
|
2728
3492
|
}
|
|
2729
|
-
}
|
|
2730
|
-
setMounted() {
|
|
2731
|
-
this.mounted = true;
|
|
2732
3493
|
}
|
|
2733
3494
|
getAdjust() {
|
|
2734
3495
|
return this.appliedAdjust;
|
|
2735
3496
|
}
|
|
3497
|
+
commitPendingAdjust(scrollTarget) {
|
|
3498
|
+
if (PlatformAdjustBreaksScroll) {
|
|
3499
|
+
const state = this.ctx.state;
|
|
3500
|
+
const pending = this.pendingAdjust;
|
|
3501
|
+
this.pendingAdjust = 0;
|
|
3502
|
+
if (pending !== 0) {
|
|
3503
|
+
let targetScroll;
|
|
3504
|
+
if ((scrollTarget == null ? void 0 : scrollTarget.index) !== void 0) {
|
|
3505
|
+
const currentOffset = calculateOffsetForIndex(this.ctx, scrollTarget.index);
|
|
3506
|
+
targetScroll = calculateOffsetWithOffsetPosition(this.ctx, currentOffset, scrollTarget);
|
|
3507
|
+
targetScroll = clampScrollOffset(this.ctx, targetScroll, scrollTarget);
|
|
3508
|
+
} else {
|
|
3509
|
+
targetScroll = clampScrollOffset(this.ctx, state.scroll + pending);
|
|
3510
|
+
}
|
|
3511
|
+
const adjustment = targetScroll - state.scroll;
|
|
3512
|
+
if (Math.abs(adjustment) > 0.1 || Math.abs(pending) > 0.1) {
|
|
3513
|
+
this.appliedAdjust += adjustment;
|
|
3514
|
+
state.scroll = targetScroll;
|
|
3515
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
3516
|
+
set$(this.ctx, "scrollAdjust", this.appliedAdjust);
|
|
3517
|
+
}
|
|
3518
|
+
set$(this.ctx, "scrollAdjustPending", 0);
|
|
3519
|
+
calculateItemsInView(this.ctx);
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
2736
3523
|
};
|
|
2737
3524
|
|
|
2738
3525
|
// src/core/updateItemSize.ts
|
|
2739
|
-
function
|
|
3526
|
+
function runOrScheduleMVCPRecalculate(ctx) {
|
|
3527
|
+
const state = ctx.state;
|
|
3528
|
+
if (Platform2.OS === "web") {
|
|
3529
|
+
if (!state.mvcpAnchorLock) {
|
|
3530
|
+
if (state.queuedMVCPRecalculate !== void 0) {
|
|
3531
|
+
cancelAnimationFrame(state.queuedMVCPRecalculate);
|
|
3532
|
+
state.queuedMVCPRecalculate = void 0;
|
|
3533
|
+
}
|
|
3534
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
3535
|
+
return;
|
|
3536
|
+
}
|
|
3537
|
+
if (state.queuedMVCPRecalculate !== void 0) {
|
|
3538
|
+
return;
|
|
3539
|
+
}
|
|
3540
|
+
state.queuedMVCPRecalculate = requestAnimationFrame(() => {
|
|
3541
|
+
state.queuedMVCPRecalculate = void 0;
|
|
3542
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
3543
|
+
});
|
|
3544
|
+
} else {
|
|
3545
|
+
calculateItemsInView(ctx, { doMVCP: true });
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
function updateItemSize(ctx, itemKey, sizeObj) {
|
|
2740
3549
|
var _a3;
|
|
3550
|
+
const state = ctx.state;
|
|
2741
3551
|
const {
|
|
3552
|
+
didContainersLayout,
|
|
2742
3553
|
sizesKnown,
|
|
2743
3554
|
props: {
|
|
2744
3555
|
getFixedItemSize,
|
|
@@ -2761,31 +3572,24 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2761
3572
|
return;
|
|
2762
3573
|
}
|
|
2763
3574
|
const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
|
|
2764
|
-
const size2 = getFixedItemSize(
|
|
3575
|
+
const size2 = getFixedItemSize(itemData, index, type);
|
|
2765
3576
|
if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
|
|
2766
3577
|
return;
|
|
2767
3578
|
}
|
|
2768
3579
|
}
|
|
2769
|
-
|
|
2770
|
-
let needsRecalculate = !containersDidLayout;
|
|
3580
|
+
let needsRecalculate = !didContainersLayout;
|
|
2771
3581
|
let shouldMaintainScrollAtEnd = false;
|
|
2772
3582
|
let minIndexSizeChanged;
|
|
2773
3583
|
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
2774
3584
|
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
2775
|
-
const diff = updateOneItemSize(ctx,
|
|
3585
|
+
const diff = updateOneItemSize(ctx, itemKey, sizeObj);
|
|
2776
3586
|
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
2777
3587
|
if (diff !== 0) {
|
|
2778
3588
|
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
2779
3589
|
const { startBuffered, endBuffered } = state;
|
|
2780
3590
|
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
2781
|
-
if (!needsRecalculate) {
|
|
2782
|
-
|
|
2783
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2784
|
-
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
2785
|
-
needsRecalculate = true;
|
|
2786
|
-
break;
|
|
2787
|
-
}
|
|
2788
|
-
}
|
|
3591
|
+
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
3592
|
+
needsRecalculate = true;
|
|
2789
3593
|
}
|
|
2790
3594
|
if (state.needsOtherAxisSize) {
|
|
2791
3595
|
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
@@ -2821,20 +3625,21 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2821
3625
|
if (!cur || maxOtherAxisSize > cur) {
|
|
2822
3626
|
set$(ctx, "otherAxisSize", maxOtherAxisSize);
|
|
2823
3627
|
}
|
|
2824
|
-
if (
|
|
3628
|
+
if (didContainersLayout || checkAllSizesKnown(state)) {
|
|
2825
3629
|
if (needsRecalculate) {
|
|
2826
3630
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
2827
|
-
|
|
3631
|
+
runOrScheduleMVCPRecalculate(ctx);
|
|
2828
3632
|
}
|
|
2829
3633
|
if (shouldMaintainScrollAtEnd) {
|
|
2830
|
-
if (maintainScrollAtEnd
|
|
2831
|
-
doMaintainScrollAtEnd(ctx
|
|
3634
|
+
if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onItemLayout) {
|
|
3635
|
+
doMaintainScrollAtEnd(ctx);
|
|
2832
3636
|
}
|
|
2833
3637
|
}
|
|
2834
3638
|
}
|
|
2835
3639
|
}
|
|
2836
|
-
function updateOneItemSize(ctx,
|
|
3640
|
+
function updateOneItemSize(ctx, itemKey, sizeObj) {
|
|
2837
3641
|
var _a3;
|
|
3642
|
+
const state = ctx.state;
|
|
2838
3643
|
const {
|
|
2839
3644
|
indexByKey,
|
|
2840
3645
|
sizesKnown,
|
|
@@ -2843,9 +3648,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2843
3648
|
} = state;
|
|
2844
3649
|
if (!data) return 0;
|
|
2845
3650
|
const index = indexByKey.get(itemKey);
|
|
2846
|
-
const prevSize = getItemSize(ctx,
|
|
3651
|
+
const prevSize = getItemSize(ctx, itemKey, index, data[index]);
|
|
2847
3652
|
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
2848
3653
|
const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
|
|
3654
|
+
const prevSizeKnown = sizesKnown.get(itemKey);
|
|
2849
3655
|
sizesKnown.set(itemKey, size);
|
|
2850
3656
|
if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
|
|
2851
3657
|
const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
|
|
@@ -2853,15 +3659,28 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2853
3659
|
if (!averages) {
|
|
2854
3660
|
averages = averageSizes[itemType] = { avg: 0, num: 0 };
|
|
2855
3661
|
}
|
|
2856
|
-
|
|
2857
|
-
|
|
3662
|
+
if (averages.num === 0) {
|
|
3663
|
+
averages.avg = size;
|
|
3664
|
+
averages.num++;
|
|
3665
|
+
} else if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
|
|
3666
|
+
averages.avg += (size - prevSizeKnown) / averages.num;
|
|
3667
|
+
} else {
|
|
3668
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
3669
|
+
averages.num++;
|
|
3670
|
+
}
|
|
2858
3671
|
}
|
|
2859
3672
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2860
|
-
setSize(ctx,
|
|
3673
|
+
setSize(ctx, itemKey, size);
|
|
2861
3674
|
return size - prevSize;
|
|
2862
3675
|
}
|
|
2863
3676
|
return 0;
|
|
2864
3677
|
}
|
|
3678
|
+
function useWrapIfItem(fn) {
|
|
3679
|
+
return useMemo(
|
|
3680
|
+
() => fn ? (arg1, arg2, arg3) => arg1 !== void 0 && arg2 !== void 0 ? fn(arg1, arg2, arg3) : void 0 : void 0,
|
|
3681
|
+
[fn]
|
|
3682
|
+
);
|
|
3683
|
+
}
|
|
2865
3684
|
var useCombinedRef = (...refs) => {
|
|
2866
3685
|
const callback = useCallback((element) => {
|
|
2867
3686
|
for (const ref of refs) {
|
|
@@ -2877,17 +3696,11 @@ var useCombinedRef = (...refs) => {
|
|
|
2877
3696
|
}, refs);
|
|
2878
3697
|
return callback;
|
|
2879
3698
|
};
|
|
2880
|
-
function getWindowSize() {
|
|
2881
|
-
const screenSize = Dimensions.get("window");
|
|
2882
|
-
return {
|
|
2883
|
-
height: screenSize.height,
|
|
2884
|
-
width: screenSize.width
|
|
2885
|
-
};
|
|
2886
|
-
}
|
|
2887
3699
|
var StyleSheet = StyleSheet$1;
|
|
2888
3700
|
function useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, onScroll2) {
|
|
3701
|
+
const shouldUseRnAnimatedEngine = !ctx.state.props.stickyPositionComponentInternal;
|
|
2889
3702
|
return useMemo(() => {
|
|
2890
|
-
if (stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.length) {
|
|
3703
|
+
if ((stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.length) && shouldUseRnAnimatedEngine) {
|
|
2891
3704
|
const { animatedScrollY } = ctx;
|
|
2892
3705
|
return Animated.event(
|
|
2893
3706
|
[
|
|
@@ -2904,7 +3717,7 @@ function useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, onScroll2)
|
|
|
2904
3717
|
);
|
|
2905
3718
|
}
|
|
2906
3719
|
return onScroll2;
|
|
2907
|
-
}, [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(","), horizontal]);
|
|
3720
|
+
}, [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(","), horizontal, shouldUseRnAnimatedEngine]);
|
|
2908
3721
|
}
|
|
2909
3722
|
|
|
2910
3723
|
// src/utils/createColumnWrapperStyle.ts
|
|
@@ -2922,31 +3735,118 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2922
3735
|
}
|
|
2923
3736
|
}
|
|
2924
3737
|
|
|
3738
|
+
// src/utils/hasActiveMVCPAnchorLock.ts
|
|
3739
|
+
function hasActiveMVCPAnchorLock(state) {
|
|
3740
|
+
const lock = state.mvcpAnchorLock;
|
|
3741
|
+
if (!lock) {
|
|
3742
|
+
return false;
|
|
3743
|
+
}
|
|
3744
|
+
if (Date.now() > lock.expiresAt) {
|
|
3745
|
+
state.mvcpAnchorLock = void 0;
|
|
3746
|
+
return false;
|
|
3747
|
+
}
|
|
3748
|
+
return true;
|
|
3749
|
+
}
|
|
3750
|
+
|
|
2925
3751
|
// src/utils/createImperativeHandle.ts
|
|
2926
|
-
function createImperativeHandle(ctx
|
|
3752
|
+
function createImperativeHandle(ctx) {
|
|
3753
|
+
const state = ctx.state;
|
|
3754
|
+
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
3755
|
+
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
3756
|
+
let imperativeScrollToken = 0;
|
|
3757
|
+
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.queuedMVCPRecalculate !== void 0 || state.ignoreScrollFromMVCP !== void 0 || hasActiveMVCPAnchorLock(state);
|
|
3758
|
+
const runWhenSettled = (token, run) => {
|
|
3759
|
+
const startedAt = Date.now();
|
|
3760
|
+
let stableFrames = 0;
|
|
3761
|
+
const check = () => {
|
|
3762
|
+
if (token !== imperativeScrollToken) {
|
|
3763
|
+
return;
|
|
3764
|
+
}
|
|
3765
|
+
if (isSettlingAfterDataChange()) {
|
|
3766
|
+
stableFrames = 0;
|
|
3767
|
+
} else {
|
|
3768
|
+
stableFrames += 1;
|
|
3769
|
+
}
|
|
3770
|
+
const timedOut = Date.now() - startedAt >= IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS;
|
|
3771
|
+
if (stableFrames >= IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES || timedOut) {
|
|
3772
|
+
run();
|
|
3773
|
+
return;
|
|
3774
|
+
}
|
|
3775
|
+
requestAnimationFrame(check);
|
|
3776
|
+
};
|
|
3777
|
+
requestAnimationFrame(check);
|
|
3778
|
+
};
|
|
3779
|
+
const runScrollWithPromise = (run) => new Promise((resolve) => {
|
|
3780
|
+
var _a3;
|
|
3781
|
+
const token = ++imperativeScrollToken;
|
|
3782
|
+
(_a3 = state.pendingScrollResolve) == null ? void 0 : _a3.call(state);
|
|
3783
|
+
state.pendingScrollResolve = resolve;
|
|
3784
|
+
const runNow = () => {
|
|
3785
|
+
if (token !== imperativeScrollToken) {
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
const didStartScroll = run();
|
|
3789
|
+
if (!didStartScroll || !state.scrollingTo) {
|
|
3790
|
+
if (state.pendingScrollResolve === resolve) {
|
|
3791
|
+
state.pendingScrollResolve = void 0;
|
|
3792
|
+
}
|
|
3793
|
+
resolve();
|
|
3794
|
+
}
|
|
3795
|
+
};
|
|
3796
|
+
if (isSettlingAfterDataChange()) {
|
|
3797
|
+
runWhenSettled(token, runNow);
|
|
3798
|
+
return;
|
|
3799
|
+
}
|
|
3800
|
+
runNow();
|
|
3801
|
+
});
|
|
2927
3802
|
const scrollIndexIntoView = (options) => {
|
|
2928
3803
|
if (state) {
|
|
2929
3804
|
const { index, ...rest } = options;
|
|
2930
3805
|
const { startNoBuffer, endNoBuffer } = state;
|
|
2931
3806
|
if (index < startNoBuffer || index > endNoBuffer) {
|
|
2932
3807
|
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
2933
|
-
scrollToIndex(ctx,
|
|
3808
|
+
scrollToIndex(ctx, {
|
|
2934
3809
|
...rest,
|
|
2935
3810
|
index,
|
|
2936
3811
|
viewPosition
|
|
2937
3812
|
});
|
|
3813
|
+
return true;
|
|
2938
3814
|
}
|
|
2939
3815
|
}
|
|
3816
|
+
return false;
|
|
2940
3817
|
};
|
|
2941
3818
|
const refScroller = state.refScroller;
|
|
3819
|
+
const clearCaches = (options) => {
|
|
3820
|
+
var _a3, _b;
|
|
3821
|
+
const mode = (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : "sizes";
|
|
3822
|
+
state.sizes.clear();
|
|
3823
|
+
state.sizesKnown.clear();
|
|
3824
|
+
for (const key in state.averageSizes) {
|
|
3825
|
+
delete state.averageSizes[key];
|
|
3826
|
+
}
|
|
3827
|
+
state.minIndexSizeChanged = 0;
|
|
3828
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
3829
|
+
state.pendingTotalSize = void 0;
|
|
3830
|
+
state.totalSize = 0;
|
|
3831
|
+
set$(ctx, "totalSize", 0);
|
|
3832
|
+
if (mode === "full") {
|
|
3833
|
+
state.indexByKey.clear();
|
|
3834
|
+
state.idCache.length = 0;
|
|
3835
|
+
state.positions.length = 0;
|
|
3836
|
+
state.columns.length = 0;
|
|
3837
|
+
state.columnSpans.length = 0;
|
|
3838
|
+
}
|
|
3839
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
3840
|
+
};
|
|
2942
3841
|
return {
|
|
3842
|
+
clearCaches,
|
|
2943
3843
|
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
2944
3844
|
getNativeScrollRef: () => refScroller.current,
|
|
2945
3845
|
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
2946
3846
|
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
2947
3847
|
getState: () => ({
|
|
2948
|
-
activeStickyIndex:
|
|
2949
|
-
contentLength:
|
|
3848
|
+
activeStickyIndex: peek$(ctx, "activeStickyIndex"),
|
|
3849
|
+
contentLength: getContentSize(ctx),
|
|
2950
3850
|
data: state.props.data,
|
|
2951
3851
|
elementAtIndex: (index) => {
|
|
2952
3852
|
var _a3;
|
|
@@ -2956,47 +3856,71 @@ function createImperativeHandle(ctx, state) {
|
|
|
2956
3856
|
endBuffered: state.endBuffered,
|
|
2957
3857
|
isAtEnd: state.isAtEnd,
|
|
2958
3858
|
isAtStart: state.isAtStart,
|
|
2959
|
-
|
|
2960
|
-
|
|
3859
|
+
isEndReached: state.isEndReached,
|
|
3860
|
+
isStartReached: state.isStartReached,
|
|
3861
|
+
listen: (signalName, cb) => listen$(ctx, signalName, cb),
|
|
3862
|
+
listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
|
|
3863
|
+
positionAtIndex: (index) => state.positions[index],
|
|
3864
|
+
positionByKey: (key) => {
|
|
3865
|
+
const index = state.indexByKey.get(key);
|
|
3866
|
+
return index === void 0 ? void 0 : state.positions[index];
|
|
3867
|
+
},
|
|
2961
3868
|
scroll: state.scroll,
|
|
2962
3869
|
scrollLength: state.scrollLength,
|
|
3870
|
+
scrollVelocity: getScrollVelocity(state),
|
|
2963
3871
|
sizeAtIndex: (index) => state.sizesKnown.get(getId(state, index)),
|
|
2964
3872
|
sizes: state.sizesKnown,
|
|
2965
3873
|
start: state.startNoBuffer,
|
|
2966
3874
|
startBuffered: state.startBuffered
|
|
2967
3875
|
}),
|
|
2968
|
-
|
|
2969
|
-
|
|
3876
|
+
reportContentInset: (inset) => {
|
|
3877
|
+
state.contentInsetOverride = inset != null ? inset : void 0;
|
|
3878
|
+
updateScroll(ctx, state.scroll, true);
|
|
3879
|
+
},
|
|
3880
|
+
scrollIndexIntoView: (options) => runScrollWithPromise(() => scrollIndexIntoView(options)),
|
|
3881
|
+
scrollItemIntoView: ({ item, ...props }) => runScrollWithPromise(() => {
|
|
2970
3882
|
const data = state.props.data;
|
|
2971
3883
|
const index = data.indexOf(item);
|
|
2972
3884
|
if (index !== -1) {
|
|
2973
3885
|
scrollIndexIntoView({ index, ...props });
|
|
3886
|
+
return true;
|
|
2974
3887
|
}
|
|
2975
|
-
|
|
2976
|
-
|
|
3888
|
+
return false;
|
|
3889
|
+
}),
|
|
3890
|
+
scrollToEnd: (options) => runScrollWithPromise(() => {
|
|
2977
3891
|
const data = state.props.data;
|
|
2978
3892
|
const stylePaddingBottom = state.props.stylePaddingBottom;
|
|
2979
3893
|
const index = data.length - 1;
|
|
2980
3894
|
if (index !== -1) {
|
|
2981
3895
|
const paddingBottom = stylePaddingBottom || 0;
|
|
2982
3896
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
2983
|
-
scrollToIndex(ctx,
|
|
3897
|
+
scrollToIndex(ctx, {
|
|
3898
|
+
...options,
|
|
2984
3899
|
index,
|
|
2985
3900
|
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
2986
|
-
viewPosition: 1
|
|
2987
|
-
...options
|
|
3901
|
+
viewPosition: 1
|
|
2988
3902
|
});
|
|
3903
|
+
return true;
|
|
2989
3904
|
}
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
3905
|
+
return false;
|
|
3906
|
+
}),
|
|
3907
|
+
scrollToIndex: (params) => runScrollWithPromise(() => {
|
|
3908
|
+
scrollToIndex(ctx, params);
|
|
3909
|
+
return true;
|
|
3910
|
+
}),
|
|
3911
|
+
scrollToItem: ({ item, ...props }) => runScrollWithPromise(() => {
|
|
2993
3912
|
const data = state.props.data;
|
|
2994
3913
|
const index = data.indexOf(item);
|
|
2995
3914
|
if (index !== -1) {
|
|
2996
|
-
scrollToIndex(ctx,
|
|
3915
|
+
scrollToIndex(ctx, { index, ...props });
|
|
3916
|
+
return true;
|
|
2997
3917
|
}
|
|
2998
|
-
|
|
2999
|
-
|
|
3918
|
+
return false;
|
|
3919
|
+
}),
|
|
3920
|
+
scrollToOffset: (params) => runScrollWithPromise(() => {
|
|
3921
|
+
scrollTo(ctx, params);
|
|
3922
|
+
return true;
|
|
3923
|
+
}),
|
|
3000
3924
|
setScrollProcessingEnabled: (enabled) => {
|
|
3001
3925
|
state.scrollProcessingEnabled = enabled;
|
|
3002
3926
|
},
|
|
@@ -3006,8 +3930,57 @@ function createImperativeHandle(ctx, state) {
|
|
|
3006
3930
|
}
|
|
3007
3931
|
};
|
|
3008
3932
|
}
|
|
3009
|
-
|
|
3933
|
+
|
|
3934
|
+
// src/utils/getAlwaysRenderIndices.ts
|
|
3935
|
+
var sortAsc = (a, b) => a - b;
|
|
3936
|
+
var toCount = (value) => typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
|
|
3937
|
+
var addIndex = (result, dataLength, index) => {
|
|
3938
|
+
if (index >= 0 && index < dataLength) {
|
|
3939
|
+
result.add(index);
|
|
3940
|
+
}
|
|
3941
|
+
};
|
|
3942
|
+
function getAlwaysRenderIndices(config, data, keyExtractor) {
|
|
3943
|
+
var _a3, _b;
|
|
3944
|
+
if (!config || data.length === 0) {
|
|
3945
|
+
return [];
|
|
3946
|
+
}
|
|
3947
|
+
const result = /* @__PURE__ */ new Set();
|
|
3948
|
+
const dataLength = data.length;
|
|
3949
|
+
const topCount = toCount(config.top);
|
|
3950
|
+
if (topCount > 0) {
|
|
3951
|
+
for (let i = 0; i < Math.min(topCount, dataLength); i++) {
|
|
3952
|
+
addIndex(result, dataLength, i);
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
const bottomCount = toCount(config.bottom);
|
|
3956
|
+
if (bottomCount > 0) {
|
|
3957
|
+
for (let i = Math.max(0, dataLength - bottomCount); i < dataLength; i++) {
|
|
3958
|
+
addIndex(result, dataLength, i);
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
if ((_a3 = config.indices) == null ? void 0 : _a3.length) {
|
|
3962
|
+
for (const index of config.indices) {
|
|
3963
|
+
if (!Number.isFinite(index)) continue;
|
|
3964
|
+
addIndex(result, dataLength, Math.floor(index));
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
if ((_b = config.keys) == null ? void 0 : _b.length) {
|
|
3968
|
+
const keys = new Set(config.keys);
|
|
3969
|
+
for (let i = 0; i < dataLength && keys.size > 0; i++) {
|
|
3970
|
+
const key = keyExtractor(data[i], i);
|
|
3971
|
+
if (keys.has(key)) {
|
|
3972
|
+
addIndex(result, dataLength, i);
|
|
3973
|
+
keys.delete(key);
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3977
|
+
const indices = Array.from(result);
|
|
3978
|
+
indices.sort(sortAsc);
|
|
3979
|
+
return indices;
|
|
3980
|
+
}
|
|
3981
|
+
function getRenderedItem(ctx, key) {
|
|
3010
3982
|
var _a3;
|
|
3983
|
+
const state = ctx.state;
|
|
3011
3984
|
if (!state) {
|
|
3012
3985
|
return null;
|
|
3013
3986
|
}
|
|
@@ -3034,6 +4007,70 @@ function getRenderedItem(ctx, state, key) {
|
|
|
3034
4007
|
}
|
|
3035
4008
|
return { index, item: data[index], renderedItem };
|
|
3036
4009
|
}
|
|
4010
|
+
|
|
4011
|
+
// src/utils/normalizeMaintainScrollAtEnd.ts
|
|
4012
|
+
function normalizeMaintainScrollAtEndOn(on, hasExplicitOn) {
|
|
4013
|
+
var _a3, _b, _c;
|
|
4014
|
+
return {
|
|
4015
|
+
animated: false,
|
|
4016
|
+
onDataChange: hasExplicitOn ? (_a3 = on == null ? void 0 : on.dataChange) != null ? _a3 : false : true,
|
|
4017
|
+
onItemLayout: hasExplicitOn ? (_b = on == null ? void 0 : on.itemLayout) != null ? _b : false : true,
|
|
4018
|
+
onLayout: hasExplicitOn ? (_c = on == null ? void 0 : on.layout) != null ? _c : false : true
|
|
4019
|
+
};
|
|
4020
|
+
}
|
|
4021
|
+
function normalizeMaintainScrollAtEnd(value) {
|
|
4022
|
+
var _a3;
|
|
4023
|
+
if (!value) {
|
|
4024
|
+
return void 0;
|
|
4025
|
+
}
|
|
4026
|
+
if (value === true) {
|
|
4027
|
+
return {
|
|
4028
|
+
...normalizeMaintainScrollAtEndOn(void 0, false),
|
|
4029
|
+
animated: false
|
|
4030
|
+
};
|
|
4031
|
+
}
|
|
4032
|
+
const normalizedTriggers = normalizeMaintainScrollAtEndOn(value.on, "on" in value);
|
|
4033
|
+
return {
|
|
4034
|
+
...normalizedTriggers,
|
|
4035
|
+
animated: (_a3 = value.animated) != null ? _a3 : false
|
|
4036
|
+
};
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4039
|
+
// src/utils/normalizeMaintainVisibleContentPosition.ts
|
|
4040
|
+
function normalizeMaintainVisibleContentPosition(value) {
|
|
4041
|
+
var _a3, _b;
|
|
4042
|
+
if (value === true) {
|
|
4043
|
+
return { data: true, size: true };
|
|
4044
|
+
}
|
|
4045
|
+
if (value && typeof value === "object") {
|
|
4046
|
+
return {
|
|
4047
|
+
data: (_a3 = value.data) != null ? _a3 : false,
|
|
4048
|
+
shouldRestorePosition: value.shouldRestorePosition,
|
|
4049
|
+
size: (_b = value.size) != null ? _b : true
|
|
4050
|
+
};
|
|
4051
|
+
}
|
|
4052
|
+
if (value === false) {
|
|
4053
|
+
return { data: false, size: false };
|
|
4054
|
+
}
|
|
4055
|
+
return { data: false, size: true };
|
|
4056
|
+
}
|
|
4057
|
+
|
|
4058
|
+
// src/utils/setPaddingTop.ts
|
|
4059
|
+
function setPaddingTop(ctx, { stylePaddingTop }) {
|
|
4060
|
+
const state = ctx.state;
|
|
4061
|
+
if (stylePaddingTop !== void 0) {
|
|
4062
|
+
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
4063
|
+
if (stylePaddingTop < prevStylePaddingTop) {
|
|
4064
|
+
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
4065
|
+
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
4066
|
+
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
4067
|
+
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
4068
|
+
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
4069
|
+
}, 16);
|
|
4070
|
+
}
|
|
4071
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
3037
4074
|
function useThrottleDebounce(mode) {
|
|
3038
4075
|
const timeoutRef = useRef(null);
|
|
3039
4076
|
const lastCallTimeRef = useRef(0);
|
|
@@ -3081,9 +4118,8 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
|
|
|
3081
4118
|
}
|
|
3082
4119
|
|
|
3083
4120
|
// src/components/LegendList.tsx
|
|
3084
|
-
var
|
|
3085
|
-
|
|
3086
|
-
var LegendList = typedMemo(
|
|
4121
|
+
var LegendList = typedMemo2(
|
|
4122
|
+
// biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
|
|
3087
4123
|
typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
3088
4124
|
const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
|
|
3089
4125
|
const isChildrenMode = children !== void 0 && dataProp === void 0;
|
|
@@ -3101,16 +4137,17 @@ var LegendList = typedMemo(
|
|
|
3101
4137
|
})
|
|
3102
4138
|
);
|
|
3103
4139
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
3104
|
-
var _a3, _b;
|
|
4140
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
3105
4141
|
const {
|
|
3106
4142
|
alignItemsAtEnd = false,
|
|
4143
|
+
alwaysRender,
|
|
3107
4144
|
columnWrapperStyle,
|
|
3108
4145
|
contentContainerStyle: contentContainerStyleProp,
|
|
4146
|
+
contentInset,
|
|
3109
4147
|
data: dataProp = [],
|
|
3110
4148
|
dataVersion,
|
|
3111
4149
|
drawDistance = 250,
|
|
3112
|
-
|
|
3113
|
-
estimatedItemSize: estimatedItemSizeProp,
|
|
4150
|
+
estimatedItemSize = 100,
|
|
3114
4151
|
estimatedListSize,
|
|
3115
4152
|
extraData,
|
|
3116
4153
|
getEstimatedItemSize,
|
|
@@ -3127,11 +4164,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3127
4164
|
ListHeaderComponent,
|
|
3128
4165
|
maintainScrollAtEnd = false,
|
|
3129
4166
|
maintainScrollAtEndThreshold = 0.1,
|
|
3130
|
-
maintainVisibleContentPosition
|
|
4167
|
+
maintainVisibleContentPosition: maintainVisibleContentPositionProp,
|
|
3131
4168
|
numColumns: numColumnsProp = 1,
|
|
4169
|
+
overrideItemLayout,
|
|
3132
4170
|
onEndReached,
|
|
3133
4171
|
onEndReachedThreshold = 0.5,
|
|
3134
4172
|
onItemSizeChanged,
|
|
4173
|
+
onMetricsChange,
|
|
3135
4174
|
onLayout: onLayoutProp,
|
|
3136
4175
|
onLoad,
|
|
3137
4176
|
onMomentumScrollEnd,
|
|
@@ -3146,50 +4185,110 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3146
4185
|
refreshControl,
|
|
3147
4186
|
refreshing,
|
|
3148
4187
|
refScrollView,
|
|
4188
|
+
renderScrollComponent,
|
|
3149
4189
|
renderItem,
|
|
3150
4190
|
scrollEventThrottle,
|
|
3151
4191
|
snapToIndices,
|
|
3152
4192
|
stickyHeaderIndices: stickyHeaderIndicesProp,
|
|
3153
4193
|
stickyIndices: stickyIndicesDeprecated,
|
|
4194
|
+
// TODOV3: Remove from v3 release
|
|
3154
4195
|
style: styleProp,
|
|
3155
4196
|
suggestEstimatedItemSize,
|
|
4197
|
+
useWindowScroll = false,
|
|
3156
4198
|
viewabilityConfig,
|
|
3157
4199
|
viewabilityConfigCallbackPairs,
|
|
3158
4200
|
waitForInitialLayout = true,
|
|
3159
4201
|
...rest
|
|
3160
4202
|
} = props;
|
|
3161
|
-
const
|
|
3162
|
-
const
|
|
4203
|
+
const animatedPropsInternal = props.animatedPropsInternal;
|
|
4204
|
+
const positionComponentInternal = props.positionComponentInternal;
|
|
4205
|
+
const stickyPositionComponentInternal = props.stickyPositionComponentInternal;
|
|
4206
|
+
const {
|
|
4207
|
+
childrenMode,
|
|
4208
|
+
positionComponentInternal: _positionComponentInternal,
|
|
4209
|
+
stickyPositionComponentInternal: _stickyPositionComponentInternal,
|
|
4210
|
+
...restProps
|
|
4211
|
+
} = rest;
|
|
4212
|
+
const contentContainerStyleBase = StyleSheet.flatten(contentContainerStyleProp);
|
|
4213
|
+
const shouldFlexGrow = alignItemsAtEnd && (horizontal ? (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minWidth) == null : (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null);
|
|
4214
|
+
const contentContainerStyle = {
|
|
4215
|
+
...contentContainerStyleBase,
|
|
4216
|
+
...alignItemsAtEnd ? {
|
|
4217
|
+
display: "flex",
|
|
4218
|
+
flexDirection: horizontal ? "row" : "column",
|
|
4219
|
+
...shouldFlexGrow ? { flexGrow: 1 } : {},
|
|
4220
|
+
justifyContent: "flex-end"
|
|
4221
|
+
} : {}
|
|
4222
|
+
};
|
|
3163
4223
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
3164
4224
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
3165
4225
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
3166
|
-
const
|
|
3167
|
-
const
|
|
4226
|
+
const maintainScrollAtEndConfig = normalizeMaintainScrollAtEnd(maintainScrollAtEnd);
|
|
4227
|
+
const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
|
|
4228
|
+
maintainVisibleContentPositionProp
|
|
4229
|
+
);
|
|
4230
|
+
const hasInitialScrollIndex = initialScrollIndexProp !== void 0 && initialScrollIndexProp !== null;
|
|
4231
|
+
const hasInitialScrollOffset = initialScrollOffsetProp !== void 0 && initialScrollOffsetProp !== null;
|
|
4232
|
+
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && hasInitialScrollOffset;
|
|
4233
|
+
const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState, viewPosition: 1 } : hasInitialScrollIndex ? typeof initialScrollIndexProp === "object" ? {
|
|
4234
|
+
index: (_a3 = initialScrollIndexProp.index) != null ? _a3 : 0,
|
|
4235
|
+
viewOffset: (_b = initialScrollIndexProp.viewOffset) != null ? _b : initialScrollIndexProp.viewPosition === 1 ? -stylePaddingBottomState : 0,
|
|
4236
|
+
viewPosition: (_c = initialScrollIndexProp.viewPosition) != null ? _c : 0
|
|
4237
|
+
} : {
|
|
4238
|
+
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
4239
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0
|
|
4240
|
+
} : initialScrollUsesOffsetOnly ? {
|
|
4241
|
+
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
4242
|
+
index: 0,
|
|
4243
|
+
viewOffset: 0
|
|
4244
|
+
} : void 0;
|
|
3168
4245
|
const [canRender, setCanRender] = React2.useState(!IsNewArchitecture);
|
|
3169
4246
|
const ctx = useStateContext();
|
|
3170
4247
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
3171
4248
|
const refScroller = useRef(null);
|
|
3172
4249
|
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
3173
|
-
const
|
|
3174
|
-
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
3175
|
-
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
|
|
4250
|
+
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : ((_item, index) => index.toString());
|
|
3176
4251
|
const stickyHeaderIndices = stickyHeaderIndicesProp != null ? stickyHeaderIndicesProp : stickyIndicesDeprecated;
|
|
4252
|
+
const alwaysRenderIndices = useMemo(() => {
|
|
4253
|
+
const indices = getAlwaysRenderIndices(alwaysRender, dataProp, keyExtractor);
|
|
4254
|
+
return { arr: indices, set: new Set(indices) };
|
|
4255
|
+
}, [
|
|
4256
|
+
alwaysRender == null ? void 0 : alwaysRender.top,
|
|
4257
|
+
alwaysRender == null ? void 0 : alwaysRender.bottom,
|
|
4258
|
+
(_d = alwaysRender == null ? void 0 : alwaysRender.indices) == null ? void 0 : _d.join(","),
|
|
4259
|
+
(_e = alwaysRender == null ? void 0 : alwaysRender.keys) == null ? void 0 : _e.join(","),
|
|
4260
|
+
dataProp,
|
|
4261
|
+
dataVersion,
|
|
4262
|
+
keyExtractor
|
|
4263
|
+
]);
|
|
3177
4264
|
if (IS_DEV && stickyIndicesDeprecated && !stickyHeaderIndicesProp) {
|
|
3178
4265
|
warnDevOnce(
|
|
3179
4266
|
"stickyIndices",
|
|
3180
4267
|
"stickyIndices has been renamed to stickyHeaderIndices. Please update your props to use stickyHeaderIndices."
|
|
3181
4268
|
);
|
|
3182
4269
|
}
|
|
3183
|
-
|
|
4270
|
+
if (IS_DEV && useWindowScroll && renderScrollComponent) {
|
|
4271
|
+
warnDevOnce(
|
|
4272
|
+
"useWindowScrollRenderScrollComponent",
|
|
4273
|
+
"useWindowScroll is not supported when renderScrollComponent is provided."
|
|
4274
|
+
);
|
|
4275
|
+
}
|
|
4276
|
+
const useWindowScrollResolved = Platform2.OS === "web" && !!useWindowScroll && !renderScrollComponent;
|
|
4277
|
+
const refState = useRef(void 0);
|
|
4278
|
+
const hasOverrideItemLayout = !!overrideItemLayout;
|
|
4279
|
+
const prevHasOverrideItemLayout = useRef(hasOverrideItemLayout);
|
|
3184
4280
|
if (!refState.current) {
|
|
3185
|
-
if (!ctx.
|
|
4281
|
+
if (!ctx.state) {
|
|
3186
4282
|
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
|
|
3187
|
-
ctx.
|
|
3188
|
-
activeStickyIndex:
|
|
4283
|
+
ctx.state = {
|
|
4284
|
+
activeStickyIndex: -1,
|
|
3189
4285
|
averageSizes: {},
|
|
3190
|
-
|
|
3191
|
-
|
|
4286
|
+
columnSpans: [],
|
|
4287
|
+
columns: [],
|
|
4288
|
+
containerItemKeys: /* @__PURE__ */ new Map(),
|
|
3192
4289
|
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
4290
|
+
contentInsetOverride: void 0,
|
|
4291
|
+
dataChangeEpoch: 0,
|
|
3193
4292
|
dataChangeNeedsScrollUpdate: false,
|
|
3194
4293
|
didColumnsChange: false,
|
|
3195
4294
|
didDataChange: false,
|
|
@@ -3201,28 +4300,39 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3201
4300
|
idCache: [],
|
|
3202
4301
|
idsInView: [],
|
|
3203
4302
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
3204
|
-
initialAnchor: (initialScrollProp == null ? void 0 : initialScrollProp.index) !== void 0 && (initialScrollProp == null ? void 0 : initialScrollProp.viewPosition) !== void 0 ? {
|
|
4303
|
+
initialAnchor: !initialScrollUsesOffsetOnly && (initialScrollProp == null ? void 0 : initialScrollProp.index) !== void 0 && (initialScrollProp == null ? void 0 : initialScrollProp.viewPosition) !== void 0 ? {
|
|
3205
4304
|
attempts: 0,
|
|
3206
4305
|
index: initialScrollProp.index,
|
|
3207
4306
|
settledTicks: 0,
|
|
3208
|
-
viewOffset: (
|
|
4307
|
+
viewOffset: (_f = initialScrollProp.viewOffset) != null ? _f : 0,
|
|
3209
4308
|
viewPosition: initialScrollProp.viewPosition
|
|
3210
4309
|
} : void 0,
|
|
4310
|
+
initialNativeScrollWatchdog: void 0,
|
|
3211
4311
|
initialScroll: initialScrollProp,
|
|
4312
|
+
initialScrollLastDidFinish: false,
|
|
4313
|
+
initialScrollLastTarget: initialScrollProp,
|
|
4314
|
+
initialScrollLastTargetUsesOffset: initialScrollUsesOffsetOnly,
|
|
4315
|
+
initialScrollPreviousDataLength: dataProp.length,
|
|
4316
|
+
initialScrollRetryLastLength: void 0,
|
|
4317
|
+
initialScrollRetryWindowUntil: 0,
|
|
4318
|
+
initialScrollUsesOffset: initialScrollUsesOffsetOnly,
|
|
3212
4319
|
isAtEnd: false,
|
|
3213
4320
|
isAtStart: false,
|
|
3214
|
-
isEndReached:
|
|
4321
|
+
isEndReached: null,
|
|
3215
4322
|
isFirst: true,
|
|
3216
|
-
isStartReached:
|
|
4323
|
+
isStartReached: null,
|
|
3217
4324
|
lastBatchingAction: Date.now(),
|
|
3218
4325
|
lastLayout: void 0,
|
|
4326
|
+
lastScrollDelta: 0,
|
|
3219
4327
|
loadStartTime: Date.now(),
|
|
3220
4328
|
minIndexSizeChanged: 0,
|
|
4329
|
+
nativeContentInset: void 0,
|
|
3221
4330
|
nativeMarginTop: 0,
|
|
3222
|
-
|
|
4331
|
+
pendingNativeMVCPAdjust: void 0,
|
|
4332
|
+
positions: [],
|
|
3223
4333
|
props: {},
|
|
3224
4334
|
queuedCalculateItemsInView: 0,
|
|
3225
|
-
refScroller:
|
|
4335
|
+
refScroller: { current: null },
|
|
3226
4336
|
scroll: 0,
|
|
3227
4337
|
scrollAdjustHandler: new ScrollAdjustHandler(ctx),
|
|
3228
4338
|
scrollForNextCalculateItemsInView: void 0,
|
|
@@ -3238,6 +4348,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3238
4348
|
startBuffered: -1,
|
|
3239
4349
|
startNoBuffer: -1,
|
|
3240
4350
|
startReachedSnapshot: void 0,
|
|
4351
|
+
startReachedSnapshotDataChangeEpoch: void 0,
|
|
3241
4352
|
stickyContainerPool: /* @__PURE__ */ new Set(),
|
|
3242
4353
|
stickyContainers: /* @__PURE__ */ new Map(),
|
|
3243
4354
|
timeoutSizeMessage: 0,
|
|
@@ -3245,18 +4356,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3245
4356
|
totalSize: 0,
|
|
3246
4357
|
viewabilityConfigCallbackPairs: void 0
|
|
3247
4358
|
};
|
|
3248
|
-
const internalState = ctx.
|
|
3249
|
-
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx,
|
|
3250
|
-
set$(ctx, "maintainVisibleContentPosition",
|
|
4359
|
+
const internalState = ctx.state;
|
|
4360
|
+
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
4361
|
+
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
3251
4362
|
set$(ctx, "extraData", extraData);
|
|
3252
4363
|
}
|
|
3253
|
-
refState.current = ctx.
|
|
4364
|
+
refState.current = ctx.state;
|
|
3254
4365
|
}
|
|
3255
4366
|
const state = refState.current;
|
|
3256
4367
|
const isFirstLocal = state.isFirst;
|
|
3257
4368
|
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3258
|
-
const
|
|
4369
|
+
const didDataReferenceChangeLocal = state.props.data !== dataProp;
|
|
4370
|
+
const didDataVersionChangeLocal = state.props.dataVersion !== dataVersion;
|
|
4371
|
+
const didDataChangeLocal = didDataVersionChangeLocal || didDataReferenceChangeLocal && checkActualChange(state, dataProp, state.props.data);
|
|
3259
4372
|
if (didDataChangeLocal) {
|
|
4373
|
+
state.dataChangeEpoch += 1;
|
|
3260
4374
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3261
4375
|
state.didDataChange = true;
|
|
3262
4376
|
state.previousData = state.props.data;
|
|
@@ -3264,20 +4378,25 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3264
4378
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3265
4379
|
state.props = {
|
|
3266
4380
|
alignItemsAtEnd,
|
|
4381
|
+
alwaysRender,
|
|
4382
|
+
alwaysRenderIndicesArr: alwaysRenderIndices.arr,
|
|
4383
|
+
alwaysRenderIndicesSet: alwaysRenderIndices.set,
|
|
4384
|
+
animatedProps: animatedPropsInternal,
|
|
4385
|
+
contentInset,
|
|
3267
4386
|
data: dataProp,
|
|
3268
4387
|
dataVersion,
|
|
3269
|
-
|
|
4388
|
+
drawDistance,
|
|
3270
4389
|
estimatedItemSize,
|
|
3271
|
-
getEstimatedItemSize,
|
|
3272
|
-
getFixedItemSize,
|
|
3273
|
-
getItemType,
|
|
4390
|
+
getEstimatedItemSize: useWrapIfItem(getEstimatedItemSize),
|
|
4391
|
+
getFixedItemSize: useWrapIfItem(getFixedItemSize),
|
|
4392
|
+
getItemType: useWrapIfItem(getItemType),
|
|
3274
4393
|
horizontal: !!horizontal,
|
|
3275
4394
|
initialContainerPoolRatio,
|
|
3276
4395
|
itemsAreEqual,
|
|
3277
|
-
keyExtractor,
|
|
3278
|
-
maintainScrollAtEnd,
|
|
4396
|
+
keyExtractor: useWrapIfItem(keyExtractor),
|
|
4397
|
+
maintainScrollAtEnd: maintainScrollAtEndConfig,
|
|
3279
4398
|
maintainScrollAtEndThreshold,
|
|
3280
|
-
maintainVisibleContentPosition,
|
|
4399
|
+
maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
|
|
3281
4400
|
numColumns: numColumnsProp,
|
|
3282
4401
|
onEndReached,
|
|
3283
4402
|
onEndReachedThreshold,
|
|
@@ -3287,15 +4406,18 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3287
4406
|
onStartReached,
|
|
3288
4407
|
onStartReachedThreshold,
|
|
3289
4408
|
onStickyHeaderChange,
|
|
4409
|
+
overrideItemLayout,
|
|
4410
|
+
positionComponentInternal,
|
|
3290
4411
|
recycleItems: !!recycleItems,
|
|
3291
4412
|
renderItem,
|
|
3292
|
-
scrollBuffer,
|
|
3293
4413
|
snapToIndices,
|
|
3294
4414
|
stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
|
|
3295
4415
|
stickyIndicesSet: useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
|
|
4416
|
+
stickyPositionComponentInternal,
|
|
3296
4417
|
stylePaddingBottom: stylePaddingBottomState,
|
|
3297
4418
|
stylePaddingTop: stylePaddingTopState,
|
|
3298
|
-
suggestEstimatedItemSize: !!suggestEstimatedItemSize
|
|
4419
|
+
suggestEstimatedItemSize: !!suggestEstimatedItemSize,
|
|
4420
|
+
useWindowScroll: useWindowScrollResolved
|
|
3299
4421
|
};
|
|
3300
4422
|
state.refScroller = refScroller;
|
|
3301
4423
|
const memoizedLastItemKeys = useMemo(() => {
|
|
@@ -3305,62 +4427,138 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3305
4427
|
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
3306
4428
|
);
|
|
3307
4429
|
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3308
|
-
const initializeStateVars = () => {
|
|
4430
|
+
const initializeStateVars = (shouldAdjustPadding) => {
|
|
3309
4431
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
3310
4432
|
set$(ctx, "numColumns", numColumnsProp);
|
|
3311
4433
|
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
3312
|
-
setPaddingTop(ctx,
|
|
4434
|
+
setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
|
|
3313
4435
|
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
3314
4436
|
let paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
3315
|
-
if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
|
|
4437
|
+
if (shouldAdjustPadding && maintainVisibleContentPositionConfig.size && paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
|
|
3316
4438
|
if (state.scroll < 0) {
|
|
3317
4439
|
paddingDiff += state.scroll;
|
|
3318
4440
|
}
|
|
3319
|
-
requestAdjust(ctx,
|
|
4441
|
+
requestAdjust(ctx, paddingDiff);
|
|
3320
4442
|
}
|
|
3321
4443
|
};
|
|
3322
4444
|
if (isFirstLocal) {
|
|
3323
|
-
initializeStateVars();
|
|
4445
|
+
initializeStateVars(false);
|
|
3324
4446
|
updateItemPositions(
|
|
3325
4447
|
ctx,
|
|
3326
|
-
state,
|
|
3327
4448
|
/*dataChanged*/
|
|
3328
4449
|
true
|
|
3329
4450
|
);
|
|
3330
4451
|
}
|
|
4452
|
+
const resolveInitialScrollOffset = useCallback((initialScroll) => {
|
|
4453
|
+
var _a4;
|
|
4454
|
+
if (state.initialScrollUsesOffset) {
|
|
4455
|
+
return clampScrollOffset(ctx, (_a4 = initialScroll.contentOffset) != null ? _a4 : 0);
|
|
4456
|
+
}
|
|
4457
|
+
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
|
|
4458
|
+
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
|
|
4459
|
+
return clampScrollOffset(ctx, resolvedOffset, initialScroll);
|
|
4460
|
+
}, []);
|
|
4461
|
+
const finishInitialScrollWithoutScroll = useCallback(() => {
|
|
4462
|
+
refState.current.initialAnchor = void 0;
|
|
4463
|
+
refState.current.initialScroll = void 0;
|
|
4464
|
+
state.initialAnchor = void 0;
|
|
4465
|
+
state.initialScroll = void 0;
|
|
4466
|
+
state.initialScrollUsesOffset = false;
|
|
4467
|
+
state.initialScrollLastTarget = void 0;
|
|
4468
|
+
state.initialScrollLastTargetUsesOffset = false;
|
|
4469
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
4470
|
+
}, []);
|
|
4471
|
+
const setActiveInitialScrollTarget = useCallback(
|
|
4472
|
+
(target, options) => {
|
|
4473
|
+
var _a4;
|
|
4474
|
+
const usesOffset = !!(options == null ? void 0 : options.usesOffset);
|
|
4475
|
+
state.initialScrollUsesOffset = usesOffset;
|
|
4476
|
+
state.initialScrollLastTarget = target;
|
|
4477
|
+
state.initialScrollLastTargetUsesOffset = usesOffset;
|
|
4478
|
+
refState.current.initialScroll = target;
|
|
4479
|
+
state.initialScroll = target;
|
|
4480
|
+
if ((options == null ? void 0 : options.resetDidFinish) && state.didFinishInitialScroll) {
|
|
4481
|
+
state.didFinishInitialScroll = false;
|
|
4482
|
+
}
|
|
4483
|
+
if (!(options == null ? void 0 : options.syncAnchor)) {
|
|
4484
|
+
return;
|
|
4485
|
+
}
|
|
4486
|
+
if (!IsNewArchitecture && !usesOffset && target.index !== void 0 && target.viewPosition !== void 0) {
|
|
4487
|
+
state.initialAnchor = {
|
|
4488
|
+
attempts: 0,
|
|
4489
|
+
index: target.index,
|
|
4490
|
+
settledTicks: 0,
|
|
4491
|
+
viewOffset: (_a4 = target.viewOffset) != null ? _a4 : 0,
|
|
4492
|
+
viewPosition: target.viewPosition
|
|
4493
|
+
};
|
|
4494
|
+
}
|
|
4495
|
+
},
|
|
4496
|
+
[]
|
|
4497
|
+
);
|
|
4498
|
+
const shouldFinishInitialScrollAtOrigin = useCallback(
|
|
4499
|
+
(initialScroll, offset) => {
|
|
4500
|
+
var _a4, _b2, _c2;
|
|
4501
|
+
if (offset !== 0 || initialScrollAtEnd) {
|
|
4502
|
+
return false;
|
|
4503
|
+
}
|
|
4504
|
+
if (state.initialScrollUsesOffset) {
|
|
4505
|
+
return Math.abs((_a4 = initialScroll.contentOffset) != null ? _a4 : 0) <= 1;
|
|
4506
|
+
}
|
|
4507
|
+
return initialScroll.index === 0 && ((_b2 = initialScroll.viewPosition) != null ? _b2 : 0) === 0 && Math.abs((_c2 = initialScroll.viewOffset) != null ? _c2 : 0) <= 1;
|
|
4508
|
+
},
|
|
4509
|
+
[initialScrollAtEnd]
|
|
4510
|
+
);
|
|
4511
|
+
const shouldFinishEmptyInitialScrollAtEnd = useCallback(
|
|
4512
|
+
(initialScroll, offset) => {
|
|
4513
|
+
return dataProp.length === 0 && initialScrollAtEnd && offset === 0 && initialScroll.viewPosition === 1;
|
|
4514
|
+
},
|
|
4515
|
+
[dataProp.length, initialScrollAtEnd]
|
|
4516
|
+
);
|
|
4517
|
+
const shouldRearmFinishedEmptyInitialScrollAtEnd = useCallback(
|
|
4518
|
+
(initialScroll) => {
|
|
4519
|
+
var _a4;
|
|
4520
|
+
return !!(state.didFinishInitialScroll && dataProp.length > 0 && initialScroll && !state.initialScrollUsesOffset && initialScroll.index === 0 && initialScroll.viewPosition === 1 && ((_a4 = initialScroll.contentOffset) != null ? _a4 : 0) === 0);
|
|
4521
|
+
},
|
|
4522
|
+
[dataProp.length]
|
|
4523
|
+
);
|
|
3331
4524
|
const initialContentOffset = useMemo(() => {
|
|
3332
|
-
var _a4
|
|
3333
|
-
|
|
3334
|
-
|
|
4525
|
+
var _a4;
|
|
4526
|
+
let value;
|
|
4527
|
+
const { initialScroll, initialAnchor } = refState.current;
|
|
4528
|
+
if (initialScroll) {
|
|
4529
|
+
if (!state.initialScrollUsesOffset && !IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
|
|
4530
|
+
refState.current.initialAnchor = {
|
|
4531
|
+
attempts: 0,
|
|
4532
|
+
index: initialScroll.index,
|
|
4533
|
+
settledTicks: 0,
|
|
4534
|
+
viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
|
|
4535
|
+
viewPosition: initialScroll.viewPosition
|
|
4536
|
+
};
|
|
4537
|
+
}
|
|
4538
|
+
if (initialScroll.contentOffset !== void 0) {
|
|
4539
|
+
value = initialScroll.contentOffset;
|
|
4540
|
+
} else {
|
|
4541
|
+
const clampedOffset = resolveInitialScrollOffset(initialScroll);
|
|
4542
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
4543
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
4544
|
+
usesOffset: state.initialScrollUsesOffset
|
|
4545
|
+
});
|
|
4546
|
+
value = clampedOffset;
|
|
4547
|
+
}
|
|
4548
|
+
} else {
|
|
3335
4549
|
refState.current.initialAnchor = void 0;
|
|
3336
|
-
|
|
3337
|
-
}
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
};
|
|
4550
|
+
value = 0;
|
|
4551
|
+
}
|
|
4552
|
+
const hasPendingDataDependentInitialScroll = !!initialScroll && dataProp.length === 0 && !shouldFinishInitialScrollAtOrigin(initialScroll, value) && !shouldFinishEmptyInitialScrollAtEnd(initialScroll, value);
|
|
4553
|
+
if (!value && !hasPendingDataDependentInitialScroll) {
|
|
4554
|
+
if (initialScroll && shouldFinishInitialScrollAtOrigin(initialScroll, value)) {
|
|
4555
|
+
finishInitialScrollWithoutScroll();
|
|
4556
|
+
} else {
|
|
4557
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
4558
|
+
}
|
|
3346
4559
|
}
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
}
|
|
3350
|
-
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
|
|
3351
|
-
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
|
|
3352
|
-
let clampedOffset = resolvedOffset;
|
|
3353
|
-
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
3354
|
-
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
3355
|
-
clampedOffset = Math.min(clampedOffset, maxOffset);
|
|
3356
|
-
}
|
|
3357
|
-
clampedOffset = Math.max(0, clampedOffset);
|
|
3358
|
-
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
3359
|
-
refState.current.initialScroll = updatedInitialScroll;
|
|
3360
|
-
state.initialScroll = updatedInitialScroll;
|
|
3361
|
-
refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
|
|
3362
|
-
return clampedOffset;
|
|
3363
|
-
}, [renderNum]);
|
|
4560
|
+
return value;
|
|
4561
|
+
}, []);
|
|
3364
4562
|
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3365
4563
|
refState.current.lastBatchingAction = Date.now();
|
|
3366
4564
|
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
@@ -3369,41 +4567,192 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3369
4567
|
"Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
|
|
3370
4568
|
);
|
|
3371
4569
|
refState.current.sizes.clear();
|
|
3372
|
-
refState.current.positions.
|
|
4570
|
+
refState.current.positions.length = 0;
|
|
3373
4571
|
refState.current.totalSize = 0;
|
|
3374
4572
|
set$(ctx, "totalSize", 0);
|
|
3375
4573
|
}
|
|
3376
4574
|
}
|
|
3377
|
-
const
|
|
3378
|
-
|
|
3379
|
-
const
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
4575
|
+
const doInitialScroll = useCallback((options) => {
|
|
4576
|
+
var _a4, _b2;
|
|
4577
|
+
const allowPostFinishRetry = !!(options == null ? void 0 : options.allowPostFinishRetry);
|
|
4578
|
+
const { didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
|
|
4579
|
+
const initialScroll = (_a4 = state.initialScroll) != null ? _a4 : allowPostFinishRetry ? state.initialScrollLastTarget : void 0;
|
|
4580
|
+
const isInitialScrollInProgress = !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll);
|
|
4581
|
+
const needsContainerLayoutForInitialScroll = !state.initialScrollUsesOffset;
|
|
4582
|
+
const shouldWaitForInitialLayout = waitForInitialLayout && needsContainerLayoutForInitialScroll && !queuedInitialLayout && !allowPostFinishRetry && !isInitialScrollInProgress;
|
|
4583
|
+
if (!initialScroll || shouldWaitForInitialLayout || didFinishInitialScroll && !allowPostFinishRetry || scrollingTo && !isInitialScrollInProgress) {
|
|
4584
|
+
return;
|
|
4585
|
+
}
|
|
4586
|
+
if (allowPostFinishRetry && state.initialScrollLastTargetUsesOffset) {
|
|
4587
|
+
return;
|
|
4588
|
+
}
|
|
4589
|
+
const didMoveAwayFromInitialTarget = allowPostFinishRetry && initialScroll.contentOffset !== void 0 && Math.abs(state.scroll - initialScroll.contentOffset) > 1;
|
|
4590
|
+
if (didMoveAwayFromInitialTarget) {
|
|
4591
|
+
state.initialScrollRetryWindowUntil = 0;
|
|
4592
|
+
return;
|
|
4593
|
+
}
|
|
4594
|
+
const offset = resolveInitialScrollOffset(initialScroll);
|
|
4595
|
+
const activeInitialTargetOffset = isInitialScrollInProgress ? (_b2 = scrollingTo.targetOffset) != null ? _b2 : scrollingTo.offset : void 0;
|
|
4596
|
+
const didOffsetChange = initialScroll.contentOffset === void 0 || Math.abs(initialScroll.contentOffset - offset) > 1;
|
|
4597
|
+
const didActiveInitialTargetChange = activeInitialTargetOffset !== void 0 && Math.abs(activeInitialTargetOffset - offset) > 1;
|
|
4598
|
+
if (!didOffsetChange && (allowPostFinishRetry || isInitialScrollInProgress && !didActiveInitialTargetChange)) {
|
|
4599
|
+
return;
|
|
4600
|
+
}
|
|
4601
|
+
if (didOffsetChange) {
|
|
4602
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: offset };
|
|
4603
|
+
if (!state.initialScrollUsesOffset) {
|
|
4604
|
+
state.initialScrollLastTarget = updatedInitialScroll;
|
|
4605
|
+
state.initialScrollLastTargetUsesOffset = false;
|
|
4606
|
+
if (state.initialScroll) {
|
|
4607
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
4608
|
+
state.initialScroll = updatedInitialScroll;
|
|
3385
4609
|
}
|
|
3386
|
-
} else {
|
|
3387
|
-
setTimeout(doInitialScroll, 17);
|
|
3388
4610
|
}
|
|
3389
4611
|
}
|
|
4612
|
+
const hasMeasuredScrollLayout = !!state.lastLayout && state.scrollLength > 0;
|
|
4613
|
+
const shouldForceNativeInitialScroll = state.initialScrollUsesOffset && hasMeasuredScrollLayout || allowPostFinishRetry || !!queuedInitialLayout || isInitialScrollInProgress && didOffsetChange;
|
|
4614
|
+
performInitialScroll(ctx, {
|
|
4615
|
+
forceScroll: shouldForceNativeInitialScroll,
|
|
4616
|
+
initialScrollUsesOffset: state.initialScrollUsesOffset,
|
|
4617
|
+
resolvedOffset: offset,
|
|
4618
|
+
target: initialScroll
|
|
4619
|
+
});
|
|
3390
4620
|
}, []);
|
|
3391
|
-
|
|
4621
|
+
useLayoutEffect(() => {
|
|
3392
4622
|
var _a4;
|
|
3393
|
-
const
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
4623
|
+
const previousDataLength = state.initialScrollPreviousDataLength;
|
|
4624
|
+
state.initialScrollPreviousDataLength = dataProp.length;
|
|
4625
|
+
if (previousDataLength !== 0 || dataProp.length === 0 || !state.initialScroll || !state.queuedInitialLayout) {
|
|
4626
|
+
return;
|
|
4627
|
+
}
|
|
4628
|
+
if (initialScrollAtEnd) {
|
|
4629
|
+
const lastIndex = Math.max(0, dataProp.length - 1);
|
|
4630
|
+
const initialScroll = state.initialScroll;
|
|
4631
|
+
const shouldRearm = shouldRearmFinishedEmptyInitialScrollAtEnd(initialScroll);
|
|
4632
|
+
if (state.didFinishInitialScroll && !shouldRearm) {
|
|
4633
|
+
return;
|
|
4634
|
+
}
|
|
4635
|
+
if (initialScroll && !state.initialScrollUsesOffset && initialScroll.index === lastIndex && initialScroll.viewPosition === 1 && !shouldRearm) {
|
|
4636
|
+
return;
|
|
4637
|
+
}
|
|
4638
|
+
const updatedInitialScroll = {
|
|
4639
|
+
contentOffset: void 0,
|
|
4640
|
+
index: lastIndex,
|
|
4641
|
+
viewOffset: (_a4 = initialScroll == null ? void 0 : initialScroll.viewOffset) != null ? _a4 : -stylePaddingBottomState,
|
|
4642
|
+
viewPosition: 1
|
|
4643
|
+
};
|
|
4644
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
4645
|
+
resetDidFinish: shouldRearm,
|
|
4646
|
+
syncAnchor: true
|
|
3401
4647
|
});
|
|
4648
|
+
doInitialScroll();
|
|
4649
|
+
return;
|
|
4650
|
+
}
|
|
4651
|
+
if (state.didFinishInitialScroll) {
|
|
4652
|
+
return;
|
|
4653
|
+
}
|
|
4654
|
+
doInitialScroll();
|
|
4655
|
+
}, [
|
|
4656
|
+
dataProp.length,
|
|
4657
|
+
doInitialScroll,
|
|
4658
|
+
initialScrollAtEnd,
|
|
4659
|
+
shouldRearmFinishedEmptyInitialScrollAtEnd,
|
|
4660
|
+
stylePaddingBottomState
|
|
4661
|
+
]);
|
|
4662
|
+
useLayoutEffect(() => {
|
|
4663
|
+
var _a4;
|
|
4664
|
+
if (!initialScrollAtEnd) {
|
|
4665
|
+
return;
|
|
4666
|
+
}
|
|
4667
|
+
const lastIndex = Math.max(0, dataProp.length - 1);
|
|
4668
|
+
const initialScroll = state.initialScroll;
|
|
4669
|
+
const shouldRearm = shouldRearmFinishedEmptyInitialScrollAtEnd(initialScroll);
|
|
4670
|
+
if (state.didFinishInitialScroll && !shouldRearm) {
|
|
4671
|
+
return;
|
|
4672
|
+
}
|
|
4673
|
+
if (shouldRearm) {
|
|
4674
|
+
state.didFinishInitialScroll = false;
|
|
3402
4675
|
}
|
|
3403
|
-
|
|
4676
|
+
if (initialScroll && !state.initialScrollUsesOffset && initialScroll.index === lastIndex && initialScroll.viewPosition === 1 && !shouldRearm) {
|
|
4677
|
+
return;
|
|
4678
|
+
}
|
|
4679
|
+
const updatedInitialScroll = {
|
|
4680
|
+
contentOffset: void 0,
|
|
4681
|
+
index: lastIndex,
|
|
4682
|
+
viewOffset: (_a4 = initialScroll == null ? void 0 : initialScroll.viewOffset) != null ? _a4 : -stylePaddingBottomState,
|
|
4683
|
+
viewPosition: 1
|
|
4684
|
+
};
|
|
4685
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
4686
|
+
resetDidFinish: shouldRearm,
|
|
4687
|
+
syncAnchor: true
|
|
4688
|
+
});
|
|
4689
|
+
doInitialScroll();
|
|
4690
|
+
}, [
|
|
4691
|
+
dataProp.length,
|
|
4692
|
+
doInitialScroll,
|
|
4693
|
+
initialScrollAtEnd,
|
|
4694
|
+
shouldRearmFinishedEmptyInitialScrollAtEnd,
|
|
4695
|
+
stylePaddingBottomState
|
|
4696
|
+
]);
|
|
4697
|
+
const onLayoutFooter = useCallback(
|
|
4698
|
+
(layout) => {
|
|
4699
|
+
var _a4;
|
|
4700
|
+
if (!initialScrollAtEnd) {
|
|
4701
|
+
return;
|
|
4702
|
+
}
|
|
4703
|
+
const { initialScroll } = state;
|
|
4704
|
+
if (!initialScroll) {
|
|
4705
|
+
return;
|
|
4706
|
+
}
|
|
4707
|
+
const lastIndex = Math.max(0, dataProp.length - 1);
|
|
4708
|
+
if (initialScroll.index !== lastIndex || initialScroll.viewPosition !== 1) {
|
|
4709
|
+
return;
|
|
4710
|
+
}
|
|
4711
|
+
const footerSize = layout[horizontal ? "width" : "height"];
|
|
4712
|
+
const viewOffset = -stylePaddingBottomState - footerSize;
|
|
4713
|
+
if (initialScroll.viewOffset !== viewOffset) {
|
|
4714
|
+
const previousTargetOffset = (_a4 = initialScroll.contentOffset) != null ? _a4 : resolveInitialScrollOffset(initialScroll);
|
|
4715
|
+
const didMoveAwayFromFinishedInitialTarget = state.didFinishInitialScroll && Math.abs(state.scroll - previousTargetOffset) > 1;
|
|
4716
|
+
if (didMoveAwayFromFinishedInitialTarget) {
|
|
4717
|
+
return;
|
|
4718
|
+
}
|
|
4719
|
+
const updatedInitialScroll = { ...initialScroll, viewOffset };
|
|
4720
|
+
setActiveInitialScrollTarget(updatedInitialScroll, {
|
|
4721
|
+
resetDidFinish: true
|
|
4722
|
+
});
|
|
4723
|
+
doInitialScroll();
|
|
4724
|
+
}
|
|
4725
|
+
},
|
|
4726
|
+
[
|
|
4727
|
+
dataProp.length,
|
|
4728
|
+
doInitialScroll,
|
|
4729
|
+
horizontal,
|
|
4730
|
+
initialScrollAtEnd,
|
|
4731
|
+
resolveInitialScrollOffset,
|
|
4732
|
+
stylePaddingBottomState
|
|
4733
|
+
]
|
|
4734
|
+
);
|
|
3404
4735
|
const onLayoutChange = useCallback((layout) => {
|
|
4736
|
+
var _a4;
|
|
4737
|
+
handleLayout(ctx, layout, setCanRender);
|
|
4738
|
+
const SCROLL_LENGTH_RETRY_WINDOW_MS = 600;
|
|
4739
|
+
const now = Date.now();
|
|
4740
|
+
const didFinishInitialScroll = !!state.didFinishInitialScroll;
|
|
4741
|
+
if (didFinishInitialScroll && !state.initialScrollLastDidFinish) {
|
|
4742
|
+
state.initialScrollRetryWindowUntil = now + SCROLL_LENGTH_RETRY_WINDOW_MS;
|
|
4743
|
+
}
|
|
4744
|
+
state.initialScrollLastDidFinish = didFinishInitialScroll;
|
|
4745
|
+
const previousScrollLength = state.initialScrollRetryLastLength;
|
|
4746
|
+
const currentScrollLength = state.scrollLength;
|
|
4747
|
+
const didScrollLengthChange = previousScrollLength === void 0 || Math.abs(currentScrollLength - previousScrollLength) > 1;
|
|
4748
|
+
if (didScrollLengthChange) {
|
|
4749
|
+
state.initialScrollRetryLastLength = currentScrollLength;
|
|
4750
|
+
}
|
|
4751
|
+
if (didFinishInitialScroll && didScrollLengthChange && now <= state.initialScrollRetryWindowUntil && !state.initialScrollLastTargetUsesOffset && ((_a4 = state.initialScrollLastTarget) == null ? void 0 : _a4.index) !== void 0) {
|
|
4752
|
+
doInitialScroll({ allowPostFinishRetry: true });
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
3405
4755
|
doInitialScroll();
|
|
3406
|
-
handleLayout(ctx, state, layout, setCanRender);
|
|
3407
4756
|
}, []);
|
|
3408
4757
|
const { onLayout } = useOnLayoutSync({
|
|
3409
4758
|
onLayoutChange,
|
|
@@ -3413,7 +4762,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3413
4762
|
});
|
|
3414
4763
|
useLayoutEffect(() => {
|
|
3415
4764
|
if (snapToIndices) {
|
|
3416
|
-
updateSnapToOffsets(ctx
|
|
4765
|
+
updateSnapToOffsets(ctx);
|
|
3417
4766
|
}
|
|
3418
4767
|
}, [snapToIndices]);
|
|
3419
4768
|
useLayoutEffect(() => {
|
|
@@ -3423,24 +4772,50 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3423
4772
|
isFirst,
|
|
3424
4773
|
props: { data }
|
|
3425
4774
|
} = state;
|
|
3426
|
-
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx
|
|
4775
|
+
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
|
|
3427
4776
|
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3428
|
-
checkResetContainers(ctx,
|
|
4777
|
+
checkResetContainers(ctx, data);
|
|
3429
4778
|
}
|
|
3430
4779
|
state.didColumnsChange = false;
|
|
3431
4780
|
state.didDataChange = false;
|
|
3432
4781
|
state.isFirst = false;
|
|
3433
4782
|
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3434
4783
|
useLayoutEffect(() => {
|
|
4784
|
+
var _a4;
|
|
3435
4785
|
set$(ctx, "extraData", extraData);
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
4786
|
+
const didToggleOverride = prevHasOverrideItemLayout.current !== hasOverrideItemLayout;
|
|
4787
|
+
prevHasOverrideItemLayout.current = hasOverrideItemLayout;
|
|
4788
|
+
if ((hasOverrideItemLayout || didToggleOverride) && numColumnsProp > 1) {
|
|
4789
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { forceFullItemPositions: true });
|
|
4790
|
+
}
|
|
4791
|
+
}, [extraData, hasOverrideItemLayout, numColumnsProp]);
|
|
4792
|
+
useLayoutEffect(
|
|
4793
|
+
() => initializeStateVars(true),
|
|
4794
|
+
[dataVersion, memoizedLastItemKeys.join(","), numColumnsProp, stylePaddingBottomState, stylePaddingTopState]
|
|
4795
|
+
);
|
|
4796
|
+
useEffect(() => {
|
|
4797
|
+
if (!onMetricsChange) {
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
let lastMetrics;
|
|
4801
|
+
const emitMetrics = () => {
|
|
4802
|
+
const metrics = {
|
|
4803
|
+
footerSize: peek$(ctx, "footerSize") || 0,
|
|
4804
|
+
headerSize: peek$(ctx, "headerSize") || 0
|
|
4805
|
+
};
|
|
4806
|
+
if (!lastMetrics || metrics.headerSize !== lastMetrics.headerSize || metrics.footerSize !== lastMetrics.footerSize) {
|
|
4807
|
+
lastMetrics = metrics;
|
|
4808
|
+
onMetricsChange(metrics);
|
|
4809
|
+
}
|
|
4810
|
+
};
|
|
4811
|
+
emitMetrics();
|
|
4812
|
+
const unsubscribe = [listen$(ctx, "headerSize", emitMetrics), listen$(ctx, "footerSize", emitMetrics)];
|
|
4813
|
+
return () => {
|
|
4814
|
+
for (const unsub of unsubscribe) {
|
|
4815
|
+
unsub();
|
|
4816
|
+
}
|
|
4817
|
+
};
|
|
4818
|
+
}, [ctx, onMetricsChange]);
|
|
3444
4819
|
useEffect(() => {
|
|
3445
4820
|
const viewability = setupViewability({
|
|
3446
4821
|
onViewableItemsChanged,
|
|
@@ -3450,53 +4825,52 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3450
4825
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
3451
4826
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3452
4827
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3453
|
-
|
|
4828
|
+
if (!IsNewArchitecture) {
|
|
4829
|
+
useInit(() => {
|
|
4830
|
+
doInitialAllocateContainers(ctx);
|
|
4831
|
+
});
|
|
4832
|
+
}
|
|
4833
|
+
useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
|
|
3454
4834
|
if (Platform2.OS === "web") {
|
|
3455
4835
|
useEffect(doInitialScroll, []);
|
|
3456
4836
|
}
|
|
3457
4837
|
const fns = useMemo(
|
|
3458
4838
|
() => ({
|
|
3459
|
-
getRenderedItem: (key) => getRenderedItem(ctx,
|
|
3460
|
-
|
|
3461
|
-
|
|
4839
|
+
getRenderedItem: (key) => getRenderedItem(ctx, key),
|
|
4840
|
+
onMomentumScrollEnd: (event) => {
|
|
4841
|
+
checkFinishedScrollFallback(ctx);
|
|
4842
|
+
if (onMomentumScrollEnd) {
|
|
4843
|
+
onMomentumScrollEnd(event);
|
|
4844
|
+
}
|
|
4845
|
+
},
|
|
4846
|
+
onScroll: (event) => onScroll(ctx, event),
|
|
4847
|
+
updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
|
|
3462
4848
|
}),
|
|
3463
4849
|
[]
|
|
3464
4850
|
);
|
|
3465
4851
|
const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
|
|
4852
|
+
const refreshControlElement = refreshControl;
|
|
3466
4853
|
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
|
|
3467
4854
|
ListComponent,
|
|
3468
4855
|
{
|
|
3469
|
-
...
|
|
4856
|
+
...restProps,
|
|
3470
4857
|
alignItemsAtEnd,
|
|
3471
4858
|
canRender,
|
|
3472
4859
|
contentContainerStyle,
|
|
4860
|
+
contentInset,
|
|
3473
4861
|
getRenderedItem: fns.getRenderedItem,
|
|
3474
4862
|
horizontal,
|
|
3475
4863
|
initialContentOffset,
|
|
3476
4864
|
ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
|
|
3477
4865
|
ListHeaderComponent,
|
|
3478
|
-
maintainVisibleContentPosition,
|
|
3479
4866
|
onLayout,
|
|
3480
|
-
|
|
3481
|
-
onMomentumScrollEnd:
|
|
3482
|
-
if (IsNewArchitecture) {
|
|
3483
|
-
requestAnimationFrame(() => {
|
|
3484
|
-
finishScrollTo(ctx, refState.current);
|
|
3485
|
-
});
|
|
3486
|
-
} else {
|
|
3487
|
-
setTimeout(() => {
|
|
3488
|
-
finishScrollTo(ctx, refState.current);
|
|
3489
|
-
}, 1e3);
|
|
3490
|
-
}
|
|
3491
|
-
if (onMomentumScrollEnd) {
|
|
3492
|
-
onMomentumScrollEnd(event);
|
|
3493
|
-
}
|
|
3494
|
-
},
|
|
4867
|
+
onLayoutFooter,
|
|
4868
|
+
onMomentumScrollEnd: fns.onMomentumScrollEnd,
|
|
3495
4869
|
onScroll: onScrollHandler,
|
|
3496
4870
|
recycleItems,
|
|
3497
|
-
refreshControl:
|
|
3498
|
-
progressViewOffset: (
|
|
3499
|
-
}) :
|
|
4871
|
+
refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControlElement, {
|
|
4872
|
+
progressViewOffset: ((_g = refreshControlElement.props.progressViewOffset) != null ? _g : 0) + stylePaddingTopState
|
|
4873
|
+
}) : refreshControlElement : onRefresh && /* @__PURE__ */ React2.createElement(
|
|
3500
4874
|
RefreshControl,
|
|
3501
4875
|
{
|
|
3502
4876
|
onRefresh,
|
|
@@ -3505,15 +4879,25 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3505
4879
|
}
|
|
3506
4880
|
),
|
|
3507
4881
|
refScrollView: combinedRef,
|
|
3508
|
-
|
|
3509
|
-
|
|
4882
|
+
renderScrollComponent,
|
|
4883
|
+
scrollAdjustHandler: (_h = refState.current) == null ? void 0 : _h.scrollAdjustHandler,
|
|
4884
|
+
scrollEventThrottle: 0,
|
|
3510
4885
|
snapToIndices,
|
|
3511
4886
|
stickyHeaderIndices,
|
|
3512
4887
|
style,
|
|
3513
4888
|
updateItemSize: fns.updateItemSize,
|
|
4889
|
+
useWindowScroll: useWindowScrollResolved,
|
|
3514
4890
|
waitForInitialLayout
|
|
3515
4891
|
}
|
|
3516
|
-
), IS_DEV && ENABLE_DEBUG_VIEW
|
|
4892
|
+
), IS_DEV && ENABLE_DEBUG_VIEW);
|
|
3517
4893
|
});
|
|
3518
4894
|
|
|
3519
|
-
|
|
4895
|
+
// src/index.ts
|
|
4896
|
+
var LegendList3 = LegendList;
|
|
4897
|
+
if (IS_DEV) {
|
|
4898
|
+
console.warn(
|
|
4899
|
+
"[legend-list] Legend List 3.0 deprecates the root import (@legendapp/list) because it now supports both react and react-native. The root import is fully functional, but please switch to platform-specific imports for strict platform types:\n - React Native: @legendapp/list/react-native\n - React: @legendapp/list/react\nSee README for details."
|
|
4900
|
+
);
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4903
|
+
export { LegendList3 as LegendList, typedForwardRef, typedMemo2 as typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|