@legendapp/list 2.0.0-next.0 → 2.0.0-next.1
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/index.d.mts +48 -6
- package/index.d.ts +48 -6
- package/index.js +1395 -1238
- package/index.mjs +1347 -1190
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React3 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
5
|
var shim = require('use-sync-external-store/shim');
|
|
6
6
|
|
|
@@ -22,12 +22,12 @@ function _interopNamespace(e) {
|
|
|
22
22
|
return Object.freeze(n);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
var
|
|
25
|
+
var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
|
|
26
26
|
|
|
27
27
|
// src/LegendList.tsx
|
|
28
|
-
var ContextState =
|
|
28
|
+
var ContextState = React3__namespace.createContext(null);
|
|
29
29
|
function StateProvider({ children }) {
|
|
30
|
-
const [value] =
|
|
30
|
+
const [value] = React3__namespace.useState(() => ({
|
|
31
31
|
listeners: /* @__PURE__ */ new Map(),
|
|
32
32
|
values: /* @__PURE__ */ new Map([
|
|
33
33
|
["alignItemsPaddingTop", 0],
|
|
@@ -41,10 +41,10 @@ function StateProvider({ children }) {
|
|
|
41
41
|
columnWrapperStyle: void 0,
|
|
42
42
|
viewRefs: /* @__PURE__ */ new Map()
|
|
43
43
|
}));
|
|
44
|
-
return /* @__PURE__ */
|
|
44
|
+
return /* @__PURE__ */ React3__namespace.createElement(ContextState.Provider, { value }, children);
|
|
45
45
|
}
|
|
46
46
|
function useStateContext() {
|
|
47
|
-
return
|
|
47
|
+
return React3__namespace.useContext(ContextState);
|
|
48
48
|
}
|
|
49
49
|
function createSelectorFunctionsArr(ctx, signalNames) {
|
|
50
50
|
let lastValues = [];
|
|
@@ -114,23 +114,23 @@ function getContentSize(ctx) {
|
|
|
114
114
|
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
115
115
|
}
|
|
116
116
|
function useArr$(signalNames) {
|
|
117
|
-
const ctx =
|
|
118
|
-
const { subscribe, get } =
|
|
117
|
+
const ctx = React3__namespace.useContext(ContextState);
|
|
118
|
+
const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
119
119
|
const value = shim.useSyncExternalStore(subscribe, get);
|
|
120
120
|
return value;
|
|
121
121
|
}
|
|
122
122
|
function useSelector$(signalName, selector) {
|
|
123
|
-
const ctx =
|
|
124
|
-
const { subscribe, get } =
|
|
123
|
+
const ctx = React3__namespace.useContext(ContextState);
|
|
124
|
+
const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
|
|
125
125
|
const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
|
|
126
126
|
return value;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
// src/DebugView.tsx
|
|
130
130
|
var DebugRow = ({ children }) => {
|
|
131
|
-
return /* @__PURE__ */
|
|
131
|
+
return /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
|
|
132
132
|
};
|
|
133
|
-
var DebugView =
|
|
133
|
+
var DebugView = React3__namespace.memo(function DebugView2({ state }) {
|
|
134
134
|
const ctx = useStateContext();
|
|
135
135
|
const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, numContainers = 0, numContainersPooled = 0] = useArr$([
|
|
136
136
|
"totalSize",
|
|
@@ -141,11 +141,11 @@ var DebugView = React2__namespace.memo(function DebugView2({ state }) {
|
|
|
141
141
|
"numContainersPooled"
|
|
142
142
|
]);
|
|
143
143
|
const contentSize = getContentSize(ctx);
|
|
144
|
-
const [, forceUpdate] =
|
|
144
|
+
const [, forceUpdate] = React3.useReducer((x) => x + 1, 0);
|
|
145
145
|
useInterval(() => {
|
|
146
146
|
forceUpdate();
|
|
147
147
|
}, 100);
|
|
148
|
-
return /* @__PURE__ */
|
|
148
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
149
149
|
reactNative.View,
|
|
150
150
|
{
|
|
151
151
|
style: {
|
|
@@ -161,18 +161,18 @@ var DebugView = React2__namespace.memo(function DebugView2({ state }) {
|
|
|
161
161
|
},
|
|
162
162
|
pointerEvents: "none"
|
|
163
163
|
},
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
-
/* @__PURE__ */
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, totalSize.toFixed(2))),
|
|
165
|
+
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, contentSize.toFixed(2))),
|
|
166
|
+
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, String(state.isAtEnd))),
|
|
167
|
+
/* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null),
|
|
168
|
+
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scrollAdjust.toFixed(2))),
|
|
169
|
+
/* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null),
|
|
170
|
+
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "RawScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, rawScroll.toFixed(2))),
|
|
171
|
+
/* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ComputedScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scroll.toFixed(2)))
|
|
172
172
|
);
|
|
173
173
|
});
|
|
174
174
|
function useInterval(callback, delay) {
|
|
175
|
-
|
|
175
|
+
React3.useEffect(() => {
|
|
176
176
|
const interval = setInterval(callback, delay);
|
|
177
177
|
return () => clearInterval(interval);
|
|
178
178
|
}, [delay]);
|
|
@@ -192,12 +192,12 @@ function warnDevOnce(id, text) {
|
|
|
192
192
|
console.warn(`[legend-list] ${text}`);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
+
function roundSize(size) {
|
|
196
|
+
return Math.floor(size * 8) / 8;
|
|
197
|
+
}
|
|
195
198
|
function isNullOrUndefined(value) {
|
|
196
199
|
return value === null || value === void 0;
|
|
197
200
|
}
|
|
198
|
-
function comparatorByDistance(a, b) {
|
|
199
|
-
return b.distance - a.distance;
|
|
200
|
-
}
|
|
201
201
|
function comparatorDefault(a, b) {
|
|
202
202
|
return a - b;
|
|
203
203
|
}
|
|
@@ -210,7 +210,7 @@ function extractPadding(style, contentContainerStyle, type) {
|
|
|
210
210
|
}
|
|
211
211
|
var symbolFirst = Symbol();
|
|
212
212
|
function useInit(cb) {
|
|
213
|
-
const refValue =
|
|
213
|
+
const refValue = React3.useRef(symbolFirst);
|
|
214
214
|
if (refValue.current === symbolFirst) {
|
|
215
215
|
refValue.current = cb();
|
|
216
216
|
}
|
|
@@ -218,10 +218,10 @@ function useInit(cb) {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
// src/ContextContainer.ts
|
|
221
|
-
var ContextContainer =
|
|
221
|
+
var ContextContainer = React3.createContext(null);
|
|
222
222
|
function useViewability(callback, configId) {
|
|
223
223
|
const ctx = useStateContext();
|
|
224
|
-
const { containerId } =
|
|
224
|
+
const { containerId } = React3.useContext(ContextContainer);
|
|
225
225
|
const key = containerId + (configId != null ? configId : "");
|
|
226
226
|
useInit(() => {
|
|
227
227
|
const value = ctx.mapViewabilityValues.get(key);
|
|
@@ -230,7 +230,7 @@ function useViewability(callback, configId) {
|
|
|
230
230
|
}
|
|
231
231
|
});
|
|
232
232
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
233
|
-
|
|
233
|
+
React3.useEffect(
|
|
234
234
|
() => () => {
|
|
235
235
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
236
236
|
},
|
|
@@ -239,7 +239,7 @@ function useViewability(callback, configId) {
|
|
|
239
239
|
}
|
|
240
240
|
function useViewabilityAmount(callback) {
|
|
241
241
|
const ctx = useStateContext();
|
|
242
|
-
const { containerId } =
|
|
242
|
+
const { containerId } = React3.useContext(ContextContainer);
|
|
243
243
|
useInit(() => {
|
|
244
244
|
const value = ctx.mapViewabilityAmountValues.get(containerId);
|
|
245
245
|
if (value) {
|
|
@@ -247,7 +247,7 @@ function useViewabilityAmount(callback) {
|
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
249
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
250
|
-
|
|
250
|
+
React3.useEffect(
|
|
251
251
|
() => () => {
|
|
252
252
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
253
253
|
},
|
|
@@ -255,12 +255,12 @@ function useViewabilityAmount(callback) {
|
|
|
255
255
|
);
|
|
256
256
|
}
|
|
257
257
|
function useRecyclingEffect(effect) {
|
|
258
|
-
const { index, value } =
|
|
259
|
-
const prevValues =
|
|
258
|
+
const { index, value } = React3.useContext(ContextContainer);
|
|
259
|
+
const prevValues = React3.useRef({
|
|
260
260
|
prevIndex: void 0,
|
|
261
261
|
prevItem: void 0
|
|
262
262
|
});
|
|
263
|
-
|
|
263
|
+
React3.useEffect(() => {
|
|
264
264
|
let ret = void 0;
|
|
265
265
|
if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
|
|
266
266
|
ret = effect({
|
|
@@ -278,33 +278,34 @@ function useRecyclingEffect(effect) {
|
|
|
278
278
|
}, [index, value]);
|
|
279
279
|
}
|
|
280
280
|
function useRecyclingState(valueOrFun) {
|
|
281
|
-
const { index, value, itemKey, triggerLayout } =
|
|
282
|
-
const refState =
|
|
281
|
+
const { index, value, itemKey, triggerLayout } = React3.useContext(ContextContainer);
|
|
282
|
+
const refState = React3.useRef({
|
|
283
283
|
itemKey: null,
|
|
284
284
|
value: null
|
|
285
285
|
});
|
|
286
|
-
const [_, setRenderNum] =
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
286
|
+
const [_, setRenderNum] = React3.useState(0);
|
|
287
|
+
const state = refState.current;
|
|
288
|
+
if (state.itemKey !== itemKey) {
|
|
289
|
+
state.itemKey = itemKey;
|
|
290
|
+
state.value = isFunction(valueOrFun) ? valueOrFun({
|
|
290
291
|
index,
|
|
291
292
|
item: value,
|
|
292
293
|
prevIndex: void 0,
|
|
293
294
|
prevItem: void 0
|
|
294
295
|
}) : valueOrFun;
|
|
295
296
|
}
|
|
296
|
-
const setState =
|
|
297
|
+
const setState = React3.useCallback(
|
|
297
298
|
(newState) => {
|
|
298
|
-
|
|
299
|
+
state.value = isFunction(newState) ? newState(state.value) : newState;
|
|
299
300
|
setRenderNum((v) => v + 1);
|
|
300
301
|
triggerLayout();
|
|
301
302
|
},
|
|
302
|
-
[triggerLayout]
|
|
303
|
+
[triggerLayout, state]
|
|
303
304
|
);
|
|
304
|
-
return [
|
|
305
|
+
return [state.value, setState];
|
|
305
306
|
}
|
|
306
307
|
function useIsLastItem() {
|
|
307
|
-
const { itemKey } =
|
|
308
|
+
const { itemKey } = React3.useContext(ContextContainer);
|
|
308
309
|
const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
|
|
309
310
|
return isLast;
|
|
310
311
|
}
|
|
@@ -312,12 +313,19 @@ function useListScrollSize() {
|
|
|
312
313
|
const [scrollSize] = useArr$(["scrollSize"]);
|
|
313
314
|
return scrollSize;
|
|
314
315
|
}
|
|
315
|
-
var LeanViewComponent =
|
|
316
|
-
return
|
|
316
|
+
var LeanViewComponent = React3__namespace.forwardRef((props, ref) => {
|
|
317
|
+
return React3__namespace.createElement("RCTView", { ...props, ref });
|
|
317
318
|
});
|
|
318
319
|
LeanViewComponent.displayName = "RCTView";
|
|
319
320
|
var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
|
|
320
321
|
|
|
322
|
+
// src/Separator.tsx
|
|
323
|
+
function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
|
|
324
|
+
const [lastItemKeys] = useArr$(["lastItemKeys"]);
|
|
325
|
+
const isALastItem = lastItemKeys.includes(itemKey);
|
|
326
|
+
return isALastItem ? null : /* @__PURE__ */ React.createElement(ItemSeparatorComponent, { leadingItem });
|
|
327
|
+
}
|
|
328
|
+
|
|
321
329
|
// src/constants.ts
|
|
322
330
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
323
331
|
var ENABLE_DEVMODE = __DEV__ && false;
|
|
@@ -329,39 +337,37 @@ var Container = ({
|
|
|
329
337
|
id,
|
|
330
338
|
recycleItems,
|
|
331
339
|
horizontal,
|
|
332
|
-
getRenderedItem,
|
|
333
|
-
updateItemSize,
|
|
340
|
+
getRenderedItem: getRenderedItem2,
|
|
341
|
+
updateItemSize: updateItemSize2,
|
|
334
342
|
ItemSeparatorComponent
|
|
335
343
|
}) => {
|
|
336
344
|
const ctx = useStateContext();
|
|
337
345
|
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
338
|
-
const [column = 0, data, itemKey, position = POSITION_OUT_OF_VIEW, numColumns,
|
|
346
|
+
const [column = 0, data, itemKey, position = POSITION_OUT_OF_VIEW, numColumns, extraData] = useArr$([
|
|
339
347
|
`containerColumn${id}`,
|
|
340
348
|
`containerItemData${id}`,
|
|
341
349
|
`containerItemKey${id}`,
|
|
342
350
|
`containerPosition${id}`,
|
|
343
351
|
"numColumns",
|
|
344
|
-
"lastItemKeys",
|
|
345
352
|
"extraData"
|
|
346
353
|
]);
|
|
347
|
-
const refLastSize =
|
|
348
|
-
const ref =
|
|
349
|
-
const [layoutRenderCount, forceLayoutRender] =
|
|
354
|
+
const refLastSize = React3.useRef();
|
|
355
|
+
const ref = React3.useRef(null);
|
|
356
|
+
const [layoutRenderCount, forceLayoutRender] = React3.useState(0);
|
|
350
357
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
351
358
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
352
|
-
const isALastItem = lastItemKeys.includes(itemKey);
|
|
353
359
|
let didLayout = false;
|
|
354
360
|
let paddingStyles;
|
|
355
361
|
if (columnWrapperStyle) {
|
|
356
362
|
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
357
363
|
if (horizontal) {
|
|
358
364
|
paddingStyles = {
|
|
359
|
-
paddingRight:
|
|
365
|
+
paddingRight: columnGap || gap || void 0,
|
|
360
366
|
paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
|
|
361
367
|
};
|
|
362
368
|
} else {
|
|
363
369
|
paddingStyles = {
|
|
364
|
-
paddingBottom:
|
|
370
|
+
paddingBottom: rowGap || gap || void 0,
|
|
365
371
|
paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
|
|
366
372
|
};
|
|
367
373
|
}
|
|
@@ -381,15 +387,15 @@ var Container = ({
|
|
|
381
387
|
top: position,
|
|
382
388
|
...paddingStyles || {}
|
|
383
389
|
};
|
|
384
|
-
const renderedItemInfo =
|
|
385
|
-
() => itemKey !== void 0 ?
|
|
390
|
+
const renderedItemInfo = React3.useMemo(
|
|
391
|
+
() => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
|
|
386
392
|
[itemKey, data, extraData]
|
|
387
393
|
);
|
|
388
394
|
const { index, renderedItem } = renderedItemInfo || {};
|
|
389
|
-
const triggerLayout =
|
|
395
|
+
const triggerLayout = React3.useCallback(() => {
|
|
390
396
|
forceLayoutRender((v) => v + 1);
|
|
391
397
|
}, []);
|
|
392
|
-
const contextValue =
|
|
398
|
+
const contextValue = React3.useMemo(() => {
|
|
393
399
|
ctx.viewRefs.set(id, ref);
|
|
394
400
|
return { containerId: id, itemKey, index, value: data, triggerLayout };
|
|
395
401
|
}, [id, itemKey, index, data]);
|
|
@@ -401,7 +407,7 @@ var Container = ({
|
|
|
401
407
|
const size = layout[horizontal ? "width" : "height"];
|
|
402
408
|
const doUpdate = () => {
|
|
403
409
|
refLastSize.current = { width: layout.width, height: layout.height };
|
|
404
|
-
|
|
410
|
+
updateItemSize2(itemKey, layout);
|
|
405
411
|
};
|
|
406
412
|
if (IsNewArchitecture || size > 0) {
|
|
407
413
|
doUpdate();
|
|
@@ -414,24 +420,24 @@ var Container = ({
|
|
|
414
420
|
}
|
|
415
421
|
};
|
|
416
422
|
if (IsNewArchitecture) {
|
|
417
|
-
|
|
423
|
+
React3.useLayoutEffect(() => {
|
|
418
424
|
var _a, _b;
|
|
419
425
|
if (!isNullOrUndefined(itemKey)) {
|
|
420
426
|
const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
|
|
421
427
|
if (measured) {
|
|
422
428
|
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
423
429
|
if (size) {
|
|
424
|
-
|
|
430
|
+
updateItemSize2(itemKey, measured);
|
|
425
431
|
}
|
|
426
432
|
}
|
|
427
433
|
}
|
|
428
|
-
}, [itemKey, layoutRenderCount
|
|
434
|
+
}, [itemKey, layoutRenderCount]);
|
|
429
435
|
} else {
|
|
430
|
-
|
|
436
|
+
React3.useEffect(() => {
|
|
431
437
|
if (!isNullOrUndefined(itemKey)) {
|
|
432
438
|
const timeout = setTimeout(() => {
|
|
433
439
|
if (!didLayout && refLastSize.current) {
|
|
434
|
-
|
|
440
|
+
updateItemSize2(itemKey, refLastSize.current);
|
|
435
441
|
}
|
|
436
442
|
}, 16);
|
|
437
443
|
return () => {
|
|
@@ -440,12 +446,19 @@ var Container = ({
|
|
|
440
446
|
}
|
|
441
447
|
}, [itemKey]);
|
|
442
448
|
}
|
|
443
|
-
return /* @__PURE__ */
|
|
449
|
+
return /* @__PURE__ */ React3__namespace.createElement(LeanView, { style, onLayout, ref, key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
450
|
+
Separator,
|
|
451
|
+
{
|
|
452
|
+
itemKey,
|
|
453
|
+
ItemSeparatorComponent,
|
|
454
|
+
leadingItem: renderedItemInfo.item
|
|
455
|
+
}
|
|
456
|
+
)));
|
|
444
457
|
};
|
|
445
|
-
var typedForwardRef =
|
|
446
|
-
var typedMemo =
|
|
458
|
+
var typedForwardRef = React3.forwardRef;
|
|
459
|
+
var typedMemo = React3.memo;
|
|
447
460
|
var useAnimatedValue = (initialValue) => {
|
|
448
|
-
return
|
|
461
|
+
return React3.useRef(new reactNative.Animated.Value(initialValue)).current;
|
|
449
462
|
};
|
|
450
463
|
|
|
451
464
|
// src/useValue$.ts
|
|
@@ -454,7 +467,7 @@ function useValue$(key, params) {
|
|
|
454
467
|
const { getValue, delay } = params || {};
|
|
455
468
|
const ctx = useStateContext();
|
|
456
469
|
const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
|
|
457
|
-
|
|
470
|
+
React3.useMemo(() => {
|
|
458
471
|
let newValue = void 0;
|
|
459
472
|
let prevValue = void 0;
|
|
460
473
|
let didQueueTask = false;
|
|
@@ -491,8 +504,8 @@ var Containers = typedMemo(function Containers2({
|
|
|
491
504
|
recycleItems,
|
|
492
505
|
ItemSeparatorComponent,
|
|
493
506
|
waitForInitialLayout,
|
|
494
|
-
updateItemSize,
|
|
495
|
-
getRenderedItem
|
|
507
|
+
updateItemSize: updateItemSize2,
|
|
508
|
+
getRenderedItem: getRenderedItem2
|
|
496
509
|
}) {
|
|
497
510
|
const ctx = useStateContext();
|
|
498
511
|
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
@@ -506,15 +519,15 @@ var Containers = typedMemo(function Containers2({
|
|
|
506
519
|
const containers = [];
|
|
507
520
|
for (let i = 0; i < numContainers; i++) {
|
|
508
521
|
containers.push(
|
|
509
|
-
/* @__PURE__ */
|
|
522
|
+
/* @__PURE__ */ React3__namespace.createElement(
|
|
510
523
|
Container,
|
|
511
524
|
{
|
|
512
525
|
id: i,
|
|
513
526
|
key: i,
|
|
514
527
|
recycleItems,
|
|
515
528
|
horizontal,
|
|
516
|
-
getRenderedItem,
|
|
517
|
-
updateItemSize,
|
|
529
|
+
getRenderedItem: getRenderedItem2,
|
|
530
|
+
updateItemSize: updateItemSize2,
|
|
518
531
|
ItemSeparatorComponent
|
|
519
532
|
}
|
|
520
533
|
)
|
|
@@ -523,25 +536,31 @@ var Containers = typedMemo(function Containers2({
|
|
|
523
536
|
const style = horizontal ? { width: animSize, opacity: animOpacity, minHeight: otherAxisSize } : { height: animSize, opacity: animOpacity, minWidth: otherAxisSize };
|
|
524
537
|
if (columnWrapperStyle && numColumns > 1) {
|
|
525
538
|
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
539
|
+
const gapX = columnGap || gap || 0;
|
|
540
|
+
const gapY = rowGap || gap || 0;
|
|
526
541
|
if (horizontal) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
542
|
+
if (gapY) {
|
|
543
|
+
style.marginVertical = -gapY / 2;
|
|
544
|
+
}
|
|
545
|
+
if (gapX) {
|
|
546
|
+
style.marginRight = -gapX;
|
|
530
547
|
}
|
|
531
548
|
} else {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
549
|
+
if (gapX) {
|
|
550
|
+
style.marginHorizontal = -gapX;
|
|
551
|
+
}
|
|
552
|
+
if (gapY) {
|
|
553
|
+
style.marginBottom = -gapY;
|
|
535
554
|
}
|
|
536
555
|
}
|
|
537
556
|
}
|
|
538
|
-
return /* @__PURE__ */
|
|
557
|
+
return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style }, containers);
|
|
539
558
|
});
|
|
540
559
|
function ScrollAdjust() {
|
|
541
560
|
const bias = 1e7;
|
|
542
561
|
const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
|
|
543
562
|
const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0) + bias;
|
|
544
|
-
return /* @__PURE__ */
|
|
563
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
545
564
|
reactNative.View,
|
|
546
565
|
{
|
|
547
566
|
style: {
|
|
@@ -557,14 +576,14 @@ function ScrollAdjust() {
|
|
|
557
576
|
function useSyncLayout({
|
|
558
577
|
onChange
|
|
559
578
|
}) {
|
|
560
|
-
const ref =
|
|
561
|
-
const onLayout =
|
|
579
|
+
const ref = React3.useRef(null);
|
|
580
|
+
const onLayout = React3.useCallback(
|
|
562
581
|
(event) => {
|
|
563
582
|
onChange(event.nativeEvent.layout, false);
|
|
564
583
|
},
|
|
565
584
|
[onChange]
|
|
566
585
|
);
|
|
567
|
-
|
|
586
|
+
React3.useLayoutEffect(() => {
|
|
568
587
|
if (ref.current) {
|
|
569
588
|
ref.current.measure((x, y, width, height) => {
|
|
570
589
|
onChange({ x, y, width, height }, true);
|
|
@@ -576,21 +595,21 @@ function useSyncLayout({
|
|
|
576
595
|
|
|
577
596
|
// src/ListComponent.tsx
|
|
578
597
|
var getComponent = (Component) => {
|
|
579
|
-
if (
|
|
598
|
+
if (React3__namespace.isValidElement(Component)) {
|
|
580
599
|
return Component;
|
|
581
600
|
}
|
|
582
601
|
if (Component) {
|
|
583
|
-
return /* @__PURE__ */
|
|
602
|
+
return /* @__PURE__ */ React3__namespace.createElement(Component, null);
|
|
584
603
|
}
|
|
585
604
|
return null;
|
|
586
605
|
};
|
|
587
606
|
var Padding = () => {
|
|
588
607
|
const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
|
|
589
|
-
return /* @__PURE__ */
|
|
608
|
+
return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } });
|
|
590
609
|
};
|
|
591
610
|
var PaddingDevMode = () => {
|
|
592
611
|
const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
|
|
593
|
-
return /* @__PURE__ */
|
|
612
|
+
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
|
|
594
613
|
reactNative.Animated.View,
|
|
595
614
|
{
|
|
596
615
|
style: {
|
|
@@ -614,15 +633,15 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
614
633
|
ItemSeparatorComponent,
|
|
615
634
|
alignItemsAtEnd,
|
|
616
635
|
waitForInitialLayout,
|
|
617
|
-
|
|
636
|
+
onScroll: onScroll2,
|
|
618
637
|
onLayout,
|
|
619
638
|
ListHeaderComponent,
|
|
620
639
|
ListHeaderComponentStyle,
|
|
621
640
|
ListFooterComponent,
|
|
622
641
|
ListFooterComponentStyle,
|
|
623
642
|
ListEmptyComponent,
|
|
624
|
-
getRenderedItem,
|
|
625
|
-
updateItemSize,
|
|
643
|
+
getRenderedItem: getRenderedItem2,
|
|
644
|
+
updateItemSize: updateItemSize2,
|
|
626
645
|
refScrollView,
|
|
627
646
|
maintainVisibleContentPosition,
|
|
628
647
|
renderScrollComponent,
|
|
@@ -634,18 +653,18 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
634
653
|
const { onLayout: onLayoutHeaderSync, ref: refHeader } = useSyncLayout({
|
|
635
654
|
onChange: onLayoutHeader
|
|
636
655
|
});
|
|
637
|
-
const ScrollComponent = renderScrollComponent ?
|
|
638
|
-
() =>
|
|
656
|
+
const ScrollComponent = renderScrollComponent ? React3.useMemo(
|
|
657
|
+
() => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
639
658
|
[renderScrollComponent]
|
|
640
659
|
) : reactNative.ScrollView;
|
|
641
|
-
|
|
660
|
+
React3__namespace.useEffect(() => {
|
|
642
661
|
if (canRender) {
|
|
643
662
|
setTimeout(() => {
|
|
644
663
|
scrollAdjustHandler.setMounted();
|
|
645
664
|
}, 0);
|
|
646
665
|
}
|
|
647
666
|
}, [canRender]);
|
|
648
|
-
return /* @__PURE__ */
|
|
667
|
+
return /* @__PURE__ */ React3__namespace.createElement(
|
|
649
668
|
ScrollComponent,
|
|
650
669
|
{
|
|
651
670
|
...rest,
|
|
@@ -657,28 +676,28 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
657
676
|
height: "100%"
|
|
658
677
|
} : {}
|
|
659
678
|
],
|
|
660
|
-
onScroll:
|
|
679
|
+
onScroll: onScroll2,
|
|
661
680
|
onLayout,
|
|
662
681
|
horizontal,
|
|
663
682
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
664
683
|
ref: refScrollView
|
|
665
684
|
},
|
|
666
|
-
maintainVisibleContentPosition && /* @__PURE__ */
|
|
667
|
-
ENABLE_DEVMODE ? /* @__PURE__ */
|
|
668
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
685
|
+
maintainVisibleContentPosition && /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
|
|
686
|
+
ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
|
|
687
|
+
ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: ListHeaderComponentStyle, onLayout: onLayoutHeaderSync, ref: refHeader }, getComponent(ListHeaderComponent)),
|
|
669
688
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
670
|
-
canRender && /* @__PURE__ */
|
|
689
|
+
canRender && /* @__PURE__ */ React3__namespace.createElement(
|
|
671
690
|
Containers,
|
|
672
691
|
{
|
|
673
692
|
horizontal,
|
|
674
693
|
recycleItems,
|
|
675
694
|
waitForInitialLayout,
|
|
676
|
-
getRenderedItem,
|
|
695
|
+
getRenderedItem: getRenderedItem2,
|
|
677
696
|
ItemSeparatorComponent,
|
|
678
|
-
updateItemSize
|
|
697
|
+
updateItemSize: updateItemSize2
|
|
679
698
|
}
|
|
680
699
|
),
|
|
681
|
-
ListFooterComponent && /* @__PURE__ */
|
|
700
|
+
ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
|
|
682
701
|
reactNative.View,
|
|
683
702
|
{
|
|
684
703
|
style: ListFooterComponentStyle,
|
|
@@ -713,22 +732,545 @@ var ScrollAdjustHandler = class {
|
|
|
713
732
|
this.mounted = true;
|
|
714
733
|
}
|
|
715
734
|
};
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
735
|
+
|
|
736
|
+
// src/getId.ts
|
|
737
|
+
function getId(state, index) {
|
|
738
|
+
const { data, keyExtractor } = state.props;
|
|
739
|
+
if (!data) {
|
|
740
|
+
return "";
|
|
741
|
+
}
|
|
742
|
+
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
743
|
+
const id = ret;
|
|
744
|
+
state.idCache.set(index, id);
|
|
745
|
+
return id;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// src/calculateOffsetForIndex.ts
|
|
749
|
+
function calculateOffsetForIndex(ctx, state, index) {
|
|
750
|
+
let position = 0;
|
|
751
|
+
if (index !== void 0) {
|
|
752
|
+
position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
|
|
753
|
+
}
|
|
754
|
+
const paddingTop = peek$(ctx, "stylePaddingTop");
|
|
755
|
+
if (paddingTop) {
|
|
756
|
+
position += paddingTop;
|
|
757
|
+
}
|
|
758
|
+
const headerSize = peek$(ctx, "headerSize");
|
|
759
|
+
if (headerSize) {
|
|
760
|
+
position += headerSize;
|
|
761
|
+
}
|
|
762
|
+
return position;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// src/getItemSize.ts
|
|
766
|
+
function getItemSize(state, key, index, data, useAverageSize) {
|
|
767
|
+
const {
|
|
768
|
+
sizesKnown,
|
|
769
|
+
sizes,
|
|
770
|
+
scrollingTo,
|
|
771
|
+
props: { estimatedItemSize, getEstimatedItemSize }
|
|
772
|
+
} = state;
|
|
773
|
+
const sizeKnown = sizesKnown.get(key);
|
|
774
|
+
if (sizeKnown !== void 0) {
|
|
775
|
+
return sizeKnown;
|
|
776
|
+
}
|
|
777
|
+
let size;
|
|
778
|
+
if (IsNewArchitecture && useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
|
|
779
|
+
size = useAverageSize;
|
|
780
|
+
}
|
|
781
|
+
if (size === void 0) {
|
|
782
|
+
size = sizes.get(key);
|
|
783
|
+
if (size !== void 0) {
|
|
784
|
+
return size;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (size === void 0) {
|
|
788
|
+
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
|
|
789
|
+
}
|
|
790
|
+
sizes.set(key, size);
|
|
791
|
+
return size;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/calculateOffsetWithOffsetPosition.ts
|
|
795
|
+
function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
796
|
+
const { index, viewOffset, viewPosition } = params;
|
|
797
|
+
let offset = offsetParam;
|
|
798
|
+
if (viewOffset) {
|
|
799
|
+
offset -= viewOffset;
|
|
800
|
+
}
|
|
801
|
+
if (viewPosition !== void 0 && index !== void 0) {
|
|
802
|
+
offset -= viewPosition * (state.scrollLength - getItemSize(state, getId(state, index), index, state.props.data[index]));
|
|
803
|
+
}
|
|
804
|
+
return offset;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// src/checkAllSizesKnown.ts
|
|
808
|
+
function checkAllSizesKnown(state) {
|
|
809
|
+
const { startBuffered, endBuffered, sizesKnown } = state;
|
|
810
|
+
if (endBuffered !== null) {
|
|
811
|
+
let areAllKnown = true;
|
|
812
|
+
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
813
|
+
const key = getId(state, i);
|
|
814
|
+
areAllKnown && (areAllKnown = sizesKnown.has(key));
|
|
815
|
+
}
|
|
816
|
+
return areAllKnown;
|
|
817
|
+
}
|
|
818
|
+
return false;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/findAvailableContainers.ts
|
|
822
|
+
function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
|
|
823
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
824
|
+
const result = [];
|
|
825
|
+
const availableContainers = [];
|
|
826
|
+
for (let u = 0; u < numContainers; u++) {
|
|
827
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
828
|
+
let isOk = key === void 0;
|
|
829
|
+
if (!isOk) {
|
|
830
|
+
const index = pendingRemoval.indexOf(u);
|
|
831
|
+
if (index !== -1) {
|
|
832
|
+
pendingRemoval.splice(index, 1);
|
|
833
|
+
isOk = true;
|
|
721
834
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
835
|
+
}
|
|
836
|
+
if (isOk) {
|
|
837
|
+
result.push(u);
|
|
838
|
+
if (result.length >= numNeeded) {
|
|
839
|
+
return result;
|
|
726
840
|
}
|
|
727
841
|
}
|
|
728
|
-
}
|
|
729
|
-
|
|
842
|
+
}
|
|
843
|
+
for (let u = 0; u < numContainers; u++) {
|
|
844
|
+
const key = peek$(ctx, `containerItemKey${u}`);
|
|
845
|
+
if (key === void 0) continue;
|
|
846
|
+
const index = state.indexByKey.get(key);
|
|
847
|
+
if (index < startBuffered) {
|
|
848
|
+
availableContainers.push({ index: u, distance: startBuffered - index });
|
|
849
|
+
} else if (index > endBuffered) {
|
|
850
|
+
availableContainers.push({ index: u, distance: index - endBuffered });
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
const remaining = numNeeded - result.length;
|
|
854
|
+
if (remaining > 0) {
|
|
855
|
+
if (availableContainers.length > 0) {
|
|
856
|
+
if (availableContainers.length > remaining) {
|
|
857
|
+
availableContainers.sort(comparatorByDistance);
|
|
858
|
+
availableContainers.length = remaining;
|
|
859
|
+
}
|
|
860
|
+
for (const container of availableContainers) {
|
|
861
|
+
result.push(container.index);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
const stillNeeded = numNeeded - result.length;
|
|
865
|
+
if (stillNeeded > 0) {
|
|
866
|
+
for (let i = 0; i < stillNeeded; i++) {
|
|
867
|
+
result.push(numContainers + i);
|
|
868
|
+
}
|
|
869
|
+
if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
|
|
870
|
+
console.warn(
|
|
871
|
+
"[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
|
|
872
|
+
{
|
|
873
|
+
debugInfo: {
|
|
874
|
+
numContainers,
|
|
875
|
+
numNeeded,
|
|
876
|
+
stillNeeded,
|
|
877
|
+
numContainersPooled: peek$(ctx, "numContainersPooled")
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
return result.sort(comparatorDefault);
|
|
885
|
+
}
|
|
886
|
+
function comparatorByDistance(a, b) {
|
|
887
|
+
return b.distance - a.distance;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// src/getScrollVelocity.ts
|
|
891
|
+
var getScrollVelocity = (state) => {
|
|
892
|
+
const { scrollHistory } = state;
|
|
893
|
+
let velocity = 0;
|
|
894
|
+
if (scrollHistory.length >= 1) {
|
|
895
|
+
const newest = scrollHistory[scrollHistory.length - 1];
|
|
896
|
+
let oldest;
|
|
897
|
+
let start = 0;
|
|
898
|
+
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
899
|
+
const entry = scrollHistory[i];
|
|
900
|
+
const nextEntry = scrollHistory[i + 1];
|
|
901
|
+
if (i > 0) {
|
|
902
|
+
const prevEntry = scrollHistory[i - 1];
|
|
903
|
+
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
904
|
+
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
905
|
+
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
906
|
+
start = i;
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
912
|
+
const entry = scrollHistory[i];
|
|
913
|
+
if (newest.time - entry.time <= 1e3) {
|
|
914
|
+
oldest = entry;
|
|
915
|
+
break;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
if (oldest) {
|
|
919
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
920
|
+
const timeDiff = newest.time - oldest.time;
|
|
921
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return velocity;
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
// src/requestAdjust.ts
|
|
928
|
+
function requestAdjust(ctx, state, positionDiff) {
|
|
929
|
+
if (Math.abs(positionDiff) > 0.1) {
|
|
930
|
+
const doit = () => {
|
|
931
|
+
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
932
|
+
};
|
|
933
|
+
state.scroll += positionDiff;
|
|
934
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
935
|
+
if (peek$(ctx, "containersDidLayout")) {
|
|
936
|
+
doit();
|
|
937
|
+
} else {
|
|
938
|
+
requestAnimationFrame(doit);
|
|
939
|
+
}
|
|
940
|
+
const threshold = state.scroll - positionDiff / 2;
|
|
941
|
+
if (!state.ignoreScrollFromMVCP) {
|
|
942
|
+
state.ignoreScrollFromMVCP = {};
|
|
943
|
+
}
|
|
944
|
+
if (positionDiff > 0) {
|
|
945
|
+
state.ignoreScrollFromMVCP.lt = threshold;
|
|
946
|
+
} else {
|
|
947
|
+
state.ignoreScrollFromMVCP.gt = threshold;
|
|
948
|
+
}
|
|
949
|
+
if (state.ignoreScrollFromMVCPTimeout) {
|
|
950
|
+
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
951
|
+
}
|
|
952
|
+
state.ignoreScrollFromMVCPTimeout = setTimeout(() => {
|
|
953
|
+
state.ignoreScrollFromMVCP = void 0;
|
|
954
|
+
}, 100);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// src/prepareMVCP.ts
|
|
959
|
+
function prepareMVCP(ctx, state) {
|
|
960
|
+
const {
|
|
961
|
+
positions,
|
|
962
|
+
scrollingTo,
|
|
963
|
+
props: { maintainVisibleContentPosition }
|
|
964
|
+
} = state;
|
|
965
|
+
let prevPosition;
|
|
966
|
+
let targetId;
|
|
967
|
+
let targetIndex;
|
|
968
|
+
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
969
|
+
if (maintainVisibleContentPosition) {
|
|
970
|
+
const indexByKey = state.indexByKey;
|
|
971
|
+
if (scrollTarget !== void 0) {
|
|
972
|
+
targetId = getId(state, scrollTarget);
|
|
973
|
+
targetIndex = scrollTarget;
|
|
974
|
+
} else if (state.idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
|
|
975
|
+
targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
976
|
+
targetIndex = indexByKey.get(targetId);
|
|
977
|
+
}
|
|
978
|
+
if (targetId !== void 0 && targetIndex !== void 0) {
|
|
979
|
+
prevPosition = positions.get(targetId);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return () => {
|
|
983
|
+
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
984
|
+
const newPosition = positions.get(targetId);
|
|
985
|
+
if (newPosition !== void 0) {
|
|
986
|
+
const positionDiff = newPosition - prevPosition;
|
|
987
|
+
if (Math.abs(positionDiff) > 0.1) {
|
|
988
|
+
requestAdjust(ctx, state, positionDiff);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// src/checkThreshold.ts
|
|
996
|
+
var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
|
|
997
|
+
const distanceAbs = Math.abs(distance);
|
|
998
|
+
const isAtThreshold = atThreshold || distanceAbs < threshold;
|
|
999
|
+
if (!isReached && !isBlockedByTimer) {
|
|
1000
|
+
if (isAtThreshold) {
|
|
1001
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1002
|
+
blockTimer == null ? void 0 : blockTimer(true);
|
|
1003
|
+
setTimeout(() => {
|
|
1004
|
+
blockTimer == null ? void 0 : blockTimer(false);
|
|
1005
|
+
}, 700);
|
|
1006
|
+
return true;
|
|
1007
|
+
}
|
|
1008
|
+
} else {
|
|
1009
|
+
if (distance >= 1.3 * threshold) {
|
|
1010
|
+
return false;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
return isReached;
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
// src/checkAtBottom.ts
|
|
1017
|
+
function checkAtBottom(ctx, state) {
|
|
1018
|
+
if (!state) {
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
const {
|
|
1022
|
+
queuedInitialLayout,
|
|
1023
|
+
scrollLength,
|
|
1024
|
+
scroll,
|
|
1025
|
+
maintainingScrollAtEnd,
|
|
1026
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1027
|
+
} = state;
|
|
1028
|
+
const contentSize = getContentSize(ctx);
|
|
1029
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1030
|
+
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1031
|
+
const isContentLess = contentSize < scrollLength;
|
|
1032
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1033
|
+
state.isEndReached = checkThreshold(
|
|
1034
|
+
distanceFromEnd,
|
|
1035
|
+
isContentLess,
|
|
1036
|
+
onEndReachedThreshold * scrollLength,
|
|
1037
|
+
state.isEndReached,
|
|
1038
|
+
state.endReachedBlockedByTimer,
|
|
1039
|
+
(distance) => {
|
|
1040
|
+
var _a, _b;
|
|
1041
|
+
return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
|
|
1042
|
+
},
|
|
1043
|
+
(block) => {
|
|
1044
|
+
state.endReachedBlockedByTimer = block;
|
|
1045
|
+
}
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// src/finishScrollTo.ts
|
|
1051
|
+
var finishScrollTo = (state) => {
|
|
1052
|
+
if (state) {
|
|
1053
|
+
state.scrollingTo = void 0;
|
|
1054
|
+
state.scrollHistory.length = 0;
|
|
1055
|
+
}
|
|
730
1056
|
};
|
|
731
1057
|
|
|
1058
|
+
// src/scrollTo.ts
|
|
1059
|
+
function scrollTo(state, params = {}) {
|
|
1060
|
+
var _a;
|
|
1061
|
+
const { animated } = params;
|
|
1062
|
+
const {
|
|
1063
|
+
refScroller,
|
|
1064
|
+
props: { horizontal }
|
|
1065
|
+
} = state;
|
|
1066
|
+
const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
|
|
1067
|
+
state.scrollHistory.length = 0;
|
|
1068
|
+
state.scrollingTo = params;
|
|
1069
|
+
state.scrollPending = offset;
|
|
1070
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1071
|
+
x: horizontal ? offset : 0,
|
|
1072
|
+
y: horizontal ? 0 : offset,
|
|
1073
|
+
animated: !!animated
|
|
1074
|
+
});
|
|
1075
|
+
if (!animated) {
|
|
1076
|
+
state.scroll = offset;
|
|
1077
|
+
setTimeout(() => finishScrollTo(state), 100);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// src/scrollToIndex.ts
|
|
1082
|
+
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1083
|
+
if (index >= state.props.data.length) {
|
|
1084
|
+
index = state.props.data.length - 1;
|
|
1085
|
+
} else if (index < 0) {
|
|
1086
|
+
index = 0;
|
|
1087
|
+
}
|
|
1088
|
+
const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
|
|
1089
|
+
const isLast = index === state.props.data.length - 1;
|
|
1090
|
+
if (isLast && viewPosition === void 0) {
|
|
1091
|
+
viewPosition = 1;
|
|
1092
|
+
}
|
|
1093
|
+
const firstIndexScrollPostion = firstIndexOffset - viewOffset;
|
|
1094
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1095
|
+
scrollTo(state, {
|
|
1096
|
+
offset: firstIndexScrollPostion,
|
|
1097
|
+
animated,
|
|
1098
|
+
index,
|
|
1099
|
+
viewPosition: viewPosition != null ? viewPosition : 0,
|
|
1100
|
+
viewOffset
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// src/setDidLayout.ts
|
|
1105
|
+
function setDidLayout(ctx, state) {
|
|
1106
|
+
const {
|
|
1107
|
+
loadStartTime,
|
|
1108
|
+
initialScroll,
|
|
1109
|
+
props: { onLoad }
|
|
1110
|
+
} = state;
|
|
1111
|
+
state.queuedInitialLayout = true;
|
|
1112
|
+
checkAtBottom(ctx, state);
|
|
1113
|
+
if (!IsNewArchitecture && initialScroll) {
|
|
1114
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1115
|
+
}
|
|
1116
|
+
set$(ctx, "containersDidLayout", true);
|
|
1117
|
+
if (onLoad) {
|
|
1118
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// src/setPaddingTop.ts
|
|
1123
|
+
function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1124
|
+
if (stylePaddingTop !== void 0) {
|
|
1125
|
+
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
1126
|
+
if (stylePaddingTop < prevStylePaddingTop) {
|
|
1127
|
+
const prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1128
|
+
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
1129
|
+
setTimeout(() => {
|
|
1130
|
+
set$(ctx, "totalSize", prevTotalSize);
|
|
1131
|
+
}, 16);
|
|
1132
|
+
}
|
|
1133
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1134
|
+
}
|
|
1135
|
+
if (alignItemsPaddingTop !== void 0) {
|
|
1136
|
+
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// src/updateAlignItemsPaddingTop.ts
|
|
1141
|
+
function updateAlignItemsPaddingTop(ctx, state) {
|
|
1142
|
+
const {
|
|
1143
|
+
scrollLength,
|
|
1144
|
+
props: { alignItemsAtEnd, data }
|
|
1145
|
+
} = state;
|
|
1146
|
+
if (alignItemsAtEnd) {
|
|
1147
|
+
let alignItemsPaddingTop = 0;
|
|
1148
|
+
if ((data == null ? void 0 : data.length) > 0) {
|
|
1149
|
+
const contentSize = getContentSize(ctx);
|
|
1150
|
+
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1151
|
+
}
|
|
1152
|
+
setPaddingTop(ctx, { alignItemsPaddingTop });
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
// src/updateTotalSize.ts
|
|
1157
|
+
function updateTotalSize(ctx, state) {
|
|
1158
|
+
const {
|
|
1159
|
+
positions,
|
|
1160
|
+
props: { data }
|
|
1161
|
+
} = state;
|
|
1162
|
+
if (data.length === 0) {
|
|
1163
|
+
addTotalSize(ctx, state, null, 0);
|
|
1164
|
+
} else {
|
|
1165
|
+
const lastId = getId(state, data.length - 1);
|
|
1166
|
+
if (lastId !== void 0) {
|
|
1167
|
+
const lastPosition = positions.get(lastId);
|
|
1168
|
+
if (lastPosition !== void 0) {
|
|
1169
|
+
const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
|
|
1170
|
+
if (lastSize !== void 0) {
|
|
1171
|
+
const totalSize = lastPosition + lastSize;
|
|
1172
|
+
addTotalSize(ctx, state, null, totalSize);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
function addTotalSize(ctx, state, key, add) {
|
|
1179
|
+
const { alignItemsAtEnd } = state.props;
|
|
1180
|
+
{
|
|
1181
|
+
state.totalSize = add;
|
|
1182
|
+
}
|
|
1183
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
1184
|
+
if (alignItemsAtEnd) {
|
|
1185
|
+
updateAlignItemsPaddingTop(ctx, state);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
// src/updateAllPositions.ts
|
|
1190
|
+
function updateAllPositions(ctx, state, dataChanged) {
|
|
1191
|
+
var _a, _b, _c, _d, _e;
|
|
1192
|
+
const { averageSizes, columns, indexByKey, positions, firstFullyOnScreenIndex, idCache, sizesKnown } = state;
|
|
1193
|
+
const data = state.props.data;
|
|
1194
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1195
|
+
const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
|
|
1196
|
+
const scrollVelocity = getScrollVelocity(state);
|
|
1197
|
+
if (dataChanged) {
|
|
1198
|
+
indexByKey.clear();
|
|
1199
|
+
idCache.clear();
|
|
1200
|
+
}
|
|
1201
|
+
const itemType = "";
|
|
1202
|
+
let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
|
|
1203
|
+
if (averageSize !== void 0) {
|
|
1204
|
+
averageSize = roundSize(averageSize);
|
|
1205
|
+
}
|
|
1206
|
+
const shouldUseBackwards = !dataChanged && scrollVelocity < 0 && firstFullyOnScreenIndex > 5 && firstFullyOnScreenIndex < data.length;
|
|
1207
|
+
if (shouldUseBackwards && firstFullyOnScreenIndex !== void 0) {
|
|
1208
|
+
const anchorId = getId(state, firstFullyOnScreenIndex);
|
|
1209
|
+
const anchorPosition = positions.get(anchorId);
|
|
1210
|
+
if (anchorPosition !== void 0) {
|
|
1211
|
+
let currentRowTop2 = anchorPosition;
|
|
1212
|
+
let maxSizeInRow2 = 0;
|
|
1213
|
+
let bailout = false;
|
|
1214
|
+
for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
|
|
1215
|
+
const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
|
|
1216
|
+
const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], averageSize);
|
|
1217
|
+
const itemColumn = columns.get(id);
|
|
1218
|
+
maxSizeInRow2 = Math.max(maxSizeInRow2, size);
|
|
1219
|
+
if (itemColumn === 1) {
|
|
1220
|
+
currentRowTop2 -= maxSizeInRow2;
|
|
1221
|
+
maxSizeInRow2 = 0;
|
|
1222
|
+
}
|
|
1223
|
+
if (currentRowTop2 < -2e3) {
|
|
1224
|
+
bailout = true;
|
|
1225
|
+
break;
|
|
1226
|
+
}
|
|
1227
|
+
positions.set(id, currentRowTop2);
|
|
1228
|
+
}
|
|
1229
|
+
if (!bailout) {
|
|
1230
|
+
updateTotalSize(ctx, state);
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
let currentRowTop = 0;
|
|
1236
|
+
let column = 1;
|
|
1237
|
+
let maxSizeInRow = 0;
|
|
1238
|
+
const hasColumns = numColumns > 1;
|
|
1239
|
+
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
1240
|
+
const dataLength = data.length;
|
|
1241
|
+
for (let i = 0; i < dataLength; i++) {
|
|
1242
|
+
const id = (_d = idCache.get(i)) != null ? _d : getId(state, i);
|
|
1243
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], averageSize);
|
|
1244
|
+
if (__DEV__ && needsIndexByKey) {
|
|
1245
|
+
if (indexByKeyForChecking.has(id)) {
|
|
1246
|
+
console.error(
|
|
1247
|
+
`[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
indexByKeyForChecking.set(id, i);
|
|
1251
|
+
}
|
|
1252
|
+
positions.set(id, currentRowTop);
|
|
1253
|
+
if (needsIndexByKey) {
|
|
1254
|
+
indexByKey.set(id, i);
|
|
1255
|
+
}
|
|
1256
|
+
columns.set(id, column);
|
|
1257
|
+
if (hasColumns) {
|
|
1258
|
+
if (size > maxSizeInRow) {
|
|
1259
|
+
maxSizeInRow = size;
|
|
1260
|
+
}
|
|
1261
|
+
column++;
|
|
1262
|
+
if (column > numColumns) {
|
|
1263
|
+
currentRowTop += maxSizeInRow;
|
|
1264
|
+
column = 1;
|
|
1265
|
+
maxSizeInRow = 0;
|
|
1266
|
+
}
|
|
1267
|
+
} else {
|
|
1268
|
+
currentRowTop += size;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
updateTotalSize(ctx, state);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
732
1274
|
// src/viewability.ts
|
|
733
1275
|
var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
|
|
734
1276
|
function setupViewability(props) {
|
|
@@ -757,7 +1299,7 @@ function setupViewability(props) {
|
|
|
757
1299
|
}
|
|
758
1300
|
return viewabilityConfigCallbackPairs;
|
|
759
1301
|
}
|
|
760
|
-
function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs,
|
|
1302
|
+
function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
|
|
761
1303
|
for (const viewabilityConfigCallbackPair of viewabilityConfigCallbackPairs) {
|
|
762
1304
|
const viewabilityState = mapViewabilityConfigCallbackPairs.get(
|
|
763
1305
|
viewabilityConfigCallbackPair.viewabilityConfig.id
|
|
@@ -767,15 +1309,15 @@ function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, getId,
|
|
|
767
1309
|
if (viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime) {
|
|
768
1310
|
const timer = setTimeout(() => {
|
|
769
1311
|
state.timeouts.delete(timer);
|
|
770
|
-
updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair,
|
|
1312
|
+
updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
|
|
771
1313
|
}, viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime);
|
|
772
1314
|
state.timeouts.add(timer);
|
|
773
1315
|
} else {
|
|
774
|
-
updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair,
|
|
1316
|
+
updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
|
|
775
1317
|
}
|
|
776
1318
|
}
|
|
777
1319
|
}
|
|
778
|
-
function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair,
|
|
1320
|
+
function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize) {
|
|
779
1321
|
const { viewabilityConfig, onViewableItemsChanged } = viewabilityConfigCallbackPair;
|
|
780
1322
|
const configId = viewabilityConfig.id;
|
|
781
1323
|
const viewabilityState = mapViewabilityConfigCallbackPairs.get(configId);
|
|
@@ -819,7 +1361,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
819
1361
|
for (let i = start; i <= end; i++) {
|
|
820
1362
|
const item = data[i];
|
|
821
1363
|
if (item) {
|
|
822
|
-
const key = getId(i);
|
|
1364
|
+
const key = getId(state, i);
|
|
823
1365
|
const containerId = findContainerId(ctx, key);
|
|
824
1366
|
if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
|
|
825
1367
|
const viewToken = {
|
|
@@ -915,9 +1457,299 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
|
915
1457
|
cb == null ? void 0 : cb(viewToken);
|
|
916
1458
|
}
|
|
917
1459
|
|
|
918
|
-
// src/
|
|
919
|
-
|
|
920
|
-
var
|
|
1460
|
+
// src/calculateItemsInView.ts
|
|
1461
|
+
function calculateItemsInView(ctx, state, params = {}) {
|
|
1462
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1463
|
+
const {
|
|
1464
|
+
scrollLength,
|
|
1465
|
+
startBufferedId: startBufferedIdOrig,
|
|
1466
|
+
positions,
|
|
1467
|
+
columns,
|
|
1468
|
+
containerItemKeys,
|
|
1469
|
+
idCache,
|
|
1470
|
+
sizes,
|
|
1471
|
+
indexByKey,
|
|
1472
|
+
scrollForNextCalculateItemsInView,
|
|
1473
|
+
enableScrollForNextCalculateItemsInView,
|
|
1474
|
+
minIndexSizeChanged
|
|
1475
|
+
} = state;
|
|
1476
|
+
const data = state.props.data;
|
|
1477
|
+
if (!data || scrollLength === 0) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
const totalSize = peek$(ctx, "totalSize");
|
|
1481
|
+
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
1482
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1483
|
+
const previousScrollAdjust = 0;
|
|
1484
|
+
const { dataChanged, doMVCP } = params;
|
|
1485
|
+
const speed = getScrollVelocity(state);
|
|
1486
|
+
if (doMVCP || dataChanged) {
|
|
1487
|
+
const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
|
|
1488
|
+
updateAllPositions(ctx, state, dataChanged);
|
|
1489
|
+
checkMVCP == null ? void 0 : checkMVCP();
|
|
1490
|
+
}
|
|
1491
|
+
const scrollExtra = 0;
|
|
1492
|
+
const { queuedInitialLayout } = state;
|
|
1493
|
+
let { scroll: scrollState } = state;
|
|
1494
|
+
const initialScroll = state.props.initialScroll;
|
|
1495
|
+
if (!queuedInitialLayout && initialScroll) {
|
|
1496
|
+
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
1497
|
+
state,
|
|
1498
|
+
calculateOffsetForIndex(ctx, state, initialScroll.index),
|
|
1499
|
+
initialScroll
|
|
1500
|
+
);
|
|
1501
|
+
scrollState = updatedOffset;
|
|
1502
|
+
}
|
|
1503
|
+
const scrollAdjustPad = -previousScrollAdjust - topPad;
|
|
1504
|
+
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
1505
|
+
if (scroll + scrollLength > totalSize) {
|
|
1506
|
+
scroll = totalSize - scrollLength;
|
|
1507
|
+
}
|
|
1508
|
+
if (ENABLE_DEBUG_VIEW) {
|
|
1509
|
+
set$(ctx, "debugRawScroll", scrollState);
|
|
1510
|
+
set$(ctx, "debugComputedScroll", scroll);
|
|
1511
|
+
}
|
|
1512
|
+
const scrollBuffer = state.props.scrollBuffer;
|
|
1513
|
+
let scrollBufferTop = scrollBuffer;
|
|
1514
|
+
let scrollBufferBottom = scrollBuffer;
|
|
1515
|
+
if (speed > 0) {
|
|
1516
|
+
scrollBufferTop = scrollBuffer * 0.5;
|
|
1517
|
+
scrollBufferBottom = scrollBuffer * 1.5;
|
|
1518
|
+
} else {
|
|
1519
|
+
scrollBufferTop = scrollBuffer * 1.5;
|
|
1520
|
+
scrollBufferBottom = scrollBuffer * 0.5;
|
|
1521
|
+
}
|
|
1522
|
+
const scrollTopBuffered = scroll - scrollBufferTop;
|
|
1523
|
+
const scrollBottom = scroll + scrollLength;
|
|
1524
|
+
const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
|
|
1525
|
+
if (scrollForNextCalculateItemsInView) {
|
|
1526
|
+
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
1527
|
+
if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
|
|
1528
|
+
return;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
let startNoBuffer = null;
|
|
1532
|
+
let startBuffered = null;
|
|
1533
|
+
let startBufferedId = null;
|
|
1534
|
+
let endNoBuffer = null;
|
|
1535
|
+
let endBuffered = null;
|
|
1536
|
+
let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1537
|
+
if (minIndexSizeChanged !== void 0) {
|
|
1538
|
+
loopStart = Math.min(minIndexSizeChanged, loopStart);
|
|
1539
|
+
state.minIndexSizeChanged = void 0;
|
|
1540
|
+
}
|
|
1541
|
+
for (let i = loopStart; i >= 0; i--) {
|
|
1542
|
+
const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
|
|
1543
|
+
const top = positions.get(id);
|
|
1544
|
+
const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
|
|
1545
|
+
const bottom = top + size;
|
|
1546
|
+
if (bottom > scroll - scrollBuffer) {
|
|
1547
|
+
loopStart = i;
|
|
1548
|
+
} else {
|
|
1549
|
+
break;
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
const loopStartMod = loopStart % numColumns;
|
|
1553
|
+
if (loopStartMod > 0) {
|
|
1554
|
+
loopStart -= loopStartMod;
|
|
1555
|
+
}
|
|
1556
|
+
let foundEnd = false;
|
|
1557
|
+
let nextTop;
|
|
1558
|
+
let nextBottom;
|
|
1559
|
+
const prevNumContainers = ctx.values.get("numContainers");
|
|
1560
|
+
let maxIndexRendered = 0;
|
|
1561
|
+
for (let i = 0; i < prevNumContainers; i++) {
|
|
1562
|
+
const key = peek$(ctx, `containerItemKey${i}`);
|
|
1563
|
+
if (key !== void 0) {
|
|
1564
|
+
const index = indexByKey.get(key);
|
|
1565
|
+
maxIndexRendered = Math.max(maxIndexRendered, index);
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
let firstFullyOnScreenIndex;
|
|
1569
|
+
const dataLength = data.length;
|
|
1570
|
+
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
1571
|
+
const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
|
|
1572
|
+
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
|
|
1573
|
+
const top = positions.get(id);
|
|
1574
|
+
if (!foundEnd) {
|
|
1575
|
+
if (startNoBuffer === null && top + size > scroll) {
|
|
1576
|
+
startNoBuffer = i;
|
|
1577
|
+
}
|
|
1578
|
+
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
|
|
1579
|
+
firstFullyOnScreenIndex = i;
|
|
1580
|
+
}
|
|
1581
|
+
if (startBuffered === null && top + size > scrollTopBuffered) {
|
|
1582
|
+
startBuffered = i;
|
|
1583
|
+
startBufferedId = id;
|
|
1584
|
+
nextTop = top;
|
|
1585
|
+
}
|
|
1586
|
+
if (startNoBuffer !== null) {
|
|
1587
|
+
if (top <= scrollBottom) {
|
|
1588
|
+
endNoBuffer = i;
|
|
1589
|
+
}
|
|
1590
|
+
if (top <= scrollBottomBuffered) {
|
|
1591
|
+
endBuffered = i;
|
|
1592
|
+
nextBottom = top + size;
|
|
1593
|
+
} else {
|
|
1594
|
+
foundEnd = true;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
const idsInView = [];
|
|
1600
|
+
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
1601
|
+
const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
|
|
1602
|
+
idsInView.push(id);
|
|
1603
|
+
}
|
|
1604
|
+
Object.assign(state, {
|
|
1605
|
+
startBuffered,
|
|
1606
|
+
startBufferedId,
|
|
1607
|
+
startNoBuffer,
|
|
1608
|
+
endBuffered,
|
|
1609
|
+
endNoBuffer,
|
|
1610
|
+
idsInView,
|
|
1611
|
+
firstFullyOnScreenIndex
|
|
1612
|
+
});
|
|
1613
|
+
if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
|
|
1614
|
+
state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
|
|
1615
|
+
top: nextTop,
|
|
1616
|
+
bottom: nextBottom
|
|
1617
|
+
} : void 0;
|
|
1618
|
+
}
|
|
1619
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
1620
|
+
const pendingRemoval = [];
|
|
1621
|
+
if (dataChanged) {
|
|
1622
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1623
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1624
|
+
if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
|
|
1625
|
+
pendingRemoval.push(i);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
if (startBuffered !== null && endBuffered !== null) {
|
|
1630
|
+
let numContainers2 = prevNumContainers;
|
|
1631
|
+
const needNewContainers = [];
|
|
1632
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
1633
|
+
const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
|
|
1634
|
+
if (!containerItemKeys.has(id)) {
|
|
1635
|
+
needNewContainers.push(i);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
if (needNewContainers.length > 0) {
|
|
1639
|
+
const availableContainers = findAvailableContainers(
|
|
1640
|
+
ctx,
|
|
1641
|
+
state,
|
|
1642
|
+
needNewContainers.length,
|
|
1643
|
+
startBuffered,
|
|
1644
|
+
endBuffered,
|
|
1645
|
+
pendingRemoval
|
|
1646
|
+
);
|
|
1647
|
+
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
1648
|
+
const i = needNewContainers[idx];
|
|
1649
|
+
const containerIndex = availableContainers[idx];
|
|
1650
|
+
const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
|
|
1651
|
+
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1652
|
+
if (oldKey && oldKey !== id) {
|
|
1653
|
+
containerItemKeys.delete(oldKey);
|
|
1654
|
+
}
|
|
1655
|
+
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
1656
|
+
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
1657
|
+
containerItemKeys.add(id);
|
|
1658
|
+
if (containerIndex >= numContainers2) {
|
|
1659
|
+
numContainers2 = containerIndex + 1;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
if (numContainers2 !== prevNumContainers) {
|
|
1663
|
+
set$(ctx, "numContainers", numContainers2);
|
|
1664
|
+
if (numContainers2 > peek$(ctx, "numContainersPooled")) {
|
|
1665
|
+
set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1671
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1672
|
+
if (pendingRemoval.includes(i)) {
|
|
1673
|
+
if (itemKey) {
|
|
1674
|
+
containerItemKeys.delete(itemKey);
|
|
1675
|
+
}
|
|
1676
|
+
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1677
|
+
set$(ctx, `containerItemData${i}`, void 0);
|
|
1678
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1679
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
1680
|
+
} else {
|
|
1681
|
+
const itemIndex = indexByKey.get(itemKey);
|
|
1682
|
+
const item = data[itemIndex];
|
|
1683
|
+
if (item !== void 0) {
|
|
1684
|
+
const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
|
|
1685
|
+
const position = positions.get(id);
|
|
1686
|
+
if (position === void 0) {
|
|
1687
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1688
|
+
} else {
|
|
1689
|
+
const pos = positions.get(id);
|
|
1690
|
+
const column = columns.get(id) || 1;
|
|
1691
|
+
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
1692
|
+
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
1693
|
+
const prevData = peek$(ctx, `containerItemData${i}`);
|
|
1694
|
+
if (!prevPos || pos > POSITION_OUT_OF_VIEW && pos !== prevPos) {
|
|
1695
|
+
set$(ctx, `containerPosition${i}`, pos);
|
|
1696
|
+
}
|
|
1697
|
+
if (column >= 0 && column !== prevColumn) {
|
|
1698
|
+
set$(ctx, `containerColumn${i}`, column);
|
|
1699
|
+
}
|
|
1700
|
+
if (prevData !== item) {
|
|
1701
|
+
set$(ctx, `containerItemData${i}`, data[itemIndex]);
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
if (!queuedInitialLayout && endBuffered !== null) {
|
|
1708
|
+
if (checkAllSizesKnown(state)) {
|
|
1709
|
+
setDidLayout(ctx, state);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
if (state.props.viewabilityConfigCallbackPairs) {
|
|
1713
|
+
updateViewableItems(
|
|
1714
|
+
state,
|
|
1715
|
+
ctx,
|
|
1716
|
+
state.props.viewabilityConfigCallbackPairs,
|
|
1717
|
+
scrollLength,
|
|
1718
|
+
startNoBuffer,
|
|
1719
|
+
endNoBuffer
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// src/checkAtTop.ts
|
|
1725
|
+
function checkAtTop(state) {
|
|
1726
|
+
if (!state) {
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
const {
|
|
1730
|
+
scrollLength,
|
|
1731
|
+
scroll,
|
|
1732
|
+
props: { onStartReachedThreshold }
|
|
1733
|
+
} = state;
|
|
1734
|
+
const distanceFromTop = scroll;
|
|
1735
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1736
|
+
state.isStartReached = checkThreshold(
|
|
1737
|
+
distanceFromTop,
|
|
1738
|
+
false,
|
|
1739
|
+
onStartReachedThreshold * scrollLength,
|
|
1740
|
+
state.isStartReached,
|
|
1741
|
+
state.startReachedBlockedByTimer,
|
|
1742
|
+
(distance) => {
|
|
1743
|
+
var _a, _b;
|
|
1744
|
+
return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
|
|
1745
|
+
},
|
|
1746
|
+
(block) => {
|
|
1747
|
+
state.startReachedBlockedByTimer = block;
|
|
1748
|
+
}
|
|
1749
|
+
);
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
// src/createColumnWrapperStyle.ts
|
|
921
1753
|
function createColumnWrapperStyle(contentContainerStyle) {
|
|
922
1754
|
const { gap, columnGap, rowGap } = contentContainerStyle;
|
|
923
1755
|
if (gap || columnGap || rowGap) {
|
|
@@ -931,15 +1763,318 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
931
1763
|
};
|
|
932
1764
|
}
|
|
933
1765
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1766
|
+
|
|
1767
|
+
// src/doInitialAllocateContainers.ts
|
|
1768
|
+
function doInitialAllocateContainers(ctx, state) {
|
|
1769
|
+
const { scrollLength } = state;
|
|
1770
|
+
const data = state.props.data;
|
|
1771
|
+
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1772
|
+
const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0]) : state.props.estimatedItemSize;
|
|
1773
|
+
const Extra = 1.5;
|
|
1774
|
+
const numContainers = Math.ceil(
|
|
1775
|
+
(scrollLength + state.props.scrollBuffer * 2) / averageItemSize * state.props.numColumns * Extra
|
|
1776
|
+
);
|
|
1777
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1778
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1779
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
1780
|
+
}
|
|
1781
|
+
set$(ctx, "numContainers", numContainers);
|
|
1782
|
+
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
1783
|
+
if (!IsNewArchitecture) {
|
|
1784
|
+
if (state.props.initialScroll) {
|
|
1785
|
+
requestAnimationFrame(() => {
|
|
1786
|
+
calculateItemsInView(ctx, state);
|
|
1787
|
+
});
|
|
1788
|
+
} else {
|
|
1789
|
+
calculateItemsInView(ctx, state);
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
return true;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
// src/doMaintainScrollAtEnd.ts
|
|
1797
|
+
function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
1798
|
+
const {
|
|
1799
|
+
refScroller,
|
|
1800
|
+
props: { maintainScrollAtEnd }
|
|
1801
|
+
} = state;
|
|
1802
|
+
if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
|
|
1803
|
+
const paddingTop = peek$(ctx, "alignItemsPaddingTop");
|
|
1804
|
+
if (paddingTop > 0) {
|
|
1805
|
+
state.scroll = 0;
|
|
1806
|
+
}
|
|
1807
|
+
requestAnimationFrame(() => {
|
|
1808
|
+
var _a;
|
|
1809
|
+
state.maintainingScrollAtEnd = true;
|
|
1810
|
+
(_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
|
|
1811
|
+
animated
|
|
1812
|
+
});
|
|
1813
|
+
setTimeout(
|
|
1814
|
+
() => {
|
|
1815
|
+
state.maintainingScrollAtEnd = false;
|
|
1816
|
+
},
|
|
1817
|
+
0
|
|
1818
|
+
);
|
|
1819
|
+
});
|
|
1820
|
+
return true;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
function getRenderedItem(ctx, state, key) {
|
|
1824
|
+
if (!state) {
|
|
1825
|
+
return null;
|
|
1826
|
+
}
|
|
1827
|
+
const {
|
|
1828
|
+
indexByKey,
|
|
1829
|
+
props: { data, renderItem: renderItem2 }
|
|
1830
|
+
} = state;
|
|
1831
|
+
const index = indexByKey.get(key);
|
|
1832
|
+
if (index === void 0) {
|
|
1833
|
+
return null;
|
|
1834
|
+
}
|
|
1835
|
+
let renderedItem = null;
|
|
1836
|
+
if (renderItem2) {
|
|
1837
|
+
const itemProps = {
|
|
1838
|
+
item: data[index],
|
|
1839
|
+
index,
|
|
1840
|
+
extraData: peek$(ctx, "extraData")
|
|
1841
|
+
};
|
|
1842
|
+
renderedItem = React3__namespace.default.createElement(renderItem2, itemProps);
|
|
1843
|
+
}
|
|
1844
|
+
return { index, item: data[index], renderedItem };
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
// src/handleLayout.ts
|
|
1848
|
+
function handleLayout(ctx, state, size, setCanRender) {
|
|
1849
|
+
const scrollLength = size[state.props.horizontal ? "width" : "height"];
|
|
1850
|
+
const otherAxisSize = size[state.props.horizontal ? "height" : "width"];
|
|
1851
|
+
const didChange = scrollLength !== state.scrollLength;
|
|
1852
|
+
const prevOtherAxisSize = state.otherAxisSize;
|
|
1853
|
+
state.scrollLength = scrollLength;
|
|
1854
|
+
state.otherAxisSize = otherAxisSize;
|
|
1855
|
+
state.lastBatchingAction = Date.now();
|
|
1856
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1857
|
+
doInitialAllocateContainers(ctx, state);
|
|
1858
|
+
if (didChange) {
|
|
1859
|
+
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1860
|
+
}
|
|
1861
|
+
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
1862
|
+
set$(ctx, "scrollSize", { width: size.width, height: size.height });
|
|
1863
|
+
}
|
|
1864
|
+
doMaintainScrollAtEnd(ctx, state, false);
|
|
1865
|
+
updateAlignItemsPaddingTop(ctx, state);
|
|
1866
|
+
checkAtBottom(ctx, state);
|
|
1867
|
+
checkAtTop(state);
|
|
1868
|
+
if (state) {
|
|
1869
|
+
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
1870
|
+
}
|
|
1871
|
+
if (__DEV__ && scrollLength === 0) {
|
|
1872
|
+
warnDevOnce(
|
|
1873
|
+
"height0",
|
|
1874
|
+
`List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1878
|
+
setCanRender(true);
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
// src/onScroll.ts
|
|
1882
|
+
function onScroll(ctx, state, event) {
|
|
1883
|
+
var _a, _b, _c, _d, _e;
|
|
1884
|
+
if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
1888
|
+
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
1889
|
+
if (ignoreScrollFromMVCP && !state.scrollingTo) {
|
|
1890
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1891
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1892
|
+
return;
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
state.scrollPending = newScroll;
|
|
1896
|
+
updateScroll(ctx, state, newScroll);
|
|
1897
|
+
(_e = (_d = state.props).onScroll) == null ? void 0 : _e.call(_d, event);
|
|
1898
|
+
}
|
|
1899
|
+
function updateScroll(ctx, state, newScroll) {
|
|
1900
|
+
const scrollingTo = state.scrollingTo;
|
|
1901
|
+
state.hasScrolled = true;
|
|
1902
|
+
state.lastBatchingAction = Date.now();
|
|
1903
|
+
const currentTime = performance.now();
|
|
1904
|
+
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1905
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1906
|
+
}
|
|
1907
|
+
if (state.scrollHistory.length > 5) {
|
|
1908
|
+
state.scrollHistory.shift();
|
|
1909
|
+
}
|
|
1910
|
+
state.scrollPrev = state.scroll;
|
|
1911
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1912
|
+
state.scroll = newScroll;
|
|
1913
|
+
state.scrollTime = currentTime;
|
|
1914
|
+
calculateItemsInView(ctx, state);
|
|
1915
|
+
checkAtBottom(ctx, state);
|
|
1916
|
+
checkAtTop(state);
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
// src/updateItemSize.ts
|
|
1920
|
+
function updateItemSizes(ctx, state, itemUpdates) {
|
|
1921
|
+
var _a;
|
|
1922
|
+
const {
|
|
1923
|
+
props: { horizontal, maintainVisibleContentPosition, suggestEstimatedItemSize, onItemSizeChanged, data }
|
|
1924
|
+
} = state;
|
|
1925
|
+
if (!data) return;
|
|
1926
|
+
let needsRecalculate = false;
|
|
1927
|
+
let shouldMaintainScrollAtEnd = false;
|
|
1928
|
+
let minIndexSizeChanged;
|
|
1929
|
+
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
1930
|
+
for (const { itemKey, sizeObj } of itemUpdates) {
|
|
1931
|
+
const index = state.indexByKey.get(itemKey);
|
|
1932
|
+
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
1933
|
+
const diff = updateOneItemSize(state, itemKey, sizeObj);
|
|
1934
|
+
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
1935
|
+
if (diff !== 0) {
|
|
1936
|
+
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
1937
|
+
if (((_a = state.scrollingTo) == null ? void 0 : _a.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index) {
|
|
1938
|
+
requestAdjust(ctx, state, diff * state.scrollingTo.viewPosition);
|
|
1939
|
+
}
|
|
1940
|
+
const { startBuffered, endBuffered } = state;
|
|
1941
|
+
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
1942
|
+
if (!needsRecalculate) {
|
|
1943
|
+
const numContainers = ctx.values.get("numContainers");
|
|
1944
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1945
|
+
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
1946
|
+
needsRecalculate = true;
|
|
1947
|
+
break;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
if (state.needsOtherAxisSize) {
|
|
1952
|
+
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
1953
|
+
maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
|
|
1954
|
+
}
|
|
1955
|
+
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
1956
|
+
shouldMaintainScrollAtEnd = true;
|
|
1957
|
+
}
|
|
1958
|
+
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
1959
|
+
size,
|
|
1960
|
+
previous: size - diff,
|
|
1961
|
+
index,
|
|
1962
|
+
itemKey,
|
|
1963
|
+
itemData: state.props.data[index]
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
if (minIndexSizeChanged !== void 0) {
|
|
1968
|
+
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
|
|
1969
|
+
}
|
|
1970
|
+
if (__DEV__ && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
|
|
1971
|
+
if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
|
|
1972
|
+
state.timeoutSizeMessage = setTimeout(() => {
|
|
1973
|
+
var _a2;
|
|
1974
|
+
state.timeoutSizeMessage = void 0;
|
|
1975
|
+
const num = state.sizesKnown.size;
|
|
1976
|
+
const avg = (_a2 = state.averageSizes[""]) == null ? void 0 : _a2.avg;
|
|
1977
|
+
console.warn(
|
|
1978
|
+
`[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
|
|
1979
|
+
);
|
|
1980
|
+
}, 1e3);
|
|
1981
|
+
}
|
|
1982
|
+
const cur = peek$(ctx, "otherAxisSize");
|
|
1983
|
+
if (!cur || maxOtherAxisSize > cur) {
|
|
1984
|
+
set$(ctx, "otherAxisSize", maxOtherAxisSize);
|
|
1985
|
+
}
|
|
1986
|
+
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
1987
|
+
if (containersDidLayout || checkAllSizesKnown(state)) {
|
|
1988
|
+
if (needsRecalculate) {
|
|
1989
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1990
|
+
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1991
|
+
}
|
|
1992
|
+
if (shouldMaintainScrollAtEnd) {
|
|
1993
|
+
doMaintainScrollAtEnd(ctx, state, false);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
1998
|
+
var _a, _b;
|
|
1999
|
+
if (IsNewArchitecture) {
|
|
2000
|
+
const { sizesKnown } = state;
|
|
2001
|
+
const numContainers = ctx.values.get("numContainers");
|
|
2002
|
+
const changes = [];
|
|
2003
|
+
for (let i = 0; i < numContainers; i++) {
|
|
2004
|
+
const containerItemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2005
|
+
if (itemKey === containerItemKey) {
|
|
2006
|
+
changes.push({ itemKey, sizeObj });
|
|
2007
|
+
} else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
|
|
2008
|
+
const containerRef = ctx.viewRefs.get(i);
|
|
2009
|
+
if (containerRef) {
|
|
2010
|
+
const measured = (_b = (_a = containerRef.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
|
|
2011
|
+
if (measured) {
|
|
2012
|
+
changes.push({ itemKey: containerItemKey, sizeObj: measured });
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
if (changes.length > 0) {
|
|
2018
|
+
updateItemSizes(ctx, state, changes);
|
|
2019
|
+
}
|
|
2020
|
+
} else {
|
|
2021
|
+
updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
2025
|
+
const {
|
|
2026
|
+
sizes,
|
|
2027
|
+
indexByKey,
|
|
2028
|
+
sizesKnown,
|
|
2029
|
+
averageSizes,
|
|
2030
|
+
props: { data, horizontal }
|
|
2031
|
+
} = state;
|
|
2032
|
+
if (!data) return 0;
|
|
2033
|
+
const index = indexByKey.get(itemKey);
|
|
2034
|
+
const prevSize = getItemSize(state, itemKey, index, data);
|
|
2035
|
+
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2036
|
+
sizesKnown.set(itemKey, size);
|
|
2037
|
+
const itemType = "";
|
|
2038
|
+
let averages = averageSizes[itemType];
|
|
2039
|
+
if (!averages) {
|
|
2040
|
+
averages = averageSizes[itemType] = { num: 0, avg: 0 };
|
|
2041
|
+
}
|
|
2042
|
+
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2043
|
+
averages.num++;
|
|
2044
|
+
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2045
|
+
sizes.set(itemKey, size);
|
|
2046
|
+
return size - prevSize;
|
|
2047
|
+
}
|
|
2048
|
+
return 0;
|
|
2049
|
+
}
|
|
2050
|
+
var useCombinedRef = (...refs) => {
|
|
2051
|
+
const callback = React3.useCallback((element) => {
|
|
2052
|
+
for (const ref of refs) {
|
|
2053
|
+
if (!ref) {
|
|
2054
|
+
continue;
|
|
2055
|
+
}
|
|
2056
|
+
if (isFunction(ref)) {
|
|
2057
|
+
ref(element);
|
|
2058
|
+
} else {
|
|
2059
|
+
ref.current = element;
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}, refs);
|
|
2063
|
+
return callback;
|
|
2064
|
+
};
|
|
2065
|
+
|
|
2066
|
+
// src/LegendList.tsx
|
|
2067
|
+
var DEFAULT_DRAW_DISTANCE = 250;
|
|
2068
|
+
var DEFAULT_ITEM_SIZE = 100;
|
|
2069
|
+
var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
2070
|
+
return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
2071
|
+
});
|
|
2072
|
+
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
2073
|
+
var _a;
|
|
2074
|
+
const {
|
|
2075
|
+
data: dataProp = [],
|
|
2076
|
+
initialScrollIndex: initialScrollIndexProp,
|
|
2077
|
+
initialScrollOffset,
|
|
943
2078
|
horizontal,
|
|
944
2079
|
drawDistance = 250,
|
|
945
2080
|
recycleItems = false,
|
|
@@ -976,84 +2111,27 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
976
2111
|
viewabilityConfig,
|
|
977
2112
|
viewabilityConfigCallbackPairs,
|
|
978
2113
|
onViewableItemsChanged,
|
|
2114
|
+
onStartReached,
|
|
2115
|
+
onEndReached,
|
|
2116
|
+
onLoad,
|
|
979
2117
|
...rest
|
|
980
2118
|
} = props;
|
|
981
|
-
const [renderNum, setRenderNum] =
|
|
2119
|
+
const [renderNum, setRenderNum] = React3.useState(0);
|
|
982
2120
|
const initialScroll = typeof initialScrollIndexProp === "number" ? { index: initialScrollIndexProp } : initialScrollIndexProp;
|
|
983
2121
|
const initialScrollIndex = initialScroll == null ? void 0 : initialScroll.index;
|
|
984
|
-
const
|
|
985
|
-
const [canRender, setCanRender] = React2__namespace.useState(!IsNewArchitecture);
|
|
986
|
-
const callbacks = React2.useRef({
|
|
987
|
-
onStartReached: rest.onStartReached,
|
|
988
|
-
onEndReached: rest.onEndReached
|
|
989
|
-
});
|
|
990
|
-
callbacks.current.onStartReached = rest.onStartReached;
|
|
991
|
-
callbacks.current.onEndReached = rest.onEndReached;
|
|
2122
|
+
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
992
2123
|
const contentContainerStyle = { ...reactNative.StyleSheet.flatten(contentContainerStyleProp) };
|
|
993
2124
|
const style = { ...reactNative.StyleSheet.flatten(styleProp) };
|
|
994
2125
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
995
2126
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
996
2127
|
const ctx = useStateContext();
|
|
997
2128
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
998
|
-
const refScroller =
|
|
2129
|
+
const refScroller = React3.useRef(null);
|
|
999
2130
|
const combinedRef = useCombinedRef(refScroller, refScrollView);
|
|
1000
2131
|
const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
|
|
1001
2132
|
const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
|
|
1002
2133
|
const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
|
|
1003
|
-
const refState =
|
|
1004
|
-
const getId = (index) => {
|
|
1005
|
-
const state = refState.current;
|
|
1006
|
-
if (!(state == null ? void 0 : state.data)) {
|
|
1007
|
-
return "";
|
|
1008
|
-
}
|
|
1009
|
-
const data = state.data;
|
|
1010
|
-
const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
|
|
1011
|
-
const id = ret;
|
|
1012
|
-
state.idCache.set(index, id);
|
|
1013
|
-
return id;
|
|
1014
|
-
};
|
|
1015
|
-
const getItemSize = (key, index, data, useAverageSize = false) => {
|
|
1016
|
-
const state = refState.current;
|
|
1017
|
-
const sizeKnown = state.sizesKnown.get(key);
|
|
1018
|
-
if (sizeKnown !== void 0) {
|
|
1019
|
-
return sizeKnown;
|
|
1020
|
-
}
|
|
1021
|
-
const sizePrevious = state.sizes.get(key);
|
|
1022
|
-
if (sizePrevious !== void 0) {
|
|
1023
|
-
return sizePrevious;
|
|
1024
|
-
}
|
|
1025
|
-
const size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
|
|
1026
|
-
state.sizes.set(key, size);
|
|
1027
|
-
return size;
|
|
1028
|
-
};
|
|
1029
|
-
const calculateOffsetForIndex = (index) => {
|
|
1030
|
-
var _a2;
|
|
1031
|
-
let position = 0;
|
|
1032
|
-
if (index !== void 0) {
|
|
1033
|
-
position = ((_a2 = refState.current) == null ? void 0 : _a2.positions.get(getId(index))) || 0;
|
|
1034
|
-
}
|
|
1035
|
-
const paddingTop = peek$(ctx, "stylePaddingTop");
|
|
1036
|
-
if (paddingTop) {
|
|
1037
|
-
position += paddingTop;
|
|
1038
|
-
}
|
|
1039
|
-
const headerSize = peek$(ctx, "headerSize");
|
|
1040
|
-
if (headerSize) {
|
|
1041
|
-
position += headerSize;
|
|
1042
|
-
}
|
|
1043
|
-
return position;
|
|
1044
|
-
};
|
|
1045
|
-
const calculateOffsetWithOffsetPosition = (offsetParam, params) => {
|
|
1046
|
-
const { index, viewOffset, viewPosition } = params;
|
|
1047
|
-
let offset = offsetParam;
|
|
1048
|
-
const state = refState.current;
|
|
1049
|
-
if (viewOffset) {
|
|
1050
|
-
offset -= viewOffset;
|
|
1051
|
-
}
|
|
1052
|
-
if (viewPosition !== void 0 && index !== void 0) {
|
|
1053
|
-
offset -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
|
|
1054
|
-
}
|
|
1055
|
-
return offset;
|
|
1056
|
-
};
|
|
2134
|
+
const refState = React3.useRef();
|
|
1057
2135
|
if (!refState.current) {
|
|
1058
2136
|
const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { width: 0, height: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
|
|
1059
2137
|
refState.current = {
|
|
@@ -1065,7 +2143,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1065
2143
|
isEndReached: false,
|
|
1066
2144
|
isAtEnd: false,
|
|
1067
2145
|
isAtStart: false,
|
|
1068
|
-
data: dataProp,
|
|
1069
2146
|
scrollLength: initialScrollLength,
|
|
1070
2147
|
startBuffered: -1,
|
|
1071
2148
|
startNoBuffer: -1,
|
|
@@ -1076,7 +2153,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1076
2153
|
totalSize: 0,
|
|
1077
2154
|
timeouts: /* @__PURE__ */ new Set(),
|
|
1078
2155
|
viewabilityConfigCallbackPairs: void 0,
|
|
1079
|
-
renderItem: void 0,
|
|
1080
2156
|
scrollAdjustHandler: new ScrollAdjustHandler(ctx),
|
|
1081
2157
|
nativeMarginTop: 0,
|
|
1082
2158
|
scrollPrev: 0,
|
|
@@ -1095,775 +2171,93 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1095
2171
|
queuedCalculateItemsInView: 0,
|
|
1096
2172
|
lastBatchingAction: Date.now(),
|
|
1097
2173
|
averageSizes: {},
|
|
1098
|
-
onScroll: onScrollProp,
|
|
1099
2174
|
idsInView: [],
|
|
1100
2175
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
1101
|
-
idCache: /* @__PURE__ */ new Map()
|
|
2176
|
+
idCache: /* @__PURE__ */ new Map(),
|
|
2177
|
+
props: {},
|
|
2178
|
+
refScroller: void 0,
|
|
2179
|
+
loadStartTime: Date.now(),
|
|
2180
|
+
initialScroll
|
|
1102
2181
|
};
|
|
1103
2182
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
1104
2183
|
set$(ctx, "extraData", extraData);
|
|
1105
2184
|
}
|
|
1106
|
-
const
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1136
|
-
const timeDiff = newest.time - oldest.time;
|
|
1137
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
return velocity;
|
|
1141
|
-
};
|
|
1142
|
-
const updateAllPositions = (dataChanged) => {
|
|
1143
|
-
var _a2, _b, _c;
|
|
1144
|
-
const { columns, data, indexByKey, positions, firstFullyOnScreenIndex, idCache, sizes } = refState.current;
|
|
1145
|
-
const numColumns = (_a2 = peek$(ctx, "numColumns")) != null ? _a2 : numColumnsProp;
|
|
1146
|
-
const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
|
|
1147
|
-
const scrollVelocity = getScrollVelocity();
|
|
1148
|
-
if (dataChanged) {
|
|
1149
|
-
indexByKey.clear();
|
|
1150
|
-
idCache.clear();
|
|
1151
|
-
}
|
|
1152
|
-
const shouldUseBackwards = !dataChanged && scrollVelocity < 0 && firstFullyOnScreenIndex > 5 && firstFullyOnScreenIndex < data.length;
|
|
1153
|
-
if (shouldUseBackwards && firstFullyOnScreenIndex !== void 0) {
|
|
1154
|
-
const anchorId = getId(firstFullyOnScreenIndex);
|
|
1155
|
-
const anchorPosition = positions.get(anchorId);
|
|
1156
|
-
if (anchorPosition !== void 0) {
|
|
1157
|
-
let currentRowTop2 = anchorPosition;
|
|
1158
|
-
let maxSizeInRow2 = 0;
|
|
1159
|
-
let bailout = false;
|
|
1160
|
-
for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
|
|
1161
|
-
const id = getId(i);
|
|
1162
|
-
const size = getItemSize(id, i, data[i], false);
|
|
1163
|
-
const itemColumn = columns.get(id);
|
|
1164
|
-
maxSizeInRow2 = Math.max(maxSizeInRow2, size);
|
|
1165
|
-
if (itemColumn === 1) {
|
|
1166
|
-
currentRowTop2 -= maxSizeInRow2;
|
|
1167
|
-
maxSizeInRow2 = 0;
|
|
1168
|
-
}
|
|
1169
|
-
if (currentRowTop2 < -2e3) {
|
|
1170
|
-
bailout = true;
|
|
1171
|
-
break;
|
|
1172
|
-
}
|
|
1173
|
-
positions.set(id, currentRowTop2);
|
|
1174
|
-
}
|
|
1175
|
-
if (!bailout) {
|
|
1176
|
-
updateTotalSize();
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
let currentRowTop = 0;
|
|
1182
|
-
let column = 1;
|
|
1183
|
-
let maxSizeInRow = 0;
|
|
1184
|
-
const hasColumns = numColumns > 1;
|
|
1185
|
-
const needsIndexByKey = dataChanged || indexByKey.size === 0;
|
|
1186
|
-
const dataLength = data.length;
|
|
1187
|
-
for (let i = 0; i < dataLength; i++) {
|
|
1188
|
-
const id = (_b = idCache.get(i)) != null ? _b : getId(i);
|
|
1189
|
-
const size = (_c = sizes.get(id)) != null ? _c : getItemSize(id, i, data[i], false);
|
|
1190
|
-
if (__DEV__ && needsIndexByKey) {
|
|
1191
|
-
if (indexByKeyForChecking.has(id)) {
|
|
1192
|
-
console.error(
|
|
1193
|
-
`[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
|
|
1194
|
-
);
|
|
1195
|
-
}
|
|
1196
|
-
indexByKeyForChecking.set(id, i);
|
|
1197
|
-
}
|
|
1198
|
-
positions.set(id, currentRowTop);
|
|
1199
|
-
if (needsIndexByKey) {
|
|
1200
|
-
indexByKey.set(id, i);
|
|
1201
|
-
}
|
|
1202
|
-
columns.set(id, column);
|
|
1203
|
-
if (hasColumns) {
|
|
1204
|
-
if (size > maxSizeInRow) {
|
|
1205
|
-
maxSizeInRow = size;
|
|
1206
|
-
}
|
|
1207
|
-
column++;
|
|
1208
|
-
if (column > numColumns) {
|
|
1209
|
-
currentRowTop += maxSizeInRow;
|
|
1210
|
-
column = 1;
|
|
1211
|
-
maxSizeInRow = 0;
|
|
1212
|
-
}
|
|
1213
|
-
} else {
|
|
1214
|
-
currentRowTop += size;
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
updateTotalSize();
|
|
1218
|
-
};
|
|
1219
|
-
const scrollToIndex = ({
|
|
1220
|
-
index,
|
|
1221
|
-
viewOffset = 0,
|
|
1222
|
-
animated = true,
|
|
1223
|
-
viewPosition
|
|
1224
|
-
}) => {
|
|
1225
|
-
const state = refState.current;
|
|
1226
|
-
if (index >= state.data.length) {
|
|
1227
|
-
index = state.data.length - 1;
|
|
1228
|
-
} else if (index < 0) {
|
|
1229
|
-
index = 0;
|
|
1230
|
-
}
|
|
1231
|
-
const firstIndexOffset = calculateOffsetForIndex(index);
|
|
1232
|
-
const isLast = index === state.data.length - 1;
|
|
1233
|
-
if (isLast && viewPosition === void 0) {
|
|
1234
|
-
viewPosition = 1;
|
|
1235
|
-
}
|
|
1236
|
-
const firstIndexScrollPostion = firstIndexOffset - viewOffset;
|
|
1237
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1238
|
-
scrollTo({ offset: firstIndexScrollPostion, animated, index, viewPosition: viewPosition != null ? viewPosition : 0, viewOffset });
|
|
1239
|
-
};
|
|
1240
|
-
const setDidLayout = () => {
|
|
1241
|
-
refState.current.queuedInitialLayout = true;
|
|
1242
|
-
checkAtBottom();
|
|
1243
|
-
set$(ctx, "containersDidLayout", true);
|
|
1244
|
-
if (props.onLoad) {
|
|
1245
|
-
props.onLoad({ elapsedTimeInMs: Date.now() - refLoadStartTime.current });
|
|
1246
|
-
}
|
|
1247
|
-
};
|
|
1248
|
-
const addTotalSize = React2.useCallback((key, add) => {
|
|
1249
|
-
const state = refState.current;
|
|
1250
|
-
if (key === null) {
|
|
1251
|
-
state.totalSize = add;
|
|
1252
|
-
} else {
|
|
1253
|
-
state.totalSize += add;
|
|
1254
|
-
}
|
|
1255
|
-
set$(ctx, "totalSize", state.totalSize);
|
|
1256
|
-
if (alignItemsAtEnd) {
|
|
1257
|
-
updateAlignItemsPaddingTop();
|
|
1258
|
-
}
|
|
1259
|
-
}, []);
|
|
1260
|
-
const checkAllSizesKnown = React2.useCallback(() => {
|
|
1261
|
-
const { startBuffered, endBuffered, sizesKnown } = refState.current;
|
|
1262
|
-
if (endBuffered !== null) {
|
|
1263
|
-
let areAllKnown = true;
|
|
1264
|
-
for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
|
|
1265
|
-
const key = getId(i);
|
|
1266
|
-
areAllKnown && (areAllKnown = sizesKnown.has(key));
|
|
1267
|
-
}
|
|
1268
|
-
return areAllKnown;
|
|
1269
|
-
}
|
|
1270
|
-
return false;
|
|
1271
|
-
}, []);
|
|
1272
|
-
const requestAdjust = (positionDiff) => {
|
|
1273
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1274
|
-
const state = refState.current;
|
|
1275
|
-
const doit = () => {
|
|
1276
|
-
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1277
|
-
};
|
|
1278
|
-
state.scroll += positionDiff;
|
|
1279
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1280
|
-
if (peek$(ctx, "containersDidLayout")) {
|
|
1281
|
-
doit();
|
|
1282
|
-
} else {
|
|
1283
|
-
requestAnimationFrame(doit);
|
|
1284
|
-
}
|
|
1285
|
-
const threshold = state.scroll - positionDiff / 2;
|
|
1286
|
-
if (!state.ignoreScrollFromMVCP) {
|
|
1287
|
-
state.ignoreScrollFromMVCP = {};
|
|
1288
|
-
}
|
|
1289
|
-
if (positionDiff > 0) {
|
|
1290
|
-
state.ignoreScrollFromMVCP.lt = threshold;
|
|
1291
|
-
} else {
|
|
1292
|
-
state.ignoreScrollFromMVCP.gt = threshold;
|
|
1293
|
-
}
|
|
1294
|
-
if (state.ignoreScrollFromMVCPTimeout) {
|
|
1295
|
-
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
1296
|
-
}
|
|
1297
|
-
state.ignoreScrollFromMVCPTimeout = setTimeout(() => {
|
|
1298
|
-
state.ignoreScrollFromMVCP = void 0;
|
|
1299
|
-
}, 100);
|
|
1300
|
-
}
|
|
1301
|
-
};
|
|
1302
|
-
const prepareMVCP = React2.useCallback(() => {
|
|
1303
|
-
const state = refState.current;
|
|
1304
|
-
const { positions, scrollingTo } = state;
|
|
1305
|
-
let prevPosition;
|
|
1306
|
-
let targetId;
|
|
1307
|
-
let targetIndex;
|
|
1308
|
-
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
1309
|
-
if (maintainVisibleContentPosition) {
|
|
1310
|
-
const indexByKey = state.indexByKey;
|
|
1311
|
-
if (scrollTarget !== void 0) {
|
|
1312
|
-
targetId = getId(scrollTarget);
|
|
1313
|
-
targetIndex = scrollTarget;
|
|
1314
|
-
} else if (state.idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
|
|
1315
|
-
targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
1316
|
-
targetIndex = indexByKey.get(targetId);
|
|
1317
|
-
}
|
|
1318
|
-
if (targetId !== void 0 && targetIndex !== void 0) {
|
|
1319
|
-
prevPosition = positions.get(targetId);
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
return () => {
|
|
1323
|
-
if (targetId !== void 0 && prevPosition !== void 0) {
|
|
1324
|
-
const newPosition = positions.get(targetId);
|
|
1325
|
-
if (newPosition !== void 0) {
|
|
1326
|
-
const positionDiff = newPosition - prevPosition;
|
|
1327
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1328
|
-
requestAdjust(positionDiff);
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
};
|
|
1333
|
-
}, []);
|
|
1334
|
-
const calculateItemsInView = React2.useCallback((params = {}) => {
|
|
1335
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
1336
|
-
const state = refState.current;
|
|
1337
|
-
const {
|
|
1338
|
-
data,
|
|
1339
|
-
scrollLength,
|
|
1340
|
-
startBufferedId: startBufferedIdOrig,
|
|
1341
|
-
positions,
|
|
1342
|
-
columns,
|
|
1343
|
-
containerItemKeys,
|
|
1344
|
-
idCache,
|
|
1345
|
-
sizes,
|
|
1346
|
-
indexByKey,
|
|
1347
|
-
scrollForNextCalculateItemsInView,
|
|
1348
|
-
enableScrollForNextCalculateItemsInView,
|
|
1349
|
-
minIndexSizeChanged
|
|
1350
|
-
} = state;
|
|
1351
|
-
if (!data || scrollLength === 0) {
|
|
1352
|
-
return;
|
|
1353
|
-
}
|
|
1354
|
-
const totalSize = peek$(ctx, "totalSize");
|
|
1355
|
-
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
1356
|
-
const numColumns = peek$(ctx, "numColumns");
|
|
1357
|
-
const previousScrollAdjust = 0;
|
|
1358
|
-
const { dataChanged, doMVCP } = params;
|
|
1359
|
-
const speed = getScrollVelocity();
|
|
1360
|
-
if (doMVCP || dataChanged) {
|
|
1361
|
-
const checkMVCP = doMVCP ? prepareMVCP() : void 0;
|
|
1362
|
-
updateAllPositions(dataChanged);
|
|
1363
|
-
checkMVCP == null ? void 0 : checkMVCP();
|
|
1364
|
-
}
|
|
1365
|
-
const scrollExtra = 0;
|
|
1366
|
-
const useAverageSize = false;
|
|
1367
|
-
const { queuedInitialLayout } = state;
|
|
1368
|
-
let { scroll: scrollState } = state;
|
|
1369
|
-
if (!queuedInitialLayout && initialScroll) {
|
|
1370
|
-
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
1371
|
-
calculateOffsetForIndex(initialScroll.index),
|
|
1372
|
-
initialScroll
|
|
1373
|
-
);
|
|
1374
|
-
scrollState = updatedOffset;
|
|
1375
|
-
}
|
|
1376
|
-
const scrollAdjustPad = -previousScrollAdjust - topPad;
|
|
1377
|
-
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
1378
|
-
if (scroll + scrollLength > totalSize) {
|
|
1379
|
-
scroll = totalSize - scrollLength;
|
|
1380
|
-
}
|
|
1381
|
-
if (ENABLE_DEBUG_VIEW) {
|
|
1382
|
-
set$(ctx, "debugRawScroll", scrollState);
|
|
1383
|
-
set$(ctx, "debugComputedScroll", scroll);
|
|
1384
|
-
}
|
|
1385
|
-
let scrollBufferTop = scrollBuffer;
|
|
1386
|
-
let scrollBufferBottom = scrollBuffer;
|
|
1387
|
-
if (speed > 0) {
|
|
1388
|
-
scrollBufferTop = scrollBuffer * 0.5;
|
|
1389
|
-
scrollBufferBottom = scrollBuffer * 1.5;
|
|
1390
|
-
} else {
|
|
1391
|
-
scrollBufferTop = scrollBuffer * 1.5;
|
|
1392
|
-
scrollBufferBottom = scrollBuffer * 0.5;
|
|
1393
|
-
}
|
|
1394
|
-
const scrollTopBuffered = scroll - scrollBufferTop;
|
|
1395
|
-
const scrollBottom = scroll + scrollLength;
|
|
1396
|
-
const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
|
|
1397
|
-
if (scrollForNextCalculateItemsInView) {
|
|
1398
|
-
const { top, bottom } = scrollForNextCalculateItemsInView;
|
|
1399
|
-
if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
|
|
1400
|
-
return;
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
let startNoBuffer = null;
|
|
1404
|
-
let startBuffered = null;
|
|
1405
|
-
let startBufferedId = null;
|
|
1406
|
-
let endNoBuffer = null;
|
|
1407
|
-
let endBuffered = null;
|
|
1408
|
-
let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
1409
|
-
if (minIndexSizeChanged !== void 0) {
|
|
1410
|
-
loopStart = Math.min(minIndexSizeChanged, loopStart);
|
|
1411
|
-
state.minIndexSizeChanged = void 0;
|
|
1412
|
-
}
|
|
1413
|
-
for (let i = loopStart; i >= 0; i--) {
|
|
1414
|
-
const id = (_a2 = idCache.get(i)) != null ? _a2 : getId(i);
|
|
1415
|
-
const top = positions.get(id);
|
|
1416
|
-
const size = (_b = sizes.get(id)) != null ? _b : getItemSize(id, i, data[i], useAverageSize);
|
|
1417
|
-
const bottom = top + size;
|
|
1418
|
-
if (bottom > scroll - scrollBuffer) {
|
|
1419
|
-
loopStart = i;
|
|
1420
|
-
} else {
|
|
1421
|
-
break;
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
const loopStartMod = loopStart % numColumns;
|
|
1425
|
-
if (loopStartMod > 0) {
|
|
1426
|
-
loopStart -= loopStartMod;
|
|
1427
|
-
}
|
|
1428
|
-
let foundEnd = false;
|
|
1429
|
-
let nextTop;
|
|
1430
|
-
let nextBottom;
|
|
1431
|
-
const prevNumContainers = ctx.values.get("numContainers");
|
|
1432
|
-
let maxIndexRendered = 0;
|
|
1433
|
-
for (let i = 0; i < prevNumContainers; i++) {
|
|
1434
|
-
const key = peek$(ctx, `containerItemKey${i}`);
|
|
1435
|
-
if (key !== void 0) {
|
|
1436
|
-
const index = indexByKey.get(key);
|
|
1437
|
-
maxIndexRendered = Math.max(maxIndexRendered, index);
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
let firstFullyOnScreenIndex;
|
|
1441
|
-
const dataLength = data.length;
|
|
1442
|
-
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
1443
|
-
const id = (_c = idCache.get(i)) != null ? _c : getId(i);
|
|
1444
|
-
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(id, i, data[i], useAverageSize);
|
|
1445
|
-
const top = positions.get(id);
|
|
1446
|
-
if (!foundEnd) {
|
|
1447
|
-
if (startNoBuffer === null && top + size > scroll) {
|
|
1448
|
-
startNoBuffer = i;
|
|
1449
|
-
}
|
|
1450
|
-
if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
|
|
1451
|
-
firstFullyOnScreenIndex = i;
|
|
1452
|
-
}
|
|
1453
|
-
if (startBuffered === null && top + size > scrollTopBuffered) {
|
|
1454
|
-
startBuffered = i;
|
|
1455
|
-
startBufferedId = id;
|
|
1456
|
-
nextTop = top;
|
|
1457
|
-
}
|
|
1458
|
-
if (startNoBuffer !== null) {
|
|
1459
|
-
if (top <= scrollBottom) {
|
|
1460
|
-
endNoBuffer = i;
|
|
1461
|
-
}
|
|
1462
|
-
if (top <= scrollBottomBuffered) {
|
|
1463
|
-
endBuffered = i;
|
|
1464
|
-
nextBottom = top + size;
|
|
1465
|
-
} else {
|
|
1466
|
-
foundEnd = true;
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
const idsInView = [];
|
|
1472
|
-
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
1473
|
-
const id = (_e = idCache.get(i)) != null ? _e : getId(i);
|
|
1474
|
-
idsInView.push(id);
|
|
1475
|
-
}
|
|
1476
|
-
Object.assign(state, {
|
|
1477
|
-
startBuffered,
|
|
1478
|
-
startBufferedId,
|
|
1479
|
-
startNoBuffer,
|
|
1480
|
-
endBuffered,
|
|
1481
|
-
endNoBuffer,
|
|
1482
|
-
idsInView,
|
|
1483
|
-
firstFullyOnScreenIndex
|
|
1484
|
-
});
|
|
1485
|
-
if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
|
|
1486
|
-
state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
|
|
1487
|
-
top: nextTop,
|
|
1488
|
-
bottom: nextBottom
|
|
1489
|
-
} : void 0;
|
|
1490
|
-
}
|
|
1491
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
1492
|
-
const pendingRemoval = [];
|
|
1493
|
-
if (dataChanged) {
|
|
1494
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1495
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1496
|
-
if (!keyExtractorProp || itemKey && indexByKey.get(itemKey) === void 0) {
|
|
1497
|
-
pendingRemoval.push(i);
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
if (startBuffered !== null && endBuffered !== null) {
|
|
1502
|
-
let numContainers2 = prevNumContainers;
|
|
1503
|
-
const needNewContainers = [];
|
|
1504
|
-
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
1505
|
-
const id = (_f = idCache.get(i)) != null ? _f : getId(i);
|
|
1506
|
-
if (!containerItemKeys.has(id)) {
|
|
1507
|
-
needNewContainers.push(i);
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
if (needNewContainers.length > 0) {
|
|
1511
|
-
const availableContainers = findAvailableContainers(
|
|
1512
|
-
needNewContainers.length,
|
|
1513
|
-
startBuffered,
|
|
1514
|
-
endBuffered,
|
|
1515
|
-
pendingRemoval
|
|
1516
|
-
);
|
|
1517
|
-
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
1518
|
-
const i = needNewContainers[idx];
|
|
1519
|
-
const containerIndex = availableContainers[idx];
|
|
1520
|
-
const id = (_g = idCache.get(i)) != null ? _g : getId(i);
|
|
1521
|
-
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1522
|
-
if (oldKey && oldKey !== id) {
|
|
1523
|
-
containerItemKeys.delete(oldKey);
|
|
1524
|
-
}
|
|
1525
|
-
set$(ctx, `containerItemKey${containerIndex}`, id);
|
|
1526
|
-
set$(ctx, `containerItemData${containerIndex}`, data[i]);
|
|
1527
|
-
containerItemKeys.add(id);
|
|
1528
|
-
if (containerIndex >= numContainers2) {
|
|
1529
|
-
numContainers2 = containerIndex + 1;
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
if (numContainers2 !== prevNumContainers) {
|
|
1533
|
-
set$(ctx, "numContainers", numContainers2);
|
|
1534
|
-
if (numContainers2 > peek$(ctx, "numContainersPooled")) {
|
|
1535
|
-
set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
for (let i = 0; i < numContainers2; i++) {
|
|
1540
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1541
|
-
if (pendingRemoval.includes(i)) {
|
|
1542
|
-
if (itemKey) {
|
|
1543
|
-
containerItemKeys.delete(itemKey);
|
|
1544
|
-
}
|
|
1545
|
-
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1546
|
-
set$(ctx, `containerItemData${i}`, void 0);
|
|
1547
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1548
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
1549
|
-
} else {
|
|
1550
|
-
const itemIndex = indexByKey.get(itemKey);
|
|
1551
|
-
const item = data[itemIndex];
|
|
1552
|
-
if (item !== void 0) {
|
|
1553
|
-
const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(itemIndex);
|
|
1554
|
-
const position = positions.get(id);
|
|
1555
|
-
if (position === void 0) {
|
|
1556
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1557
|
-
} else {
|
|
1558
|
-
const pos = positions.get(id);
|
|
1559
|
-
const column = columns.get(id) || 1;
|
|
1560
|
-
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
1561
|
-
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
1562
|
-
const prevData = peek$(ctx, `containerItemData${i}`);
|
|
1563
|
-
if (!prevPos || pos > POSITION_OUT_OF_VIEW && pos !== prevPos) {
|
|
1564
|
-
set$(ctx, `containerPosition${i}`, pos);
|
|
1565
|
-
}
|
|
1566
|
-
if (column >= 0 && column !== prevColumn) {
|
|
1567
|
-
set$(ctx, `containerColumn${i}`, column);
|
|
1568
|
-
}
|
|
1569
|
-
if (prevData !== item) {
|
|
1570
|
-
set$(ctx, `containerItemData${i}`, data[itemIndex]);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
if (!queuedInitialLayout && endBuffered !== null) {
|
|
1578
|
-
if (checkAllSizesKnown()) {
|
|
1579
|
-
setDidLayout();
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
if (viewabilityConfigCallbackPairs) {
|
|
1583
|
-
updateViewableItems(
|
|
1584
|
-
state,
|
|
1585
|
-
ctx,
|
|
1586
|
-
viewabilityConfigCallbackPairs,
|
|
1587
|
-
getId,
|
|
1588
|
-
scrollLength,
|
|
1589
|
-
startNoBuffer,
|
|
1590
|
-
endNoBuffer
|
|
1591
|
-
);
|
|
1592
|
-
}
|
|
1593
|
-
}, []);
|
|
1594
|
-
const setPaddingTop = ({
|
|
1595
|
-
stylePaddingTop,
|
|
1596
|
-
alignItemsPaddingTop
|
|
1597
|
-
}) => {
|
|
1598
|
-
if (stylePaddingTop !== void 0) {
|
|
1599
|
-
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
1600
|
-
if (stylePaddingTop < prevStylePaddingTop) {
|
|
1601
|
-
const prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1602
|
-
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
1603
|
-
setTimeout(() => {
|
|
1604
|
-
set$(ctx, "totalSize", prevTotalSize);
|
|
1605
|
-
}, 16);
|
|
1606
|
-
}
|
|
1607
|
-
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1608
|
-
}
|
|
1609
|
-
if (alignItemsPaddingTop !== void 0) {
|
|
1610
|
-
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1611
|
-
}
|
|
1612
|
-
};
|
|
1613
|
-
const updateAlignItemsPaddingTop = () => {
|
|
1614
|
-
if (alignItemsAtEnd) {
|
|
1615
|
-
const { data, scrollLength } = refState.current;
|
|
1616
|
-
let alignItemsPaddingTop = 0;
|
|
1617
|
-
if ((data == null ? void 0 : data.length) > 0) {
|
|
1618
|
-
const contentSize = getContentSize(ctx);
|
|
1619
|
-
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1620
|
-
}
|
|
1621
|
-
setPaddingTop({ alignItemsPaddingTop });
|
|
1622
|
-
}
|
|
1623
|
-
};
|
|
1624
|
-
const finishScrollTo = () => {
|
|
1625
|
-
const state = refState.current;
|
|
1626
|
-
if (state) {
|
|
1627
|
-
state.scrollingTo = void 0;
|
|
1628
|
-
state.scrollHistory.length = 0;
|
|
1629
|
-
}
|
|
1630
|
-
};
|
|
1631
|
-
const scrollTo = (params = {}) => {
|
|
1632
|
-
var _a2;
|
|
1633
|
-
const state = refState.current;
|
|
1634
|
-
const { animated } = params;
|
|
1635
|
-
const offset = calculateOffsetWithOffsetPosition(params.offset, params);
|
|
1636
|
-
state.scrollHistory.length = 0;
|
|
1637
|
-
state.scrollingTo = params;
|
|
1638
|
-
state.scrollPending = offset;
|
|
1639
|
-
(_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
|
|
1640
|
-
x: horizontal ? offset : 0,
|
|
1641
|
-
y: horizontal ? 0 : offset,
|
|
1642
|
-
animated: !!animated
|
|
1643
|
-
});
|
|
1644
|
-
if (!animated) {
|
|
1645
|
-
refState.current.scroll = offset;
|
|
1646
|
-
setTimeout(finishScrollTo, 100);
|
|
1647
|
-
}
|
|
1648
|
-
};
|
|
1649
|
-
const doMaintainScrollAtEnd = (animated) => {
|
|
1650
|
-
const state = refState.current;
|
|
1651
|
-
if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
|
|
1652
|
-
const paddingTop = peek$(ctx, "alignItemsPaddingTop");
|
|
1653
|
-
if (paddingTop > 0) {
|
|
1654
|
-
state.scroll = 0;
|
|
1655
|
-
}
|
|
1656
|
-
requestAnimationFrame(() => {
|
|
1657
|
-
var _a2;
|
|
1658
|
-
state.maintainingScrollAtEnd = true;
|
|
1659
|
-
(_a2 = refScroller.current) == null ? void 0 : _a2.scrollToEnd({
|
|
1660
|
-
animated
|
|
1661
|
-
});
|
|
1662
|
-
setTimeout(
|
|
1663
|
-
() => {
|
|
1664
|
-
state.maintainingScrollAtEnd = false;
|
|
1665
|
-
},
|
|
1666
|
-
0
|
|
1667
|
-
);
|
|
1668
|
-
});
|
|
1669
|
-
return true;
|
|
1670
|
-
}
|
|
1671
|
-
};
|
|
1672
|
-
const checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
|
|
1673
|
-
const distanceAbs = Math.abs(distance);
|
|
1674
|
-
const isAtThreshold = atThreshold || distanceAbs < threshold;
|
|
1675
|
-
if (!isReached && !isBlockedByTimer) {
|
|
1676
|
-
if (isAtThreshold) {
|
|
1677
|
-
onReached == null ? void 0 : onReached(distance);
|
|
1678
|
-
blockTimer == null ? void 0 : blockTimer(true);
|
|
1679
|
-
setTimeout(() => {
|
|
1680
|
-
blockTimer == null ? void 0 : blockTimer(false);
|
|
1681
|
-
}, 700);
|
|
1682
|
-
return true;
|
|
1683
|
-
}
|
|
1684
|
-
} else {
|
|
1685
|
-
if (distance >= 1.3 * threshold) {
|
|
1686
|
-
return false;
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
return isReached;
|
|
1690
|
-
};
|
|
1691
|
-
const checkAtBottom = () => {
|
|
1692
|
-
if (!refState.current) {
|
|
1693
|
-
return;
|
|
1694
|
-
}
|
|
1695
|
-
const { queuedInitialLayout, scrollLength, scroll, maintainingScrollAtEnd } = refState.current;
|
|
1696
|
-
const contentSize = getContentSize(ctx);
|
|
1697
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1698
|
-
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1699
|
-
const isContentLess = contentSize < scrollLength;
|
|
1700
|
-
refState.current.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1701
|
-
refState.current.isEndReached = checkThreshold(
|
|
1702
|
-
distanceFromEnd,
|
|
1703
|
-
isContentLess,
|
|
1704
|
-
onEndReachedThreshold * scrollLength,
|
|
1705
|
-
refState.current.isEndReached,
|
|
1706
|
-
refState.current.endReachedBlockedByTimer,
|
|
1707
|
-
(distance) => {
|
|
1708
|
-
var _a2, _b;
|
|
1709
|
-
return (_b = (_a2 = callbacks.current).onEndReached) == null ? void 0 : _b.call(_a2, { distanceFromEnd: distance });
|
|
1710
|
-
},
|
|
1711
|
-
(block) => {
|
|
1712
|
-
refState.current.endReachedBlockedByTimer = block;
|
|
1713
|
-
}
|
|
1714
|
-
);
|
|
1715
|
-
}
|
|
1716
|
-
};
|
|
1717
|
-
const checkAtTop = () => {
|
|
1718
|
-
if (!refState.current) {
|
|
1719
|
-
return;
|
|
1720
|
-
}
|
|
1721
|
-
const { scrollLength, scroll } = refState.current;
|
|
1722
|
-
const distanceFromTop = scroll;
|
|
1723
|
-
refState.current.isAtStart = distanceFromTop <= 0;
|
|
1724
|
-
refState.current.isStartReached = checkThreshold(
|
|
1725
|
-
distanceFromTop,
|
|
1726
|
-
false,
|
|
1727
|
-
onStartReachedThreshold * scrollLength,
|
|
1728
|
-
refState.current.isStartReached,
|
|
1729
|
-
refState.current.startReachedBlockedByTimer,
|
|
1730
|
-
(distance) => {
|
|
1731
|
-
var _a2, _b;
|
|
1732
|
-
return (_b = (_a2 = callbacks.current).onStartReached) == null ? void 0 : _b.call(_a2, { distanceFromStart: distance });
|
|
1733
|
-
},
|
|
1734
|
-
(block) => {
|
|
1735
|
-
refState.current.startReachedBlockedByTimer = block;
|
|
1736
|
-
}
|
|
1737
|
-
);
|
|
2185
|
+
const state = refState.current;
|
|
2186
|
+
const isFirst = !state.props.renderItem;
|
|
2187
|
+
const didDataChange = state.props.data !== dataProp;
|
|
2188
|
+
state.props = {
|
|
2189
|
+
alignItemsAtEnd,
|
|
2190
|
+
data: dataProp,
|
|
2191
|
+
estimatedItemSize,
|
|
2192
|
+
maintainScrollAtEnd,
|
|
2193
|
+
maintainScrollAtEndThreshold,
|
|
2194
|
+
onEndReachedThreshold,
|
|
2195
|
+
onStartReachedThreshold,
|
|
2196
|
+
stylePaddingBottom: stylePaddingBottomState,
|
|
2197
|
+
horizontal: !!horizontal,
|
|
2198
|
+
maintainVisibleContentPosition,
|
|
2199
|
+
onItemSizeChanged,
|
|
2200
|
+
suggestEstimatedItemSize: !!suggestEstimatedItemSize,
|
|
2201
|
+
keyExtractor,
|
|
2202
|
+
onScroll: onScrollProp,
|
|
2203
|
+
getEstimatedItemSize,
|
|
2204
|
+
onStartReached,
|
|
2205
|
+
onEndReached,
|
|
2206
|
+
onLoad,
|
|
2207
|
+
renderItem: renderItem2,
|
|
2208
|
+
initialScroll,
|
|
2209
|
+
scrollBuffer,
|
|
2210
|
+
viewabilityConfigCallbackPairs: void 0,
|
|
2211
|
+
numColumns: numColumnsProp,
|
|
2212
|
+
initialContainerPoolRatio,
|
|
2213
|
+
stylePaddingTop: stylePaddingTopState
|
|
1738
2214
|
};
|
|
2215
|
+
state.refScroller = refScroller;
|
|
1739
2216
|
const checkResetContainers = (isFirst2) => {
|
|
1740
|
-
const
|
|
1741
|
-
if (
|
|
1742
|
-
|
|
2217
|
+
const state2 = refState.current;
|
|
2218
|
+
if (state2) {
|
|
2219
|
+
state2.props.data = dataProp;
|
|
1743
2220
|
if (!isFirst2) {
|
|
1744
|
-
calculateItemsInView({ dataChanged: true, doMVCP: true });
|
|
1745
|
-
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1746
|
-
if (!didMaintainScrollAtEnd && dataProp.length >
|
|
1747
|
-
|
|
2221
|
+
calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
|
|
2222
|
+
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(ctx, state2, false);
|
|
2223
|
+
if (!didMaintainScrollAtEnd && dataProp.length > state2.props.data.length) {
|
|
2224
|
+
state2.isEndReached = false;
|
|
1748
2225
|
}
|
|
1749
2226
|
if (!didMaintainScrollAtEnd) {
|
|
1750
|
-
checkAtTop();
|
|
1751
|
-
checkAtBottom();
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
};
|
|
1756
|
-
const updateTotalSize = () => {
|
|
1757
|
-
const { data, positions } = refState.current;
|
|
1758
|
-
if (data.length === 0) {
|
|
1759
|
-
addTotalSize(null, 0);
|
|
1760
|
-
} else {
|
|
1761
|
-
const lastId = getId(data.length - 1);
|
|
1762
|
-
if (lastId !== void 0) {
|
|
1763
|
-
const lastPosition = positions.get(lastId);
|
|
1764
|
-
if (lastPosition !== void 0) {
|
|
1765
|
-
const lastSize = getItemSize(lastId, data.length - 1, data[dataProp.length - 1]);
|
|
1766
|
-
if (lastSize !== void 0) {
|
|
1767
|
-
const totalSize = lastPosition + lastSize;
|
|
1768
|
-
addTotalSize(null, totalSize);
|
|
1769
|
-
}
|
|
2227
|
+
checkAtTop(state2);
|
|
2228
|
+
checkAtBottom(ctx, state2);
|
|
1770
2229
|
}
|
|
1771
2230
|
}
|
|
1772
2231
|
}
|
|
1773
2232
|
};
|
|
1774
|
-
const
|
|
1775
|
-
const state = refState.current;
|
|
1776
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
1777
|
-
const result = [];
|
|
1778
|
-
const availableContainers = [];
|
|
1779
|
-
for (let u = 0; u < numContainers; u++) {
|
|
1780
|
-
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1781
|
-
let isOk = key === void 0;
|
|
1782
|
-
if (!isOk) {
|
|
1783
|
-
const index = pendingRemoval.indexOf(u);
|
|
1784
|
-
if (index !== -1) {
|
|
1785
|
-
pendingRemoval.splice(index, 1);
|
|
1786
|
-
isOk = true;
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
if (isOk) {
|
|
1790
|
-
result.push(u);
|
|
1791
|
-
if (result.length >= numNeeded) {
|
|
1792
|
-
return result;
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
for (let u = 0; u < numContainers; u++) {
|
|
1797
|
-
const key = peek$(ctx, `containerItemKey${u}`);
|
|
1798
|
-
if (key === void 0) continue;
|
|
1799
|
-
const index = state.indexByKey.get(key);
|
|
1800
|
-
if (index < startBuffered) {
|
|
1801
|
-
availableContainers.push({ index: u, distance: startBuffered - index });
|
|
1802
|
-
} else if (index > endBuffered) {
|
|
1803
|
-
availableContainers.push({ index: u, distance: index - endBuffered });
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
const remaining = numNeeded - result.length;
|
|
1807
|
-
if (remaining > 0) {
|
|
1808
|
-
if (availableContainers.length > 0) {
|
|
1809
|
-
if (availableContainers.length > remaining) {
|
|
1810
|
-
availableContainers.sort(comparatorByDistance);
|
|
1811
|
-
availableContainers.length = remaining;
|
|
1812
|
-
}
|
|
1813
|
-
for (const container of availableContainers) {
|
|
1814
|
-
result.push(container.index);
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
const stillNeeded = numNeeded - result.length;
|
|
1818
|
-
if (stillNeeded > 0) {
|
|
1819
|
-
for (let i = 0; i < stillNeeded; i++) {
|
|
1820
|
-
result.push(numContainers + i);
|
|
1821
|
-
}
|
|
1822
|
-
if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
|
|
1823
|
-
console.warn(
|
|
1824
|
-
"[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
|
|
1825
|
-
{
|
|
1826
|
-
debugInfo: {
|
|
1827
|
-
numContainers,
|
|
1828
|
-
numNeeded,
|
|
1829
|
-
stillNeeded,
|
|
1830
|
-
numContainersPooled: peek$(ctx, "numContainersPooled")
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
);
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
return result.sort(comparatorDefault);
|
|
1838
|
-
};
|
|
1839
|
-
const isFirst = !refState.current.renderItem;
|
|
1840
|
-
const memoizedLastItemKeys = React2.useMemo(() => {
|
|
2233
|
+
const memoizedLastItemKeys = React3.useMemo(() => {
|
|
1841
2234
|
if (!dataProp.length) return [];
|
|
1842
2235
|
return Array.from(
|
|
1843
2236
|
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
1844
|
-
(_, i) => getId(dataProp.length - 1 - i)
|
|
2237
|
+
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
1845
2238
|
);
|
|
1846
2239
|
}, [dataProp, numColumnsProp]);
|
|
1847
2240
|
const initalizeStateVars = () => {
|
|
1848
2241
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
1849
2242
|
set$(ctx, "numColumns", numColumnsProp);
|
|
1850
2243
|
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
1851
|
-
setPaddingTop({ stylePaddingTop: stylePaddingTopState });
|
|
1852
|
-
refState.current.stylePaddingBottom = stylePaddingBottomState;
|
|
2244
|
+
setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
|
|
2245
|
+
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
1853
2246
|
const paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
1854
2247
|
if (paddingDiff && prevPaddingTop !== void 0 && reactNative.Platform.OS === "ios") {
|
|
1855
|
-
|
|
2248
|
+
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
2249
|
+
requestAdjust(ctx, state, paddingDiff);
|
|
1856
2250
|
}
|
|
1857
2251
|
};
|
|
1858
2252
|
if (isFirst) {
|
|
1859
2253
|
initalizeStateVars();
|
|
1860
|
-
updateAllPositions();
|
|
2254
|
+
updateAllPositions(ctx, state);
|
|
1861
2255
|
}
|
|
1862
|
-
const initialContentOffset =
|
|
1863
|
-
const initialContentOffset2 = initialScrollOffset || calculateOffsetForIndex(initialScrollIndex);
|
|
2256
|
+
const initialContentOffset = React3.useMemo(() => {
|
|
2257
|
+
const initialContentOffset2 = initialScrollOffset || calculateOffsetForIndex(ctx, state, initialScrollIndex);
|
|
1864
2258
|
refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
|
|
1865
2259
|
if (initialContentOffset2 > 0) {
|
|
1866
|
-
scrollTo({ offset: initialContentOffset2, animated: false, index: initialScrollIndex });
|
|
2260
|
+
scrollTo(state, { offset: initialContentOffset2, animated: false, index: initialScrollIndex });
|
|
1867
2261
|
}
|
|
1868
2262
|
return initialContentOffset2;
|
|
1869
2263
|
}, [renderNum]);
|
|
@@ -1878,22 +2272,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1878
2272
|
refState.current.positions.clear();
|
|
1879
2273
|
}
|
|
1880
2274
|
}
|
|
1881
|
-
|
|
2275
|
+
React3.useLayoutEffect(() => {
|
|
1882
2276
|
var _a2, _b;
|
|
1883
2277
|
if (IsNewArchitecture) {
|
|
1884
2278
|
const measured = (_b = (_a2 = refScroller.current) == null ? void 0 : _a2.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a2);
|
|
1885
2279
|
if (measured) {
|
|
1886
2280
|
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
1887
2281
|
if (size) {
|
|
1888
|
-
handleLayout(measured);
|
|
2282
|
+
handleLayout(ctx, state, measured, setCanRender);
|
|
1889
2283
|
}
|
|
1890
2284
|
}
|
|
1891
2285
|
}
|
|
1892
2286
|
if (!isFirst) {
|
|
1893
|
-
calculateItemsInView({ doMVCP: true });
|
|
2287
|
+
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1894
2288
|
}
|
|
1895
2289
|
}, [dataProp]);
|
|
1896
|
-
const onLayoutHeader =
|
|
2290
|
+
const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
|
|
1897
2291
|
const size = rect[horizontal ? "width" : "height"];
|
|
1898
2292
|
set$(ctx, "headerSize", size);
|
|
1899
2293
|
if (initialScroll) {
|
|
@@ -1903,13 +2297,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1903
2297
|
}
|
|
1904
2298
|
} else {
|
|
1905
2299
|
setTimeout(() => {
|
|
1906
|
-
scrollToIndex({ ...initialScroll, animated: false });
|
|
2300
|
+
scrollToIndex(ctx, state, { ...initialScroll, animated: false });
|
|
1907
2301
|
}, 17);
|
|
1908
2302
|
}
|
|
1909
2303
|
}
|
|
1910
2304
|
}, []);
|
|
1911
|
-
|
|
1912
|
-
const didAllocateContainers =
|
|
2305
|
+
React3.useLayoutEffect(() => {
|
|
2306
|
+
const didAllocateContainers = doInitialAllocateContainersCallback();
|
|
1913
2307
|
if (!didAllocateContainers) {
|
|
1914
2308
|
checkResetContainers(
|
|
1915
2309
|
/*isFirst*/
|
|
@@ -1917,297 +2311,51 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1917
2311
|
);
|
|
1918
2312
|
}
|
|
1919
2313
|
}, [dataProp, numColumnsProp]);
|
|
1920
|
-
|
|
2314
|
+
React3.useLayoutEffect(() => {
|
|
1921
2315
|
set$(ctx, "extraData", extraData);
|
|
1922
2316
|
}, [extraData]);
|
|
1923
|
-
|
|
1924
|
-
React2.useLayoutEffect(initalizeStateVars, [
|
|
2317
|
+
React3.useLayoutEffect(initalizeStateVars, [
|
|
1925
2318
|
memoizedLastItemKeys.join(","),
|
|
1926
2319
|
numColumnsProp,
|
|
1927
2320
|
stylePaddingTopState,
|
|
1928
2321
|
stylePaddingBottomState
|
|
1929
2322
|
]);
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
if (!state) {
|
|
1933
|
-
return null;
|
|
1934
|
-
}
|
|
1935
|
-
const { data, indexByKey } = state;
|
|
1936
|
-
const index = indexByKey.get(key);
|
|
1937
|
-
if (index === void 0) {
|
|
1938
|
-
return null;
|
|
1939
|
-
}
|
|
1940
|
-
const renderItemProp = refState.current.renderItem;
|
|
1941
|
-
let renderedItem = null;
|
|
1942
|
-
if (renderItemProp) {
|
|
1943
|
-
const itemProps = {
|
|
1944
|
-
item: data[index],
|
|
1945
|
-
index,
|
|
1946
|
-
extraData: peek$(ctx, "extraData")
|
|
1947
|
-
};
|
|
1948
|
-
renderedItem = React2__namespace.createElement(renderItemProp, itemProps);
|
|
1949
|
-
}
|
|
1950
|
-
return { index, item: data[index], renderedItem };
|
|
1951
|
-
}, []);
|
|
1952
|
-
const doInitialAllocateContainers = () => {
|
|
1953
|
-
const state = refState.current;
|
|
1954
|
-
const { scrollLength, data } = state;
|
|
1955
|
-
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
1956
|
-
const averageItemSize = getEstimatedItemSize ? getEstimatedItemSize(0, data[0]) : estimatedItemSize;
|
|
1957
|
-
const Extra = 1.5;
|
|
1958
|
-
const numContainers = Math.ceil(
|
|
1959
|
-
(scrollLength + scrollBuffer * 2) / averageItemSize * numColumnsProp * Extra
|
|
1960
|
-
);
|
|
1961
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1962
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1963
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
1964
|
-
}
|
|
1965
|
-
set$(ctx, "numContainers", numContainers);
|
|
1966
|
-
set$(ctx, "numContainersPooled", numContainers * initialContainerPoolRatio);
|
|
1967
|
-
if (!IsNewArchitecture) {
|
|
1968
|
-
if (initialScroll) {
|
|
1969
|
-
requestAnimationFrame(() => {
|
|
1970
|
-
calculateItemsInView();
|
|
1971
|
-
});
|
|
1972
|
-
} else {
|
|
1973
|
-
calculateItemsInView();
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
return true;
|
|
1977
|
-
}
|
|
2323
|
+
const doInitialAllocateContainersCallback = () => {
|
|
2324
|
+
return doInitialAllocateContainers(ctx, state);
|
|
1978
2325
|
};
|
|
1979
|
-
|
|
1980
|
-
const state = refState.current;
|
|
2326
|
+
React3.useEffect(() => {
|
|
1981
2327
|
const viewability = setupViewability({
|
|
1982
2328
|
viewabilityConfig,
|
|
1983
2329
|
viewabilityConfigCallbackPairs,
|
|
1984
2330
|
onViewableItemsChanged
|
|
1985
2331
|
});
|
|
1986
2332
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
2333
|
+
state.props.viewabilityConfigCallbackPairs = viewability;
|
|
1987
2334
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
1988
2335
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
1989
2336
|
if (!IsNewArchitecture) {
|
|
1990
2337
|
useInit(() => {
|
|
1991
|
-
|
|
2338
|
+
doInitialAllocateContainersCallback();
|
|
1992
2339
|
});
|
|
1993
2340
|
}
|
|
1994
|
-
const
|
|
1995
|
-
const state = refState.current;
|
|
1996
|
-
const { sizes, indexByKey, sizesKnown, data, averageSizes } = state;
|
|
1997
|
-
if (!data) return 0;
|
|
1998
|
-
const index = indexByKey.get(itemKey);
|
|
1999
|
-
const prevSize = getItemSize(itemKey, index, data);
|
|
2000
|
-
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2001
|
-
sizesKnown.set(itemKey, size);
|
|
2002
|
-
const itemType = "";
|
|
2003
|
-
let averages = averageSizes[itemType];
|
|
2004
|
-
if (!averages) {
|
|
2005
|
-
averages = averageSizes[itemType] = { num: 0, avg: 0 };
|
|
2006
|
-
}
|
|
2007
|
-
averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
|
|
2008
|
-
averages.num++;
|
|
2009
|
-
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2010
|
-
sizes.set(itemKey, size);
|
|
2011
|
-
return size - prevSize;
|
|
2012
|
-
}
|
|
2013
|
-
return 0;
|
|
2014
|
-
}, []);
|
|
2015
|
-
const updateItemSizes = React2.useCallback(
|
|
2016
|
-
(itemUpdates) => {
|
|
2017
|
-
var _a2;
|
|
2018
|
-
const state = refState.current;
|
|
2019
|
-
if (!state.data) return;
|
|
2020
|
-
let needsRecalculate = false;
|
|
2021
|
-
let shouldMaintainScrollAtEnd = false;
|
|
2022
|
-
let minIndexSizeChanged;
|
|
2023
|
-
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
2024
|
-
for (const { itemKey, sizeObj } of itemUpdates) {
|
|
2025
|
-
const index = state.indexByKey.get(itemKey);
|
|
2026
|
-
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
2027
|
-
const diff = updateOneItemSize(itemKey, sizeObj);
|
|
2028
|
-
const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
|
|
2029
|
-
if (diff !== 0) {
|
|
2030
|
-
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
2031
|
-
if (((_a2 = state.scrollingTo) == null ? void 0 : _a2.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index) {
|
|
2032
|
-
requestAdjust(diff * state.scrollingTo.viewPosition);
|
|
2033
|
-
}
|
|
2034
|
-
const { startBuffered, endBuffered } = state;
|
|
2035
|
-
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
2036
|
-
if (!needsRecalculate) {
|
|
2037
|
-
const numContainers = ctx.values.get("numContainers");
|
|
2038
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2039
|
-
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
2040
|
-
needsRecalculate = true;
|
|
2041
|
-
break;
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
}
|
|
2045
|
-
if (state.needsOtherAxisSize) {
|
|
2046
|
-
const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
|
|
2047
|
-
maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
|
|
2048
|
-
}
|
|
2049
|
-
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
2050
|
-
shouldMaintainScrollAtEnd = true;
|
|
2051
|
-
}
|
|
2052
|
-
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
2053
|
-
size,
|
|
2054
|
-
previous: size - diff,
|
|
2055
|
-
index,
|
|
2056
|
-
itemKey,
|
|
2057
|
-
itemData: state.data[index]
|
|
2058
|
-
});
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2061
|
-
if (minIndexSizeChanged !== void 0) {
|
|
2062
|
-
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
|
|
2063
|
-
}
|
|
2064
|
-
if (__DEV__ && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
|
|
2065
|
-
if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
|
|
2066
|
-
state.timeoutSizeMessage = setTimeout(() => {
|
|
2067
|
-
var _a3;
|
|
2068
|
-
state.timeoutSizeMessage = void 0;
|
|
2069
|
-
const num = state.sizesKnown.size;
|
|
2070
|
-
const avg = (_a3 = state.averageSizes[""]) == null ? void 0 : _a3.avg;
|
|
2071
|
-
console.warn(
|
|
2072
|
-
`[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
|
|
2073
|
-
);
|
|
2074
|
-
}, 1e3);
|
|
2075
|
-
}
|
|
2076
|
-
const cur = peek$(ctx, "otherAxisSize");
|
|
2077
|
-
if (!cur || maxOtherAxisSize > cur) {
|
|
2078
|
-
set$(ctx, "otherAxisSize", maxOtherAxisSize);
|
|
2079
|
-
}
|
|
2080
|
-
const containersDidLayout = peek$(ctx, "containersDidLayout");
|
|
2081
|
-
if (containersDidLayout || checkAllSizesKnown()) {
|
|
2082
|
-
if (needsRecalculate) {
|
|
2083
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2084
|
-
calculateItemsInView({ doMVCP: true });
|
|
2085
|
-
}
|
|
2086
|
-
if (shouldMaintainScrollAtEnd) {
|
|
2087
|
-
doMaintainScrollAtEnd(false);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
},
|
|
2091
|
-
[]
|
|
2092
|
-
);
|
|
2093
|
-
const updateItemSize = React2.useCallback((itemKey, sizeObj) => {
|
|
2094
|
-
var _a2, _b;
|
|
2095
|
-
if (IsNewArchitecture) {
|
|
2096
|
-
const { sizesKnown } = refState.current;
|
|
2097
|
-
const numContainers = ctx.values.get("numContainers");
|
|
2098
|
-
const changes = [];
|
|
2099
|
-
for (let i = 0; i < numContainers; i++) {
|
|
2100
|
-
const containerItemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2101
|
-
if (itemKey === containerItemKey) {
|
|
2102
|
-
changes.push({ itemKey, sizeObj });
|
|
2103
|
-
} else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
|
|
2104
|
-
const containerRef = ctx.viewRefs.get(i);
|
|
2105
|
-
if (containerRef) {
|
|
2106
|
-
const measured = (_b = (_a2 = containerRef.current) == null ? void 0 : _a2.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a2);
|
|
2107
|
-
if (measured) {
|
|
2108
|
-
changes.push({ itemKey: containerItemKey, sizeObj: measured });
|
|
2109
|
-
}
|
|
2110
|
-
}
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
if (changes.length > 0) {
|
|
2114
|
-
updateItemSizes(changes);
|
|
2115
|
-
}
|
|
2116
|
-
} else {
|
|
2117
|
-
updateItemSizes([{ itemKey, sizeObj }]);
|
|
2118
|
-
}
|
|
2119
|
-
}, []);
|
|
2120
|
-
const handleLayout = React2.useCallback((size) => {
|
|
2121
|
-
const scrollLength = size[horizontal ? "width" : "height"];
|
|
2122
|
-
const otherAxisSize = size[horizontal ? "height" : "width"];
|
|
2123
|
-
const state = refState.current;
|
|
2124
|
-
const didChange = scrollLength !== state.scrollLength;
|
|
2125
|
-
const prevOtherAxisSize = state.otherAxisSize;
|
|
2126
|
-
state.scrollLength = scrollLength;
|
|
2127
|
-
state.otherAxisSize = otherAxisSize;
|
|
2128
|
-
state.lastBatchingAction = Date.now();
|
|
2129
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2130
|
-
doInitialAllocateContainers();
|
|
2131
|
-
if (didChange) {
|
|
2132
|
-
calculateItemsInView({ doMVCP: true });
|
|
2133
|
-
}
|
|
2134
|
-
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
2135
|
-
set$(ctx, "scrollSize", { width: size.width, height: size.height });
|
|
2136
|
-
}
|
|
2137
|
-
doMaintainScrollAtEnd(false);
|
|
2138
|
-
updateAlignItemsPaddingTop();
|
|
2139
|
-
checkAtBottom();
|
|
2140
|
-
checkAtTop();
|
|
2141
|
-
if (refState.current) {
|
|
2142
|
-
refState.current.needsOtherAxisSize = otherAxisSize - (stylePaddingTopState || 0) < 10;
|
|
2143
|
-
}
|
|
2144
|
-
if (__DEV__ && scrollLength === 0) {
|
|
2145
|
-
warnDevOnce(
|
|
2146
|
-
"height0",
|
|
2147
|
-
`List ${horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
2148
|
-
);
|
|
2149
|
-
}
|
|
2150
|
-
calculateItemsInView({ doMVCP: true });
|
|
2151
|
-
setCanRender(true);
|
|
2152
|
-
}, []);
|
|
2153
|
-
const onLayout = React2.useCallback((event) => {
|
|
2341
|
+
const onLayout = React3.useCallback((event) => {
|
|
2154
2342
|
const layout = event.nativeEvent.layout;
|
|
2155
|
-
handleLayout(layout);
|
|
2343
|
+
handleLayout(ctx, state, layout, setCanRender);
|
|
2156
2344
|
if (onLayoutProp) {
|
|
2157
2345
|
onLayoutProp(event);
|
|
2158
2346
|
}
|
|
2159
2347
|
}, []);
|
|
2160
|
-
|
|
2161
|
-
(event) => {
|
|
2162
|
-
var _a2, _b, _c, _d;
|
|
2163
|
-
if (((_b = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
2164
|
-
return;
|
|
2165
|
-
}
|
|
2166
|
-
const state = refState.current;
|
|
2167
|
-
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
2168
|
-
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
2169
|
-
if (ignoreScrollFromMVCP && !state.scrollingTo) {
|
|
2170
|
-
const { lt, gt } = ignoreScrollFromMVCP;
|
|
2171
|
-
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
2172
|
-
return;
|
|
2173
|
-
}
|
|
2174
|
-
}
|
|
2175
|
-
state.scrollPending = newScroll;
|
|
2176
|
-
updateScroll(newScroll);
|
|
2177
|
-
(_d = state.onScroll) == null ? void 0 : _d.call(state, event);
|
|
2178
|
-
},
|
|
2179
|
-
[]
|
|
2180
|
-
);
|
|
2181
|
-
const updateScroll = React2.useCallback((newScroll) => {
|
|
2182
|
-
const state = refState.current;
|
|
2183
|
-
const scrollingTo = state.scrollingTo;
|
|
2184
|
-
state.hasScrolled = true;
|
|
2185
|
-
state.lastBatchingAction = Date.now();
|
|
2186
|
-
const currentTime = performance.now();
|
|
2187
|
-
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
2188
|
-
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2189
|
-
}
|
|
2190
|
-
if (state.scrollHistory.length > 5) {
|
|
2191
|
-
state.scrollHistory.shift();
|
|
2192
|
-
}
|
|
2193
|
-
state.scrollPrev = state.scroll;
|
|
2194
|
-
state.scrollPrevTime = state.scrollTime;
|
|
2195
|
-
state.scroll = newScroll;
|
|
2196
|
-
state.scrollTime = currentTime;
|
|
2197
|
-
calculateItemsInView();
|
|
2198
|
-
checkAtBottom();
|
|
2199
|
-
checkAtTop();
|
|
2200
|
-
}, []);
|
|
2201
|
-
React2.useImperativeHandle(
|
|
2348
|
+
React3.useImperativeHandle(
|
|
2202
2349
|
forwardedRef,
|
|
2203
2350
|
() => {
|
|
2204
2351
|
const scrollIndexIntoView = (options) => {
|
|
2205
|
-
|
|
2352
|
+
const state2 = refState.current;
|
|
2353
|
+
if (state2) {
|
|
2206
2354
|
const { index, ...rest2 } = options;
|
|
2207
|
-
const { startNoBuffer, endNoBuffer } =
|
|
2355
|
+
const { startNoBuffer, endNoBuffer } = state2;
|
|
2208
2356
|
if (index < startNoBuffer || index > endNoBuffer) {
|
|
2209
2357
|
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
2210
|
-
scrollToIndex({
|
|
2358
|
+
scrollToIndex(ctx, state2, {
|
|
2211
2359
|
...rest2,
|
|
2212
2360
|
viewPosition,
|
|
2213
2361
|
index
|
|
@@ -2221,45 +2369,46 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2221
2369
|
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
2222
2370
|
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
2223
2371
|
getState: () => {
|
|
2224
|
-
const
|
|
2225
|
-
return
|
|
2226
|
-
contentLength:
|
|
2227
|
-
end:
|
|
2228
|
-
endBuffered:
|
|
2229
|
-
isAtEnd:
|
|
2230
|
-
isAtStart:
|
|
2231
|
-
scroll:
|
|
2232
|
-
scrollLength:
|
|
2233
|
-
start:
|
|
2234
|
-
startBuffered:
|
|
2235
|
-
sizes:
|
|
2236
|
-
sizeAtIndex: (index) =>
|
|
2372
|
+
const state2 = refState.current;
|
|
2373
|
+
return state2 ? {
|
|
2374
|
+
contentLength: state2.totalSize,
|
|
2375
|
+
end: state2.endNoBuffer,
|
|
2376
|
+
endBuffered: state2.endBuffered,
|
|
2377
|
+
isAtEnd: state2.isAtEnd,
|
|
2378
|
+
isAtStart: state2.isAtStart,
|
|
2379
|
+
scroll: state2.scroll,
|
|
2380
|
+
scrollLength: state2.scrollLength,
|
|
2381
|
+
start: state2.startNoBuffer,
|
|
2382
|
+
startBuffered: state2.startBuffered,
|
|
2383
|
+
sizes: state2.sizesKnown,
|
|
2384
|
+
sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index))
|
|
2237
2385
|
} : {};
|
|
2238
2386
|
},
|
|
2239
2387
|
scrollIndexIntoView,
|
|
2240
2388
|
scrollItemIntoView: ({ item, ...props2 }) => {
|
|
2241
|
-
const
|
|
2389
|
+
const data = refState.current.props.data;
|
|
2242
2390
|
const index = data.indexOf(item);
|
|
2243
2391
|
if (index !== -1) {
|
|
2244
2392
|
scrollIndexIntoView({ index, ...props2 });
|
|
2245
2393
|
}
|
|
2246
2394
|
},
|
|
2247
|
-
scrollToIndex,
|
|
2395
|
+
scrollToIndex: (params) => scrollToIndex(ctx, state, params),
|
|
2248
2396
|
scrollToItem: ({ item, ...props2 }) => {
|
|
2249
|
-
const
|
|
2397
|
+
const data = refState.current.props.data;
|
|
2250
2398
|
const index = data.indexOf(item);
|
|
2251
2399
|
if (index !== -1) {
|
|
2252
|
-
scrollToIndex({ index, ...props2 });
|
|
2400
|
+
scrollToIndex(ctx, state, { index, ...props2 });
|
|
2253
2401
|
}
|
|
2254
2402
|
},
|
|
2255
|
-
scrollToOffset: (params) => scrollTo(params),
|
|
2403
|
+
scrollToOffset: (params) => scrollTo(state, params),
|
|
2256
2404
|
scrollToEnd: (options) => {
|
|
2257
|
-
const
|
|
2405
|
+
const data = refState.current.props.data;
|
|
2406
|
+
const stylePaddingBottom = refState.current.props.stylePaddingBottom;
|
|
2258
2407
|
const index = data.length - 1;
|
|
2259
2408
|
if (index !== -1) {
|
|
2260
2409
|
const paddingBottom = stylePaddingBottom || 0;
|
|
2261
2410
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
2262
|
-
scrollToIndex({
|
|
2411
|
+
scrollToIndex(ctx, state, {
|
|
2263
2412
|
index,
|
|
2264
2413
|
viewPosition: 1,
|
|
2265
2414
|
viewOffset: -paddingBottom - footerSize,
|
|
@@ -2276,13 +2425,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2276
2425
|
[]
|
|
2277
2426
|
);
|
|
2278
2427
|
if (reactNative.Platform.OS === "web") {
|
|
2279
|
-
|
|
2428
|
+
React3.useEffect(() => {
|
|
2280
2429
|
if (initialContentOffset) {
|
|
2281
|
-
scrollTo({ offset: initialContentOffset, animated: false });
|
|
2430
|
+
scrollTo(state, { offset: initialContentOffset, animated: false });
|
|
2282
2431
|
}
|
|
2283
2432
|
}, []);
|
|
2284
2433
|
}
|
|
2285
|
-
|
|
2434
|
+
const fns = React3.useMemo(
|
|
2435
|
+
() => ({
|
|
2436
|
+
updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj),
|
|
2437
|
+
getRenderedItem: (key) => getRenderedItem(ctx, state, key),
|
|
2438
|
+
onScroll: (event) => onScroll(ctx, state, event)
|
|
2439
|
+
}),
|
|
2440
|
+
[]
|
|
2441
|
+
);
|
|
2442
|
+
return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
|
|
2286
2443
|
ListComponent,
|
|
2287
2444
|
{
|
|
2288
2445
|
...rest,
|
|
@@ -2290,12 +2447,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2290
2447
|
horizontal,
|
|
2291
2448
|
refScrollView: combinedRef,
|
|
2292
2449
|
initialContentOffset,
|
|
2293
|
-
getRenderedItem,
|
|
2294
|
-
updateItemSize,
|
|
2295
|
-
|
|
2450
|
+
getRenderedItem: fns.getRenderedItem,
|
|
2451
|
+
updateItemSize: fns.updateItemSize,
|
|
2452
|
+
onScroll: fns.onScroll,
|
|
2296
2453
|
onMomentumScrollEnd: (event) => {
|
|
2297
2454
|
requestAnimationFrame(() => {
|
|
2298
|
-
finishScrollTo();
|
|
2455
|
+
finishScrollTo(refState.current);
|
|
2299
2456
|
});
|
|
2300
2457
|
if (onMomentumScrollEnd) {
|
|
2301
2458
|
onMomentumScrollEnd(event);
|
|
@@ -2309,9 +2466,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2309
2466
|
maintainVisibleContentPosition,
|
|
2310
2467
|
scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
|
|
2311
2468
|
waitForInitialLayout,
|
|
2312
|
-
refreshControl: refreshControl ? stylePaddingTopState > 0 ?
|
|
2469
|
+
refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
|
|
2313
2470
|
progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
|
|
2314
|
-
}) : refreshControl : onRefresh && /* @__PURE__ */
|
|
2471
|
+
}) : refreshControl : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
|
|
2315
2472
|
reactNative.RefreshControl,
|
|
2316
2473
|
{
|
|
2317
2474
|
refreshing: !!refreshing,
|
|
@@ -2324,17 +2481,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2324
2481
|
scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
|
|
2325
2482
|
onLayoutHeader
|
|
2326
2483
|
}
|
|
2327
|
-
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */
|
|
2484
|
+
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
|
|
2328
2485
|
});
|
|
2329
|
-
var typedForwardRef2 =
|
|
2486
|
+
var typedForwardRef2 = React3.forwardRef;
|
|
2330
2487
|
var renderItem = ({ item }) => item;
|
|
2331
2488
|
var LazyLegendList = typedForwardRef2(function LazyLegendList2(props, forwardedRef) {
|
|
2332
2489
|
const { LegendList: LegendListProp, children, ...rest } = props;
|
|
2333
2490
|
const LegendListComponent = LegendListProp != null ? LegendListProp : LegendList;
|
|
2334
|
-
const data = (isArray(children) ? children :
|
|
2491
|
+
const data = (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1);
|
|
2335
2492
|
return (
|
|
2336
2493
|
// @ts-expect-error TODO: Fix this type
|
|
2337
|
-
/* @__PURE__ */
|
|
2494
|
+
/* @__PURE__ */ React3__namespace.createElement(LegendListComponent, { ...rest, data, renderItem, ref: forwardedRef })
|
|
2338
2495
|
);
|
|
2339
2496
|
});
|
|
2340
2497
|
|