@legendapp/list 3.3.10 → 3.4.0
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 +17 -0
- package/animated.d.ts +6 -0
- package/keyboard.d.ts +1 -1
- package/keyboard.js +2 -4
- package/keyboard.mjs +2 -4
- package/package.json +1 -1
- package/react-native.d.ts +6 -0
- package/react-native.js +715 -536
- package/react-native.mjs +715 -536
- package/react-native.web.d.ts +8 -0
- package/react-native.web.js +547 -342
- package/react-native.web.mjs +547 -342
- package/react.d.ts +8 -0
- package/react.js +547 -342
- package/react.mjs +547 -342
- package/reanimated.d.ts +6 -0
- package/section-list.d.ts +6 -0
package/react-native.mjs
CHANGED
|
@@ -437,6 +437,14 @@ var EDGE_POSITION_EPSILON = 1;
|
|
|
437
437
|
var ENABLE_DEVMODE = IS_DEV && false;
|
|
438
438
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
439
439
|
|
|
440
|
+
// src/core/endOfContentTarget.ts
|
|
441
|
+
function getEndAlignedViewOffset(stylePaddingEnd, footerSize = 0) {
|
|
442
|
+
return -stylePaddingEnd - footerSize;
|
|
443
|
+
}
|
|
444
|
+
function isEndOfContentTarget(target, dataLength) {
|
|
445
|
+
return !!target && dataLength > 0 && target.viewPosition === 1 && !!target.preserveForBottomPadding && target.index !== void 0 && target.index >= dataLength - 1;
|
|
446
|
+
}
|
|
447
|
+
|
|
440
448
|
// src/core/cancelImperativeScroll.ts
|
|
441
449
|
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
442
450
|
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
@@ -621,26 +629,25 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
|
|
|
621
629
|
scrollPosition: context.scrollPosition
|
|
622
630
|
});
|
|
623
631
|
};
|
|
632
|
+
let reached = !!wasReached;
|
|
624
633
|
if (!wasReached) {
|
|
625
|
-
if (
|
|
626
|
-
return false;
|
|
627
|
-
}
|
|
628
|
-
onReached(distance);
|
|
629
|
-
updateSnapshot();
|
|
630
|
-
return true;
|
|
631
|
-
}
|
|
632
|
-
const reset = isOutsideThresholdHysteresis(distance, atThreshold, threshold);
|
|
633
|
-
if (reset) {
|
|
634
|
-
setSnapshot(void 0);
|
|
635
|
-
return false;
|
|
636
|
-
}
|
|
637
|
-
if (within) {
|
|
638
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
639
|
-
if (changed) {
|
|
634
|
+
if (within && onReached(distance)) {
|
|
640
635
|
updateSnapshot();
|
|
636
|
+
reached = true;
|
|
637
|
+
}
|
|
638
|
+
} else {
|
|
639
|
+
const reset = isOutsideThresholdHysteresis(distance, atThreshold, threshold);
|
|
640
|
+
if (reset) {
|
|
641
|
+
setSnapshot(void 0);
|
|
642
|
+
reached = false;
|
|
643
|
+
} else if (within) {
|
|
644
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
645
|
+
if (changed) {
|
|
646
|
+
updateSnapshot();
|
|
647
|
+
}
|
|
641
648
|
}
|
|
642
649
|
}
|
|
643
|
-
return
|
|
650
|
+
return reached;
|
|
644
651
|
};
|
|
645
652
|
|
|
646
653
|
// src/utils/edgeReachedGate.ts
|
|
@@ -687,7 +694,6 @@ function beginReachedEdgeUserScroll(ctx, scrollDelta) {
|
|
|
687
694
|
return void 0;
|
|
688
695
|
}
|
|
689
696
|
const allowedEdge = scrollDelta < 0 ? "start" : "end";
|
|
690
|
-
state.edgeReachedGate = "closed";
|
|
691
697
|
resetEdgeLatch(ctx, allowedEdge);
|
|
692
698
|
return allowedEdge;
|
|
693
699
|
}
|
|
@@ -728,7 +734,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
728
734
|
set$(
|
|
729
735
|
ctx,
|
|
730
736
|
"isWithinMaintainScrollAtEndThreshold",
|
|
731
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd
|
|
737
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || !!maintainingScrollAtEnd
|
|
732
738
|
);
|
|
733
739
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
734
740
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -744,11 +750,13 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
744
750
|
scrollPosition: scroll
|
|
745
751
|
},
|
|
746
752
|
(distance) => {
|
|
747
|
-
|
|
748
|
-
if (canDispatchReachedEdge(ctx, "end", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
753
|
+
let dispatched = false;
|
|
754
|
+
if (state.props.onEndReached && canDispatchReachedEdge(ctx, "end", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
749
755
|
markReachedEdge(ctx);
|
|
750
|
-
|
|
756
|
+
state.props.onEndReached({ distanceFromEnd: distance });
|
|
757
|
+
dispatched = true;
|
|
751
758
|
}
|
|
759
|
+
return dispatched;
|
|
752
760
|
},
|
|
753
761
|
(snapshot) => {
|
|
754
762
|
state.endReachedSnapshot = snapshot;
|
|
@@ -781,7 +789,7 @@ function checkAtTop(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
781
789
|
}
|
|
782
790
|
set$(ctx, "isAtStart", scroll <= EDGE_POSITION_EPSILON);
|
|
783
791
|
set$(ctx, "isNearStart", scroll <= threshold);
|
|
784
|
-
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || !!state.scrollingTo;
|
|
792
|
+
const shouldSkipThresholdChecks = !state.queuedInitialLayout || hasActiveInitialScroll(state) || !!state.scrollingTo;
|
|
785
793
|
if (!shouldSkipThresholdChecks) {
|
|
786
794
|
state.isStartReached = checkThreshold(
|
|
787
795
|
scroll,
|
|
@@ -795,11 +803,13 @@ function checkAtTop(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
795
803
|
scrollPosition: scroll
|
|
796
804
|
},
|
|
797
805
|
(distance) => {
|
|
798
|
-
|
|
799
|
-
if (canDispatchReachedEdge(ctx, "start", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
806
|
+
let dispatched = false;
|
|
807
|
+
if (state.props.onStartReached && canDispatchReachedEdge(ctx, "start", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
800
808
|
markReachedEdge(ctx);
|
|
801
|
-
|
|
809
|
+
state.props.onStartReached({ distanceFromStart: distance });
|
|
810
|
+
dispatched = true;
|
|
802
811
|
}
|
|
812
|
+
return dispatched;
|
|
803
813
|
},
|
|
804
814
|
(snapshot) => {
|
|
805
815
|
state.startReachedSnapshot = snapshot;
|
|
@@ -918,6 +928,11 @@ function resetInitialRenderState(ctx, {
|
|
|
918
928
|
if (resetLayout) {
|
|
919
929
|
state.didContainersLayout = false;
|
|
920
930
|
state.queuedInitialLayout = false;
|
|
931
|
+
state.edgeReachedGate = void 0;
|
|
932
|
+
state.isStartReached = null;
|
|
933
|
+
state.isEndReached = null;
|
|
934
|
+
state.startReachedSnapshot = void 0;
|
|
935
|
+
state.endReachedSnapshot = void 0;
|
|
921
936
|
}
|
|
922
937
|
if (resetInitialScroll) {
|
|
923
938
|
state.didFinishInitialScroll = false;
|
|
@@ -932,7 +947,7 @@ function setInitialRenderState(ctx, {
|
|
|
932
947
|
const { state } = ctx;
|
|
933
948
|
const {
|
|
934
949
|
loadStartTime,
|
|
935
|
-
props: { onLoad }
|
|
950
|
+
props: { onLoad, onReady }
|
|
936
951
|
} = state;
|
|
937
952
|
if (didLayout) {
|
|
938
953
|
state.didContainersLayout = true;
|
|
@@ -953,6 +968,7 @@ function setInitialRenderState(ctx, {
|
|
|
953
968
|
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
954
969
|
}
|
|
955
970
|
}
|
|
971
|
+
onReady == null ? void 0 : onReady();
|
|
956
972
|
}
|
|
957
973
|
}
|
|
958
974
|
|
|
@@ -993,6 +1009,7 @@ function supersedeInitialScroll(ctx) {
|
|
|
993
1009
|
function finishInitialScroll(ctx, options) {
|
|
994
1010
|
var _a3, _b, _c;
|
|
995
1011
|
const state = ctx.state;
|
|
1012
|
+
const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
|
|
996
1013
|
if ((options == null ? void 0 : options.resolvedOffset) !== void 0) {
|
|
997
1014
|
syncInitialScrollOffset(state, options.resolvedOffset);
|
|
998
1015
|
} else if ((options == null ? void 0 : options.syncObservedOffset) && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset") {
|
|
@@ -1002,9 +1019,13 @@ function finishInitialScroll(ctx, options) {
|
|
|
1002
1019
|
}
|
|
1003
1020
|
}
|
|
1004
1021
|
const complete = () => {
|
|
1005
|
-
var _a4, _b2, _c2, _d, _e;
|
|
1006
|
-
|
|
1007
|
-
|
|
1022
|
+
var _a4, _b2, _c2, _d, _e, _f;
|
|
1023
|
+
if (freshDataTransitionEpoch !== state.freshDataTransitionEpoch) {
|
|
1024
|
+
(_a4 = options == null ? void 0 : options.onFinished) == null ? void 0 : _a4.call(options);
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
const shouldReleaseDeferredPublicOnScroll = Platform.OS === "web" && ((_b2 = state.initialScrollSession) == null ? void 0 : _b2.kind) === "bootstrap";
|
|
1028
|
+
const finalScrollOffset = (_e = (_d = (_c2 = options == null ? void 0 : options.resolvedOffset) != null ? _c2 : state.scrollPending) != null ? _d : state.scroll) != null ? _e : 0;
|
|
1008
1029
|
initialScrollWatchdog.clear(state);
|
|
1009
1030
|
if ((options == null ? void 0 : options.preserveTarget) && state.initialScroll) {
|
|
1010
1031
|
state.clearPreservedInitialScrollOnNextFinish = void 0;
|
|
@@ -1033,7 +1054,7 @@ function finishInitialScroll(ctx, options) {
|
|
|
1033
1054
|
if (shouldReleaseDeferredPublicOnScroll) {
|
|
1034
1055
|
releaseDeferredPublicOnScroll(ctx, finalScrollOffset);
|
|
1035
1056
|
}
|
|
1036
|
-
(
|
|
1057
|
+
(_f = options == null ? void 0 : options.onFinished) == null ? void 0 : _f.call(options);
|
|
1037
1058
|
};
|
|
1038
1059
|
if (options == null ? void 0 : options.waitForCompletionFrame) {
|
|
1039
1060
|
requestAnimationFrame(complete);
|
|
@@ -1293,10 +1314,6 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
|
1293
1314
|
const itemSize = Math.max(0, measuredItemSize - (isOutOfBounds ? 0 : ctx.scrollAxisGap));
|
|
1294
1315
|
const trailingInset = getContentInsetEnd(ctx);
|
|
1295
1316
|
offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
|
|
1296
|
-
if (!isOutOfBounds && index === state.props.data.length - 1) {
|
|
1297
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
1298
|
-
offset += footerSize;
|
|
1299
|
-
}
|
|
1300
1317
|
}
|
|
1301
1318
|
return offset;
|
|
1302
1319
|
}
|
|
@@ -1317,246 +1334,21 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
|
1317
1334
|
return clampedOffset;
|
|
1318
1335
|
}
|
|
1319
1336
|
|
|
1320
|
-
// src/core/finishScrollTo.ts
|
|
1321
|
-
function finishScrollTo(ctx) {
|
|
1322
|
-
var _a3, _b;
|
|
1323
|
-
const state = ctx.state;
|
|
1324
|
-
if (state == null ? void 0 : state.scrollingTo) {
|
|
1325
|
-
cancelScrollCompletionChecks(state);
|
|
1326
|
-
const resolvePendingScroll = state.pendingScrollResolve;
|
|
1327
|
-
state.pendingScrollResolve = void 0;
|
|
1328
|
-
const scrollingTo = state.scrollingTo;
|
|
1329
|
-
state.scrollHistory.length = 0;
|
|
1330
|
-
state.scrollingTo = void 0;
|
|
1331
|
-
state.scrollTargetPinnedRange = void 0;
|
|
1332
|
-
if (state.pendingTotalSize !== void 0) {
|
|
1333
|
-
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1334
|
-
}
|
|
1335
|
-
if (PlatformAdjustBreaksScroll) {
|
|
1336
|
-
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1337
|
-
}
|
|
1338
|
-
if (scrollingTo.isInitialScroll || state.initialScroll) {
|
|
1339
|
-
const isOffsetSession = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset";
|
|
1340
|
-
const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_b = state.initialScroll) == null ? void 0 : _b.viewPosition) === 1;
|
|
1341
|
-
finishInitialScroll(ctx, {
|
|
1342
|
-
onFinished: () => {
|
|
1343
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1344
|
-
},
|
|
1345
|
-
preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
|
|
1346
|
-
recalculateItems: true,
|
|
1347
|
-
schedulePreservedTargetClear: shouldPreserveResizeTarget,
|
|
1348
|
-
syncObservedOffset: isOffsetSession,
|
|
1349
|
-
waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
|
|
1350
|
-
});
|
|
1351
|
-
return;
|
|
1352
|
-
}
|
|
1353
|
-
recalculateSettledScroll(ctx);
|
|
1354
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
// src/core/checkFinishedScroll.ts
|
|
1359
|
-
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
1360
|
-
var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
|
|
1361
|
-
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
1362
|
-
var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
|
|
1363
|
-
var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
|
|
1364
|
-
function checkFinishedScroll(ctx, options) {
|
|
1365
|
-
const scrollingTo = ctx.state.scrollingTo;
|
|
1366
|
-
if (options == null ? void 0 : options.onlyIfAligned) {
|
|
1367
|
-
if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
|
|
1368
|
-
return;
|
|
1369
|
-
}
|
|
1370
|
-
if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
|
|
1371
|
-
return;
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
|
|
1375
|
-
}
|
|
1376
|
-
function hasScrollCompletionOwnership(state, options) {
|
|
1377
|
-
const { clampedTargetOffset, scrollingTo } = options;
|
|
1378
|
-
return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
|
|
1379
|
-
}
|
|
1380
|
-
function isSilentInitialDispatch(state, scrollingTo) {
|
|
1381
|
-
return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
|
|
1382
|
-
}
|
|
1383
|
-
function getInitialScrollWatchdogTargetOffset(state) {
|
|
1384
|
-
var _a3;
|
|
1385
|
-
return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
|
|
1386
|
-
}
|
|
1387
|
-
function isNativeInitialNonZeroTarget(state) {
|
|
1388
|
-
const targetOffset = getInitialScrollWatchdogTargetOffset(state);
|
|
1389
|
-
return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
|
|
1390
|
-
}
|
|
1391
|
-
function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
|
|
1392
|
-
var _a3, _b;
|
|
1393
|
-
if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
|
|
1394
|
-
return false;
|
|
1395
|
-
}
|
|
1396
|
-
if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
|
|
1397
|
-
return false;
|
|
1398
|
-
}
|
|
1399
|
-
const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
|
|
1400
|
-
if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
|
|
1401
|
-
return false;
|
|
1402
|
-
}
|
|
1403
|
-
if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
|
|
1404
|
-
return false;
|
|
1405
|
-
}
|
|
1406
|
-
return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
|
|
1407
|
-
}
|
|
1408
|
-
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
1409
|
-
var _a3;
|
|
1410
|
-
const { state } = ctx;
|
|
1411
|
-
return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
|
|
1412
|
-
}
|
|
1413
|
-
function isEndAlignedLastItemTarget(ctx, scrollingTo) {
|
|
1414
|
-
return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
|
|
1415
|
-
}
|
|
1416
|
-
function getCurrentTargetOffset(ctx, scrollingTo) {
|
|
1417
|
-
var _a3;
|
|
1418
|
-
const index = scrollingTo.index;
|
|
1419
|
-
const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
|
|
1420
|
-
const requestedTargetOffset = shouldRecomputeEndTarget && index !== void 0 ? calculateOffsetWithOffsetPosition(ctx, calculateOffsetForIndex(ctx, index), scrollingTo) : (_a3 = scrollingTo.targetOffset) != null ? _a3 : clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0), scrollingTo);
|
|
1421
|
-
return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
|
|
1422
|
-
}
|
|
1423
|
-
function getResolvedScrollCompletionState(ctx, scrollingTo) {
|
|
1424
|
-
const { state } = ctx;
|
|
1425
|
-
const scroll = state.scrollPending;
|
|
1426
|
-
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
1427
|
-
const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
|
|
1428
|
-
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
1429
|
-
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
1430
|
-
const adjustedTargetOffset = clampedTargetOffset + adjust;
|
|
1431
|
-
const diff2 = Math.abs(scroll - adjustedTargetOffset);
|
|
1432
|
-
const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
|
|
1433
|
-
return {
|
|
1434
|
-
clampedTargetOffset,
|
|
1435
|
-
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
|
|
1436
|
-
};
|
|
1437
|
-
}
|
|
1438
|
-
function checkFinishedScrollFrame(ctx) {
|
|
1439
|
-
const scrollingTo = ctx.state.scrollingTo;
|
|
1440
|
-
if (!scrollingTo) {
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
const { state } = ctx;
|
|
1444
|
-
const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
|
|
1445
|
-
if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
|
|
1446
|
-
clampedTargetOffset: completionState.clampedTargetOffset,
|
|
1447
|
-
scrollingTo
|
|
1448
|
-
})) {
|
|
1449
|
-
finishScrollTo(ctx);
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
function scrollToFallbackOffset(ctx, offset) {
|
|
1453
|
-
var _a3;
|
|
1454
|
-
(_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
1455
|
-
animated: false,
|
|
1456
|
-
x: ctx.state.props.horizontal ? offset : 0,
|
|
1457
|
-
y: ctx.state.props.horizontal ? 0 : offset
|
|
1458
|
-
});
|
|
1459
|
-
}
|
|
1460
|
-
function checkFinishedScrollFallback(ctx) {
|
|
1461
|
-
const state = ctx.state;
|
|
1462
|
-
if (state.scheduledWork.has("checkFinishedScrollFallback")) {
|
|
1463
|
-
return;
|
|
1464
|
-
}
|
|
1465
|
-
const scrollingTo = state.scrollingTo;
|
|
1466
|
-
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
1467
|
-
const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
|
|
1468
|
-
const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
|
|
1469
|
-
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
|
|
1470
|
-
const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
|
|
1471
|
-
let numChecks = 0;
|
|
1472
|
-
const scheduleFallbackCheck = (delay) => {
|
|
1473
|
-
state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
|
|
1474
|
-
};
|
|
1475
|
-
const checkHasScrolled = () => {
|
|
1476
|
-
var _a3, _b, _c, _d;
|
|
1477
|
-
const isStillScrollingTo = state.scrollingTo;
|
|
1478
|
-
if (isStillScrollingTo) {
|
|
1479
|
-
numChecks++;
|
|
1480
|
-
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
1481
|
-
const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
1482
|
-
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
1483
|
-
const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
|
|
1484
|
-
state,
|
|
1485
|
-
isStillScrollingTo
|
|
1486
|
-
);
|
|
1487
|
-
const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
|
|
1488
|
-
const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
|
|
1489
|
-
const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
|
|
1490
|
-
const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
|
|
1491
|
-
const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
1492
|
-
const shouldRetryUnalignedEndScroll = Platform.OS === "ios" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
1493
|
-
if (shouldRetrySilentInitialNativeScroll) {
|
|
1494
|
-
const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
|
|
1495
|
-
const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
|
|
1496
|
-
initialScrollCompletion.markSilentInitialScrollRetry(state);
|
|
1497
|
-
scrollToFallbackOffset(ctx, jiggleOffset);
|
|
1498
|
-
state.scheduledWork.frame(
|
|
1499
|
-
() => scrollToFallbackOffset(ctx, targetOffset),
|
|
1500
|
-
"checkFinishedScrollRetryFrame"
|
|
1501
|
-
);
|
|
1502
|
-
scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
|
|
1503
|
-
} else if (shouldRetryUnalignedEndScroll) {
|
|
1504
|
-
scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
|
|
1505
|
-
scheduleFallbackCheck(100);
|
|
1506
|
-
} else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
|
|
1507
|
-
finishScrollTo(ctx);
|
|
1508
|
-
} else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
|
|
1509
|
-
const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
|
|
1510
|
-
scrollToFallbackOffset(ctx, targetOffset);
|
|
1511
|
-
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
1512
|
-
} else {
|
|
1513
|
-
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
};
|
|
1517
|
-
scheduleFallbackCheck(initialDelay);
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
// src/core/doScrollTo.native.ts
|
|
1521
|
-
function doScrollTo(ctx, params) {
|
|
1522
|
-
const state = ctx.state;
|
|
1523
|
-
const { animated, horizontal, isInitialScroll, offset } = params;
|
|
1524
|
-
const isAnimated = !!animated;
|
|
1525
|
-
const { refScroller } = state;
|
|
1526
|
-
const scroller = refScroller.current;
|
|
1527
|
-
if (!scroller) {
|
|
1528
|
-
return;
|
|
1529
|
-
}
|
|
1530
|
-
const isHorizontal = !!horizontal;
|
|
1531
|
-
const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
|
|
1532
|
-
const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
|
|
1533
|
-
scroller.scrollTo({
|
|
1534
|
-
animated: isAnimated,
|
|
1535
|
-
x: isHorizontal ? nativeOffset : 0,
|
|
1536
|
-
y: isHorizontal ? 0 : offset
|
|
1537
|
-
});
|
|
1538
|
-
if (isInitialScroll) {
|
|
1539
|
-
initialScrollCompletion.markInitialScrollNativeDispatch(state);
|
|
1540
|
-
}
|
|
1541
|
-
if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
|
|
1542
|
-
checkFinishedScroll(ctx);
|
|
1543
|
-
}
|
|
1544
|
-
if (!isAnimated) {
|
|
1545
|
-
state.scroll = offset;
|
|
1546
|
-
checkFinishedScrollFallback(ctx);
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
1337
|
// src/core/scrollRequestTracker.ts
|
|
1551
1338
|
function getScrollRequestTracker(ctx) {
|
|
1552
1339
|
if (!ctx.scrollRequestTracker) {
|
|
1553
1340
|
let currentToken = 0;
|
|
1554
|
-
|
|
1341
|
+
let waitingToken;
|
|
1342
|
+
const start = (resolve, isInternal = false) => {
|
|
1555
1343
|
const state = ctx.state;
|
|
1344
|
+
if (!isInternal && (state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd)) {
|
|
1345
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1346
|
+
}
|
|
1556
1347
|
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1557
1348
|
const token = ++currentToken;
|
|
1558
1349
|
settlePendingImperativeScroll(state);
|
|
1559
1350
|
state.pendingScrollResolve = resolve;
|
|
1351
|
+
waitingToken = token;
|
|
1560
1352
|
return token;
|
|
1561
1353
|
};
|
|
1562
1354
|
const runNow = (token, resolve, run) => {
|
|
@@ -1564,6 +1356,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1564
1356
|
if (token !== currentToken) {
|
|
1565
1357
|
return;
|
|
1566
1358
|
}
|
|
1359
|
+
waitingToken = void 0;
|
|
1567
1360
|
const didStartScroll = run();
|
|
1568
1361
|
if (!didStartScroll || !state.scrollingTo) {
|
|
1569
1362
|
if (state.pendingScrollResolve === resolve) {
|
|
@@ -1574,6 +1367,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1574
1367
|
};
|
|
1575
1368
|
ctx.scrollRequestTracker = {
|
|
1576
1369
|
isCurrent: (token) => token === currentToken,
|
|
1370
|
+
isWaitingToRun: () => waitingToken === currentToken && !!ctx.state.pendingScrollResolve,
|
|
1577
1371
|
runNow,
|
|
1578
1372
|
runNowIfIdle: (run) => {
|
|
1579
1373
|
const state = ctx.state;
|
|
@@ -1581,7 +1375,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1581
1375
|
return Promise.resolve();
|
|
1582
1376
|
}
|
|
1583
1377
|
return new Promise((resolve) => {
|
|
1584
|
-
const token = start(resolve);
|
|
1378
|
+
const token = start(resolve, true);
|
|
1585
1379
|
runNow(token, resolve, run);
|
|
1586
1380
|
});
|
|
1587
1381
|
},
|
|
@@ -1645,87 +1439,6 @@ function requestAdjust(ctx, positionDiff, source) {
|
|
|
1645
1439
|
}
|
|
1646
1440
|
}
|
|
1647
1441
|
|
|
1648
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
1649
|
-
function finishMaintainScrollAtEnd(ctx) {
|
|
1650
|
-
var _a3;
|
|
1651
|
-
const { state } = ctx;
|
|
1652
|
-
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1653
|
-
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1654
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1655
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1656
|
-
if (currentPadding !== nextPadding) {
|
|
1657
|
-
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1658
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1659
|
-
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1660
|
-
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1661
|
-
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
function doMaintainScrollAtEnd(ctx) {
|
|
1665
|
-
const state = ctx.state;
|
|
1666
|
-
const {
|
|
1667
|
-
didContainersLayout,
|
|
1668
|
-
didFinishInitialScroll,
|
|
1669
|
-
pendingNativeMVCPAdjust,
|
|
1670
|
-
props: { maintainScrollAtEnd }
|
|
1671
|
-
} = state;
|
|
1672
|
-
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1673
|
-
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1674
|
-
const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1675
|
-
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1676
|
-
state.pendingMaintainScrollAtEnd = true;
|
|
1677
|
-
return false;
|
|
1678
|
-
}
|
|
1679
|
-
if (pendingNativeMVCPAdjust) {
|
|
1680
|
-
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1681
|
-
return false;
|
|
1682
|
-
}
|
|
1683
|
-
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1684
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1685
|
-
const contentSize = getContentSize(ctx);
|
|
1686
|
-
if (contentSize < state.scrollLength) {
|
|
1687
|
-
state.scroll = 0;
|
|
1688
|
-
}
|
|
1689
|
-
if (!state.maintainingScrollAtEnd) {
|
|
1690
|
-
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1691
|
-
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1692
|
-
const scrollAtRequest = state.scroll;
|
|
1693
|
-
state.maintainingScrollAtEnd = pendingState;
|
|
1694
|
-
requestAnimationFrame(() => {
|
|
1695
|
-
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1696
|
-
return;
|
|
1697
|
-
}
|
|
1698
|
-
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1699
|
-
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1700
|
-
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1701
|
-
state.maintainingScrollAtEnd = activeState;
|
|
1702
|
-
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1703
|
-
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1704
|
-
);
|
|
1705
|
-
void scrollPromise.then(() => {
|
|
1706
|
-
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1707
|
-
return;
|
|
1708
|
-
}
|
|
1709
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1710
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1711
|
-
doMaintainScrollAtEnd(ctx);
|
|
1712
|
-
} else {
|
|
1713
|
-
finishMaintainScrollAtEnd(ctx);
|
|
1714
|
-
}
|
|
1715
|
-
});
|
|
1716
|
-
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1717
|
-
finishMaintainScrollAtEnd(ctx);
|
|
1718
|
-
}
|
|
1719
|
-
});
|
|
1720
|
-
} else {
|
|
1721
|
-
state.pendingMaintainScrollAtEnd = true;
|
|
1722
|
-
}
|
|
1723
|
-
return true;
|
|
1724
|
-
}
|
|
1725
|
-
finishMaintainScrollAtEnd(ctx);
|
|
1726
|
-
return false;
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
1442
|
// src/core/mvcp.ts
|
|
1730
1443
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1731
1444
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -2043,125 +1756,489 @@ var getScrollVelocity = (state) => {
|
|
|
2043
1756
|
if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2044
1757
|
return 0;
|
|
2045
1758
|
}
|
|
2046
|
-
let direction = 0;
|
|
2047
|
-
let weightedVelocity = 0;
|
|
2048
|
-
let totalWeight = 0;
|
|
2049
|
-
for (let i = newestIndex; i > 0; i--) {
|
|
2050
|
-
const current = scrollHistory[i];
|
|
2051
|
-
const previous = scrollHistory[i - 1];
|
|
2052
|
-
const scrollDiff = current.scroll - previous.scroll;
|
|
2053
|
-
const timeDiff = current.time - previous.time;
|
|
2054
|
-
const deltaSign = Math.sign(scrollDiff);
|
|
2055
|
-
if (deltaSign !== 0) {
|
|
2056
|
-
if (direction === 0) {
|
|
2057
|
-
direction = deltaSign;
|
|
2058
|
-
} else if (deltaSign !== direction) {
|
|
2059
|
-
break;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2063
|
-
break;
|
|
2064
|
-
}
|
|
2065
|
-
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
2066
|
-
continue;
|
|
2067
|
-
}
|
|
2068
|
-
const age = newest.time - current.time;
|
|
2069
|
-
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
2070
|
-
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
2071
|
-
totalWeight += weight;
|
|
1759
|
+
let direction = 0;
|
|
1760
|
+
let weightedVelocity = 0;
|
|
1761
|
+
let totalWeight = 0;
|
|
1762
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
1763
|
+
const current = scrollHistory[i];
|
|
1764
|
+
const previous = scrollHistory[i - 1];
|
|
1765
|
+
const scrollDiff = current.scroll - previous.scroll;
|
|
1766
|
+
const timeDiff = current.time - previous.time;
|
|
1767
|
+
const deltaSign = Math.sign(scrollDiff);
|
|
1768
|
+
if (deltaSign !== 0) {
|
|
1769
|
+
if (direction === 0) {
|
|
1770
|
+
direction = deltaSign;
|
|
1771
|
+
} else if (deltaSign !== direction) {
|
|
1772
|
+
break;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
1776
|
+
break;
|
|
1777
|
+
}
|
|
1778
|
+
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
1779
|
+
continue;
|
|
1780
|
+
}
|
|
1781
|
+
const age = newest.time - current.time;
|
|
1782
|
+
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
1783
|
+
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
1784
|
+
totalWeight += weight;
|
|
1785
|
+
}
|
|
1786
|
+
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
1787
|
+
};
|
|
1788
|
+
|
|
1789
|
+
// src/utils/isInMVCPActiveMode.native.ts
|
|
1790
|
+
function isInMVCPActiveMode(state) {
|
|
1791
|
+
return state.dataChangeNeedsScrollUpdate;
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
// src/core/updateScroll.ts
|
|
1795
|
+
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
1796
|
+
var _a3;
|
|
1797
|
+
const state = ctx.state;
|
|
1798
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
1799
|
+
const prevScroll = state.scroll;
|
|
1800
|
+
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
1801
|
+
state.hasScrolled = true;
|
|
1802
|
+
}
|
|
1803
|
+
const currentTime = Date.now();
|
|
1804
|
+
state.lastBatchingAction = currentTime;
|
|
1805
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
1806
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
1807
|
+
if (adjustChanged) {
|
|
1808
|
+
scrollHistory.length = 0;
|
|
1809
|
+
}
|
|
1810
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
1811
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1812
|
+
if (!adjustChanged) {
|
|
1813
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
if (scrollHistory.length > 5) {
|
|
1817
|
+
scrollHistory.shift();
|
|
1818
|
+
}
|
|
1819
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1820
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1821
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1822
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
state.scrollPrev = prevScroll;
|
|
1827
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1828
|
+
state.scroll = newScroll;
|
|
1829
|
+
state.scrollTime = currentTime;
|
|
1830
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1831
|
+
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
1832
|
+
const didCancelMaintainScrollAtEnd = Platform.OS === "web" && isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
1833
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
1834
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1835
|
+
}
|
|
1836
|
+
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
1837
|
+
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1838
|
+
const scrollLength = state.scrollLength;
|
|
1839
|
+
const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
|
|
1840
|
+
const scrollVelocity = getScrollVelocity(state);
|
|
1841
|
+
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
1842
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
1843
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1844
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1845
|
+
if (shouldUpdate) {
|
|
1846
|
+
state.scrollLastCalculate = state.scroll;
|
|
1847
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
1848
|
+
state.lastScrollDelta = scrollDelta;
|
|
1849
|
+
const runCalculateItems = () => {
|
|
1850
|
+
var _a4;
|
|
1851
|
+
const calculateItemsParams = {
|
|
1852
|
+
doMVCP: scrollingTo !== void 0,
|
|
1853
|
+
scrollVelocity
|
|
1854
|
+
};
|
|
1855
|
+
if (isLargeUserScrollJump) {
|
|
1856
|
+
calculateItemsParams.drawDistanceMode = "visible-first";
|
|
1857
|
+
}
|
|
1858
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
|
|
1859
|
+
checkThresholds(ctx, allowedEdge);
|
|
1860
|
+
};
|
|
1861
|
+
if (isLargeUserScrollJump) {
|
|
1862
|
+
state.mvcpAnchorLock = void 0;
|
|
1863
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1864
|
+
state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
|
|
1865
|
+
state.scheduledWork.cancel("mvcpRecalculate");
|
|
1866
|
+
flushSync(runCalculateItems);
|
|
1867
|
+
scheduleFullDrawDistancePrewarm(ctx);
|
|
1868
|
+
} else {
|
|
1869
|
+
runCalculateItems();
|
|
1870
|
+
}
|
|
1871
|
+
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
1872
|
+
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
1873
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1874
|
+
doMaintainScrollAtEnd(ctx);
|
|
1875
|
+
}
|
|
1876
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
1877
|
+
state.lastScrollDelta = 0;
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1882
|
+
function interruptMaintainScrollAtEnd(ctx) {
|
|
1883
|
+
var _a3;
|
|
1884
|
+
const { state } = ctx;
|
|
1885
|
+
const maintaining = state.maintainingScrollAtEnd;
|
|
1886
|
+
const cancelActiveScroll = !!(maintaining === "animated" || maintaining === "instant" || maintaining && ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isScrollToEnd));
|
|
1887
|
+
if (cancelActiveScroll) {
|
|
1888
|
+
cancelImperativeScroll(state);
|
|
1889
|
+
}
|
|
1890
|
+
if (maintaining || state.pendingMaintainScrollAtEnd) {
|
|
1891
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1892
|
+
}
|
|
1893
|
+
return cancelActiveScroll;
|
|
1894
|
+
}
|
|
1895
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1896
|
+
var _a3;
|
|
1897
|
+
const { state } = ctx;
|
|
1898
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1899
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1900
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1901
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1902
|
+
if (currentPadding !== nextPadding) {
|
|
1903
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1904
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1905
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1906
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1907
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
function doMaintainScrollAtEnd(ctx, options) {
|
|
1911
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
1912
|
+
const state = ctx.state;
|
|
1913
|
+
let didMaintain = false;
|
|
1914
|
+
if (state.isDragging) {
|
|
1915
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1916
|
+
} else {
|
|
1917
|
+
const {
|
|
1918
|
+
didContainersLayout,
|
|
1919
|
+
didFinishInitialScroll,
|
|
1920
|
+
pendingNativeMVCPAdjust,
|
|
1921
|
+
props: { maintainScrollAtEnd }
|
|
1922
|
+
} = state;
|
|
1923
|
+
const immediate = (options == null ? void 0 : options.immediate) && Platform.OS === "web" && !(maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.animated);
|
|
1924
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1925
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1926
|
+
const shouldMaintainScrollAtEnd = !!(!((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) && (!state.scrollingTo || state.scrollingTo.isScrollToEnd) && (isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain || ((_b = state.scrollingTo) == null ? void 0 : _b.isScrollToEnd)) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1927
|
+
if (shouldMaintainScrollAtEnd && !state.scrollingTo) {
|
|
1928
|
+
const scroller = state.refScroller.current;
|
|
1929
|
+
const nativeMax = (_c = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _c.call(scroller);
|
|
1930
|
+
const observed = (_d = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _d.call(scroller);
|
|
1931
|
+
if (nativeMax !== void 0 && observed !== void 0 && nativeMax < state.scroll - 1 && Math.abs(observed - nativeMax) <= 1) {
|
|
1932
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1933
|
+
state.scrollPending = observed;
|
|
1934
|
+
updateScroll(ctx, observed, true, { markHasScrolled: false });
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1938
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1939
|
+
} else if (pendingNativeMVCPAdjust) {
|
|
1940
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1941
|
+
} else if (shouldMaintainScrollAtEnd && (state.scrollingTo || state.pendingScrollResolve)) {
|
|
1942
|
+
if (immediate && ((_e = state.scrollingTo) == null ? void 0 : _e.isScrollToEnd) && !state.scrollingTo.animated) {
|
|
1943
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1944
|
+
ctx.scrollToEnd({ animated: false });
|
|
1945
|
+
didMaintain = true;
|
|
1946
|
+
} else {
|
|
1947
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1948
|
+
(_f = state.maintainingScrollAtEnd) != null ? _f : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1949
|
+
}
|
|
1950
|
+
} else if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1951
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1952
|
+
const contentSize = getContentSize(ctx);
|
|
1953
|
+
if (contentSize < state.scrollLength) {
|
|
1954
|
+
state.scroll = 0;
|
|
1955
|
+
}
|
|
1956
|
+
if (!state.maintainingScrollAtEnd || immediate && state.maintainingScrollAtEnd === "pending-instant") {
|
|
1957
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1958
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1959
|
+
const scrollAtRequest = state.scroll;
|
|
1960
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1961
|
+
const run = () => {
|
|
1962
|
+
if (state.maintainingScrollAtEnd === pendingState) {
|
|
1963
|
+
if (state.isDragging) {
|
|
1964
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1965
|
+
} else {
|
|
1966
|
+
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1967
|
+
const didScrollSinceRequest = Platform.OS === "web" && state.scroll !== scrollAtRequest;
|
|
1968
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1969
|
+
if (state.scrollingTo || state.pendingScrollResolve) {
|
|
1970
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1971
|
+
} else {
|
|
1972
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1973
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1974
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1975
|
+
);
|
|
1976
|
+
void scrollPromise.then(() => {
|
|
1977
|
+
if (state.maintainingScrollAtEnd === activeState) {
|
|
1978
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1979
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1980
|
+
doMaintainScrollAtEnd(ctx);
|
|
1981
|
+
} else {
|
|
1982
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1988
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
};
|
|
1993
|
+
if (immediate) {
|
|
1994
|
+
run();
|
|
1995
|
+
} else {
|
|
1996
|
+
requestAnimationFrame(run);
|
|
1997
|
+
}
|
|
1998
|
+
} else {
|
|
1999
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
2000
|
+
}
|
|
2001
|
+
didMaintain = true;
|
|
2002
|
+
} else {
|
|
2003
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
return didMaintain;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
// src/core/finishScrollTo.ts
|
|
2010
|
+
function finishScrollTo(ctx) {
|
|
2011
|
+
var _a3, _b, _c;
|
|
2012
|
+
const state = ctx.state;
|
|
2013
|
+
if (state == null ? void 0 : state.scrollingTo) {
|
|
2014
|
+
cancelScrollCompletionChecks(state);
|
|
2015
|
+
const resolvePendingScroll = ((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) ? void 0 : state.pendingScrollResolve;
|
|
2016
|
+
if (resolvePendingScroll) {
|
|
2017
|
+
state.pendingScrollResolve = void 0;
|
|
2018
|
+
}
|
|
2019
|
+
const scrollingTo = state.scrollingTo;
|
|
2020
|
+
state.scrollHistory.length = 0;
|
|
2021
|
+
state.scrollingTo = void 0;
|
|
2022
|
+
state.scrollTargetPinnedRange = void 0;
|
|
2023
|
+
if (state.pendingTotalSize !== void 0) {
|
|
2024
|
+
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
2025
|
+
}
|
|
2026
|
+
if (PlatformAdjustBreaksScroll) {
|
|
2027
|
+
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
2028
|
+
}
|
|
2029
|
+
if (scrollingTo.isInitialScroll || state.initialScroll) {
|
|
2030
|
+
const isOffsetSession = ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) === "offset";
|
|
2031
|
+
const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_c = state.initialScroll) == null ? void 0 : _c.viewPosition) === 1;
|
|
2032
|
+
finishInitialScroll(ctx, {
|
|
2033
|
+
onFinished: () => {
|
|
2034
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
2035
|
+
},
|
|
2036
|
+
preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
|
|
2037
|
+
recalculateItems: true,
|
|
2038
|
+
schedulePreservedTargetClear: shouldPreserveResizeTarget,
|
|
2039
|
+
syncObservedOffset: isOffsetSession,
|
|
2040
|
+
waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
|
|
2041
|
+
});
|
|
2042
|
+
return;
|
|
2043
|
+
}
|
|
2044
|
+
recalculateSettledScroll(ctx);
|
|
2045
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
2046
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
2047
|
+
state.maintainingScrollAtEnd = void 0;
|
|
2048
|
+
doMaintainScrollAtEnd(ctx);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
// src/core/checkFinishedScroll.ts
|
|
2054
|
+
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
2055
|
+
var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
|
|
2056
|
+
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
2057
|
+
var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
|
|
2058
|
+
var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
|
|
2059
|
+
function checkFinishedScroll(ctx, options) {
|
|
2060
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
2061
|
+
if (options == null ? void 0 : options.onlyIfAligned) {
|
|
2062
|
+
if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
|
|
2070
|
+
}
|
|
2071
|
+
function hasScrollCompletionOwnership(state, options) {
|
|
2072
|
+
const { clampedTargetOffset, scrollingTo } = options;
|
|
2073
|
+
return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
|
|
2074
|
+
}
|
|
2075
|
+
function isSilentInitialDispatch(state, scrollingTo) {
|
|
2076
|
+
return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
|
|
2077
|
+
}
|
|
2078
|
+
function getInitialScrollWatchdogTargetOffset(state) {
|
|
2079
|
+
var _a3;
|
|
2080
|
+
return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
|
|
2081
|
+
}
|
|
2082
|
+
function isNativeInitialNonZeroTarget(state) {
|
|
2083
|
+
const targetOffset = getInitialScrollWatchdogTargetOffset(state);
|
|
2084
|
+
return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
|
|
2085
|
+
}
|
|
2086
|
+
function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
|
|
2087
|
+
var _a3, _b;
|
|
2088
|
+
if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
|
|
2089
|
+
return false;
|
|
2090
|
+
}
|
|
2091
|
+
if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
|
|
2092
|
+
return false;
|
|
2093
|
+
}
|
|
2094
|
+
const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
|
|
2095
|
+
if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
|
|
2096
|
+
return false;
|
|
2097
|
+
}
|
|
2098
|
+
if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
|
|
2099
|
+
return false;
|
|
2100
|
+
}
|
|
2101
|
+
return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
|
|
2102
|
+
}
|
|
2103
|
+
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
2104
|
+
var _a3;
|
|
2105
|
+
const { state } = ctx;
|
|
2106
|
+
return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
|
|
2107
|
+
}
|
|
2108
|
+
function isEndAlignedLastItemTarget(ctx, scrollingTo) {
|
|
2109
|
+
return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
|
|
2110
|
+
}
|
|
2111
|
+
function getCurrentTargetOffset(ctx, scrollingTo) {
|
|
2112
|
+
var _a3;
|
|
2113
|
+
const index = scrollingTo.index;
|
|
2114
|
+
const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
|
|
2115
|
+
const requestedTargetOffset = shouldRecomputeEndTarget && index !== void 0 ? calculateOffsetWithOffsetPosition(ctx, calculateOffsetForIndex(ctx, index), scrollingTo) : (_a3 = scrollingTo.targetOffset) != null ? _a3 : clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0), scrollingTo);
|
|
2116
|
+
return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
|
|
2117
|
+
}
|
|
2118
|
+
function getResolvedScrollCompletionState(ctx, scrollingTo) {
|
|
2119
|
+
const { state } = ctx;
|
|
2120
|
+
const scroll = state.scrollPending;
|
|
2121
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2122
|
+
const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
|
|
2123
|
+
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
2124
|
+
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
2125
|
+
const adjustedTargetOffset = clampedTargetOffset + adjust;
|
|
2126
|
+
const diff2 = Math.abs(scroll - adjustedTargetOffset);
|
|
2127
|
+
const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
|
|
2128
|
+
return {
|
|
2129
|
+
clampedTargetOffset,
|
|
2130
|
+
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
|
|
2131
|
+
};
|
|
2132
|
+
}
|
|
2133
|
+
function checkFinishedScrollFrame(ctx) {
|
|
2134
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
2135
|
+
if (!scrollingTo) {
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
const { state } = ctx;
|
|
2139
|
+
const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
|
|
2140
|
+
if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
|
|
2141
|
+
clampedTargetOffset: completionState.clampedTargetOffset,
|
|
2142
|
+
scrollingTo
|
|
2143
|
+
})) {
|
|
2144
|
+
finishScrollTo(ctx);
|
|
2072
2145
|
}
|
|
2073
|
-
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
2074
|
-
};
|
|
2075
|
-
|
|
2076
|
-
// src/utils/isInMVCPActiveMode.native.ts
|
|
2077
|
-
function isInMVCPActiveMode(state) {
|
|
2078
|
-
return state.dataChangeNeedsScrollUpdate;
|
|
2079
2146
|
}
|
|
2080
|
-
|
|
2081
|
-
// src/core/updateScroll.ts
|
|
2082
|
-
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
2147
|
+
function scrollToFallbackOffset(ctx, offset) {
|
|
2083
2148
|
var _a3;
|
|
2149
|
+
(_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
2150
|
+
animated: false,
|
|
2151
|
+
x: ctx.state.props.horizontal ? offset : 0,
|
|
2152
|
+
y: ctx.state.props.horizontal ? 0 : offset
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
function checkFinishedScrollFallback(ctx) {
|
|
2084
2156
|
const state = ctx.state;
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
2088
|
-
state.hasScrolled = true;
|
|
2089
|
-
}
|
|
2090
|
-
const currentTime = Date.now();
|
|
2091
|
-
state.lastBatchingAction = currentTime;
|
|
2092
|
-
const adjust = scrollAdjustHandler.getAdjust();
|
|
2093
|
-
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
2094
|
-
if (adjustChanged) {
|
|
2095
|
-
scrollHistory.length = 0;
|
|
2157
|
+
if (state.scheduledWork.has("checkFinishedScrollFallback")) {
|
|
2158
|
+
return;
|
|
2096
2159
|
}
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2160
|
+
const scrollingTo = state.scrollingTo;
|
|
2161
|
+
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
2162
|
+
const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
|
|
2163
|
+
const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
|
|
2164
|
+
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
|
|
2165
|
+
const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
|
|
2166
|
+
let numChecks = 0;
|
|
2167
|
+
const scheduleFallbackCheck = (delay) => {
|
|
2168
|
+
state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
|
|
2169
|
+
};
|
|
2170
|
+
const checkHasScrolled = () => {
|
|
2171
|
+
var _a3, _b, _c, _d;
|
|
2172
|
+
const isStillScrollingTo = state.scrollingTo;
|
|
2173
|
+
if (isStillScrollingTo) {
|
|
2174
|
+
numChecks++;
|
|
2175
|
+
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
2176
|
+
const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
2177
|
+
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
2178
|
+
const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
|
|
2179
|
+
state,
|
|
2180
|
+
isStillScrollingTo
|
|
2181
|
+
);
|
|
2182
|
+
const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
|
|
2183
|
+
const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
|
|
2184
|
+
const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
|
|
2185
|
+
const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
|
|
2186
|
+
const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2187
|
+
const shouldRetryUnalignedEndScroll = Platform.OS !== "web" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2188
|
+
if (shouldRetrySilentInitialNativeScroll) {
|
|
2189
|
+
const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
|
|
2190
|
+
const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
|
|
2191
|
+
initialScrollCompletion.markSilentInitialScrollRetry(state);
|
|
2192
|
+
scrollToFallbackOffset(ctx, jiggleOffset);
|
|
2193
|
+
state.scheduledWork.frame(
|
|
2194
|
+
() => scrollToFallbackOffset(ctx, targetOffset),
|
|
2195
|
+
"checkFinishedScrollRetryFrame"
|
|
2196
|
+
);
|
|
2197
|
+
scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
|
|
2198
|
+
} else if (shouldRetryUnalignedEndScroll) {
|
|
2199
|
+
scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
|
|
2200
|
+
scheduleFallbackCheck(100);
|
|
2201
|
+
} else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
|
|
2202
|
+
finishScrollTo(ctx);
|
|
2203
|
+
} else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
|
|
2204
|
+
const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
|
|
2205
|
+
scrollToFallbackOffset(ctx, targetOffset);
|
|
2206
|
+
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
2207
|
+
} else {
|
|
2208
|
+
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
2209
|
+
}
|
|
2101
2210
|
}
|
|
2211
|
+
};
|
|
2212
|
+
scheduleFallbackCheck(initialDelay);
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
// src/core/doScrollTo.native.ts
|
|
2216
|
+
function doScrollTo(ctx, params) {
|
|
2217
|
+
const state = ctx.state;
|
|
2218
|
+
const { animated, horizontal, isInitialScroll, offset } = params;
|
|
2219
|
+
const isAnimated = !!animated;
|
|
2220
|
+
const { refScroller } = state;
|
|
2221
|
+
const scroller = refScroller.current;
|
|
2222
|
+
if (!scroller) {
|
|
2223
|
+
return;
|
|
2102
2224
|
}
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2225
|
+
const isHorizontal = !!horizontal;
|
|
2226
|
+
const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
|
|
2227
|
+
const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
|
|
2228
|
+
scroller.scrollTo({
|
|
2229
|
+
animated: isAnimated,
|
|
2230
|
+
x: isHorizontal ? nativeOffset : 0,
|
|
2231
|
+
y: isHorizontal ? 0 : offset
|
|
2232
|
+
});
|
|
2233
|
+
if (isInitialScroll) {
|
|
2234
|
+
initialScrollCompletion.markInitialScrollNativeDispatch(state);
|
|
2112
2235
|
}
|
|
2113
|
-
state.
|
|
2114
|
-
|
|
2115
|
-
state.scroll = newScroll;
|
|
2116
|
-
state.scrollTime = currentTime;
|
|
2117
|
-
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2118
|
-
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
2119
|
-
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
2120
|
-
if (didCancelMaintainScrollAtEnd) {
|
|
2121
|
-
finishMaintainScrollAtEnd(ctx);
|
|
2236
|
+
if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
|
|
2237
|
+
checkFinishedScroll(ctx);
|
|
2122
2238
|
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
|
|
2127
|
-
const scrollVelocity = getScrollVelocity(state);
|
|
2128
|
-
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
2129
|
-
const lastCalculated = state.scrollLastCalculate;
|
|
2130
|
-
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2131
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2132
|
-
if (shouldUpdate) {
|
|
2133
|
-
state.scrollLastCalculate = state.scroll;
|
|
2134
|
-
state.ignoreScrollFromMVCPIgnored = false;
|
|
2135
|
-
state.lastScrollDelta = scrollDelta;
|
|
2136
|
-
const runCalculateItems = () => {
|
|
2137
|
-
var _a4;
|
|
2138
|
-
const calculateItemsParams = {
|
|
2139
|
-
doMVCP: scrollingTo !== void 0,
|
|
2140
|
-
scrollVelocity
|
|
2141
|
-
};
|
|
2142
|
-
if (isLargeUserScrollJump) {
|
|
2143
|
-
calculateItemsParams.drawDistanceMode = "visible-first";
|
|
2144
|
-
}
|
|
2145
|
-
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
|
|
2146
|
-
checkThresholds(ctx, allowedEdge);
|
|
2147
|
-
};
|
|
2148
|
-
if (isLargeUserScrollJump) {
|
|
2149
|
-
state.mvcpAnchorLock = void 0;
|
|
2150
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
2151
|
-
state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
|
|
2152
|
-
state.scheduledWork.cancel("mvcpRecalculate");
|
|
2153
|
-
flushSync(runCalculateItems);
|
|
2154
|
-
scheduleFullDrawDistancePrewarm(ctx);
|
|
2155
|
-
} else {
|
|
2156
|
-
runCalculateItems();
|
|
2157
|
-
}
|
|
2158
|
-
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
2159
|
-
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
2160
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
2161
|
-
doMaintainScrollAtEnd(ctx);
|
|
2162
|
-
}
|
|
2163
|
-
state.dataChangeNeedsScrollUpdate = false;
|
|
2164
|
-
state.lastScrollDelta = 0;
|
|
2239
|
+
if (!isAnimated) {
|
|
2240
|
+
state.scroll = offset;
|
|
2241
|
+
checkFinishedScrollFallback(ctx);
|
|
2165
2242
|
}
|
|
2166
2243
|
}
|
|
2167
2244
|
|
|
@@ -2315,7 +2392,9 @@ function scrollTo(ctx, params) {
|
|
|
2315
2392
|
pinScrollTargetRenderRange(ctx, targetOffset, scrollTarget.index);
|
|
2316
2393
|
}
|
|
2317
2394
|
}
|
|
2318
|
-
|
|
2395
|
+
if (!animated || isInitialScroll) {
|
|
2396
|
+
state.scrollPending = targetOffset;
|
|
2397
|
+
}
|
|
2319
2398
|
syncInitialScrollNativeWatchdog(state, { isInitialScroll, requestedOffset: offset, targetOffset });
|
|
2320
2399
|
if (!isInitialScroll && !noScrollingTo && Math.abs(state.scroll - targetOffset) > 1) {
|
|
2321
2400
|
if (animated) {
|
|
@@ -2692,13 +2771,13 @@ function rearmBootstrapInitialScroll(ctx, options) {
|
|
|
2692
2771
|
queueBootstrapInitialScrollReevaluation(ctx.state);
|
|
2693
2772
|
}
|
|
2694
2773
|
function createInitialScrollAtEndTarget(options) {
|
|
2695
|
-
const { dataLength, footerSize, preserveForFooterLayout, stylePaddingEnd } = options;
|
|
2774
|
+
const { dataLength, footerSize, index, preserveForFooterLayout, stylePaddingEnd } = options;
|
|
2696
2775
|
return {
|
|
2697
2776
|
contentOffset: void 0,
|
|
2698
|
-
index: Math.max(0, dataLength - 1),
|
|
2777
|
+
index: index != null ? index : Math.max(0, dataLength - 1),
|
|
2699
2778
|
preserveForBottomPadding: true,
|
|
2700
2779
|
preserveForFooterLayout,
|
|
2701
|
-
viewOffset:
|
|
2780
|
+
viewOffset: getEndAlignedViewOffset(stylePaddingEnd, footerSize),
|
|
2702
2781
|
viewPosition: 1
|
|
2703
2782
|
};
|
|
2704
2783
|
}
|
|
@@ -2714,13 +2793,14 @@ function isRetargetableBottomAlignedInitialScrollTarget(target) {
|
|
|
2714
2793
|
function createRetargetedBottomAlignedInitialScroll(options) {
|
|
2715
2794
|
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingEnd, target } = options;
|
|
2716
2795
|
const preserveForFooterLayout = shouldPreserveInitialScrollForFooterLayout(target);
|
|
2796
|
+
const alignsToContentEnd = initialScrollAtEnd || isEndOfContentTarget(target, dataLength);
|
|
2717
2797
|
return {
|
|
2718
2798
|
...target,
|
|
2719
2799
|
contentOffset: void 0,
|
|
2720
2800
|
index: initialScrollAtEnd ? Math.max(0, dataLength - 1) : target.index,
|
|
2721
2801
|
preserveForBottomPadding: true,
|
|
2722
2802
|
preserveForFooterLayout,
|
|
2723
|
-
viewOffset:
|
|
2803
|
+
viewOffset: getEndAlignedViewOffset(stylePaddingEnd, alignsToContentEnd ? footerSize : 0),
|
|
2724
2804
|
viewPosition: 1
|
|
2725
2805
|
};
|
|
2726
2806
|
}
|
|
@@ -2734,7 +2814,7 @@ function clearPendingInitialScrollFooterLayout(ctx, options) {
|
|
|
2734
2814
|
}
|
|
2735
2815
|
const clearedFooterTarget = createInitialScrollAtEndTarget({
|
|
2736
2816
|
dataLength,
|
|
2737
|
-
footerSize: 0,
|
|
2817
|
+
footerSize: peek$(ctx, "footerSize") || 0,
|
|
2738
2818
|
preserveForFooterLayout: void 0,
|
|
2739
2819
|
stylePaddingEnd
|
|
2740
2820
|
});
|
|
@@ -2757,13 +2837,12 @@ function getObservedBootstrapInitialScrollOffset(state) {
|
|
|
2757
2837
|
return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
|
|
2758
2838
|
}
|
|
2759
2839
|
function getPreservedEndAnchorOffsetDiff(ctx) {
|
|
2760
|
-
var _a3;
|
|
2761
2840
|
const state = ctx.state;
|
|
2762
2841
|
const initialScroll = state.initialScroll;
|
|
2763
|
-
if (!state.didFinishInitialScroll ||
|
|
2842
|
+
if (!state.didFinishInitialScroll || state.scrollingTo || state.pendingScrollResolve || state.maintainingScrollAtEnd || state.isDragging || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
|
|
2764
2843
|
return;
|
|
2765
2844
|
}
|
|
2766
|
-
const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2845
|
+
const currentOffset = Platform.OS !== "web" && typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2767
2846
|
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
2768
2847
|
}
|
|
2769
2848
|
function schedulePreservedEndAnchorCorrection(ctx) {
|
|
@@ -2791,6 +2870,9 @@ function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
|
|
|
2791
2870
|
const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
|
|
2792
2871
|
if (hasObservedNativeScrollAfterRequest) {
|
|
2793
2872
|
activeCorrection.lastRequestTime = Date.now();
|
|
2873
|
+
if (Platform.OS === "web") {
|
|
2874
|
+
state.scroll = getObservedBootstrapInitialScrollOffset(state);
|
|
2875
|
+
}
|
|
2794
2876
|
requestAdjust(ctx, offsetDiff);
|
|
2795
2877
|
}
|
|
2796
2878
|
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
@@ -2913,10 +2995,10 @@ function handleBootstrapInitialScrollDataChange(ctx, options) {
|
|
|
2913
2995
|
function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
2914
2996
|
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingEnd } = options;
|
|
2915
2997
|
const state = ctx.state;
|
|
2916
|
-
|
|
2998
|
+
const initialScroll = state.initialScroll;
|
|
2999
|
+
if (!initialScrollAtEnd && !isEndOfContentTarget(initialScroll, dataLength)) {
|
|
2917
3000
|
return;
|
|
2918
3001
|
}
|
|
2919
|
-
const initialScroll = state.initialScroll;
|
|
2920
3002
|
if (isOffsetInitialScrollSession(state) || dataLength === 0 || !initialScroll) {
|
|
2921
3003
|
return;
|
|
2922
3004
|
}
|
|
@@ -2934,6 +3016,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2934
3016
|
const updatedInitialScroll = createInitialScrollAtEndTarget({
|
|
2935
3017
|
dataLength,
|
|
2936
3018
|
footerSize,
|
|
3019
|
+
index: initialScrollAtEnd ? void 0 : initialScroll.index,
|
|
2937
3020
|
preserveForFooterLayout: shouldPreserveInitialScrollForFooterLayout(initialScroll),
|
|
2938
3021
|
stylePaddingEnd
|
|
2939
3022
|
});
|
|
@@ -3170,6 +3253,11 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3170
3253
|
const state = ctx.state;
|
|
3171
3254
|
const previousInitialScrollDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
|
|
3172
3255
|
const shouldUseLatestInitialScroll = dataLength > 0 && (!state.hasHadNonEmptyData || didStartFreshData);
|
|
3256
|
+
if (didStartFreshData) {
|
|
3257
|
+
cancelImperativeScroll(state);
|
|
3258
|
+
state.maintainingScrollAtEnd = void 0;
|
|
3259
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
3260
|
+
}
|
|
3173
3261
|
if (dataLength > 0) {
|
|
3174
3262
|
state.hasHadNonEmptyData = true;
|
|
3175
3263
|
}
|
|
@@ -3888,7 +3976,7 @@ function getExpandedContainerPoolSize(dataLength, numContainers) {
|
|
|
3888
3976
|
}
|
|
3889
3977
|
|
|
3890
3978
|
// src/utils/findAvailableContainers.ts
|
|
3891
|
-
function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffered, pendingRemoval,
|
|
3979
|
+
function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffered, pendingRemoval, protectedKeys, reverseItemOrder = false) {
|
|
3892
3980
|
var _a3;
|
|
3893
3981
|
const numNeeded = needNewContainers.length;
|
|
3894
3982
|
if (numNeeded === 0) {
|
|
@@ -3897,16 +3985,27 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
3897
3985
|
const numContainers = peek$(ctx, "numContainers");
|
|
3898
3986
|
const state = ctx.state;
|
|
3899
3987
|
const { containerItemMetadata, stickyContainerPool } = state;
|
|
3988
|
+
const { data, getItemType } = state.props;
|
|
3989
|
+
const hasItemTypes = !!getItemType;
|
|
3900
3990
|
const shouldAvoidAssignedContainerReuse = state.props.recycleItems && !!state.props.positionComponentInternal;
|
|
3901
3991
|
const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
|
|
3902
|
-
const requests =
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
order
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3992
|
+
const requests = new Array(numNeeded);
|
|
3993
|
+
const normalRequests = [];
|
|
3994
|
+
const stickyRequests = [];
|
|
3995
|
+
for (let order = 0; order < numNeeded; order++) {
|
|
3996
|
+
const itemIndex = needNewContainers[order];
|
|
3997
|
+
const itemType = getItemType == null ? void 0 : getItemType(data[itemIndex], itemIndex);
|
|
3998
|
+
const request = {
|
|
3999
|
+
isBuffered: itemIndex >= startBuffered && itemIndex <= endBuffered,
|
|
4000
|
+
isSticky: state.props.stickyHeaderIndicesSet.has(itemIndex),
|
|
4001
|
+
itemIndex,
|
|
4002
|
+
itemType: hasItemTypes ? itemType !== void 0 ? String(itemType) : "" : void 0,
|
|
4003
|
+
order,
|
|
4004
|
+
renderPriority: reverseItemOrder ? -itemIndex : itemIndex
|
|
4005
|
+
};
|
|
4006
|
+
requests[order] = request;
|
|
4007
|
+
(request.isSticky ? stickyRequests : normalRequests).push(request);
|
|
4008
|
+
}
|
|
3910
4009
|
const normalCandidates = [];
|
|
3911
4010
|
const stickyCandidates = [];
|
|
3912
4011
|
for (let containerIndex = 0; containerIndex < numContainers; containerIndex++) {
|
|
@@ -3962,7 +4061,7 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
3962
4061
|
}
|
|
3963
4062
|
};
|
|
3964
4063
|
const assignFromPool = (pendingRequests, candidates, allowCrossType) => {
|
|
3965
|
-
if (
|
|
4064
|
+
if (hasItemTypes) {
|
|
3966
4065
|
assignMatching(
|
|
3967
4066
|
pendingRequests,
|
|
3968
4067
|
candidates,
|
|
@@ -3986,6 +4085,11 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
3986
4085
|
}
|
|
3987
4086
|
assign(request, containerIndex);
|
|
3988
4087
|
}
|
|
4088
|
+
if (normalRequests.length > 1 || stickyRequests.length > 1) {
|
|
4089
|
+
const containerIndices = [];
|
|
4090
|
+
reorderPoolAssignments(normalRequests, allocations, containerIndices, hasItemTypes);
|
|
4091
|
+
reorderPoolAssignments(stickyRequests, allocations, containerIndices, hasItemTypes);
|
|
4092
|
+
}
|
|
3989
4093
|
if (pendingRemovalChanged) {
|
|
3990
4094
|
pendingRemoval.length = 0;
|
|
3991
4095
|
if (pendingRemovalSet) {
|
|
@@ -4015,12 +4119,53 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
4015
4119
|
function comparatorByDistance(a, b) {
|
|
4016
4120
|
return b.distance - a.distance;
|
|
4017
4121
|
}
|
|
4122
|
+
function comparatorByRenderPriority(a, b) {
|
|
4123
|
+
return Number(b.isBuffered) - Number(a.isBuffered) || a.renderPriority - b.renderPriority;
|
|
4124
|
+
}
|
|
4125
|
+
function comparatorByIndex(a, b) {
|
|
4126
|
+
return a - b;
|
|
4127
|
+
}
|
|
4128
|
+
function reorderPoolAssignments(requests, allocations, containerIndices, groupByType) {
|
|
4129
|
+
if (requests.length >= 2) {
|
|
4130
|
+
if (groupByType) {
|
|
4131
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4132
|
+
for (const request of requests) {
|
|
4133
|
+
const group = groups.get(request.itemType);
|
|
4134
|
+
if (group) {
|
|
4135
|
+
group.push(request);
|
|
4136
|
+
} else {
|
|
4137
|
+
groups.set(request.itemType, [request]);
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
for (const group of groups.values()) {
|
|
4141
|
+
reorderPoolAssignments(group, allocations, containerIndices, false);
|
|
4142
|
+
}
|
|
4143
|
+
} else {
|
|
4144
|
+
containerIndices.length = 0;
|
|
4145
|
+
let indicesSorted = true;
|
|
4146
|
+
for (let i = 0; i < requests.length; i++) {
|
|
4147
|
+
const containerIndex = allocations[requests[i].order].containerIndex;
|
|
4148
|
+
if (i > 0 && containerIndex < containerIndices[i - 1]) {
|
|
4149
|
+
indicesSorted = false;
|
|
4150
|
+
}
|
|
4151
|
+
containerIndices.push(containerIndex);
|
|
4152
|
+
}
|
|
4153
|
+
if (!indicesSorted) {
|
|
4154
|
+
containerIndices.sort(comparatorByIndex);
|
|
4155
|
+
}
|
|
4156
|
+
requests.sort(comparatorByRenderPriority);
|
|
4157
|
+
for (let i = 0; i < requests.length; i++) {
|
|
4158
|
+
allocations[requests[i].order].containerIndex = containerIndices[i];
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4018
4163
|
|
|
4019
4164
|
// src/utils/setDidLayout.ts
|
|
4020
4165
|
function setDidLayout(ctx) {
|
|
4021
4166
|
const state = ctx.state;
|
|
4022
4167
|
state.queuedInitialLayout = true;
|
|
4023
|
-
|
|
4168
|
+
checkThresholds(ctx);
|
|
4024
4169
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4025
4170
|
if (state.pendingMaintainScrollAtEnd) {
|
|
4026
4171
|
doMaintainScrollAtEnd(ctx);
|
|
@@ -4248,9 +4393,9 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4248
4393
|
enableScrollForNextCalculateItemsInView,
|
|
4249
4394
|
idCache,
|
|
4250
4395
|
indexByKey,
|
|
4251
|
-
|
|
4396
|
+
positionRecalculationStartIndex,
|
|
4252
4397
|
positions,
|
|
4253
|
-
props: { alwaysRenderIndicesArr, alwaysRenderIndicesSet,
|
|
4398
|
+
props: { alwaysRenderIndicesArr, alwaysRenderIndicesSet, keyExtractor, onStickyHeaderChange },
|
|
4254
4399
|
scrollForNextCalculateItemsInView,
|
|
4255
4400
|
scrollLength,
|
|
4256
4401
|
sizes,
|
|
@@ -4366,21 +4511,21 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4366
4511
|
if (dataChanged) {
|
|
4367
4512
|
resetLayoutCachesForDataChange(state);
|
|
4368
4513
|
}
|
|
4369
|
-
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_e =
|
|
4370
|
-
const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 &&
|
|
4514
|
+
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_e = positionRecalculationStartIndex != null ? positionRecalculationStartIndex : state.startBuffered) != null ? _e : 0;
|
|
4515
|
+
const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 && positionRecalculationStartIndex !== void 0;
|
|
4371
4516
|
updateItemPositions(ctx, dataChanged, {
|
|
4372
4517
|
doMVCP,
|
|
4373
4518
|
// A changed size shifts every following position. The scrolling early-exit
|
|
4374
4519
|
// would leave the untouched suffix in the old coordinate space.
|
|
4375
|
-
forceFullUpdate: !!forceFullItemPositions ||
|
|
4520
|
+
forceFullUpdate: !!forceFullItemPositions || positionRecalculationStartIndex !== void 0,
|
|
4376
4521
|
optimizeForVisibleWindow,
|
|
4377
4522
|
scrollBottomBuffered,
|
|
4378
4523
|
scrollVelocity: speed,
|
|
4379
4524
|
startIndex
|
|
4380
4525
|
});
|
|
4381
4526
|
totalSize = getContentSize(ctx);
|
|
4382
|
-
if (
|
|
4383
|
-
state.
|
|
4527
|
+
if (positionRecalculationStartIndex !== void 0) {
|
|
4528
|
+
state.positionRecalculationStartIndex = void 0;
|
|
4384
4529
|
}
|
|
4385
4530
|
let protectedContainerKeys;
|
|
4386
4531
|
if (dataChanged && doMVCP && state.props.maintainVisibleContentPosition.data && state.didContainersLayout && state.idsInView.length > 0) {
|
|
@@ -4556,18 +4701,18 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4556
4701
|
set$(ctx, "activeStickyIndex", -1);
|
|
4557
4702
|
}
|
|
4558
4703
|
if (needNewContainers.length > 0) {
|
|
4559
|
-
const getRequiredItemType = getItemType ? (i) => {
|
|
4560
|
-
const itemType = getItemType(data[i], i);
|
|
4561
|
-
return itemType !== void 0 ? String(itemType) : "";
|
|
4562
|
-
} : void 0;
|
|
4563
4704
|
const availableContainerAllocations = findAvailableContainers(
|
|
4564
4705
|
ctx,
|
|
4565
4706
|
needNewContainers,
|
|
4566
4707
|
startBuffered,
|
|
4567
4708
|
endBuffered,
|
|
4568
4709
|
pendingRemoval,
|
|
4569
|
-
|
|
4570
|
-
|
|
4710
|
+
protectedContainerKeys,
|
|
4711
|
+
// Initial end alignment has no scroll velocity yet. Keep its
|
|
4712
|
+
// target-side rows first until the initial scroll settles.
|
|
4713
|
+
// After a pause velocity can be zero on the first movement;
|
|
4714
|
+
// use its displacement without treating initial insets as motion.
|
|
4715
|
+
hasActiveInitialScroll(state) ? (initialScroll == null ? void 0 : initialScroll.viewPosition) === 1 : (speed || (state.hasScrolled ? state.scroll - state.scrollPrev : 0)) < 0
|
|
4571
4716
|
);
|
|
4572
4717
|
for (const allocation of availableContainerAllocations) {
|
|
4573
4718
|
const i = allocation.itemIndex;
|
|
@@ -4714,6 +4859,7 @@ function maybeUpdateAnchoredEndSpace(ctx) {
|
|
|
4714
4859
|
const nextAnchorIndex = anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex;
|
|
4715
4860
|
let nextAnchorKey;
|
|
4716
4861
|
let isReady = true;
|
|
4862
|
+
let canUpdateSize = true;
|
|
4717
4863
|
let nextSize = 0;
|
|
4718
4864
|
if (anchoredEndSpace) {
|
|
4719
4865
|
const { anchorIndex, anchorMaxSize, anchorOffset = 0 } = anchoredEndSpace;
|
|
@@ -4735,25 +4881,30 @@ function maybeUpdateAnchoredEndSpace(ctx) {
|
|
|
4735
4881
|
contentBelowAnchor = Math.max(0, contentBelowAnchor - ctx.scrollAxisGap);
|
|
4736
4882
|
contentBelowAnchor += (ctx.values.get("footerSize") || 0) + getStylePaddingEnd(state.props);
|
|
4737
4883
|
isReady = !hasUnknownTailSize;
|
|
4738
|
-
|
|
4884
|
+
const knownSizeBound = Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset);
|
|
4885
|
+
nextSize = hasUnknownTailSize ? Math.min(previousSize || 0, knownSizeBound) : knownSizeBound;
|
|
4739
4886
|
} else if (anchorIndex >= 0) {
|
|
4740
4887
|
isReady = false;
|
|
4888
|
+
canUpdateSize = false;
|
|
4741
4889
|
}
|
|
4742
4890
|
}
|
|
4743
4891
|
const didSizeChange = previousSize !== nextSize && (previousSize !== void 0 || anchoredEndSpace !== void 0);
|
|
4744
4892
|
const didEffectiveSizeChange = (previousSize || 0) !== nextSize;
|
|
4893
|
+
const canApplySizeChange = canUpdateSize && (isReady || previousSize !== void 0);
|
|
4745
4894
|
const didReadyAnchorChange = previousReadyAnchorIndex !== nextAnchorIndex || previousReadyAnchorKey !== nextAnchorKey;
|
|
4746
|
-
|
|
4895
|
+
const didBecomeReady = isReady && state.anchoredEndSpacePendingReady;
|
|
4896
|
+
state.anchoredEndSpacePendingReady = !isReady;
|
|
4897
|
+
if (canApplySizeChange && didSizeChange) {
|
|
4898
|
+
set$(ctx, "anchoredEndSpaceSize", nextSize);
|
|
4899
|
+
(_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
|
|
4900
|
+
}
|
|
4901
|
+
if (canApplySizeChange && didEffectiveSizeChange) {
|
|
4902
|
+
updateContentMetricsState(ctx);
|
|
4903
|
+
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
4904
|
+
}
|
|
4905
|
+
if (isReady && (didSizeChange || didReadyAnchorChange || didBecomeReady)) {
|
|
4747
4906
|
state.anchoredEndSpaceReadyAnchorIndex = nextAnchorIndex;
|
|
4748
4907
|
state.anchoredEndSpaceReadyAnchorKey = nextAnchorKey;
|
|
4749
|
-
if (didSizeChange) {
|
|
4750
|
-
set$(ctx, "anchoredEndSpaceSize", nextSize);
|
|
4751
|
-
(_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
|
|
4752
|
-
}
|
|
4753
|
-
if (didEffectiveSizeChange) {
|
|
4754
|
-
updateContentMetricsState(ctx);
|
|
4755
|
-
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
4756
|
-
}
|
|
4757
4908
|
(_b = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onReady) == null ? void 0 : _b.call(anchoredEndSpace, { anchorIndex: nextAnchorIndex, anchorKey: nextAnchorKey, size: nextSize });
|
|
4758
4909
|
}
|
|
4759
4910
|
return nextSize;
|
|
@@ -4857,6 +5008,7 @@ function updateItemSizesBatch(ctx, measurements) {
|
|
|
4857
5008
|
var _a3;
|
|
4858
5009
|
const state = ctx.state;
|
|
4859
5010
|
const result = {};
|
|
5011
|
+
const previousTotalSize = state.totalSize;
|
|
4860
5012
|
for (const measurement of measurements) {
|
|
4861
5013
|
const ownsMeasuredItem = measurement.containerId === void 0 || peek$(ctx, `containerItemKey${measurement.containerId}`) === measurement.itemKey;
|
|
4862
5014
|
if (ownsMeasuredItem) {
|
|
@@ -4867,6 +5019,9 @@ function updateItemSizesBatch(ctx, measurements) {
|
|
|
4867
5019
|
mergeItemSizeUpdateResult(result, nextResult);
|
|
4868
5020
|
}
|
|
4869
5021
|
}
|
|
5022
|
+
if (state.totalSize !== previousTotalSize) {
|
|
5023
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
5024
|
+
}
|
|
4870
5025
|
flushItemSizeUpdates(ctx, result);
|
|
4871
5026
|
}
|
|
4872
5027
|
function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
@@ -4905,12 +5060,12 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4905
5060
|
}
|
|
4906
5061
|
let needsRecalculate = !didContainersLayout;
|
|
4907
5062
|
let shouldMaintainScrollAtEnd = false;
|
|
4908
|
-
let
|
|
5063
|
+
let positionRecalculationStartIndex;
|
|
4909
5064
|
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
4910
|
-
const diff = updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem);
|
|
5065
|
+
const diff = updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem, false);
|
|
4911
5066
|
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
4912
5067
|
if (diff !== 0) {
|
|
4913
|
-
|
|
5068
|
+
positionRecalculationStartIndex = positionRecalculationStartIndex !== void 0 ? Math.min(positionRecalculationStartIndex, index) : index;
|
|
4914
5069
|
const { startBuffered, endBuffered } = state;
|
|
4915
5070
|
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
4916
5071
|
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
@@ -4927,8 +5082,8 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4927
5082
|
size
|
|
4928
5083
|
});
|
|
4929
5084
|
}
|
|
4930
|
-
if (
|
|
4931
|
-
state.
|
|
5085
|
+
if (positionRecalculationStartIndex !== void 0) {
|
|
5086
|
+
state.positionRecalculationStartIndex = state.positionRecalculationStartIndex !== void 0 ? Math.min(state.positionRecalculationStartIndex, positionRecalculationStartIndex) : positionRecalculationStartIndex;
|
|
4932
5087
|
}
|
|
4933
5088
|
updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
|
|
4934
5089
|
if (didContainersLayout || checkAllSizesKnown(state, state.startBuffered, state.endBuffered)) {
|
|
@@ -4945,7 +5100,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4945
5100
|
didMeasureUserScrollAnchorResetItem
|
|
4946
5101
|
};
|
|
4947
5102
|
}
|
|
4948
|
-
function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
5103
|
+
function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem, notifyTotalSize = true) {
|
|
4949
5104
|
var _a3, _b;
|
|
4950
5105
|
const state = ctx.state;
|
|
4951
5106
|
const {
|
|
@@ -4968,7 +5123,16 @@ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4968
5123
|
fixedItemSize,
|
|
4969
5124
|
itemType
|
|
4970
5125
|
} : void 0;
|
|
4971
|
-
const prevSize = getItemSize(
|
|
5126
|
+
const prevSize = getItemSize(
|
|
5127
|
+
ctx,
|
|
5128
|
+
itemKey,
|
|
5129
|
+
index,
|
|
5130
|
+
itemData,
|
|
5131
|
+
void 0,
|
|
5132
|
+
void 0,
|
|
5133
|
+
notifyTotalSize,
|
|
5134
|
+
resolvedItemSize
|
|
5135
|
+
);
|
|
4972
5136
|
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
4973
5137
|
const prevSizeKnown = sizesKnown.get(itemKey);
|
|
4974
5138
|
if (Platform.OS !== "web" && prevSizeKnown !== void 0 && isNativeLayoutNoise(rawSize - prevSizeKnown)) {
|
|
@@ -4993,7 +5157,7 @@ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4993
5157
|
}
|
|
4994
5158
|
}
|
|
4995
5159
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
4996
|
-
setSize(ctx, itemKey, size);
|
|
5160
|
+
setSize(ctx, itemKey, size, notifyTotalSize);
|
|
4997
5161
|
return size - prevSize;
|
|
4998
5162
|
}
|
|
4999
5163
|
return 0;
|
|
@@ -5144,10 +5308,16 @@ function useValue$(key, params) {
|
|
|
5144
5308
|
var _a3;
|
|
5145
5309
|
return (_a3 = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a3 : 0;
|
|
5146
5310
|
};
|
|
5147
|
-
const
|
|
5311
|
+
const initialValue = getNewValue();
|
|
5312
|
+
const animValue = useAnimatedValue(initialValue);
|
|
5313
|
+
const lastValue = useRef(initialValue);
|
|
5148
5314
|
useLayoutEffect(() => {
|
|
5149
5315
|
const syncCurrentValue = () => {
|
|
5150
|
-
|
|
5316
|
+
const nextValue = getNewValue();
|
|
5317
|
+
if (lastValue.current !== nextValue) {
|
|
5318
|
+
lastValue.current = nextValue;
|
|
5319
|
+
animValue.setValue(nextValue);
|
|
5320
|
+
}
|
|
5151
5321
|
};
|
|
5152
5322
|
const unsubscribe = listen$(ctx, key, syncCurrentValue);
|
|
5153
5323
|
syncCurrentValue();
|
|
@@ -6062,6 +6232,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
6062
6232
|
renderScrollComponent,
|
|
6063
6233
|
onLayoutFooter,
|
|
6064
6234
|
onInternalScrollBeginDrag,
|
|
6235
|
+
onInternalScrollEndDrag,
|
|
6065
6236
|
onInternalScrollEnd,
|
|
6066
6237
|
scrollAdjustHandler,
|
|
6067
6238
|
snapToIndices,
|
|
@@ -6133,7 +6304,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
6133
6304
|
SnapOrScroll,
|
|
6134
6305
|
{
|
|
6135
6306
|
...rest,
|
|
6136
|
-
...Platform.OS === "web" ? ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, useWindowScroll } : {} : { onScrollBeginDrag: onInternalScrollBeginDrag },
|
|
6307
|
+
...Platform.OS === "web" ? ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, useWindowScroll } : {} : { onScrollBeginDrag: onInternalScrollBeginDrag, onScrollEndDrag: onInternalScrollEndDrag },
|
|
6137
6308
|
contentContainerStyle: [
|
|
6138
6309
|
horizontal ? { height: "100%" } : {},
|
|
6139
6310
|
contentContainerStyle,
|
|
@@ -6252,7 +6423,7 @@ function checkResetContainers(ctx, dataProp, { didColumnsChange = false } = {})
|
|
|
6252
6423
|
for (const key in state.averageSizes) {
|
|
6253
6424
|
delete state.averageSizes[key];
|
|
6254
6425
|
}
|
|
6255
|
-
state.
|
|
6426
|
+
state.positionRecalculationStartIndex = 0;
|
|
6256
6427
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
6257
6428
|
}
|
|
6258
6429
|
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
@@ -6416,7 +6587,7 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
6416
6587
|
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
6417
6588
|
}
|
|
6418
6589
|
if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onLayout) {
|
|
6419
|
-
doMaintainScrollAtEnd(ctx);
|
|
6590
|
+
doMaintainScrollAtEnd(ctx, { immediate: true });
|
|
6420
6591
|
}
|
|
6421
6592
|
checkThresholds(ctx);
|
|
6422
6593
|
if (state) {
|
|
@@ -6649,14 +6820,17 @@ function scrollToEnd(ctx, options) {
|
|
|
6649
6820
|
if (index === -1) {
|
|
6650
6821
|
return false;
|
|
6651
6822
|
}
|
|
6652
|
-
const paddingBottom = state.props
|
|
6823
|
+
const paddingBottom = getStylePaddingEnd(state.props);
|
|
6653
6824
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
6654
6825
|
scrollToIndex(ctx, {
|
|
6655
6826
|
...options,
|
|
6656
6827
|
index,
|
|
6657
|
-
viewOffset:
|
|
6828
|
+
viewOffset: getEndAlignedViewOffset(paddingBottom, footerSize) + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6658
6829
|
viewPosition: 1
|
|
6659
6830
|
});
|
|
6831
|
+
if (state.scrollingTo) {
|
|
6832
|
+
state.scrollingTo.isScrollToEnd = true;
|
|
6833
|
+
}
|
|
6660
6834
|
return true;
|
|
6661
6835
|
}
|
|
6662
6836
|
|
|
@@ -6854,7 +7028,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6854
7028
|
for (const key in state.averageSizes) {
|
|
6855
7029
|
delete state.averageSizes[key];
|
|
6856
7030
|
}
|
|
6857
|
-
state.
|
|
7031
|
+
state.positionRecalculationStartIndex = 0;
|
|
6858
7032
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
6859
7033
|
state.pendingTotalSize = void 0;
|
|
6860
7034
|
state.totalSize = 0;
|
|
@@ -7248,10 +7422,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7248
7422
|
onMetricsChange,
|
|
7249
7423
|
onLayout: onLayoutProp,
|
|
7250
7424
|
onLoad,
|
|
7425
|
+
onReady,
|
|
7251
7426
|
onMomentumScrollEnd,
|
|
7252
7427
|
onRefresh,
|
|
7253
7428
|
onScroll: onScrollProp,
|
|
7254
7429
|
onScrollBeginDrag,
|
|
7430
|
+
onScrollEndDrag,
|
|
7255
7431
|
onStartReached,
|
|
7256
7432
|
onStartReachedThreshold = 0.5,
|
|
7257
7433
|
onStickyHeaderChange,
|
|
@@ -7320,17 +7496,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7320
7496
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7321
7497
|
index: Math.max(0, dataProp.length - 1),
|
|
7322
7498
|
preserveForBottomPadding: true,
|
|
7323
|
-
viewOffset:
|
|
7499
|
+
viewOffset: getEndAlignedViewOffset(stylePaddingEndState),
|
|
7324
7500
|
viewPosition: 1
|
|
7325
7501
|
} : hasInitialScrollIndex ? typeof initialScrollIndexProp === "object" ? {
|
|
7326
7502
|
index: (_b = initialScrollIndexProp.index) != null ? _b : 0,
|
|
7327
7503
|
preserveForBottomPadding: initialScrollIndexProp.viewOffset === void 0 && initialScrollIndexProp.viewPosition === 1 ? true : void 0,
|
|
7328
|
-
viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 ?
|
|
7504
|
+
viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
|
|
7329
7505
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7330
7506
|
} : {
|
|
7331
7507
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7332
7508
|
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7333
|
-
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ?
|
|
7509
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
|
|
7334
7510
|
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7335
7511
|
} : initialScrollUsesOffsetOnly ? {
|
|
7336
7512
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
@@ -7390,6 +7566,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7390
7566
|
endReachedSnapshot: void 0,
|
|
7391
7567
|
firstFullyOnScreenIndex: -1,
|
|
7392
7568
|
freshDataTransitionEpoch: 0,
|
|
7569
|
+
handledDataChangeEpoch: 0,
|
|
7570
|
+
handledFreshDataTransitionEpoch: 0,
|
|
7393
7571
|
hasHadNonEmptyData: dataProp.length > 0,
|
|
7394
7572
|
idCache: [],
|
|
7395
7573
|
idsInView: [],
|
|
@@ -7406,11 +7584,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7406
7584
|
lastLayout: void 0,
|
|
7407
7585
|
lastScrollDelta: 0,
|
|
7408
7586
|
loadStartTime: Date.now(),
|
|
7409
|
-
minIndexSizeChanged: 0,
|
|
7410
7587
|
nativeContentInset: void 0,
|
|
7411
7588
|
nativeMarginTop: 0,
|
|
7412
7589
|
pendingDataComparison: void 0,
|
|
7413
7590
|
pendingNativeMVCPAdjust: void 0,
|
|
7591
|
+
positionRecalculationStartIndex: 0,
|
|
7414
7592
|
positions: [],
|
|
7415
7593
|
props: {},
|
|
7416
7594
|
queuedCalculateItemsInView: 0,
|
|
@@ -7449,8 +7627,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7449
7627
|
refState.current = ctx.state;
|
|
7450
7628
|
}
|
|
7451
7629
|
const state = refState.current;
|
|
7452
|
-
const handledDataChangeEpochRef = useRef(state.dataChangeEpoch);
|
|
7453
|
-
const handledFreshDataTransitionEpochRef = useRef(state.freshDataTransitionEpoch);
|
|
7454
7630
|
const isFirstLocal = state.isFirst;
|
|
7455
7631
|
const previousAdaptiveRender = state.props.adaptiveRender;
|
|
7456
7632
|
const previousHideItemsUntilMeasured = state.props.hideItemsUntilMeasured;
|
|
@@ -7515,8 +7691,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7515
7691
|
onItemSizeChanged,
|
|
7516
7692
|
onLoad,
|
|
7517
7693
|
onMomentumScrollEnd,
|
|
7694
|
+
onReady,
|
|
7518
7695
|
onScroll: throttleScrollFn,
|
|
7519
7696
|
onScrollBeginDrag,
|
|
7697
|
+
onScrollEndDrag,
|
|
7520
7698
|
onStartReached,
|
|
7521
7699
|
onStartReachedThreshold,
|
|
7522
7700
|
onStickyHeaderChange,
|
|
@@ -7605,10 +7783,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7605
7783
|
useDevChecks(props);
|
|
7606
7784
|
}
|
|
7607
7785
|
useLayoutEffect(() => {
|
|
7608
|
-
const didDataChange =
|
|
7609
|
-
const didStartFreshData =
|
|
7610
|
-
|
|
7611
|
-
|
|
7786
|
+
const didDataChange = state.handledDataChangeEpoch !== dataChangeEpoch;
|
|
7787
|
+
const didStartFreshData = state.handledFreshDataTransitionEpoch !== freshDataTransitionEpoch;
|
|
7788
|
+
state.handledDataChangeEpoch = dataChangeEpoch;
|
|
7789
|
+
state.handledFreshDataTransitionEpoch = freshDataTransitionEpoch;
|
|
7612
7790
|
if (didStartFreshData) {
|
|
7613
7791
|
resetInitialRenderState(ctx, {
|
|
7614
7792
|
resetInitialScroll: !!initialScrollProp,
|
|
@@ -7812,17 +7990,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7812
7990
|
onScroll: (event) => onScroll(ctx, event),
|
|
7813
7991
|
onScrollBeginDrag: (event) => {
|
|
7814
7992
|
var _a4, _b2;
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
cancelImperativeScroll(state);
|
|
7818
|
-
}
|
|
7819
|
-
if (maintainingScrollAtEnd) {
|
|
7820
|
-
finishMaintainScrollAtEnd(ctx);
|
|
7821
|
-
}
|
|
7993
|
+
state.isDragging = true;
|
|
7994
|
+
interruptMaintainScrollAtEnd(ctx);
|
|
7822
7995
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
7823
7996
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
7824
7997
|
},
|
|
7825
|
-
onScrollEnd: () => prepareReachedEdgeForNextUserScroll(ctx)
|
|
7998
|
+
onScrollEnd: () => prepareReachedEdgeForNextUserScroll(ctx),
|
|
7999
|
+
onScrollEndDrag: (event) => {
|
|
8000
|
+
var _a4, _b2;
|
|
8001
|
+
state.isDragging = false;
|
|
8002
|
+
(_b2 = (_a4 = state.props).onScrollEndDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
8003
|
+
}
|
|
7826
8004
|
}),
|
|
7827
8005
|
[]
|
|
7828
8006
|
);
|
|
@@ -7846,6 +8024,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7846
8024
|
ListHeaderComponent,
|
|
7847
8025
|
onInternalScrollBeginDrag: fns.onScrollBeginDrag,
|
|
7848
8026
|
onInternalScrollEnd: fns.onScrollEnd,
|
|
8027
|
+
onInternalScrollEndDrag: fns.onScrollEndDrag,
|
|
7849
8028
|
onLayout,
|
|
7850
8029
|
onLayoutFooter,
|
|
7851
8030
|
onMomentumScrollEnd: fns.onMomentumScrollEnd,
|