@legendapp/list 2.1.0-beta.1 → 2.1.0-beta.10
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/CHANGELOG.md +3 -0
- package/index.d.mts +43 -15
- package/index.d.ts +43 -15
- package/index.js +753 -614
- package/index.mjs +753 -614
- package/index.native.d.mts +671 -0
- package/index.native.d.ts +671 -0
- package/index.native.js +3417 -0
- package/index.native.mjs +3389 -0
- package/package.json +9 -4
package/index.js
CHANGED
|
@@ -54,7 +54,10 @@ function StateProvider({ children }) {
|
|
|
54
54
|
["stylePaddingTop", 0],
|
|
55
55
|
["headerSize", 0],
|
|
56
56
|
["numContainers", 0],
|
|
57
|
-
["
|
|
57
|
+
["activeStickyIndex", void 0],
|
|
58
|
+
["totalSize", 0],
|
|
59
|
+
["scrollAdjustPending", 0],
|
|
60
|
+
["scrollingTo", void 0]
|
|
58
61
|
]),
|
|
59
62
|
viewRefs: /* @__PURE__ */ new Map()
|
|
60
63
|
}));
|
|
@@ -208,6 +211,47 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
|
208
211
|
var typedForwardRef = React3.forwardRef;
|
|
209
212
|
var typedMemo = React3.memo;
|
|
210
213
|
|
|
214
|
+
// src/utils/helpers.ts
|
|
215
|
+
function isFunction(obj) {
|
|
216
|
+
return typeof obj === "function";
|
|
217
|
+
}
|
|
218
|
+
function isArray(obj) {
|
|
219
|
+
return Array.isArray(obj);
|
|
220
|
+
}
|
|
221
|
+
var warned = /* @__PURE__ */ new Set();
|
|
222
|
+
function warnDevOnce(id, text) {
|
|
223
|
+
if (IS_DEV && !warned.has(id)) {
|
|
224
|
+
warned.add(id);
|
|
225
|
+
console.warn(`[legend-list] ${text}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function roundSize(size) {
|
|
229
|
+
return Math.floor(size * 8) / 8;
|
|
230
|
+
}
|
|
231
|
+
function isNullOrUndefined(value) {
|
|
232
|
+
return value === null || value === void 0;
|
|
233
|
+
}
|
|
234
|
+
function comparatorDefault(a, b) {
|
|
235
|
+
return a - b;
|
|
236
|
+
}
|
|
237
|
+
function getPadding(s, type) {
|
|
238
|
+
var _a3, _b, _c;
|
|
239
|
+
return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
240
|
+
}
|
|
241
|
+
function extractPadding(style, contentContainerStyle, type) {
|
|
242
|
+
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
243
|
+
}
|
|
244
|
+
function findContainerId(ctx, key) {
|
|
245
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
246
|
+
for (let i = 0; i < numContainers; i++) {
|
|
247
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
248
|
+
if (itemKey === key) {
|
|
249
|
+
return i;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return -1;
|
|
253
|
+
}
|
|
254
|
+
|
|
211
255
|
// src/components/PositionView.tsx
|
|
212
256
|
var PositionViewState = typedMemo(function PositionView({
|
|
213
257
|
id,
|
|
@@ -217,8 +261,11 @@ var PositionViewState = typedMemo(function PositionView({
|
|
|
217
261
|
...rest
|
|
218
262
|
}) {
|
|
219
263
|
const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
|
|
220
|
-
const base =
|
|
221
|
-
|
|
264
|
+
const base = {
|
|
265
|
+
contain: "paint layout style"
|
|
266
|
+
};
|
|
267
|
+
const composed = isArray(style) ? Object.assign({}, ...style) : style;
|
|
268
|
+
const combinedStyle = horizontal ? { ...base, ...composed, left: position } : { ...base, ...composed, top: position };
|
|
222
269
|
return /* @__PURE__ */ React3__namespace.createElement("div", { ref: refView, style: combinedStyle, ...rest });
|
|
223
270
|
});
|
|
224
271
|
var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
@@ -227,19 +274,42 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
227
274
|
style,
|
|
228
275
|
refView,
|
|
229
276
|
index,
|
|
277
|
+
stickyOffset,
|
|
278
|
+
animatedScrollY: _animatedScrollY,
|
|
279
|
+
children,
|
|
230
280
|
...rest
|
|
231
281
|
}) {
|
|
232
|
-
const [position = POSITION_OUT_OF_VIEW,
|
|
282
|
+
const [position = POSITION_OUT_OF_VIEW, headerSize = 0, activeStickyIndex] = useArr$([
|
|
283
|
+
`containerPosition${id}`,
|
|
284
|
+
"headerSize",
|
|
285
|
+
"activeStickyIndex"
|
|
286
|
+
]);
|
|
287
|
+
const base = {
|
|
288
|
+
contain: "paint layout style"
|
|
289
|
+
};
|
|
290
|
+
const composed = React3__namespace.useMemo(
|
|
291
|
+
() => {
|
|
292
|
+
var _a3;
|
|
293
|
+
return (_a3 = isArray(style) ? Object.assign({}, ...style) : style) != null ? _a3 : {};
|
|
294
|
+
},
|
|
295
|
+
[style]
|
|
296
|
+
);
|
|
233
297
|
const viewStyle = React3__namespace.useMemo(() => {
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
298
|
+
var _a3;
|
|
299
|
+
const styleBase = { ...base, ...composed };
|
|
300
|
+
delete styleBase.transform;
|
|
301
|
+
const offset = (_a3 = stickyOffset != null ? stickyOffset : headerSize) != null ? _a3 : 0;
|
|
302
|
+
const isActive = activeStickyIndex === index;
|
|
303
|
+
styleBase.position = isActive ? "sticky" : "absolute";
|
|
304
|
+
styleBase.zIndex = index + 1e3;
|
|
305
|
+
if (horizontal) {
|
|
306
|
+
styleBase.left = isActive ? offset : position;
|
|
307
|
+
} else {
|
|
308
|
+
styleBase.top = isActive ? offset : position;
|
|
309
|
+
}
|
|
310
|
+
return styleBase;
|
|
311
|
+
}, [composed, horizontal, position, index, stickyOffset, headerSize, activeStickyIndex]);
|
|
312
|
+
return /* @__PURE__ */ React3__namespace.createElement("div", { ref: refView, style: viewStyle, ...rest }, children);
|
|
243
313
|
});
|
|
244
314
|
var PositionView2 = PositionViewState;
|
|
245
315
|
|
|
@@ -254,37 +324,6 @@ function useInit(cb) {
|
|
|
254
324
|
return refValue.current;
|
|
255
325
|
}
|
|
256
326
|
|
|
257
|
-
// src/utils/helpers.ts
|
|
258
|
-
function isFunction(obj) {
|
|
259
|
-
return typeof obj === "function";
|
|
260
|
-
}
|
|
261
|
-
function isArray(obj) {
|
|
262
|
-
return Array.isArray(obj);
|
|
263
|
-
}
|
|
264
|
-
var warned = /* @__PURE__ */ new Set();
|
|
265
|
-
function warnDevOnce(id, text) {
|
|
266
|
-
if (IS_DEV && !warned.has(id)) {
|
|
267
|
-
warned.add(id);
|
|
268
|
-
console.warn(`[legend-list] ${text}`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
function roundSize(size) {
|
|
272
|
-
return Math.floor(size * 8) / 8;
|
|
273
|
-
}
|
|
274
|
-
function isNullOrUndefined(value) {
|
|
275
|
-
return value === null || value === void 0;
|
|
276
|
-
}
|
|
277
|
-
function comparatorDefault(a, b) {
|
|
278
|
-
return a - b;
|
|
279
|
-
}
|
|
280
|
-
function getPadding(s, type) {
|
|
281
|
-
var _a3, _b, _c;
|
|
282
|
-
return (_c = (_b = (_a3 = s[`padding${type}`]) != null ? _a3 : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
283
|
-
}
|
|
284
|
-
function extractPadding(style, contentContainerStyle, type) {
|
|
285
|
-
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
327
|
// src/state/ContextContainer.ts
|
|
289
328
|
var ContextContainer = React3.createContext(null);
|
|
290
329
|
function useViewability(callback, configId) {
|
|
@@ -413,6 +452,10 @@ function getGlobalResizeObserver() {
|
|
|
413
452
|
}
|
|
414
453
|
var callbackMap = /* @__PURE__ */ new WeakMap();
|
|
415
454
|
function createResizeObserver(element, callback) {
|
|
455
|
+
if (typeof ResizeObserver === "undefined") {
|
|
456
|
+
return () => {
|
|
457
|
+
};
|
|
458
|
+
}
|
|
416
459
|
if (!element) {
|
|
417
460
|
return () => {
|
|
418
461
|
};
|
|
@@ -448,7 +491,7 @@ function useOnLayoutSync({
|
|
|
448
491
|
const current = ref.current;
|
|
449
492
|
const scrollableNode = (_b = (_a3 = current == null ? void 0 : current.getScrollableNode) == null ? void 0 : _a3.call(current)) != null ? _b : null;
|
|
450
493
|
const element = scrollableNode || current;
|
|
451
|
-
if (!element
|
|
494
|
+
if (!element) {
|
|
452
495
|
return;
|
|
453
496
|
}
|
|
454
497
|
const emit = (layout, fromLayoutEffect) => {
|
|
@@ -470,6 +513,9 @@ function useOnLayoutSync({
|
|
|
470
513
|
return {};
|
|
471
514
|
}
|
|
472
515
|
function toLayout(rect) {
|
|
516
|
+
if (!rect) {
|
|
517
|
+
return { height: 0, width: 0, x: 0, y: 0 };
|
|
518
|
+
}
|
|
473
519
|
return {
|
|
474
520
|
height: rect.height,
|
|
475
521
|
width: rect.width,
|
|
@@ -571,7 +617,7 @@ var Container = typedMemo(function Container2({
|
|
|
571
617
|
}
|
|
572
618
|
didLayoutRef.current = true;
|
|
573
619
|
let layout = rectangle;
|
|
574
|
-
|
|
620
|
+
roundSize(rectangle[currentHorizontal ? "width" : "height"]);
|
|
575
621
|
const doUpdate = () => {
|
|
576
622
|
itemLayoutRef.current.lastSize = { height: layout.height, width: layout.width };
|
|
577
623
|
updateItemSizeFn(currentItemKey, layout);
|
|
@@ -729,7 +775,7 @@ var ContainersInner = typedMemo(function ContainersInner2({ horizontal, numColum
|
|
|
729
775
|
const columnWrapperStyle = ctx.columnWrapperStyle;
|
|
730
776
|
const [totalSize, otherAxisSize] = useArr$(["totalSize", "otherAxisSize"]);
|
|
731
777
|
useDOMOrder(ref);
|
|
732
|
-
const style = horizontal ? { minHeight: otherAxisSize, width: totalSize } : { height: totalSize, minWidth: otherAxisSize };
|
|
778
|
+
const style = horizontal ? { minHeight: otherAxisSize, position: "relative", width: totalSize } : { height: totalSize, minWidth: otherAxisSize, position: "relative" };
|
|
733
779
|
if (columnWrapperStyle && numColumns > 1) {
|
|
734
780
|
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
735
781
|
const gapX = columnGap || gap || 0;
|
|
@@ -801,7 +847,7 @@ function DevNumbers() {
|
|
|
801
847
|
|
|
802
848
|
// src/platform/StyleSheet.tsx
|
|
803
849
|
function flattenStyles(styles) {
|
|
804
|
-
if (
|
|
850
|
+
if (isArray(styles)) {
|
|
805
851
|
return Object.assign({}, ...styles.filter(Boolean));
|
|
806
852
|
}
|
|
807
853
|
return styles;
|
|
@@ -991,10 +1037,11 @@ function PaddingDevMode() {
|
|
|
991
1037
|
function useValueListener$(key, callback) {
|
|
992
1038
|
const ctx = useStateContext();
|
|
993
1039
|
React3.useLayoutEffect(() => {
|
|
994
|
-
listen$(ctx, key, (value) => {
|
|
1040
|
+
const unsubscribe = listen$(ctx, key, (value) => {
|
|
995
1041
|
callback(value);
|
|
996
1042
|
});
|
|
997
|
-
|
|
1043
|
+
return unsubscribe;
|
|
1044
|
+
}, [callback, ctx, key]);
|
|
998
1045
|
}
|
|
999
1046
|
|
|
1000
1047
|
// src/components/ScrollAdjust.tsx
|
|
@@ -1159,13 +1206,100 @@ function calculateOffsetForIndex(ctx, state, index) {
|
|
|
1159
1206
|
return position;
|
|
1160
1207
|
}
|
|
1161
1208
|
|
|
1209
|
+
// src/utils/setPaddingTop.ts
|
|
1210
|
+
function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
|
|
1211
|
+
if (stylePaddingTop !== void 0) {
|
|
1212
|
+
const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
|
|
1213
|
+
if (stylePaddingTop < prevStylePaddingTop) {
|
|
1214
|
+
let prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1215
|
+
set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
|
|
1216
|
+
state.timeoutSetPaddingTop = setTimeout(() => {
|
|
1217
|
+
prevTotalSize = peek$(ctx, "totalSize") || 0;
|
|
1218
|
+
set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
|
|
1219
|
+
}, 16);
|
|
1220
|
+
}
|
|
1221
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1222
|
+
}
|
|
1223
|
+
if (alignItemsPaddingTop !== void 0) {
|
|
1224
|
+
set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
// src/utils/updateAlignItemsPaddingTop.ts
|
|
1229
|
+
function updateAlignItemsPaddingTop(ctx, state) {
|
|
1230
|
+
const {
|
|
1231
|
+
scrollLength,
|
|
1232
|
+
props: { alignItemsAtEnd, data }
|
|
1233
|
+
} = state;
|
|
1234
|
+
if (alignItemsAtEnd) {
|
|
1235
|
+
let alignItemsPaddingTop = 0;
|
|
1236
|
+
if ((data == null ? void 0 : data.length) > 0) {
|
|
1237
|
+
const contentSize = getContentSize(ctx);
|
|
1238
|
+
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1239
|
+
}
|
|
1240
|
+
setPaddingTop(ctx, state, { alignItemsPaddingTop });
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// src/core/updateTotalSize.ts
|
|
1245
|
+
function updateTotalSize(ctx, state) {
|
|
1246
|
+
const {
|
|
1247
|
+
positions,
|
|
1248
|
+
props: { data }
|
|
1249
|
+
} = state;
|
|
1250
|
+
if (data.length === 0) {
|
|
1251
|
+
addTotalSize(ctx, state, null, 0);
|
|
1252
|
+
} else {
|
|
1253
|
+
const lastId = getId(state, data.length - 1);
|
|
1254
|
+
if (lastId !== void 0) {
|
|
1255
|
+
const lastPosition = positions.get(lastId);
|
|
1256
|
+
if (lastPosition !== void 0) {
|
|
1257
|
+
const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
|
|
1258
|
+
if (lastSize !== void 0) {
|
|
1259
|
+
const totalSize = lastPosition + lastSize;
|
|
1260
|
+
addTotalSize(ctx, state, null, totalSize);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
function addTotalSize(ctx, state, key, add) {
|
|
1267
|
+
const { alignItemsAtEnd } = state.props;
|
|
1268
|
+
const prevTotalSize = state.totalSize;
|
|
1269
|
+
if (key === null) {
|
|
1270
|
+
state.totalSize = add;
|
|
1271
|
+
if (state.timeoutSetPaddingTop) {
|
|
1272
|
+
clearTimeout(state.timeoutSetPaddingTop);
|
|
1273
|
+
state.timeoutSetPaddingTop = void 0;
|
|
1274
|
+
}
|
|
1275
|
+
} else {
|
|
1276
|
+
state.totalSize += add;
|
|
1277
|
+
}
|
|
1278
|
+
if (prevTotalSize !== state.totalSize) {
|
|
1279
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
1280
|
+
if (alignItemsAtEnd) {
|
|
1281
|
+
updateAlignItemsPaddingTop(ctx, state);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// src/core/setSize.ts
|
|
1287
|
+
function setSize(ctx, state, itemKey, size) {
|
|
1288
|
+
const { sizes } = state;
|
|
1289
|
+
const previousSize = sizes.get(itemKey);
|
|
1290
|
+
const diff = previousSize !== void 0 ? size - previousSize : size;
|
|
1291
|
+
if (diff !== 0) {
|
|
1292
|
+
addTotalSize(ctx, state, itemKey, diff);
|
|
1293
|
+
}
|
|
1294
|
+
sizes.set(itemKey, size);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1162
1297
|
// src/utils/getItemSize.ts
|
|
1163
|
-
function getItemSize(state, key, index, data, useAverageSize) {
|
|
1298
|
+
function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
|
|
1164
1299
|
var _a3, _b;
|
|
1165
1300
|
const {
|
|
1166
1301
|
sizesKnown,
|
|
1167
1302
|
sizes,
|
|
1168
|
-
scrollingTo,
|
|
1169
1303
|
averageSizes,
|
|
1170
1304
|
props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
|
|
1171
1305
|
} = state;
|
|
@@ -1175,6 +1309,13 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
1175
1309
|
}
|
|
1176
1310
|
let size;
|
|
1177
1311
|
const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
|
|
1312
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1313
|
+
if (preferCachedSize) {
|
|
1314
|
+
const cachedSize = sizes.get(key);
|
|
1315
|
+
if (cachedSize !== void 0) {
|
|
1316
|
+
return cachedSize;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1178
1319
|
if (getFixedItemSize) {
|
|
1179
1320
|
size = getFixedItemSize(index, data, itemType);
|
|
1180
1321
|
if (size !== void 0) {
|
|
@@ -1196,56 +1337,235 @@ function getItemSize(state, key, index, data, useAverageSize) {
|
|
|
1196
1337
|
if (size === void 0) {
|
|
1197
1338
|
size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
|
|
1198
1339
|
}
|
|
1199
|
-
|
|
1340
|
+
setSize(ctx, state, key, size);
|
|
1200
1341
|
return size;
|
|
1201
1342
|
}
|
|
1202
1343
|
|
|
1203
1344
|
// src/core/calculateOffsetWithOffsetPosition.ts
|
|
1204
|
-
function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
|
|
1345
|
+
function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
|
|
1205
1346
|
const { index, viewOffset, viewPosition } = params;
|
|
1206
1347
|
let offset = offsetParam;
|
|
1207
1348
|
if (viewOffset) {
|
|
1208
1349
|
offset -= viewOffset;
|
|
1209
1350
|
}
|
|
1210
1351
|
if (viewPosition !== void 0 && index !== void 0) {
|
|
1211
|
-
offset -= viewPosition * (state.scrollLength - getItemSize(state, getId(state, index), index, state.props.data[index]));
|
|
1352
|
+
offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
|
|
1212
1353
|
}
|
|
1213
1354
|
return offset;
|
|
1214
1355
|
}
|
|
1215
1356
|
|
|
1216
|
-
// src/
|
|
1217
|
-
var
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1357
|
+
// src/utils/checkThreshold.ts
|
|
1358
|
+
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1359
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
1360
|
+
const absDistance = Math.abs(distance);
|
|
1361
|
+
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1362
|
+
const updateSnapshot = () => {
|
|
1363
|
+
setSnapshot == null ? void 0 : setSnapshot({
|
|
1364
|
+
atThreshold,
|
|
1365
|
+
contentSize: context.contentSize,
|
|
1366
|
+
dataLength: context.dataLength,
|
|
1367
|
+
scrollPosition: context.scrollPosition
|
|
1368
|
+
});
|
|
1369
|
+
};
|
|
1370
|
+
if (!wasReached) {
|
|
1371
|
+
if (!within) {
|
|
1372
|
+
return false;
|
|
1373
|
+
}
|
|
1374
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1375
|
+
updateSnapshot();
|
|
1376
|
+
return true;
|
|
1377
|
+
}
|
|
1378
|
+
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1379
|
+
if (reset) {
|
|
1380
|
+
setSnapshot == null ? void 0 : setSnapshot(void 0);
|
|
1381
|
+
return false;
|
|
1382
|
+
}
|
|
1383
|
+
if (within) {
|
|
1384
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1385
|
+
if (changed) {
|
|
1386
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1387
|
+
updateSnapshot();
|
|
1388
|
+
}
|
|
1221
1389
|
}
|
|
1390
|
+
return true;
|
|
1222
1391
|
};
|
|
1223
1392
|
|
|
1224
|
-
// src/
|
|
1225
|
-
function
|
|
1393
|
+
// src/utils/checkAtBottom.ts
|
|
1394
|
+
function checkAtBottom(ctx, state) {
|
|
1226
1395
|
var _a3;
|
|
1227
|
-
|
|
1396
|
+
if (!state) {
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1228
1399
|
const {
|
|
1229
|
-
|
|
1230
|
-
|
|
1400
|
+
queuedInitialLayout,
|
|
1401
|
+
scrollLength,
|
|
1402
|
+
scroll,
|
|
1403
|
+
maintainingScrollAtEnd,
|
|
1404
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1231
1405
|
} = state;
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1406
|
+
const contentSize = getContentSize(ctx);
|
|
1407
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1408
|
+
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1409
|
+
const isContentLess = contentSize < scrollLength;
|
|
1410
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1411
|
+
state.isEndReached = checkThreshold(
|
|
1412
|
+
distanceFromEnd,
|
|
1413
|
+
isContentLess,
|
|
1414
|
+
onEndReachedThreshold * scrollLength,
|
|
1415
|
+
state.isEndReached,
|
|
1416
|
+
state.endReachedSnapshot,
|
|
1417
|
+
{
|
|
1418
|
+
contentSize,
|
|
1419
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1420
|
+
scrollPosition: scroll
|
|
1421
|
+
},
|
|
1422
|
+
(distance) => {
|
|
1423
|
+
var _a4, _b;
|
|
1424
|
+
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1425
|
+
},
|
|
1426
|
+
(snapshot) => {
|
|
1427
|
+
state.endReachedSnapshot = snapshot;
|
|
1428
|
+
}
|
|
1429
|
+
);
|
|
1244
1430
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
// src/utils/checkAtTop.ts
|
|
1434
|
+
function checkAtTop(state) {
|
|
1435
|
+
var _a3;
|
|
1436
|
+
if (!state) {
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
const {
|
|
1440
|
+
scrollLength,
|
|
1441
|
+
scroll,
|
|
1442
|
+
props: { onStartReachedThreshold }
|
|
1443
|
+
} = state;
|
|
1444
|
+
const distanceFromTop = scroll;
|
|
1445
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1446
|
+
state.isStartReached = checkThreshold(
|
|
1447
|
+
distanceFromTop,
|
|
1448
|
+
false,
|
|
1449
|
+
onStartReachedThreshold * scrollLength,
|
|
1450
|
+
state.isStartReached,
|
|
1451
|
+
state.startReachedSnapshot,
|
|
1452
|
+
{
|
|
1453
|
+
contentSize: state.totalSize,
|
|
1454
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1455
|
+
scrollPosition: scroll
|
|
1456
|
+
},
|
|
1457
|
+
(distance) => {
|
|
1458
|
+
var _a4, _b;
|
|
1459
|
+
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1460
|
+
},
|
|
1461
|
+
(snapshot) => {
|
|
1462
|
+
state.startReachedSnapshot = snapshot;
|
|
1463
|
+
}
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// src/core/onScroll.ts
|
|
1468
|
+
function onScroll(ctx, state, event) {
|
|
1469
|
+
var _a3, _b, _c;
|
|
1470
|
+
const {
|
|
1471
|
+
scrollProcessingEnabled,
|
|
1472
|
+
props: { onScroll: onScrollProp }
|
|
1473
|
+
} = state;
|
|
1474
|
+
if (scrollProcessingEnabled === false) {
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1477
|
+
if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
1481
|
+
state.scrollPending = newScroll;
|
|
1482
|
+
updateScroll(ctx, state, newScroll);
|
|
1483
|
+
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
1484
|
+
}
|
|
1485
|
+
function updateScroll(ctx, state, newScroll, forceUpdate) {
|
|
1486
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1487
|
+
state.hasScrolled = true;
|
|
1488
|
+
state.lastBatchingAction = Date.now();
|
|
1489
|
+
const currentTime = Date.now();
|
|
1490
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
1491
|
+
const lastHistoryAdjust = state.lastScrollAdjustForHistory;
|
|
1492
|
+
const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
|
|
1493
|
+
if (adjustChanged) {
|
|
1494
|
+
state.scrollHistory.length = 0;
|
|
1495
|
+
}
|
|
1496
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
1497
|
+
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1498
|
+
if (!adjustChanged) {
|
|
1499
|
+
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
if (state.scrollHistory.length > 5) {
|
|
1503
|
+
state.scrollHistory.shift();
|
|
1504
|
+
}
|
|
1505
|
+
state.scrollPrev = state.scroll;
|
|
1506
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1507
|
+
state.scroll = newScroll;
|
|
1508
|
+
state.scrollTime = currentTime;
|
|
1509
|
+
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
1510
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1511
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1512
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1513
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
|
|
1518
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
1519
|
+
calculateItemsInView(ctx, state, { doMVCP: scrollingTo !== void 0 });
|
|
1520
|
+
checkAtBottom(ctx, state);
|
|
1521
|
+
checkAtTop(state);
|
|
1522
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
// src/core/finishScrollTo.ts
|
|
1527
|
+
function finishScrollTo(ctx, state) {
|
|
1528
|
+
var _a3, _b;
|
|
1529
|
+
if (state) {
|
|
1530
|
+
state.scrollHistory.length = 0;
|
|
1531
|
+
state.initialScroll = void 0;
|
|
1532
|
+
set$(ctx, "scrollingTo", void 0);
|
|
1533
|
+
if ((_a3 = state.props) == null ? void 0 : _a3.data) {
|
|
1534
|
+
(_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
// src/core/scrollTo.ts
|
|
1540
|
+
function scrollTo(ctx, state, params) {
|
|
1541
|
+
var _a3;
|
|
1542
|
+
const { noScrollingTo, ...scrollTarget } = params;
|
|
1543
|
+
const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
|
|
1544
|
+
const {
|
|
1545
|
+
refScroller,
|
|
1546
|
+
props: { horizontal }
|
|
1547
|
+
} = state;
|
|
1548
|
+
let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
|
|
1549
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
1550
|
+
const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
1551
|
+
offset = Math.min(offset, maxOffset);
|
|
1552
|
+
}
|
|
1553
|
+
state.scrollHistory.length = 0;
|
|
1554
|
+
if (!noScrollingTo) {
|
|
1555
|
+
set$(ctx, "scrollingTo", scrollTarget);
|
|
1556
|
+
}
|
|
1557
|
+
state.scrollPending = offset;
|
|
1558
|
+
if (!isInitialScroll || Platform.OS === "android") {
|
|
1559
|
+
(_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
1560
|
+
animated: !!animated,
|
|
1561
|
+
x: horizontal ? offset : 0,
|
|
1562
|
+
y: horizontal ? 0 : offset
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
if (!animated) {
|
|
1566
|
+
state.scroll = offset;
|
|
1567
|
+
setTimeout(() => finishScrollTo(ctx, state), 100);
|
|
1568
|
+
if (isInitialScroll) {
|
|
1249
1569
|
setTimeout(() => {
|
|
1250
1570
|
state.initialScroll = void 0;
|
|
1251
1571
|
}, 500);
|
|
@@ -1266,24 +1586,6 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
|
|
|
1266
1586
|
const didLayout = peek$(ctx, "containersDidLayout");
|
|
1267
1587
|
if (didLayout) {
|
|
1268
1588
|
doit();
|
|
1269
|
-
const threshold = state.scroll - positionDiff / 2;
|
|
1270
|
-
if (!state.ignoreScrollFromMVCP) {
|
|
1271
|
-
state.ignoreScrollFromMVCP = {};
|
|
1272
|
-
}
|
|
1273
|
-
if (positionDiff > 0) {
|
|
1274
|
-
state.ignoreScrollFromMVCP.lt = threshold;
|
|
1275
|
-
} else {
|
|
1276
|
-
state.ignoreScrollFromMVCP.gt = threshold;
|
|
1277
|
-
}
|
|
1278
|
-
if (state.ignoreScrollFromMVCPTimeout) {
|
|
1279
|
-
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
1280
|
-
}
|
|
1281
|
-
state.ignoreScrollFromMVCPTimeout = setTimeout(
|
|
1282
|
-
() => {
|
|
1283
|
-
state.ignoreScrollFromMVCP = void 0;
|
|
1284
|
-
},
|
|
1285
|
-
100
|
|
1286
|
-
);
|
|
1287
1589
|
} else {
|
|
1288
1590
|
requestAnimationFrame(doit);
|
|
1289
1591
|
}
|
|
@@ -1295,9 +1597,9 @@ function prepareMVCP(ctx, state, dataChanged) {
|
|
|
1295
1597
|
const {
|
|
1296
1598
|
idsInView,
|
|
1297
1599
|
positions,
|
|
1298
|
-
scrollingTo,
|
|
1299
1600
|
props: { maintainVisibleContentPosition }
|
|
1300
1601
|
} = state;
|
|
1602
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1301
1603
|
let prevPosition;
|
|
1302
1604
|
let targetId;
|
|
1303
1605
|
const idsInViewWithPositions = [];
|
|
@@ -1373,7 +1675,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
|
|
|
1373
1675
|
const prevId = state.idCache[prevIndex];
|
|
1374
1676
|
const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
|
|
1375
1677
|
const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
|
|
1376
|
-
const prevRowHeight = calculateRowMaxSize(state, prevRowStart, prevIndex, useAverageSize);
|
|
1678
|
+
const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
|
|
1377
1679
|
currentRowTop = prevPosition + prevRowHeight;
|
|
1378
1680
|
}
|
|
1379
1681
|
return {
|
|
@@ -1396,7 +1698,7 @@ function findRowStartIndex(state, numColumns, index) {
|
|
|
1396
1698
|
}
|
|
1397
1699
|
return rowStart;
|
|
1398
1700
|
}
|
|
1399
|
-
function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
1701
|
+
function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
|
|
1400
1702
|
if (endIndex < startIndex) {
|
|
1401
1703
|
return 0;
|
|
1402
1704
|
}
|
|
@@ -1410,7 +1712,7 @@ function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
|
1410
1712
|
continue;
|
|
1411
1713
|
}
|
|
1412
1714
|
const id = state.idCache[i];
|
|
1413
|
-
const size = getItemSize(state, id, i, data[i], useAverageSize);
|
|
1715
|
+
const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
|
|
1414
1716
|
if (size > maxSize) {
|
|
1415
1717
|
maxSize = size;
|
|
1416
1718
|
}
|
|
@@ -1418,82 +1720,43 @@ function calculateRowMaxSize(state, startIndex, endIndex, useAverageSize) {
|
|
|
1418
1720
|
return maxSize;
|
|
1419
1721
|
}
|
|
1420
1722
|
|
|
1421
|
-
// src/utils/
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
// src/utils/updateAlignItemsPaddingTop.ts
|
|
1441
|
-
function updateAlignItemsPaddingTop(ctx, state) {
|
|
1442
|
-
const {
|
|
1443
|
-
scrollLength,
|
|
1444
|
-
props: { alignItemsAtEnd, data }
|
|
1445
|
-
} = state;
|
|
1446
|
-
if (alignItemsAtEnd) {
|
|
1447
|
-
let alignItemsPaddingTop = 0;
|
|
1448
|
-
if ((data == null ? void 0 : data.length) > 0) {
|
|
1449
|
-
const contentSize = getContentSize(ctx);
|
|
1450
|
-
alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1451
|
-
}
|
|
1452
|
-
setPaddingTop(ctx, state, { alignItemsPaddingTop });
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
// src/core/updateTotalSize.ts
|
|
1457
|
-
function updateTotalSize(ctx, state) {
|
|
1458
|
-
const {
|
|
1459
|
-
positions,
|
|
1460
|
-
props: { data }
|
|
1461
|
-
} = state;
|
|
1462
|
-
if (data.length === 0) {
|
|
1463
|
-
addTotalSize(ctx, state, null, 0);
|
|
1464
|
-
} else {
|
|
1465
|
-
const lastId = getId(state, data.length - 1);
|
|
1466
|
-
if (lastId !== void 0) {
|
|
1467
|
-
const lastPosition = positions.get(lastId);
|
|
1468
|
-
if (lastPosition !== void 0) {
|
|
1469
|
-
const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
|
|
1470
|
-
if (lastSize !== void 0) {
|
|
1471
|
-
const totalSize = lastPosition + lastSize;
|
|
1472
|
-
addTotalSize(ctx, state, null, totalSize);
|
|
1723
|
+
// src/utils/getScrollVelocity.ts
|
|
1724
|
+
var getScrollVelocity = (state) => {
|
|
1725
|
+
const { scrollHistory } = state;
|
|
1726
|
+
let velocity = 0;
|
|
1727
|
+
if (scrollHistory.length >= 1) {
|
|
1728
|
+
const newest = scrollHistory[scrollHistory.length - 1];
|
|
1729
|
+
let oldest;
|
|
1730
|
+
let start = 0;
|
|
1731
|
+
const now = Date.now();
|
|
1732
|
+
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
1733
|
+
const entry = scrollHistory[i];
|
|
1734
|
+
const nextEntry = scrollHistory[i + 1];
|
|
1735
|
+
if (i > 0) {
|
|
1736
|
+
const prevEntry = scrollHistory[i - 1];
|
|
1737
|
+
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
1738
|
+
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1739
|
+
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1740
|
+
start = i;
|
|
1741
|
+
break;
|
|
1473
1742
|
}
|
|
1474
1743
|
}
|
|
1475
1744
|
}
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
state.totalSize = add;
|
|
1483
|
-
if (state.timeoutSetPaddingTop) {
|
|
1484
|
-
clearTimeout(state.timeoutSetPaddingTop);
|
|
1485
|
-
state.timeoutSetPaddingTop = void 0;
|
|
1745
|
+
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
1746
|
+
const entry = scrollHistory[i];
|
|
1747
|
+
if (now - entry.time <= 1e3) {
|
|
1748
|
+
oldest = entry;
|
|
1749
|
+
break;
|
|
1750
|
+
}
|
|
1486
1751
|
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
set$(ctx, "totalSize", state.totalSize);
|
|
1492
|
-
if (alignItemsAtEnd) {
|
|
1493
|
-
updateAlignItemsPaddingTop(ctx, state);
|
|
1752
|
+
if (oldest && oldest !== newest) {
|
|
1753
|
+
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1754
|
+
const timeDiff = newest.time - oldest.time;
|
|
1755
|
+
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1494
1756
|
}
|
|
1495
1757
|
}
|
|
1496
|
-
|
|
1758
|
+
return velocity;
|
|
1759
|
+
};
|
|
1497
1760
|
|
|
1498
1761
|
// src/utils/updateSnapToOffsets.ts
|
|
1499
1762
|
function updateSnapToOffsets(ctx, state) {
|
|
@@ -1511,23 +1774,30 @@ function updateSnapToOffsets(ctx, state) {
|
|
|
1511
1774
|
}
|
|
1512
1775
|
|
|
1513
1776
|
// src/core/updateItemPositions.ts
|
|
1514
|
-
function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered
|
|
1515
|
-
|
|
1777
|
+
function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false } = {
|
|
1778
|
+
forceFullUpdate: false,
|
|
1779
|
+
scrollBottomBuffered: -1,
|
|
1780
|
+
startIndex: 0
|
|
1781
|
+
}) {
|
|
1782
|
+
var _a3, _b, _c, _d, _e;
|
|
1516
1783
|
const {
|
|
1517
1784
|
columns,
|
|
1518
1785
|
indexByKey,
|
|
1519
1786
|
positions,
|
|
1520
1787
|
idCache,
|
|
1521
1788
|
sizesKnown,
|
|
1522
|
-
props: { getEstimatedItemSize, snapToIndices, enableAverages }
|
|
1789
|
+
props: { getEstimatedItemSize, snapToIndices, enableAverages, maintainVisibleContentPosition }
|
|
1523
1790
|
} = state;
|
|
1524
1791
|
const data = state.props.data;
|
|
1525
1792
|
const dataLength = data.length;
|
|
1526
1793
|
const numColumns = peek$(ctx, "numColumns");
|
|
1794
|
+
const scrollingTo = peek$(ctx, "scrollingTo");
|
|
1527
1795
|
const hasColumns = numColumns > 1;
|
|
1528
1796
|
const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
|
|
1797
|
+
const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
|
|
1529
1798
|
const maxVisibleArea = scrollBottomBuffered + 1e3;
|
|
1530
1799
|
const useAverageSize = enableAverages && !getEstimatedItemSize;
|
|
1800
|
+
const preferCachedSize = maintainVisibleContentPosition && (dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0);
|
|
1531
1801
|
let currentRowTop = 0;
|
|
1532
1802
|
let column = 1;
|
|
1533
1803
|
let maxSizeInRow = 0;
|
|
@@ -1544,8 +1814,8 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1544
1814
|
} else if (startIndex < dataLength) {
|
|
1545
1815
|
const prevIndex = startIndex - 1;
|
|
1546
1816
|
const prevId = getId(state, prevIndex);
|
|
1547
|
-
const prevPosition = (
|
|
1548
|
-
const prevSize = (
|
|
1817
|
+
const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
|
|
1818
|
+
const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
|
|
1549
1819
|
currentRowTop = prevPosition + prevSize;
|
|
1550
1820
|
}
|
|
1551
1821
|
}
|
|
@@ -1553,16 +1823,16 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
|
|
|
1553
1823
|
let didBreakEarly = false;
|
|
1554
1824
|
let breakAt;
|
|
1555
1825
|
for (let i = startIndex; i < dataLength; i++) {
|
|
1556
|
-
if (breakAt && i > breakAt) {
|
|
1826
|
+
if (shouldOptimize && breakAt !== void 0 && i > breakAt) {
|
|
1557
1827
|
didBreakEarly = true;
|
|
1558
1828
|
break;
|
|
1559
1829
|
}
|
|
1560
|
-
if (breakAt === void 0 && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1830
|
+
if (shouldOptimize && breakAt === void 0 && !scrollingTo && !dataChanged && currentRowTop > maxVisibleArea) {
|
|
1561
1831
|
const itemsPerRow = hasColumns ? numColumns : 1;
|
|
1562
1832
|
breakAt = i + itemsPerRow + 10;
|
|
1563
1833
|
}
|
|
1564
|
-
const id = (
|
|
1565
|
-
const size = (
|
|
1834
|
+
const id = (_d = idCache[i]) != null ? _d : getId(state, i);
|
|
1835
|
+
const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
|
|
1566
1836
|
if (IS_DEV && needsIndexByKey) {
|
|
1567
1837
|
if (indexByKeyForChecking.has(id)) {
|
|
1568
1838
|
console.error(
|
|
@@ -1780,16 +2050,6 @@ function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize,
|
|
|
1780
2050
|
const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
|
|
1781
2051
|
return value.isViewable;
|
|
1782
2052
|
}
|
|
1783
|
-
function findContainerId(ctx, key) {
|
|
1784
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
1785
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1786
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1787
|
-
if (itemKey === key) {
|
|
1788
|
-
return i;
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
return -1;
|
|
1792
|
-
}
|
|
1793
2053
|
function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
|
|
1794
2054
|
const key = containerId + configId;
|
|
1795
2055
|
ctx.mapViewabilityValues.set(key, viewToken);
|
|
@@ -1838,7 +2098,7 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1838
2098
|
for (const containerIndex of stickyContainerPool) {
|
|
1839
2099
|
const key = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
1840
2100
|
const isPendingRemoval = pendingRemovalSet.has(containerIndex);
|
|
1841
|
-
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
|
|
2101
|
+
if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType) && !result.includes(containerIndex)) {
|
|
1842
2102
|
result.push(containerIndex);
|
|
1843
2103
|
if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
|
|
1844
2104
|
pendingRemovalChanged = true;
|
|
@@ -1926,149 +2186,35 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
|
|
|
1926
2186
|
if (pendingRemovalChanged) {
|
|
1927
2187
|
pendingRemoval.length = 0;
|
|
1928
2188
|
for (const value of pendingRemovalSet) {
|
|
1929
|
-
pendingRemoval.push(value);
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
return result.sort(comparatorDefault);
|
|
1933
|
-
}
|
|
1934
|
-
function comparatorByDistance(a, b) {
|
|
1935
|
-
return b.distance - a.distance;
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
// src/utils/getScrollVelocity.ts
|
|
1939
|
-
var getScrollVelocity = (state) => {
|
|
1940
|
-
const { scrollHistory } = state;
|
|
1941
|
-
let velocity = 0;
|
|
1942
|
-
if (scrollHistory.length >= 1) {
|
|
1943
|
-
const newest = scrollHistory[scrollHistory.length - 1];
|
|
1944
|
-
let oldest;
|
|
1945
|
-
let start = 0;
|
|
1946
|
-
const now = Date.now();
|
|
1947
|
-
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
1948
|
-
const entry = scrollHistory[i];
|
|
1949
|
-
const nextEntry = scrollHistory[i + 1];
|
|
1950
|
-
if (i > 0) {
|
|
1951
|
-
const prevEntry = scrollHistory[i - 1];
|
|
1952
|
-
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
1953
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
1954
|
-
if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
|
|
1955
|
-
start = i;
|
|
1956
|
-
break;
|
|
1957
|
-
}
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
1961
|
-
const entry = scrollHistory[i];
|
|
1962
|
-
if (now - entry.time <= 1e3) {
|
|
1963
|
-
oldest = entry;
|
|
1964
|
-
break;
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
if (oldest && oldest !== newest) {
|
|
1968
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
1969
|
-
const timeDiff = newest.time - oldest.time;
|
|
1970
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
1971
|
-
}
|
|
1972
|
-
}
|
|
1973
|
-
return velocity;
|
|
1974
|
-
};
|
|
1975
|
-
|
|
1976
|
-
// src/core/scrollToIndex.ts
|
|
1977
|
-
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
1978
|
-
if (index >= state.props.data.length) {
|
|
1979
|
-
index = state.props.data.length - 1;
|
|
1980
|
-
} else if (index < 0) {
|
|
1981
|
-
index = 0;
|
|
1982
|
-
}
|
|
1983
|
-
const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
|
|
1984
|
-
const isLast = index === state.props.data.length - 1;
|
|
1985
|
-
if (isLast && viewPosition === void 0) {
|
|
1986
|
-
viewPosition = 1;
|
|
1987
|
-
}
|
|
1988
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1989
|
-
scrollTo(state, {
|
|
1990
|
-
animated,
|
|
1991
|
-
index,
|
|
1992
|
-
offset: firstIndexOffset,
|
|
1993
|
-
viewOffset,
|
|
1994
|
-
viewPosition: viewPosition != null ? viewPosition : 0
|
|
1995
|
-
});
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
// src/utils/checkThreshold.ts
|
|
1999
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
2000
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
|
|
2001
|
-
const absDistance = Math.abs(distance);
|
|
2002
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
2003
|
-
const updateSnapshot = () => {
|
|
2004
|
-
setSnapshot == null ? void 0 : setSnapshot({
|
|
2005
|
-
atThreshold,
|
|
2006
|
-
contentSize: context.contentSize,
|
|
2007
|
-
dataLength: context.dataLength,
|
|
2008
|
-
scrollPosition: context.scrollPosition
|
|
2009
|
-
});
|
|
2010
|
-
};
|
|
2011
|
-
if (!wasReached) {
|
|
2012
|
-
if (!within) {
|
|
2013
|
-
return false;
|
|
2014
|
-
}
|
|
2015
|
-
onReached == null ? void 0 : onReached(distance);
|
|
2016
|
-
updateSnapshot();
|
|
2017
|
-
return true;
|
|
2018
|
-
}
|
|
2019
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
2020
|
-
if (reset) {
|
|
2021
|
-
setSnapshot == null ? void 0 : setSnapshot(void 0);
|
|
2022
|
-
return false;
|
|
2023
|
-
}
|
|
2024
|
-
if (within) {
|
|
2025
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
2026
|
-
if (changed) {
|
|
2027
|
-
onReached == null ? void 0 : onReached(distance);
|
|
2028
|
-
updateSnapshot();
|
|
2189
|
+
pendingRemoval.push(value);
|
|
2029
2190
|
}
|
|
2030
2191
|
}
|
|
2031
|
-
return
|
|
2032
|
-
}
|
|
2192
|
+
return result.sort(comparatorDefault);
|
|
2193
|
+
}
|
|
2194
|
+
function comparatorByDistance(a, b) {
|
|
2195
|
+
return b.distance - a.distance;
|
|
2196
|
+
}
|
|
2033
2197
|
|
|
2034
|
-
// src/
|
|
2035
|
-
function
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2198
|
+
// src/core/scrollToIndex.ts
|
|
2199
|
+
function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
|
|
2200
|
+
if (index >= state.props.data.length) {
|
|
2201
|
+
index = state.props.data.length - 1;
|
|
2202
|
+
} else if (index < 0) {
|
|
2203
|
+
index = 0;
|
|
2039
2204
|
}
|
|
2040
|
-
const
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
maintainingScrollAtEnd,
|
|
2045
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
2046
|
-
} = state;
|
|
2047
|
-
const contentSize = getContentSize(ctx);
|
|
2048
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
2049
|
-
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
2050
|
-
const isContentLess = contentSize < scrollLength;
|
|
2051
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
2052
|
-
state.isEndReached = checkThreshold(
|
|
2053
|
-
distanceFromEnd,
|
|
2054
|
-
isContentLess,
|
|
2055
|
-
onEndReachedThreshold * scrollLength,
|
|
2056
|
-
state.isEndReached,
|
|
2057
|
-
state.endReachedSnapshot,
|
|
2058
|
-
{
|
|
2059
|
-
scrollPosition: scroll,
|
|
2060
|
-
contentSize,
|
|
2061
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length
|
|
2062
|
-
},
|
|
2063
|
-
(distance) => {
|
|
2064
|
-
var _a4, _b;
|
|
2065
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
2066
|
-
},
|
|
2067
|
-
(snapshot) => {
|
|
2068
|
-
state.endReachedSnapshot = snapshot;
|
|
2069
|
-
}
|
|
2070
|
-
);
|
|
2205
|
+
const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
|
|
2206
|
+
const isLast = index === state.props.data.length - 1;
|
|
2207
|
+
if (isLast && viewPosition === void 0) {
|
|
2208
|
+
viewPosition = 1;
|
|
2071
2209
|
}
|
|
2210
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2211
|
+
scrollTo(ctx, state, {
|
|
2212
|
+
animated,
|
|
2213
|
+
index,
|
|
2214
|
+
offset: firstIndexOffset,
|
|
2215
|
+
viewOffset,
|
|
2216
|
+
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2217
|
+
});
|
|
2072
2218
|
}
|
|
2073
2219
|
|
|
2074
2220
|
// src/utils/setDidLayout.ts
|
|
@@ -2150,7 +2296,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2150
2296
|
const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
|
|
2151
2297
|
if (currentId) {
|
|
2152
2298
|
const currentPos = state.positions.get(currentId);
|
|
2153
|
-
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2299
|
+
const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
|
|
2154
2300
|
shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
|
|
2155
2301
|
}
|
|
2156
2302
|
}
|
|
@@ -2161,21 +2307,22 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
|
|
|
2161
2307
|
}
|
|
2162
2308
|
function calculateItemsInView(ctx, state, params = {}) {
|
|
2163
2309
|
reactDom.unstable_batchedUpdates(() => {
|
|
2164
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2310
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2165
2311
|
const {
|
|
2166
2312
|
columns,
|
|
2167
2313
|
containerItemKeys,
|
|
2168
2314
|
enableScrollForNextCalculateItemsInView,
|
|
2169
2315
|
idCache,
|
|
2170
2316
|
indexByKey,
|
|
2317
|
+
initialScroll,
|
|
2171
2318
|
minIndexSizeChanged,
|
|
2172
2319
|
positions,
|
|
2320
|
+
props: { getItemType, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer },
|
|
2173
2321
|
scrollForNextCalculateItemsInView,
|
|
2174
2322
|
scrollLength,
|
|
2175
2323
|
sizes,
|
|
2176
2324
|
startBufferedId: startBufferedIdOrig,
|
|
2177
|
-
viewabilityConfigCallbackPairs
|
|
2178
|
-
props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, onStickyHeaderChange, scrollBuffer }
|
|
2325
|
+
viewabilityConfigCallbackPairs
|
|
2179
2326
|
} = state;
|
|
2180
2327
|
const { data } = state.props;
|
|
2181
2328
|
const stickyIndicesArr = state.props.stickyIndicesArr || [];
|
|
@@ -2187,20 +2334,22 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2187
2334
|
const totalSize = peek$(ctx, "totalSize");
|
|
2188
2335
|
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
2189
2336
|
const numColumns = peek$(ctx, "numColumns");
|
|
2190
|
-
const { dataChanged, doMVCP } = params;
|
|
2337
|
+
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
2191
2338
|
const speed = getScrollVelocity(state);
|
|
2192
2339
|
const scrollExtra = 0;
|
|
2193
2340
|
const { queuedInitialLayout } = state;
|
|
2194
2341
|
let { scroll: scrollState } = state;
|
|
2195
2342
|
if (!queuedInitialLayout && initialScroll) {
|
|
2196
2343
|
const updatedOffset = calculateOffsetWithOffsetPosition(
|
|
2344
|
+
ctx,
|
|
2197
2345
|
state,
|
|
2198
2346
|
calculateOffsetForIndex(ctx, state, initialScroll.index),
|
|
2199
2347
|
initialScroll
|
|
2200
2348
|
);
|
|
2201
2349
|
scrollState = updatedOffset;
|
|
2202
2350
|
}
|
|
2203
|
-
const
|
|
2351
|
+
const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
|
|
2352
|
+
const scrollAdjustPad = scrollAdjustPending - topPad;
|
|
2204
2353
|
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
2205
2354
|
if (scroll + scrollLength > totalSize) {
|
|
2206
2355
|
scroll = Math.max(0, totalSize - scrollLength);
|
|
@@ -2213,6 +2362,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2213
2362
|
const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
|
|
2214
2363
|
const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
|
|
2215
2364
|
state.activeStickyIndex = nextActiveStickyIndex;
|
|
2365
|
+
set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
|
|
2216
2366
|
let scrollBufferTop = scrollBuffer;
|
|
2217
2367
|
let scrollBufferBottom = scrollBuffer;
|
|
2218
2368
|
if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
|
|
@@ -2237,8 +2387,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2237
2387
|
idCache.length = 0;
|
|
2238
2388
|
positions.clear();
|
|
2239
2389
|
}
|
|
2240
|
-
const startIndex = dataChanged ? 0 : (
|
|
2241
|
-
updateItemPositions(ctx, state, dataChanged, {
|
|
2390
|
+
const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
|
|
2391
|
+
updateItemPositions(ctx, state, dataChanged, {
|
|
2392
|
+
forceFullUpdate: !!forceFullItemPositions,
|
|
2393
|
+
scrollBottomBuffered,
|
|
2394
|
+
startIndex
|
|
2395
|
+
});
|
|
2242
2396
|
if (minIndexSizeChanged !== void 0) {
|
|
2243
2397
|
state.minIndexSizeChanged = void 0;
|
|
2244
2398
|
}
|
|
@@ -2250,9 +2404,9 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2250
2404
|
let endBuffered = null;
|
|
2251
2405
|
let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
|
|
2252
2406
|
for (let i = loopStart; i >= 0; i--) {
|
|
2253
|
-
const id = (
|
|
2407
|
+
const id = (_c = idCache[i]) != null ? _c : getId(state, i);
|
|
2254
2408
|
const top = positions.get(id);
|
|
2255
|
-
const size = (
|
|
2409
|
+
const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
|
|
2256
2410
|
const bottom = top + size;
|
|
2257
2411
|
if (bottom > scroll - scrollBuffer) {
|
|
2258
2412
|
loopStart = i;
|
|
@@ -2278,8 +2432,8 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2278
2432
|
let firstFullyOnScreenIndex;
|
|
2279
2433
|
const dataLength = data.length;
|
|
2280
2434
|
for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
|
|
2281
|
-
const id = (
|
|
2282
|
-
const size = (
|
|
2435
|
+
const id = (_e = idCache[i]) != null ? _e : getId(state, i);
|
|
2436
|
+
const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
|
|
2283
2437
|
const top = positions.get(id);
|
|
2284
2438
|
if (!foundEnd) {
|
|
2285
2439
|
if (startNoBuffer === null && top + size > scroll) {
|
|
@@ -2308,7 +2462,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2308
2462
|
}
|
|
2309
2463
|
const idsInView = [];
|
|
2310
2464
|
for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
|
|
2311
|
-
const id = (
|
|
2465
|
+
const id = (_g = idCache[i]) != null ? _g : getId(state, i);
|
|
2312
2466
|
idsInView.push(id);
|
|
2313
2467
|
}
|
|
2314
2468
|
Object.assign(state, {
|
|
@@ -2340,7 +2494,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2340
2494
|
let numContainers2 = prevNumContainers;
|
|
2341
2495
|
const needNewContainers = [];
|
|
2342
2496
|
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
2343
|
-
const id = (
|
|
2497
|
+
const id = (_h = idCache[i]) != null ? _h : getId(state, i);
|
|
2344
2498
|
if (!containerItemKeys.has(id)) {
|
|
2345
2499
|
needNewContainers.push(i);
|
|
2346
2500
|
}
|
|
@@ -2358,6 +2512,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2358
2512
|
);
|
|
2359
2513
|
} else {
|
|
2360
2514
|
state.activeStickyIndex = void 0;
|
|
2515
|
+
set$(ctx, "activeStickyIndex", void 0);
|
|
2361
2516
|
}
|
|
2362
2517
|
if (needNewContainers.length > 0) {
|
|
2363
2518
|
const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
|
|
@@ -2377,7 +2532,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2377
2532
|
for (let idx = 0; idx < needNewContainers.length; idx++) {
|
|
2378
2533
|
const i = needNewContainers[idx];
|
|
2379
2534
|
const containerIndex = availableContainers[idx];
|
|
2380
|
-
const id = (
|
|
2535
|
+
const id = (_i = idCache[i]) != null ? _i : getId(state, i);
|
|
2381
2536
|
const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
|
|
2382
2537
|
if (oldKey && oldKey !== id) {
|
|
2383
2538
|
containerItemKeys.delete(oldKey);
|
|
@@ -2416,7 +2571,7 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2416
2571
|
for (let i = 0; i < numContainers; i++) {
|
|
2417
2572
|
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
2418
2573
|
if (pendingRemoval.includes(i)) {
|
|
2419
|
-
if (itemKey) {
|
|
2574
|
+
if (itemKey !== void 0) {
|
|
2420
2575
|
containerItemKeys.delete(itemKey);
|
|
2421
2576
|
}
|
|
2422
2577
|
state.containerItemTypes.delete(i);
|
|
@@ -2433,11 +2588,12 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2433
2588
|
const itemIndex = indexByKey.get(itemKey);
|
|
2434
2589
|
const item = data[itemIndex];
|
|
2435
2590
|
if (item !== void 0) {
|
|
2436
|
-
const id = (
|
|
2437
|
-
const
|
|
2438
|
-
if (
|
|
2591
|
+
const id = (_j = idCache[itemIndex]) != null ? _j : getId(state, itemIndex);
|
|
2592
|
+
const positionValue = positions.get(id);
|
|
2593
|
+
if (positionValue === void 0) {
|
|
2439
2594
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
2440
2595
|
} else {
|
|
2596
|
+
const position = (positionValue || 0) - scrollAdjustPending;
|
|
2441
2597
|
const column = columns.get(id) || 1;
|
|
2442
2598
|
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
2443
2599
|
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
@@ -2476,6 +2632,26 @@ function calculateItemsInView(ctx, state, params = {}) {
|
|
|
2476
2632
|
});
|
|
2477
2633
|
}
|
|
2478
2634
|
|
|
2635
|
+
// src/core/checkActualChange.ts
|
|
2636
|
+
function checkActualChange(state, dataProp, previousData) {
|
|
2637
|
+
if (!previousData || !dataProp || dataProp.length !== previousData.length) {
|
|
2638
|
+
return true;
|
|
2639
|
+
}
|
|
2640
|
+
const {
|
|
2641
|
+
idCache,
|
|
2642
|
+
props: { keyExtractor }
|
|
2643
|
+
} = state;
|
|
2644
|
+
for (let i = 0; i < dataProp.length; i++) {
|
|
2645
|
+
if (dataProp[i] !== previousData[i]) {
|
|
2646
|
+
return true;
|
|
2647
|
+
}
|
|
2648
|
+
if (keyExtractor ? idCache[i] !== keyExtractor(previousData[i], i) : dataProp[i] !== previousData[i]) {
|
|
2649
|
+
return true;
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
return false;
|
|
2653
|
+
}
|
|
2654
|
+
|
|
2479
2655
|
// src/core/doMaintainScrollAtEnd.ts
|
|
2480
2656
|
function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
2481
2657
|
const {
|
|
@@ -2506,40 +2682,6 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
|
|
|
2506
2682
|
}
|
|
2507
2683
|
}
|
|
2508
2684
|
|
|
2509
|
-
// src/utils/checkAtTop.ts
|
|
2510
|
-
function checkAtTop(state) {
|
|
2511
|
-
var _a3;
|
|
2512
|
-
if (!state) {
|
|
2513
|
-
return;
|
|
2514
|
-
}
|
|
2515
|
-
const {
|
|
2516
|
-
scrollLength,
|
|
2517
|
-
scroll,
|
|
2518
|
-
props: { onStartReachedThreshold }
|
|
2519
|
-
} = state;
|
|
2520
|
-
const distanceFromTop = scroll;
|
|
2521
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
2522
|
-
state.isStartReached = checkThreshold(
|
|
2523
|
-
distanceFromTop,
|
|
2524
|
-
false,
|
|
2525
|
-
onStartReachedThreshold * scrollLength,
|
|
2526
|
-
state.isStartReached,
|
|
2527
|
-
state.startReachedSnapshot,
|
|
2528
|
-
{
|
|
2529
|
-
scrollPosition: scroll,
|
|
2530
|
-
contentSize: state.totalSize,
|
|
2531
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length
|
|
2532
|
-
},
|
|
2533
|
-
(distance) => {
|
|
2534
|
-
var _a4, _b;
|
|
2535
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
2536
|
-
},
|
|
2537
|
-
(snapshot) => {
|
|
2538
|
-
state.startReachedSnapshot = snapshot;
|
|
2539
|
-
}
|
|
2540
|
-
);
|
|
2541
|
-
}
|
|
2542
|
-
|
|
2543
2685
|
// src/utils/updateAveragesOnDataChange.ts
|
|
2544
2686
|
function updateAveragesOnDataChange(state, oldData, newData) {
|
|
2545
2687
|
var _a3;
|
|
@@ -2593,25 +2735,23 @@ function updateAveragesOnDataChange(state, oldData, newData) {
|
|
|
2593
2735
|
}
|
|
2594
2736
|
|
|
2595
2737
|
// src/core/checkResetContainers.ts
|
|
2596
|
-
function checkResetContainers(ctx, state,
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
state.isEndReached = false;
|
|
2608
|
-
}
|
|
2609
|
-
if (!didMaintainScrollAtEnd) {
|
|
2610
|
-
checkAtTop(state);
|
|
2611
|
-
checkAtBottom(ctx, state);
|
|
2612
|
-
}
|
|
2613
|
-
}
|
|
2738
|
+
function checkResetContainers(ctx, state, dataProp) {
|
|
2739
|
+
const { previousData } = state;
|
|
2740
|
+
if (previousData) {
|
|
2741
|
+
updateAveragesOnDataChange(state, previousData, dataProp);
|
|
2742
|
+
}
|
|
2743
|
+
const { maintainScrollAtEnd } = state.props;
|
|
2744
|
+
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2745
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2746
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
|
|
2747
|
+
if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
|
|
2748
|
+
state.isEndReached = false;
|
|
2614
2749
|
}
|
|
2750
|
+
if (!didMaintainScrollAtEnd) {
|
|
2751
|
+
checkAtTop(state);
|
|
2752
|
+
checkAtBottom(ctx, state);
|
|
2753
|
+
}
|
|
2754
|
+
delete state.previousData;
|
|
2615
2755
|
}
|
|
2616
2756
|
|
|
2617
2757
|
// src/core/doInitialAllocateContainers.ts
|
|
@@ -2652,7 +2792,7 @@ function doInitialAllocateContainers(ctx, state) {
|
|
|
2652
2792
|
set$(ctx, "numContainers", numContainers);
|
|
2653
2793
|
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
2654
2794
|
if (state.lastLayout) {
|
|
2655
|
-
if (state.
|
|
2795
|
+
if (state.initialScroll) {
|
|
2656
2796
|
requestAnimationFrame(() => {
|
|
2657
2797
|
calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
|
|
2658
2798
|
});
|
|
@@ -2708,78 +2848,47 @@ function handleLayout(ctx, state, layout, setCanRender) {
|
|
|
2708
2848
|
setCanRender(true);
|
|
2709
2849
|
}
|
|
2710
2850
|
|
|
2711
|
-
// src/core/onScroll.ts
|
|
2712
|
-
function onScroll(ctx, state, event) {
|
|
2713
|
-
var _a3, _b, _c;
|
|
2714
|
-
const {
|
|
2715
|
-
scrollProcessingEnabled,
|
|
2716
|
-
props: { onScroll: onScrollProp }
|
|
2717
|
-
} = state;
|
|
2718
|
-
if (scrollProcessingEnabled === false) {
|
|
2719
|
-
return;
|
|
2720
|
-
}
|
|
2721
|
-
if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
|
|
2722
|
-
return;
|
|
2723
|
-
}
|
|
2724
|
-
const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
|
|
2725
|
-
state.scrollPending = newScroll;
|
|
2726
|
-
updateScroll(ctx, state, newScroll);
|
|
2727
|
-
onScrollProp == null ? void 0 : onScrollProp(event);
|
|
2728
|
-
}
|
|
2729
|
-
function updateScroll(ctx, state, newScroll) {
|
|
2730
|
-
const scrollingTo = state.scrollingTo;
|
|
2731
|
-
state.hasScrolled = true;
|
|
2732
|
-
state.lastBatchingAction = Date.now();
|
|
2733
|
-
const currentTime = Date.now();
|
|
2734
|
-
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2735
|
-
const lastHistoryAdjust = state.lastScrollAdjustForHistory;
|
|
2736
|
-
const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
|
|
2737
|
-
if (adjustChanged) {
|
|
2738
|
-
state.scrollHistory.length = 0;
|
|
2739
|
-
}
|
|
2740
|
-
state.lastScrollAdjustForHistory = adjust;
|
|
2741
|
-
if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
2742
|
-
if (!adjustChanged) {
|
|
2743
|
-
state.scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
|
-
if (state.scrollHistory.length > 5) {
|
|
2747
|
-
state.scrollHistory.shift();
|
|
2748
|
-
}
|
|
2749
|
-
state.scrollPrev = state.scroll;
|
|
2750
|
-
state.scrollPrevTime = state.scrollTime;
|
|
2751
|
-
state.scroll = newScroll;
|
|
2752
|
-
state.scrollTime = currentTime;
|
|
2753
|
-
const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
|
|
2754
|
-
if (ignoreScrollFromMVCP && !state.scrollingTo) {
|
|
2755
|
-
const { lt, gt } = ignoreScrollFromMVCP;
|
|
2756
|
-
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
2757
|
-
return;
|
|
2758
|
-
}
|
|
2759
|
-
}
|
|
2760
|
-
if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
|
|
2761
|
-
calculateItemsInView(ctx, state, { doMVCP: state.scrollingTo !== void 0 });
|
|
2762
|
-
checkAtBottom(ctx, state);
|
|
2763
|
-
checkAtTop(state);
|
|
2764
|
-
state.dataChangeNeedsScrollUpdate = false;
|
|
2765
|
-
}
|
|
2766
|
-
}
|
|
2767
|
-
|
|
2768
2851
|
// src/core/ScrollAdjustHandler.ts
|
|
2769
2852
|
var ScrollAdjustHandler = class {
|
|
2770
2853
|
constructor(ctx) {
|
|
2771
2854
|
this.appliedAdjust = 0;
|
|
2855
|
+
this.pendingAdjust = 0;
|
|
2772
2856
|
this.mounted = false;
|
|
2773
2857
|
this.context = ctx;
|
|
2858
|
+
{
|
|
2859
|
+
const commitPendingAdjust = () => {
|
|
2860
|
+
const state = this.context.internalState;
|
|
2861
|
+
const pending = this.pendingAdjust;
|
|
2862
|
+
if (pending !== 0) {
|
|
2863
|
+
this.pendingAdjust = 0;
|
|
2864
|
+
this.appliedAdjust += pending;
|
|
2865
|
+
state.scroll += pending;
|
|
2866
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2867
|
+
set$(this.context, "scrollAdjustPending", 0);
|
|
2868
|
+
set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
2869
|
+
calculateItemsInView(this.context, this.context.internalState);
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
listen$(this.context, "scrollingTo", (value) => {
|
|
2873
|
+
if (value === void 0) {
|
|
2874
|
+
commitPendingAdjust();
|
|
2875
|
+
}
|
|
2876
|
+
});
|
|
2877
|
+
}
|
|
2774
2878
|
}
|
|
2775
2879
|
requestAdjust(add) {
|
|
2776
|
-
const
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
set();
|
|
2880
|
+
const scrollingTo = peek$(this.context, "scrollingTo");
|
|
2881
|
+
if ((scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
|
|
2882
|
+
this.pendingAdjust += add;
|
|
2883
|
+
set$(this.context, "scrollAdjustPending", this.pendingAdjust);
|
|
2781
2884
|
} else {
|
|
2782
|
-
|
|
2885
|
+
this.appliedAdjust += add;
|
|
2886
|
+
const setter = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
|
|
2887
|
+
if (this.mounted) {
|
|
2888
|
+
setter();
|
|
2889
|
+
} else {
|
|
2890
|
+
requestAnimationFrame(setter);
|
|
2891
|
+
}
|
|
2783
2892
|
}
|
|
2784
2893
|
}
|
|
2785
2894
|
setMounted() {
|
|
@@ -2827,8 +2936,8 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2827
2936
|
let minIndexSizeChanged;
|
|
2828
2937
|
let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
|
|
2829
2938
|
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
2830
|
-
const diff = updateOneItemSize(state, itemKey, sizeObj);
|
|
2831
|
-
const size =
|
|
2939
|
+
const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
|
|
2940
|
+
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
2832
2941
|
if (diff !== 0) {
|
|
2833
2942
|
minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
|
|
2834
2943
|
const { startBuffered, endBuffered } = state;
|
|
@@ -2849,7 +2958,6 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2849
2958
|
if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
|
|
2850
2959
|
shouldMaintainScrollAtEnd = true;
|
|
2851
2960
|
}
|
|
2852
|
-
addTotalSize(ctx, state, itemKey, diff);
|
|
2853
2961
|
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
2854
2962
|
index,
|
|
2855
2963
|
itemData: state.props.data[index],
|
|
@@ -2889,7 +2997,7 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2889
2997
|
}
|
|
2890
2998
|
}
|
|
2891
2999
|
}
|
|
2892
|
-
function updateOneItemSize(state, itemKey, sizeObj) {
|
|
3000
|
+
function updateOneItemSize(ctx, state, itemKey, sizeObj) {
|
|
2893
3001
|
var _a3;
|
|
2894
3002
|
const {
|
|
2895
3003
|
sizes,
|
|
@@ -2900,7 +3008,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
|
|
|
2900
3008
|
} = state;
|
|
2901
3009
|
if (!data) return 0;
|
|
2902
3010
|
const index = indexByKey.get(itemKey);
|
|
2903
|
-
const prevSize = getItemSize(state, itemKey, index, data[index]);
|
|
3011
|
+
const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
|
|
2904
3012
|
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
2905
3013
|
const size = Math.round(rawSize) ;
|
|
2906
3014
|
sizesKnown.set(itemKey, size);
|
|
@@ -2914,7 +3022,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
|
|
|
2914
3022
|
averages.num++;
|
|
2915
3023
|
}
|
|
2916
3024
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
2917
|
-
|
|
3025
|
+
setSize(ctx, state, itemKey, size);
|
|
2918
3026
|
return size - prevSize;
|
|
2919
3027
|
}
|
|
2920
3028
|
return 0;
|
|
@@ -2959,6 +3067,91 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
2959
3067
|
};
|
|
2960
3068
|
}
|
|
2961
3069
|
}
|
|
3070
|
+
|
|
3071
|
+
// src/utils/createImperativeHandle.ts
|
|
3072
|
+
function createImperativeHandle(ctx, state) {
|
|
3073
|
+
const scrollIndexIntoView = (options) => {
|
|
3074
|
+
if (state) {
|
|
3075
|
+
const { index, ...rest } = options;
|
|
3076
|
+
const { startNoBuffer, endNoBuffer } = state;
|
|
3077
|
+
if (index < startNoBuffer || index > endNoBuffer) {
|
|
3078
|
+
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
3079
|
+
scrollToIndex(ctx, state, {
|
|
3080
|
+
...rest,
|
|
3081
|
+
index,
|
|
3082
|
+
viewPosition
|
|
3083
|
+
});
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
};
|
|
3087
|
+
const refScroller = state.refScroller;
|
|
3088
|
+
return {
|
|
3089
|
+
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
3090
|
+
getNativeScrollRef: () => refScroller.current,
|
|
3091
|
+
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
3092
|
+
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
3093
|
+
getState: () => ({
|
|
3094
|
+
activeStickyIndex: state.activeStickyIndex,
|
|
3095
|
+
contentLength: state.totalSize,
|
|
3096
|
+
data: state.props.data,
|
|
3097
|
+
elementAtIndex: (index) => {
|
|
3098
|
+
var _a3;
|
|
3099
|
+
return (_a3 = ctx.viewRefs.get(findContainerId(ctx, getId(state, index)))) == null ? void 0 : _a3.current;
|
|
3100
|
+
},
|
|
3101
|
+
end: state.endNoBuffer,
|
|
3102
|
+
endBuffered: state.endBuffered,
|
|
3103
|
+
isAtEnd: state.isAtEnd,
|
|
3104
|
+
isAtStart: state.isAtStart,
|
|
3105
|
+
positionAtIndex: (index) => state.positions.get(getId(state, index)),
|
|
3106
|
+
positions: state.positions,
|
|
3107
|
+
scroll: state.scroll,
|
|
3108
|
+
scrollLength: state.scrollLength,
|
|
3109
|
+
sizeAtIndex: (index) => state.sizesKnown.get(getId(state, index)),
|
|
3110
|
+
sizes: state.sizesKnown,
|
|
3111
|
+
start: state.startNoBuffer,
|
|
3112
|
+
startBuffered: state.startBuffered
|
|
3113
|
+
}),
|
|
3114
|
+
scrollIndexIntoView,
|
|
3115
|
+
scrollItemIntoView: ({ item, ...props }) => {
|
|
3116
|
+
const data = state.props.data;
|
|
3117
|
+
const index = data.indexOf(item);
|
|
3118
|
+
if (index !== -1) {
|
|
3119
|
+
scrollIndexIntoView({ index, ...props });
|
|
3120
|
+
}
|
|
3121
|
+
},
|
|
3122
|
+
scrollToEnd: (options) => {
|
|
3123
|
+
const data = state.props.data;
|
|
3124
|
+
const stylePaddingBottom = state.props.stylePaddingBottom;
|
|
3125
|
+
const index = data.length - 1;
|
|
3126
|
+
if (index !== -1) {
|
|
3127
|
+
const paddingBottom = stylePaddingBottom || 0;
|
|
3128
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
3129
|
+
scrollToIndex(ctx, state, {
|
|
3130
|
+
index,
|
|
3131
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
3132
|
+
viewPosition: 1,
|
|
3133
|
+
...options
|
|
3134
|
+
});
|
|
3135
|
+
}
|
|
3136
|
+
},
|
|
3137
|
+
scrollToIndex: (params) => scrollToIndex(ctx, state, params),
|
|
3138
|
+
scrollToItem: ({ item, ...props }) => {
|
|
3139
|
+
const data = state.props.data;
|
|
3140
|
+
const index = data.indexOf(item);
|
|
3141
|
+
if (index !== -1) {
|
|
3142
|
+
scrollToIndex(ctx, state, { index, ...props });
|
|
3143
|
+
}
|
|
3144
|
+
},
|
|
3145
|
+
scrollToOffset: (params) => scrollTo(ctx, state, params),
|
|
3146
|
+
setScrollProcessingEnabled: (enabled) => {
|
|
3147
|
+
state.scrollProcessingEnabled = enabled;
|
|
3148
|
+
},
|
|
3149
|
+
setVisibleContentAnchorOffset: (value) => {
|
|
3150
|
+
const val = isFunction(value) ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
|
|
3151
|
+
set$(ctx, "scrollAdjustUserOffset", val);
|
|
3152
|
+
}
|
|
3153
|
+
};
|
|
3154
|
+
}
|
|
2962
3155
|
function getRenderedItem(ctx, state, key) {
|
|
2963
3156
|
var _a3;
|
|
2964
3157
|
if (!state) {
|
|
@@ -3059,6 +3252,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3059
3252
|
columnWrapperStyle,
|
|
3060
3253
|
contentContainerStyle: contentContainerStyleProp,
|
|
3061
3254
|
data: dataProp = [],
|
|
3255
|
+
dataVersion,
|
|
3062
3256
|
drawDistance = 250,
|
|
3063
3257
|
enableAverages = true,
|
|
3064
3258
|
estimatedItemSize: estimatedItemSizeProp,
|
|
@@ -3069,6 +3263,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3069
3263
|
getItemType,
|
|
3070
3264
|
horizontal,
|
|
3071
3265
|
initialContainerPoolRatio = 2,
|
|
3266
|
+
initialScrollAtEnd = false,
|
|
3072
3267
|
initialScrollIndex: initialScrollIndexProp,
|
|
3073
3268
|
initialScrollOffset: initialScrollOffsetProp,
|
|
3074
3269
|
itemsAreEqual,
|
|
@@ -3107,13 +3302,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3107
3302
|
waitForInitialLayout = true,
|
|
3108
3303
|
...rest
|
|
3109
3304
|
} = props;
|
|
3110
|
-
const [renderNum, setRenderNum] = React3.useState(0);
|
|
3111
|
-
const initialScroll = initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3112
|
-
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
3113
3305
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
3114
3306
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
3115
3307
|
const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
|
|
3116
3308
|
const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
|
|
3309
|
+
const [renderNum, setRenderNum] = React3.useState(0);
|
|
3310
|
+
const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
|
|
3311
|
+
const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
|
|
3117
3312
|
const ctx = useStateContext();
|
|
3118
3313
|
ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
|
|
3119
3314
|
const refScroller = React3.useRef(null);
|
|
@@ -3132,6 +3327,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3132
3327
|
containerItemKeys: /* @__PURE__ */ new Set(),
|
|
3133
3328
|
containerItemTypes: /* @__PURE__ */ new Map(),
|
|
3134
3329
|
dataChangeNeedsScrollUpdate: false,
|
|
3330
|
+
didColumnsChange: false,
|
|
3331
|
+
didDataChange: false,
|
|
3135
3332
|
enableScrollForNextCalculateItemsInView: true,
|
|
3136
3333
|
endBuffered: -1,
|
|
3137
3334
|
endNoBuffer: -1,
|
|
@@ -3140,10 +3337,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3140
3337
|
idCache: [],
|
|
3141
3338
|
idsInView: [],
|
|
3142
3339
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
3143
|
-
initialScroll,
|
|
3340
|
+
initialScroll: initialScrollProp,
|
|
3144
3341
|
isAtEnd: false,
|
|
3145
3342
|
isAtStart: false,
|
|
3146
3343
|
isEndReached: false,
|
|
3344
|
+
isFirst: true,
|
|
3147
3345
|
isStartReached: false,
|
|
3148
3346
|
lastBatchingAction: Date.now(),
|
|
3149
3347
|
lastLayout: void 0,
|
|
@@ -3176,21 +3374,27 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3176
3374
|
totalSize: 0,
|
|
3177
3375
|
viewabilityConfigCallbackPairs: void 0
|
|
3178
3376
|
};
|
|
3377
|
+
const internalState = ctx.internalState;
|
|
3378
|
+
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
|
|
3179
3379
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
3180
3380
|
set$(ctx, "extraData", extraData);
|
|
3181
3381
|
}
|
|
3182
3382
|
refState.current = ctx.internalState;
|
|
3183
3383
|
}
|
|
3184
3384
|
const state = refState.current;
|
|
3185
|
-
const
|
|
3186
|
-
|
|
3187
|
-
|
|
3385
|
+
const isFirstLocal = state.isFirst;
|
|
3386
|
+
state.didColumnsChange = numColumnsProp !== state.props.numColumns;
|
|
3387
|
+
const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
|
|
3388
|
+
if (didDataChangeLocal) {
|
|
3188
3389
|
state.dataChangeNeedsScrollUpdate = true;
|
|
3390
|
+
state.didDataChange = true;
|
|
3391
|
+
state.previousData = state.props.data;
|
|
3189
3392
|
}
|
|
3190
3393
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
|
|
3191
3394
|
state.props = {
|
|
3192
3395
|
alignItemsAtEnd,
|
|
3193
3396
|
data: dataProp,
|
|
3397
|
+
dataVersion,
|
|
3194
3398
|
enableAverages,
|
|
3195
3399
|
estimatedItemSize,
|
|
3196
3400
|
getEstimatedItemSize,
|
|
@@ -3198,7 +3402,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3198
3402
|
getItemType,
|
|
3199
3403
|
horizontal: !!horizontal,
|
|
3200
3404
|
initialContainerPoolRatio,
|
|
3201
|
-
initialScroll,
|
|
3202
3405
|
itemsAreEqual,
|
|
3203
3406
|
keyExtractor,
|
|
3204
3407
|
maintainScrollAtEnd,
|
|
@@ -3230,7 +3433,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3230
3433
|
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
3231
3434
|
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
3232
3435
|
);
|
|
3233
|
-
}, [dataProp, numColumnsProp]);
|
|
3436
|
+
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3234
3437
|
const initializeStateVars = () => {
|
|
3235
3438
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
3236
3439
|
set$(ctx, "numColumns", numColumnsProp);
|
|
@@ -3245,7 +3448,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3245
3448
|
requestAdjust(ctx, state, paddingDiff);
|
|
3246
3449
|
}
|
|
3247
3450
|
};
|
|
3248
|
-
if (
|
|
3451
|
+
if (isFirstLocal) {
|
|
3249
3452
|
initializeStateVars();
|
|
3250
3453
|
updateItemPositions(
|
|
3251
3454
|
ctx,
|
|
@@ -3255,38 +3458,42 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3255
3458
|
);
|
|
3256
3459
|
}
|
|
3257
3460
|
const initialContentOffset = React3.useMemo(() => {
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3461
|
+
const { initialScroll } = refState.current;
|
|
3462
|
+
if (!initialScroll) {
|
|
3463
|
+
return 0;
|
|
3464
|
+
}
|
|
3465
|
+
if (initialScroll.contentOffset !== void 0) {
|
|
3466
|
+
return initialScroll.contentOffset;
|
|
3467
|
+
}
|
|
3468
|
+
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
|
|
3469
|
+
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
|
|
3470
|
+
let clampedOffset = resolvedOffset;
|
|
3471
|
+
if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
|
|
3472
|
+
const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
|
|
3473
|
+
clampedOffset = Math.min(clampedOffset, maxOffset);
|
|
3474
|
+
}
|
|
3475
|
+
clampedOffset = Math.max(0, clampedOffset);
|
|
3476
|
+
const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
|
|
3477
|
+
refState.current.initialScroll = updatedInitialScroll;
|
|
3478
|
+
state.initialScroll = updatedInitialScroll;
|
|
3479
|
+
refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
|
|
3480
|
+
return clampedOffset;
|
|
3481
|
+
}, [renderNum, state.initialScroll]);
|
|
3482
|
+
if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
3279
3483
|
refState.current.lastBatchingAction = Date.now();
|
|
3280
|
-
if (!keyExtractorProp && !
|
|
3484
|
+
if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
|
|
3281
3485
|
IS_DEV && warnDevOnce(
|
|
3282
3486
|
"keyExtractor",
|
|
3283
3487
|
"Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
|
|
3284
3488
|
);
|
|
3285
3489
|
refState.current.sizes.clear();
|
|
3286
3490
|
refState.current.positions.clear();
|
|
3491
|
+
refState.current.totalSize = 0;
|
|
3492
|
+
set$(ctx, "totalSize", 0);
|
|
3287
3493
|
}
|
|
3288
3494
|
}
|
|
3289
3495
|
const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
|
|
3496
|
+
const { initialScroll } = refState.current;
|
|
3290
3497
|
const size = rect[horizontal ? "width" : "height"];
|
|
3291
3498
|
set$(ctx, "headerSize", size);
|
|
3292
3499
|
if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
|
|
@@ -3297,31 +3504,57 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3297
3504
|
}
|
|
3298
3505
|
}
|
|
3299
3506
|
}, []);
|
|
3507
|
+
const doInitialScroll = React3.useCallback(() => {
|
|
3508
|
+
var _a4;
|
|
3509
|
+
const initialScroll = state.initialScroll;
|
|
3510
|
+
if (initialScroll) {
|
|
3511
|
+
scrollTo(ctx, state, {
|
|
3512
|
+
animated: false,
|
|
3513
|
+
index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
|
|
3514
|
+
offset: initialContentOffset,
|
|
3515
|
+
precomputedWithViewOffset: true
|
|
3516
|
+
});
|
|
3517
|
+
}
|
|
3518
|
+
}, [initialContentOffset, state.initialScroll]);
|
|
3519
|
+
const onLayoutChange = React3.useCallback((layout) => {
|
|
3520
|
+
doInitialScroll();
|
|
3521
|
+
handleLayout(ctx, state, layout, setCanRender);
|
|
3522
|
+
}, []);
|
|
3523
|
+
const { onLayout } = useOnLayoutSync({
|
|
3524
|
+
onLayoutChange,
|
|
3525
|
+
onLayoutProp,
|
|
3526
|
+
ref: refScroller
|
|
3527
|
+
// the type of ScrollView doesn't include measure?
|
|
3528
|
+
});
|
|
3300
3529
|
React3.useLayoutEffect(() => {
|
|
3301
3530
|
if (snapToIndices) {
|
|
3302
3531
|
updateSnapToOffsets(ctx, state);
|
|
3303
3532
|
}
|
|
3304
3533
|
}, [snapToIndices]);
|
|
3305
3534
|
React3.useLayoutEffect(() => {
|
|
3306
|
-
const
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
);
|
|
3315
|
-
}
|
|
3316
|
-
|
|
3535
|
+
const {
|
|
3536
|
+
didColumnsChange,
|
|
3537
|
+
didDataChange,
|
|
3538
|
+
isFirst,
|
|
3539
|
+
props: { data }
|
|
3540
|
+
} = state;
|
|
3541
|
+
const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
|
|
3542
|
+
if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
|
|
3543
|
+
checkResetContainers(ctx, state, data);
|
|
3544
|
+
}
|
|
3545
|
+
state.didColumnsChange = false;
|
|
3546
|
+
state.didDataChange = false;
|
|
3547
|
+
state.isFirst = false;
|
|
3548
|
+
}, [dataProp, dataVersion, numColumnsProp]);
|
|
3317
3549
|
React3.useLayoutEffect(() => {
|
|
3318
3550
|
set$(ctx, "extraData", extraData);
|
|
3319
3551
|
}, [extraData]);
|
|
3320
3552
|
React3.useLayoutEffect(initializeStateVars, [
|
|
3553
|
+
dataVersion,
|
|
3321
3554
|
memoizedLastItemKeys.join(","),
|
|
3322
3555
|
numColumnsProp,
|
|
3323
|
-
|
|
3324
|
-
|
|
3556
|
+
stylePaddingBottomState,
|
|
3557
|
+
stylePaddingTopState
|
|
3325
3558
|
]);
|
|
3326
3559
|
React3.useEffect(() => {
|
|
3327
3560
|
const viewability = setupViewability({
|
|
@@ -3332,103 +3565,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3332
3565
|
state.viewabilityConfigCallbackPairs = viewability;
|
|
3333
3566
|
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
3334
3567
|
}, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
|
|
3335
|
-
|
|
3336
|
-
handleLayout(ctx, state, layout, setCanRender);
|
|
3337
|
-
}, []);
|
|
3338
|
-
const { onLayout } = useOnLayoutSync({
|
|
3339
|
-
onLayoutChange,
|
|
3340
|
-
onLayoutProp,
|
|
3341
|
-
ref: refScroller
|
|
3342
|
-
// the type of ScrollView doesn't include measure?
|
|
3343
|
-
});
|
|
3344
|
-
React3.useImperativeHandle(forwardedRef, () => {
|
|
3345
|
-
const scrollIndexIntoView = (options) => {
|
|
3346
|
-
const state2 = refState.current;
|
|
3347
|
-
if (state2) {
|
|
3348
|
-
const { index, ...rest2 } = options;
|
|
3349
|
-
const { startNoBuffer, endNoBuffer } = state2;
|
|
3350
|
-
if (index < startNoBuffer || index > endNoBuffer) {
|
|
3351
|
-
const viewPosition = index < startNoBuffer ? 0 : 1;
|
|
3352
|
-
scrollToIndex(ctx, state2, {
|
|
3353
|
-
...rest2,
|
|
3354
|
-
index,
|
|
3355
|
-
viewPosition
|
|
3356
|
-
});
|
|
3357
|
-
}
|
|
3358
|
-
}
|
|
3359
|
-
};
|
|
3360
|
-
return {
|
|
3361
|
-
flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
|
|
3362
|
-
getNativeScrollRef: () => refScroller.current,
|
|
3363
|
-
getScrollableNode: () => refScroller.current.getScrollableNode(),
|
|
3364
|
-
getScrollResponder: () => refScroller.current.getScrollResponder(),
|
|
3365
|
-
getState: () => {
|
|
3366
|
-
const state2 = refState.current;
|
|
3367
|
-
return state2 ? {
|
|
3368
|
-
activeStickyIndex: state2.activeStickyIndex,
|
|
3369
|
-
contentLength: state2.totalSize,
|
|
3370
|
-
data: state2.props.data,
|
|
3371
|
-
end: state2.endNoBuffer,
|
|
3372
|
-
endBuffered: state2.endBuffered,
|
|
3373
|
-
isAtEnd: state2.isAtEnd,
|
|
3374
|
-
isAtStart: state2.isAtStart,
|
|
3375
|
-
positionAtIndex: (index) => state2.positions.get(getId(state2, index)),
|
|
3376
|
-
positions: state2.positions,
|
|
3377
|
-
scroll: state2.scroll,
|
|
3378
|
-
scrollLength: state2.scrollLength,
|
|
3379
|
-
sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index)),
|
|
3380
|
-
sizes: state2.sizesKnown,
|
|
3381
|
-
start: state2.startNoBuffer,
|
|
3382
|
-
startBuffered: state2.startBuffered
|
|
3383
|
-
} : {};
|
|
3384
|
-
},
|
|
3385
|
-
scrollIndexIntoView,
|
|
3386
|
-
scrollItemIntoView: ({ item, ...props2 }) => {
|
|
3387
|
-
const data = refState.current.props.data;
|
|
3388
|
-
const index = data.indexOf(item);
|
|
3389
|
-
if (index !== -1) {
|
|
3390
|
-
scrollIndexIntoView({ index, ...props2 });
|
|
3391
|
-
}
|
|
3392
|
-
},
|
|
3393
|
-
scrollToEnd: (options) => {
|
|
3394
|
-
const data = refState.current.props.data;
|
|
3395
|
-
const stylePaddingBottom = refState.current.props.stylePaddingBottom;
|
|
3396
|
-
const index = data.length - 1;
|
|
3397
|
-
if (index !== -1) {
|
|
3398
|
-
const paddingBottom = stylePaddingBottom || 0;
|
|
3399
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
3400
|
-
scrollToIndex(ctx, state, {
|
|
3401
|
-
index,
|
|
3402
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
3403
|
-
viewPosition: 1,
|
|
3404
|
-
...options
|
|
3405
|
-
});
|
|
3406
|
-
}
|
|
3407
|
-
},
|
|
3408
|
-
scrollToIndex: (params) => scrollToIndex(ctx, state, params),
|
|
3409
|
-
scrollToItem: ({ item, ...props2 }) => {
|
|
3410
|
-
const data = refState.current.props.data;
|
|
3411
|
-
const index = data.indexOf(item);
|
|
3412
|
-
if (index !== -1) {
|
|
3413
|
-
scrollToIndex(ctx, state, { index, ...props2 });
|
|
3414
|
-
}
|
|
3415
|
-
},
|
|
3416
|
-
scrollToOffset: (params) => scrollTo(state, params),
|
|
3417
|
-
setScrollProcessingEnabled: (enabled) => {
|
|
3418
|
-
refState.current.scrollProcessingEnabled = enabled;
|
|
3419
|
-
},
|
|
3420
|
-
setVisibleContentAnchorOffset: (value) => {
|
|
3421
|
-
const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
|
|
3422
|
-
set$(ctx, "scrollAdjustUserOffset", val);
|
|
3423
|
-
}
|
|
3424
|
-
};
|
|
3425
|
-
}, []);
|
|
3568
|
+
React3.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
|
|
3426
3569
|
{
|
|
3427
|
-
React3.useEffect(
|
|
3428
|
-
if (initialContentOffset) {
|
|
3429
|
-
scrollTo(state, { animated: false, offset: initialContentOffset, ...initialScroll || {} });
|
|
3430
|
-
}
|
|
3431
|
-
}, []);
|
|
3570
|
+
React3.useEffect(doInitialScroll, []);
|
|
3432
3571
|
}
|
|
3433
3572
|
const fns = React3.useMemo(
|
|
3434
3573
|
() => ({
|
|
@@ -3457,7 +3596,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
3457
3596
|
onMomentumScrollEnd: (event) => {
|
|
3458
3597
|
{
|
|
3459
3598
|
requestAnimationFrame(() => {
|
|
3460
|
-
finishScrollTo(refState.current);
|
|
3599
|
+
finishScrollTo(ctx, refState.current);
|
|
3461
3600
|
});
|
|
3462
3601
|
}
|
|
3463
3602
|
if (onMomentumScrollEnd) {
|