@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.js
CHANGED
|
@@ -458,6 +458,14 @@ var EDGE_POSITION_EPSILON = 1;
|
|
|
458
458
|
var ENABLE_DEVMODE = IS_DEV && false;
|
|
459
459
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
460
460
|
|
|
461
|
+
// src/core/endOfContentTarget.ts
|
|
462
|
+
function getEndAlignedViewOffset(stylePaddingEnd, footerSize = 0) {
|
|
463
|
+
return -stylePaddingEnd - footerSize;
|
|
464
|
+
}
|
|
465
|
+
function isEndOfContentTarget(target, dataLength) {
|
|
466
|
+
return !!target && dataLength > 0 && target.viewPosition === 1 && !!target.preserveForBottomPadding && target.index !== void 0 && target.index >= dataLength - 1;
|
|
467
|
+
}
|
|
468
|
+
|
|
461
469
|
// src/core/cancelImperativeScroll.ts
|
|
462
470
|
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
463
471
|
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
@@ -642,26 +650,25 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
|
|
|
642
650
|
scrollPosition: context.scrollPosition
|
|
643
651
|
});
|
|
644
652
|
};
|
|
653
|
+
let reached = !!wasReached;
|
|
645
654
|
if (!wasReached) {
|
|
646
|
-
if (
|
|
647
|
-
return false;
|
|
648
|
-
}
|
|
649
|
-
onReached(distance);
|
|
650
|
-
updateSnapshot();
|
|
651
|
-
return true;
|
|
652
|
-
}
|
|
653
|
-
const reset = isOutsideThresholdHysteresis(distance, atThreshold, threshold);
|
|
654
|
-
if (reset) {
|
|
655
|
-
setSnapshot(void 0);
|
|
656
|
-
return false;
|
|
657
|
-
}
|
|
658
|
-
if (within) {
|
|
659
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
660
|
-
if (changed) {
|
|
655
|
+
if (within && onReached(distance)) {
|
|
661
656
|
updateSnapshot();
|
|
657
|
+
reached = true;
|
|
658
|
+
}
|
|
659
|
+
} else {
|
|
660
|
+
const reset = isOutsideThresholdHysteresis(distance, atThreshold, threshold);
|
|
661
|
+
if (reset) {
|
|
662
|
+
setSnapshot(void 0);
|
|
663
|
+
reached = false;
|
|
664
|
+
} else if (within) {
|
|
665
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
666
|
+
if (changed) {
|
|
667
|
+
updateSnapshot();
|
|
668
|
+
}
|
|
662
669
|
}
|
|
663
670
|
}
|
|
664
|
-
return
|
|
671
|
+
return reached;
|
|
665
672
|
};
|
|
666
673
|
|
|
667
674
|
// src/utils/edgeReachedGate.ts
|
|
@@ -708,7 +715,6 @@ function beginReachedEdgeUserScroll(ctx, scrollDelta) {
|
|
|
708
715
|
return void 0;
|
|
709
716
|
}
|
|
710
717
|
const allowedEdge = scrollDelta < 0 ? "start" : "end";
|
|
711
|
-
state.edgeReachedGate = "closed";
|
|
712
718
|
resetEdgeLatch(ctx, allowedEdge);
|
|
713
719
|
return allowedEdge;
|
|
714
720
|
}
|
|
@@ -749,7 +755,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
749
755
|
set$(
|
|
750
756
|
ctx,
|
|
751
757
|
"isWithinMaintainScrollAtEndThreshold",
|
|
752
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd
|
|
758
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || !!maintainingScrollAtEnd
|
|
753
759
|
);
|
|
754
760
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
755
761
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -765,11 +771,13 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
765
771
|
scrollPosition: scroll
|
|
766
772
|
},
|
|
767
773
|
(distance) => {
|
|
768
|
-
|
|
769
|
-
if (canDispatchReachedEdge(ctx, "end", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
774
|
+
let dispatched = false;
|
|
775
|
+
if (state.props.onEndReached && canDispatchReachedEdge(ctx, "end", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
770
776
|
markReachedEdge(ctx);
|
|
771
|
-
|
|
777
|
+
state.props.onEndReached({ distanceFromEnd: distance });
|
|
778
|
+
dispatched = true;
|
|
772
779
|
}
|
|
780
|
+
return dispatched;
|
|
773
781
|
},
|
|
774
782
|
(snapshot) => {
|
|
775
783
|
state.endReachedSnapshot = snapshot;
|
|
@@ -802,7 +810,7 @@ function checkAtTop(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
802
810
|
}
|
|
803
811
|
set$(ctx, "isAtStart", scroll <= EDGE_POSITION_EPSILON);
|
|
804
812
|
set$(ctx, "isNearStart", scroll <= threshold);
|
|
805
|
-
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || !!state.scrollingTo;
|
|
813
|
+
const shouldSkipThresholdChecks = !state.queuedInitialLayout || hasActiveInitialScroll(state) || !!state.scrollingTo;
|
|
806
814
|
if (!shouldSkipThresholdChecks) {
|
|
807
815
|
state.isStartReached = checkThreshold(
|
|
808
816
|
scroll,
|
|
@@ -816,11 +824,13 @@ function checkAtTop(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
816
824
|
scrollPosition: scroll
|
|
817
825
|
},
|
|
818
826
|
(distance) => {
|
|
819
|
-
|
|
820
|
-
if (canDispatchReachedEdge(ctx, "start", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
827
|
+
let dispatched = false;
|
|
828
|
+
if (state.props.onStartReached && canDispatchReachedEdge(ctx, "start", allowedEdge, allowGateCreatedInCurrentCheck)) {
|
|
821
829
|
markReachedEdge(ctx);
|
|
822
|
-
|
|
830
|
+
state.props.onStartReached({ distanceFromStart: distance });
|
|
831
|
+
dispatched = true;
|
|
823
832
|
}
|
|
833
|
+
return dispatched;
|
|
824
834
|
},
|
|
825
835
|
(snapshot) => {
|
|
826
836
|
state.startReachedSnapshot = snapshot;
|
|
@@ -939,6 +949,11 @@ function resetInitialRenderState(ctx, {
|
|
|
939
949
|
if (resetLayout) {
|
|
940
950
|
state.didContainersLayout = false;
|
|
941
951
|
state.queuedInitialLayout = false;
|
|
952
|
+
state.edgeReachedGate = void 0;
|
|
953
|
+
state.isStartReached = null;
|
|
954
|
+
state.isEndReached = null;
|
|
955
|
+
state.startReachedSnapshot = void 0;
|
|
956
|
+
state.endReachedSnapshot = void 0;
|
|
942
957
|
}
|
|
943
958
|
if (resetInitialScroll) {
|
|
944
959
|
state.didFinishInitialScroll = false;
|
|
@@ -953,7 +968,7 @@ function setInitialRenderState(ctx, {
|
|
|
953
968
|
const { state } = ctx;
|
|
954
969
|
const {
|
|
955
970
|
loadStartTime,
|
|
956
|
-
props: { onLoad }
|
|
971
|
+
props: { onLoad, onReady }
|
|
957
972
|
} = state;
|
|
958
973
|
if (didLayout) {
|
|
959
974
|
state.didContainersLayout = true;
|
|
@@ -974,6 +989,7 @@ function setInitialRenderState(ctx, {
|
|
|
974
989
|
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
975
990
|
}
|
|
976
991
|
}
|
|
992
|
+
onReady == null ? void 0 : onReady();
|
|
977
993
|
}
|
|
978
994
|
}
|
|
979
995
|
|
|
@@ -1014,6 +1030,7 @@ function supersedeInitialScroll(ctx) {
|
|
|
1014
1030
|
function finishInitialScroll(ctx, options) {
|
|
1015
1031
|
var _a3, _b, _c;
|
|
1016
1032
|
const state = ctx.state;
|
|
1033
|
+
const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
|
|
1017
1034
|
if ((options == null ? void 0 : options.resolvedOffset) !== void 0) {
|
|
1018
1035
|
syncInitialScrollOffset(state, options.resolvedOffset);
|
|
1019
1036
|
} else if ((options == null ? void 0 : options.syncObservedOffset) && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset") {
|
|
@@ -1023,9 +1040,13 @@ function finishInitialScroll(ctx, options) {
|
|
|
1023
1040
|
}
|
|
1024
1041
|
}
|
|
1025
1042
|
const complete = () => {
|
|
1026
|
-
var _a4, _b2, _c2, _d, _e;
|
|
1027
|
-
|
|
1028
|
-
|
|
1043
|
+
var _a4, _b2, _c2, _d, _e, _f;
|
|
1044
|
+
if (freshDataTransitionEpoch !== state.freshDataTransitionEpoch) {
|
|
1045
|
+
(_a4 = options == null ? void 0 : options.onFinished) == null ? void 0 : _a4.call(options);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
const shouldReleaseDeferredPublicOnScroll = Platform.OS === "web" && ((_b2 = state.initialScrollSession) == null ? void 0 : _b2.kind) === "bootstrap";
|
|
1049
|
+
const finalScrollOffset = (_e = (_d = (_c2 = options == null ? void 0 : options.resolvedOffset) != null ? _c2 : state.scrollPending) != null ? _d : state.scroll) != null ? _e : 0;
|
|
1029
1050
|
initialScrollWatchdog.clear(state);
|
|
1030
1051
|
if ((options == null ? void 0 : options.preserveTarget) && state.initialScroll) {
|
|
1031
1052
|
state.clearPreservedInitialScrollOnNextFinish = void 0;
|
|
@@ -1054,7 +1075,7 @@ function finishInitialScroll(ctx, options) {
|
|
|
1054
1075
|
if (shouldReleaseDeferredPublicOnScroll) {
|
|
1055
1076
|
releaseDeferredPublicOnScroll(ctx, finalScrollOffset);
|
|
1056
1077
|
}
|
|
1057
|
-
(
|
|
1078
|
+
(_f = options == null ? void 0 : options.onFinished) == null ? void 0 : _f.call(options);
|
|
1058
1079
|
};
|
|
1059
1080
|
if (options == null ? void 0 : options.waitForCompletionFrame) {
|
|
1060
1081
|
requestAnimationFrame(complete);
|
|
@@ -1314,10 +1335,6 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
|
|
|
1314
1335
|
const itemSize = Math.max(0, measuredItemSize - (isOutOfBounds ? 0 : ctx.scrollAxisGap));
|
|
1315
1336
|
const trailingInset = getContentInsetEnd(ctx);
|
|
1316
1337
|
offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
|
|
1317
|
-
if (!isOutOfBounds && index === state.props.data.length - 1) {
|
|
1318
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
1319
|
-
offset += footerSize;
|
|
1320
|
-
}
|
|
1321
1338
|
}
|
|
1322
1339
|
return offset;
|
|
1323
1340
|
}
|
|
@@ -1338,246 +1355,21 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
|
1338
1355
|
return clampedOffset;
|
|
1339
1356
|
}
|
|
1340
1357
|
|
|
1341
|
-
// src/core/finishScrollTo.ts
|
|
1342
|
-
function finishScrollTo(ctx) {
|
|
1343
|
-
var _a3, _b;
|
|
1344
|
-
const state = ctx.state;
|
|
1345
|
-
if (state == null ? void 0 : state.scrollingTo) {
|
|
1346
|
-
cancelScrollCompletionChecks(state);
|
|
1347
|
-
const resolvePendingScroll = state.pendingScrollResolve;
|
|
1348
|
-
state.pendingScrollResolve = void 0;
|
|
1349
|
-
const scrollingTo = state.scrollingTo;
|
|
1350
|
-
state.scrollHistory.length = 0;
|
|
1351
|
-
state.scrollingTo = void 0;
|
|
1352
|
-
state.scrollTargetPinnedRange = void 0;
|
|
1353
|
-
if (state.pendingTotalSize !== void 0) {
|
|
1354
|
-
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
1355
|
-
}
|
|
1356
|
-
if (PlatformAdjustBreaksScroll) {
|
|
1357
|
-
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1358
|
-
}
|
|
1359
|
-
if (scrollingTo.isInitialScroll || state.initialScroll) {
|
|
1360
|
-
const isOffsetSession = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset";
|
|
1361
|
-
const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_b = state.initialScroll) == null ? void 0 : _b.viewPosition) === 1;
|
|
1362
|
-
finishInitialScroll(ctx, {
|
|
1363
|
-
onFinished: () => {
|
|
1364
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1365
|
-
},
|
|
1366
|
-
preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
|
|
1367
|
-
recalculateItems: true,
|
|
1368
|
-
schedulePreservedTargetClear: shouldPreserveResizeTarget,
|
|
1369
|
-
syncObservedOffset: isOffsetSession,
|
|
1370
|
-
waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
|
|
1371
|
-
});
|
|
1372
|
-
return;
|
|
1373
|
-
}
|
|
1374
|
-
recalculateSettledScroll(ctx);
|
|
1375
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
|
|
1379
|
-
// src/core/checkFinishedScroll.ts
|
|
1380
|
-
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
1381
|
-
var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
|
|
1382
|
-
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
1383
|
-
var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
|
|
1384
|
-
var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
|
|
1385
|
-
function checkFinishedScroll(ctx, options) {
|
|
1386
|
-
const scrollingTo = ctx.state.scrollingTo;
|
|
1387
|
-
if (options == null ? void 0 : options.onlyIfAligned) {
|
|
1388
|
-
if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
|
|
1389
|
-
return;
|
|
1390
|
-
}
|
|
1391
|
-
if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
|
|
1392
|
-
return;
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
|
|
1396
|
-
}
|
|
1397
|
-
function hasScrollCompletionOwnership(state, options) {
|
|
1398
|
-
const { clampedTargetOffset, scrollingTo } = options;
|
|
1399
|
-
return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
|
|
1400
|
-
}
|
|
1401
|
-
function isSilentInitialDispatch(state, scrollingTo) {
|
|
1402
|
-
return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
|
|
1403
|
-
}
|
|
1404
|
-
function getInitialScrollWatchdogTargetOffset(state) {
|
|
1405
|
-
var _a3;
|
|
1406
|
-
return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
|
|
1407
|
-
}
|
|
1408
|
-
function isNativeInitialNonZeroTarget(state) {
|
|
1409
|
-
const targetOffset = getInitialScrollWatchdogTargetOffset(state);
|
|
1410
|
-
return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
|
|
1411
|
-
}
|
|
1412
|
-
function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
|
|
1413
|
-
var _a3, _b;
|
|
1414
|
-
if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
|
|
1415
|
-
return false;
|
|
1416
|
-
}
|
|
1417
|
-
if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
|
|
1418
|
-
return false;
|
|
1419
|
-
}
|
|
1420
|
-
const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
|
|
1421
|
-
if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
|
|
1422
|
-
return false;
|
|
1423
|
-
}
|
|
1424
|
-
if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
|
|
1425
|
-
return false;
|
|
1426
|
-
}
|
|
1427
|
-
return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
|
|
1428
|
-
}
|
|
1429
|
-
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
1430
|
-
var _a3;
|
|
1431
|
-
const { state } = ctx;
|
|
1432
|
-
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;
|
|
1433
|
-
}
|
|
1434
|
-
function isEndAlignedLastItemTarget(ctx, scrollingTo) {
|
|
1435
|
-
return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
|
|
1436
|
-
}
|
|
1437
|
-
function getCurrentTargetOffset(ctx, scrollingTo) {
|
|
1438
|
-
var _a3;
|
|
1439
|
-
const index = scrollingTo.index;
|
|
1440
|
-
const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
|
|
1441
|
-
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);
|
|
1442
|
-
return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
|
|
1443
|
-
}
|
|
1444
|
-
function getResolvedScrollCompletionState(ctx, scrollingTo) {
|
|
1445
|
-
const { state } = ctx;
|
|
1446
|
-
const scroll = state.scrollPending;
|
|
1447
|
-
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
1448
|
-
const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
|
|
1449
|
-
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
1450
|
-
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
1451
|
-
const adjustedTargetOffset = clampedTargetOffset + adjust;
|
|
1452
|
-
const diff2 = Math.abs(scroll - adjustedTargetOffset);
|
|
1453
|
-
const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
|
|
1454
|
-
return {
|
|
1455
|
-
clampedTargetOffset,
|
|
1456
|
-
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
|
|
1457
|
-
};
|
|
1458
|
-
}
|
|
1459
|
-
function checkFinishedScrollFrame(ctx) {
|
|
1460
|
-
const scrollingTo = ctx.state.scrollingTo;
|
|
1461
|
-
if (!scrollingTo) {
|
|
1462
|
-
return;
|
|
1463
|
-
}
|
|
1464
|
-
const { state } = ctx;
|
|
1465
|
-
const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
|
|
1466
|
-
if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
|
|
1467
|
-
clampedTargetOffset: completionState.clampedTargetOffset,
|
|
1468
|
-
scrollingTo
|
|
1469
|
-
})) {
|
|
1470
|
-
finishScrollTo(ctx);
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
function scrollToFallbackOffset(ctx, offset) {
|
|
1474
|
-
var _a3;
|
|
1475
|
-
(_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
1476
|
-
animated: false,
|
|
1477
|
-
x: ctx.state.props.horizontal ? offset : 0,
|
|
1478
|
-
y: ctx.state.props.horizontal ? 0 : offset
|
|
1479
|
-
});
|
|
1480
|
-
}
|
|
1481
|
-
function checkFinishedScrollFallback(ctx) {
|
|
1482
|
-
const state = ctx.state;
|
|
1483
|
-
if (state.scheduledWork.has("checkFinishedScrollFallback")) {
|
|
1484
|
-
return;
|
|
1485
|
-
}
|
|
1486
|
-
const scrollingTo = state.scrollingTo;
|
|
1487
|
-
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
1488
|
-
const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
|
|
1489
|
-
const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
|
|
1490
|
-
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
|
|
1491
|
-
const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
|
|
1492
|
-
let numChecks = 0;
|
|
1493
|
-
const scheduleFallbackCheck = (delay) => {
|
|
1494
|
-
state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
|
|
1495
|
-
};
|
|
1496
|
-
const checkHasScrolled = () => {
|
|
1497
|
-
var _a3, _b, _c, _d;
|
|
1498
|
-
const isStillScrollingTo = state.scrollingTo;
|
|
1499
|
-
if (isStillScrollingTo) {
|
|
1500
|
-
numChecks++;
|
|
1501
|
-
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
1502
|
-
const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
1503
|
-
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
1504
|
-
const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
|
|
1505
|
-
state,
|
|
1506
|
-
isStillScrollingTo
|
|
1507
|
-
);
|
|
1508
|
-
const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
|
|
1509
|
-
const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
|
|
1510
|
-
const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
|
|
1511
|
-
const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
|
|
1512
|
-
const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
1513
|
-
const shouldRetryUnalignedEndScroll = Platform.OS === "ios" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
1514
|
-
if (shouldRetrySilentInitialNativeScroll) {
|
|
1515
|
-
const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
|
|
1516
|
-
const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
|
|
1517
|
-
initialScrollCompletion.markSilentInitialScrollRetry(state);
|
|
1518
|
-
scrollToFallbackOffset(ctx, jiggleOffset);
|
|
1519
|
-
state.scheduledWork.frame(
|
|
1520
|
-
() => scrollToFallbackOffset(ctx, targetOffset),
|
|
1521
|
-
"checkFinishedScrollRetryFrame"
|
|
1522
|
-
);
|
|
1523
|
-
scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
|
|
1524
|
-
} else if (shouldRetryUnalignedEndScroll) {
|
|
1525
|
-
scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
|
|
1526
|
-
scheduleFallbackCheck(100);
|
|
1527
|
-
} else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
|
|
1528
|
-
finishScrollTo(ctx);
|
|
1529
|
-
} else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
|
|
1530
|
-
const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
|
|
1531
|
-
scrollToFallbackOffset(ctx, targetOffset);
|
|
1532
|
-
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
1533
|
-
} else {
|
|
1534
|
-
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
};
|
|
1538
|
-
scheduleFallbackCheck(initialDelay);
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
// src/core/doScrollTo.native.ts
|
|
1542
|
-
function doScrollTo(ctx, params) {
|
|
1543
|
-
const state = ctx.state;
|
|
1544
|
-
const { animated, horizontal, isInitialScroll, offset } = params;
|
|
1545
|
-
const isAnimated = !!animated;
|
|
1546
|
-
const { refScroller } = state;
|
|
1547
|
-
const scroller = refScroller.current;
|
|
1548
|
-
if (!scroller) {
|
|
1549
|
-
return;
|
|
1550
|
-
}
|
|
1551
|
-
const isHorizontal = !!horizontal;
|
|
1552
|
-
const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
|
|
1553
|
-
const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
|
|
1554
|
-
scroller.scrollTo({
|
|
1555
|
-
animated: isAnimated,
|
|
1556
|
-
x: isHorizontal ? nativeOffset : 0,
|
|
1557
|
-
y: isHorizontal ? 0 : offset
|
|
1558
|
-
});
|
|
1559
|
-
if (isInitialScroll) {
|
|
1560
|
-
initialScrollCompletion.markInitialScrollNativeDispatch(state);
|
|
1561
|
-
}
|
|
1562
|
-
if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
|
|
1563
|
-
checkFinishedScroll(ctx);
|
|
1564
|
-
}
|
|
1565
|
-
if (!isAnimated) {
|
|
1566
|
-
state.scroll = offset;
|
|
1567
|
-
checkFinishedScrollFallback(ctx);
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
1358
|
// src/core/scrollRequestTracker.ts
|
|
1572
1359
|
function getScrollRequestTracker(ctx) {
|
|
1573
1360
|
if (!ctx.scrollRequestTracker) {
|
|
1574
1361
|
let currentToken = 0;
|
|
1575
|
-
|
|
1362
|
+
let waitingToken;
|
|
1363
|
+
const start = (resolve, isInternal = false) => {
|
|
1576
1364
|
const state = ctx.state;
|
|
1365
|
+
if (!isInternal && (state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd)) {
|
|
1366
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1367
|
+
}
|
|
1577
1368
|
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1578
1369
|
const token = ++currentToken;
|
|
1579
1370
|
settlePendingImperativeScroll(state);
|
|
1580
1371
|
state.pendingScrollResolve = resolve;
|
|
1372
|
+
waitingToken = token;
|
|
1581
1373
|
return token;
|
|
1582
1374
|
};
|
|
1583
1375
|
const runNow = (token, resolve, run) => {
|
|
@@ -1585,6 +1377,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1585
1377
|
if (token !== currentToken) {
|
|
1586
1378
|
return;
|
|
1587
1379
|
}
|
|
1380
|
+
waitingToken = void 0;
|
|
1588
1381
|
const didStartScroll = run();
|
|
1589
1382
|
if (!didStartScroll || !state.scrollingTo) {
|
|
1590
1383
|
if (state.pendingScrollResolve === resolve) {
|
|
@@ -1595,6 +1388,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1595
1388
|
};
|
|
1596
1389
|
ctx.scrollRequestTracker = {
|
|
1597
1390
|
isCurrent: (token) => token === currentToken,
|
|
1391
|
+
isWaitingToRun: () => waitingToken === currentToken && !!ctx.state.pendingScrollResolve,
|
|
1598
1392
|
runNow,
|
|
1599
1393
|
runNowIfIdle: (run) => {
|
|
1600
1394
|
const state = ctx.state;
|
|
@@ -1602,7 +1396,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1602
1396
|
return Promise.resolve();
|
|
1603
1397
|
}
|
|
1604
1398
|
return new Promise((resolve) => {
|
|
1605
|
-
const token = start(resolve);
|
|
1399
|
+
const token = start(resolve, true);
|
|
1606
1400
|
runNow(token, resolve, run);
|
|
1607
1401
|
});
|
|
1608
1402
|
},
|
|
@@ -1666,87 +1460,6 @@ function requestAdjust(ctx, positionDiff, source) {
|
|
|
1666
1460
|
}
|
|
1667
1461
|
}
|
|
1668
1462
|
|
|
1669
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
1670
|
-
function finishMaintainScrollAtEnd(ctx) {
|
|
1671
|
-
var _a3;
|
|
1672
|
-
const { state } = ctx;
|
|
1673
|
-
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1674
|
-
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1675
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1676
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1677
|
-
if (currentPadding !== nextPadding) {
|
|
1678
|
-
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1679
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1680
|
-
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1681
|
-
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1682
|
-
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
function doMaintainScrollAtEnd(ctx) {
|
|
1686
|
-
const state = ctx.state;
|
|
1687
|
-
const {
|
|
1688
|
-
didContainersLayout,
|
|
1689
|
-
didFinishInitialScroll,
|
|
1690
|
-
pendingNativeMVCPAdjust,
|
|
1691
|
-
props: { maintainScrollAtEnd }
|
|
1692
|
-
} = state;
|
|
1693
|
-
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1694
|
-
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1695
|
-
const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1696
|
-
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1697
|
-
state.pendingMaintainScrollAtEnd = true;
|
|
1698
|
-
return false;
|
|
1699
|
-
}
|
|
1700
|
-
if (pendingNativeMVCPAdjust) {
|
|
1701
|
-
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1702
|
-
return false;
|
|
1703
|
-
}
|
|
1704
|
-
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1705
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1706
|
-
const contentSize = getContentSize(ctx);
|
|
1707
|
-
if (contentSize < state.scrollLength) {
|
|
1708
|
-
state.scroll = 0;
|
|
1709
|
-
}
|
|
1710
|
-
if (!state.maintainingScrollAtEnd) {
|
|
1711
|
-
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1712
|
-
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1713
|
-
const scrollAtRequest = state.scroll;
|
|
1714
|
-
state.maintainingScrollAtEnd = pendingState;
|
|
1715
|
-
requestAnimationFrame(() => {
|
|
1716
|
-
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1717
|
-
return;
|
|
1718
|
-
}
|
|
1719
|
-
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1720
|
-
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1721
|
-
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1722
|
-
state.maintainingScrollAtEnd = activeState;
|
|
1723
|
-
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1724
|
-
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1725
|
-
);
|
|
1726
|
-
void scrollPromise.then(() => {
|
|
1727
|
-
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1728
|
-
return;
|
|
1729
|
-
}
|
|
1730
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1731
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1732
|
-
doMaintainScrollAtEnd(ctx);
|
|
1733
|
-
} else {
|
|
1734
|
-
finishMaintainScrollAtEnd(ctx);
|
|
1735
|
-
}
|
|
1736
|
-
});
|
|
1737
|
-
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1738
|
-
finishMaintainScrollAtEnd(ctx);
|
|
1739
|
-
}
|
|
1740
|
-
});
|
|
1741
|
-
} else {
|
|
1742
|
-
state.pendingMaintainScrollAtEnd = true;
|
|
1743
|
-
}
|
|
1744
|
-
return true;
|
|
1745
|
-
}
|
|
1746
|
-
finishMaintainScrollAtEnd(ctx);
|
|
1747
|
-
return false;
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
1463
|
// src/core/mvcp.ts
|
|
1751
1464
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1752
1465
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -2064,125 +1777,489 @@ var getScrollVelocity = (state) => {
|
|
|
2064
1777
|
if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2065
1778
|
return 0;
|
|
2066
1779
|
}
|
|
2067
|
-
let direction = 0;
|
|
2068
|
-
let weightedVelocity = 0;
|
|
2069
|
-
let totalWeight = 0;
|
|
2070
|
-
for (let i = newestIndex; i > 0; i--) {
|
|
2071
|
-
const current = scrollHistory[i];
|
|
2072
|
-
const previous = scrollHistory[i - 1];
|
|
2073
|
-
const scrollDiff = current.scroll - previous.scroll;
|
|
2074
|
-
const timeDiff = current.time - previous.time;
|
|
2075
|
-
const deltaSign = Math.sign(scrollDiff);
|
|
2076
|
-
if (deltaSign !== 0) {
|
|
2077
|
-
if (direction === 0) {
|
|
2078
|
-
direction = deltaSign;
|
|
2079
|
-
} else if (deltaSign !== direction) {
|
|
2080
|
-
break;
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2084
|
-
break;
|
|
2085
|
-
}
|
|
2086
|
-
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
2087
|
-
continue;
|
|
2088
|
-
}
|
|
2089
|
-
const age = newest.time - current.time;
|
|
2090
|
-
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
2091
|
-
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
2092
|
-
totalWeight += weight;
|
|
1780
|
+
let direction = 0;
|
|
1781
|
+
let weightedVelocity = 0;
|
|
1782
|
+
let totalWeight = 0;
|
|
1783
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
1784
|
+
const current = scrollHistory[i];
|
|
1785
|
+
const previous = scrollHistory[i - 1];
|
|
1786
|
+
const scrollDiff = current.scroll - previous.scroll;
|
|
1787
|
+
const timeDiff = current.time - previous.time;
|
|
1788
|
+
const deltaSign = Math.sign(scrollDiff);
|
|
1789
|
+
if (deltaSign !== 0) {
|
|
1790
|
+
if (direction === 0) {
|
|
1791
|
+
direction = deltaSign;
|
|
1792
|
+
} else if (deltaSign !== direction) {
|
|
1793
|
+
break;
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
1797
|
+
break;
|
|
1798
|
+
}
|
|
1799
|
+
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
const age = newest.time - current.time;
|
|
1803
|
+
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
1804
|
+
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
1805
|
+
totalWeight += weight;
|
|
1806
|
+
}
|
|
1807
|
+
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1810
|
+
// src/utils/isInMVCPActiveMode.native.ts
|
|
1811
|
+
function isInMVCPActiveMode(state) {
|
|
1812
|
+
return state.dataChangeNeedsScrollUpdate;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
// src/core/updateScroll.ts
|
|
1816
|
+
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
1817
|
+
var _a3;
|
|
1818
|
+
const state = ctx.state;
|
|
1819
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
1820
|
+
const prevScroll = state.scroll;
|
|
1821
|
+
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
1822
|
+
state.hasScrolled = true;
|
|
1823
|
+
}
|
|
1824
|
+
const currentTime = Date.now();
|
|
1825
|
+
state.lastBatchingAction = currentTime;
|
|
1826
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
1827
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
1828
|
+
if (adjustChanged) {
|
|
1829
|
+
scrollHistory.length = 0;
|
|
1830
|
+
}
|
|
1831
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
1832
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1833
|
+
if (!adjustChanged) {
|
|
1834
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
if (scrollHistory.length > 5) {
|
|
1838
|
+
scrollHistory.shift();
|
|
1839
|
+
}
|
|
1840
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1841
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1842
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1843
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
1844
|
+
return;
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
state.scrollPrev = prevScroll;
|
|
1848
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1849
|
+
state.scroll = newScroll;
|
|
1850
|
+
state.scrollTime = currentTime;
|
|
1851
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1852
|
+
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
1853
|
+
const didCancelMaintainScrollAtEnd = Platform.OS === "web" && isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
1854
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
1855
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1856
|
+
}
|
|
1857
|
+
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
1858
|
+
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1859
|
+
const scrollLength = state.scrollLength;
|
|
1860
|
+
const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
|
|
1861
|
+
const scrollVelocity = getScrollVelocity(state);
|
|
1862
|
+
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
1863
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
1864
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1865
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1866
|
+
if (shouldUpdate) {
|
|
1867
|
+
state.scrollLastCalculate = state.scroll;
|
|
1868
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
1869
|
+
state.lastScrollDelta = scrollDelta;
|
|
1870
|
+
const runCalculateItems = () => {
|
|
1871
|
+
var _a4;
|
|
1872
|
+
const calculateItemsParams = {
|
|
1873
|
+
doMVCP: scrollingTo !== void 0,
|
|
1874
|
+
scrollVelocity
|
|
1875
|
+
};
|
|
1876
|
+
if (isLargeUserScrollJump) {
|
|
1877
|
+
calculateItemsParams.drawDistanceMode = "visible-first";
|
|
1878
|
+
}
|
|
1879
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
|
|
1880
|
+
checkThresholds(ctx, allowedEdge);
|
|
1881
|
+
};
|
|
1882
|
+
if (isLargeUserScrollJump) {
|
|
1883
|
+
state.mvcpAnchorLock = void 0;
|
|
1884
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1885
|
+
state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
|
|
1886
|
+
state.scheduledWork.cancel("mvcpRecalculate");
|
|
1887
|
+
flushSync(runCalculateItems);
|
|
1888
|
+
scheduleFullDrawDistancePrewarm(ctx);
|
|
1889
|
+
} else {
|
|
1890
|
+
runCalculateItems();
|
|
1891
|
+
}
|
|
1892
|
+
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
1893
|
+
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
1894
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1895
|
+
doMaintainScrollAtEnd(ctx);
|
|
1896
|
+
}
|
|
1897
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
1898
|
+
state.lastScrollDelta = 0;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1903
|
+
function interruptMaintainScrollAtEnd(ctx) {
|
|
1904
|
+
var _a3;
|
|
1905
|
+
const { state } = ctx;
|
|
1906
|
+
const maintaining = state.maintainingScrollAtEnd;
|
|
1907
|
+
const cancelActiveScroll = !!(maintaining === "animated" || maintaining === "instant" || maintaining && ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isScrollToEnd));
|
|
1908
|
+
if (cancelActiveScroll) {
|
|
1909
|
+
cancelImperativeScroll(state);
|
|
1910
|
+
}
|
|
1911
|
+
if (maintaining || state.pendingMaintainScrollAtEnd) {
|
|
1912
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1913
|
+
}
|
|
1914
|
+
return cancelActiveScroll;
|
|
1915
|
+
}
|
|
1916
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1917
|
+
var _a3;
|
|
1918
|
+
const { state } = ctx;
|
|
1919
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1920
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1921
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1922
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1923
|
+
if (currentPadding !== nextPadding) {
|
|
1924
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1925
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1926
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1927
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1928
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
function doMaintainScrollAtEnd(ctx, options) {
|
|
1932
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
1933
|
+
const state = ctx.state;
|
|
1934
|
+
let didMaintain = false;
|
|
1935
|
+
if (state.isDragging) {
|
|
1936
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1937
|
+
} else {
|
|
1938
|
+
const {
|
|
1939
|
+
didContainersLayout,
|
|
1940
|
+
didFinishInitialScroll,
|
|
1941
|
+
pendingNativeMVCPAdjust,
|
|
1942
|
+
props: { maintainScrollAtEnd }
|
|
1943
|
+
} = state;
|
|
1944
|
+
const immediate = (options == null ? void 0 : options.immediate) && Platform.OS === "web" && !(maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.animated);
|
|
1945
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1946
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1947
|
+
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);
|
|
1948
|
+
if (shouldMaintainScrollAtEnd && !state.scrollingTo) {
|
|
1949
|
+
const scroller = state.refScroller.current;
|
|
1950
|
+
const nativeMax = (_c = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _c.call(scroller);
|
|
1951
|
+
const observed = (_d = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _d.call(scroller);
|
|
1952
|
+
if (nativeMax !== void 0 && observed !== void 0 && nativeMax < state.scroll - 1 && Math.abs(observed - nativeMax) <= 1) {
|
|
1953
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1954
|
+
state.scrollPending = observed;
|
|
1955
|
+
updateScroll(ctx, observed, true, { markHasScrolled: false });
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1959
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1960
|
+
} else if (pendingNativeMVCPAdjust) {
|
|
1961
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1962
|
+
} else if (shouldMaintainScrollAtEnd && (state.scrollingTo || state.pendingScrollResolve)) {
|
|
1963
|
+
if (immediate && ((_e = state.scrollingTo) == null ? void 0 : _e.isScrollToEnd) && !state.scrollingTo.animated) {
|
|
1964
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1965
|
+
ctx.scrollToEnd({ animated: false });
|
|
1966
|
+
didMaintain = true;
|
|
1967
|
+
} else {
|
|
1968
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1969
|
+
(_f = state.maintainingScrollAtEnd) != null ? _f : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1970
|
+
}
|
|
1971
|
+
} else if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1972
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1973
|
+
const contentSize = getContentSize(ctx);
|
|
1974
|
+
if (contentSize < state.scrollLength) {
|
|
1975
|
+
state.scroll = 0;
|
|
1976
|
+
}
|
|
1977
|
+
if (!state.maintainingScrollAtEnd || immediate && state.maintainingScrollAtEnd === "pending-instant") {
|
|
1978
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1979
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1980
|
+
const scrollAtRequest = state.scroll;
|
|
1981
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1982
|
+
const run = () => {
|
|
1983
|
+
if (state.maintainingScrollAtEnd === pendingState) {
|
|
1984
|
+
if (state.isDragging) {
|
|
1985
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1986
|
+
} else {
|
|
1987
|
+
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1988
|
+
const didScrollSinceRequest = Platform.OS === "web" && state.scroll !== scrollAtRequest;
|
|
1989
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1990
|
+
if (state.scrollingTo || state.pendingScrollResolve) {
|
|
1991
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1992
|
+
} else {
|
|
1993
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1994
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1995
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1996
|
+
);
|
|
1997
|
+
void scrollPromise.then(() => {
|
|
1998
|
+
if (state.maintainingScrollAtEnd === activeState) {
|
|
1999
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
2000
|
+
state.maintainingScrollAtEnd = void 0;
|
|
2001
|
+
doMaintainScrollAtEnd(ctx);
|
|
2002
|
+
} else {
|
|
2003
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
2009
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
if (immediate) {
|
|
2015
|
+
run();
|
|
2016
|
+
} else {
|
|
2017
|
+
requestAnimationFrame(run);
|
|
2018
|
+
}
|
|
2019
|
+
} else {
|
|
2020
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
2021
|
+
}
|
|
2022
|
+
didMaintain = true;
|
|
2023
|
+
} else {
|
|
2024
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
return didMaintain;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// src/core/finishScrollTo.ts
|
|
2031
|
+
function finishScrollTo(ctx) {
|
|
2032
|
+
var _a3, _b, _c;
|
|
2033
|
+
const state = ctx.state;
|
|
2034
|
+
if (state == null ? void 0 : state.scrollingTo) {
|
|
2035
|
+
cancelScrollCompletionChecks(state);
|
|
2036
|
+
const resolvePendingScroll = ((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) ? void 0 : state.pendingScrollResolve;
|
|
2037
|
+
if (resolvePendingScroll) {
|
|
2038
|
+
state.pendingScrollResolve = void 0;
|
|
2039
|
+
}
|
|
2040
|
+
const scrollingTo = state.scrollingTo;
|
|
2041
|
+
state.scrollHistory.length = 0;
|
|
2042
|
+
state.scrollingTo = void 0;
|
|
2043
|
+
state.scrollTargetPinnedRange = void 0;
|
|
2044
|
+
if (state.pendingTotalSize !== void 0) {
|
|
2045
|
+
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
2046
|
+
}
|
|
2047
|
+
if (PlatformAdjustBreaksScroll) {
|
|
2048
|
+
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
2049
|
+
}
|
|
2050
|
+
if (scrollingTo.isInitialScroll || state.initialScroll) {
|
|
2051
|
+
const isOffsetSession = ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) === "offset";
|
|
2052
|
+
const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_c = state.initialScroll) == null ? void 0 : _c.viewPosition) === 1;
|
|
2053
|
+
finishInitialScroll(ctx, {
|
|
2054
|
+
onFinished: () => {
|
|
2055
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
2056
|
+
},
|
|
2057
|
+
preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
|
|
2058
|
+
recalculateItems: true,
|
|
2059
|
+
schedulePreservedTargetClear: shouldPreserveResizeTarget,
|
|
2060
|
+
syncObservedOffset: isOffsetSession,
|
|
2061
|
+
waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
|
|
2062
|
+
});
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
recalculateSettledScroll(ctx);
|
|
2066
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
2067
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
2068
|
+
state.maintainingScrollAtEnd = void 0;
|
|
2069
|
+
doMaintainScrollAtEnd(ctx);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
// src/core/checkFinishedScroll.ts
|
|
2075
|
+
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
2076
|
+
var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
|
|
2077
|
+
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
2078
|
+
var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
|
|
2079
|
+
var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
|
|
2080
|
+
function checkFinishedScroll(ctx, options) {
|
|
2081
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
2082
|
+
if (options == null ? void 0 : options.onlyIfAligned) {
|
|
2083
|
+
if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
|
|
2091
|
+
}
|
|
2092
|
+
function hasScrollCompletionOwnership(state, options) {
|
|
2093
|
+
const { clampedTargetOffset, scrollingTo } = options;
|
|
2094
|
+
return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
|
|
2095
|
+
}
|
|
2096
|
+
function isSilentInitialDispatch(state, scrollingTo) {
|
|
2097
|
+
return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
|
|
2098
|
+
}
|
|
2099
|
+
function getInitialScrollWatchdogTargetOffset(state) {
|
|
2100
|
+
var _a3;
|
|
2101
|
+
return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
|
|
2102
|
+
}
|
|
2103
|
+
function isNativeInitialNonZeroTarget(state) {
|
|
2104
|
+
const targetOffset = getInitialScrollWatchdogTargetOffset(state);
|
|
2105
|
+
return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
|
|
2106
|
+
}
|
|
2107
|
+
function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
|
|
2108
|
+
var _a3, _b;
|
|
2109
|
+
if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
|
|
2110
|
+
return false;
|
|
2111
|
+
}
|
|
2112
|
+
if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
|
|
2113
|
+
return false;
|
|
2114
|
+
}
|
|
2115
|
+
const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
|
|
2116
|
+
if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
|
|
2117
|
+
return false;
|
|
2118
|
+
}
|
|
2119
|
+
if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
|
|
2120
|
+
return false;
|
|
2121
|
+
}
|
|
2122
|
+
return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
|
|
2123
|
+
}
|
|
2124
|
+
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
2125
|
+
var _a3;
|
|
2126
|
+
const { state } = ctx;
|
|
2127
|
+
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;
|
|
2128
|
+
}
|
|
2129
|
+
function isEndAlignedLastItemTarget(ctx, scrollingTo) {
|
|
2130
|
+
return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
|
|
2131
|
+
}
|
|
2132
|
+
function getCurrentTargetOffset(ctx, scrollingTo) {
|
|
2133
|
+
var _a3;
|
|
2134
|
+
const index = scrollingTo.index;
|
|
2135
|
+
const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
|
|
2136
|
+
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);
|
|
2137
|
+
return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
|
|
2138
|
+
}
|
|
2139
|
+
function getResolvedScrollCompletionState(ctx, scrollingTo) {
|
|
2140
|
+
const { state } = ctx;
|
|
2141
|
+
const scroll = state.scrollPending;
|
|
2142
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2143
|
+
const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
|
|
2144
|
+
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
2145
|
+
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
2146
|
+
const adjustedTargetOffset = clampedTargetOffset + adjust;
|
|
2147
|
+
const diff2 = Math.abs(scroll - adjustedTargetOffset);
|
|
2148
|
+
const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
|
|
2149
|
+
return {
|
|
2150
|
+
clampedTargetOffset,
|
|
2151
|
+
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
|
|
2152
|
+
};
|
|
2153
|
+
}
|
|
2154
|
+
function checkFinishedScrollFrame(ctx) {
|
|
2155
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
2156
|
+
if (!scrollingTo) {
|
|
2157
|
+
return;
|
|
2158
|
+
}
|
|
2159
|
+
const { state } = ctx;
|
|
2160
|
+
const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
|
|
2161
|
+
if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
|
|
2162
|
+
clampedTargetOffset: completionState.clampedTargetOffset,
|
|
2163
|
+
scrollingTo
|
|
2164
|
+
})) {
|
|
2165
|
+
finishScrollTo(ctx);
|
|
2093
2166
|
}
|
|
2094
|
-
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
2095
|
-
};
|
|
2096
|
-
|
|
2097
|
-
// src/utils/isInMVCPActiveMode.native.ts
|
|
2098
|
-
function isInMVCPActiveMode(state) {
|
|
2099
|
-
return state.dataChangeNeedsScrollUpdate;
|
|
2100
2167
|
}
|
|
2101
|
-
|
|
2102
|
-
// src/core/updateScroll.ts
|
|
2103
|
-
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
2168
|
+
function scrollToFallbackOffset(ctx, offset) {
|
|
2104
2169
|
var _a3;
|
|
2170
|
+
(_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
2171
|
+
animated: false,
|
|
2172
|
+
x: ctx.state.props.horizontal ? offset : 0,
|
|
2173
|
+
y: ctx.state.props.horizontal ? 0 : offset
|
|
2174
|
+
});
|
|
2175
|
+
}
|
|
2176
|
+
function checkFinishedScrollFallback(ctx) {
|
|
2105
2177
|
const state = ctx.state;
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
2109
|
-
state.hasScrolled = true;
|
|
2110
|
-
}
|
|
2111
|
-
const currentTime = Date.now();
|
|
2112
|
-
state.lastBatchingAction = currentTime;
|
|
2113
|
-
const adjust = scrollAdjustHandler.getAdjust();
|
|
2114
|
-
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
2115
|
-
if (adjustChanged) {
|
|
2116
|
-
scrollHistory.length = 0;
|
|
2178
|
+
if (state.scheduledWork.has("checkFinishedScrollFallback")) {
|
|
2179
|
+
return;
|
|
2117
2180
|
}
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2181
|
+
const scrollingTo = state.scrollingTo;
|
|
2182
|
+
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
2183
|
+
const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
|
|
2184
|
+
const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
|
|
2185
|
+
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
|
|
2186
|
+
const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
|
|
2187
|
+
let numChecks = 0;
|
|
2188
|
+
const scheduleFallbackCheck = (delay) => {
|
|
2189
|
+
state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
|
|
2190
|
+
};
|
|
2191
|
+
const checkHasScrolled = () => {
|
|
2192
|
+
var _a3, _b, _c, _d;
|
|
2193
|
+
const isStillScrollingTo = state.scrollingTo;
|
|
2194
|
+
if (isStillScrollingTo) {
|
|
2195
|
+
numChecks++;
|
|
2196
|
+
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
2197
|
+
const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
2198
|
+
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
2199
|
+
const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
|
|
2200
|
+
state,
|
|
2201
|
+
isStillScrollingTo
|
|
2202
|
+
);
|
|
2203
|
+
const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
|
|
2204
|
+
const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
|
|
2205
|
+
const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
|
|
2206
|
+
const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
|
|
2207
|
+
const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2208
|
+
const shouldRetryUnalignedEndScroll = Platform.OS !== "web" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2209
|
+
if (shouldRetrySilentInitialNativeScroll) {
|
|
2210
|
+
const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
|
|
2211
|
+
const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
|
|
2212
|
+
initialScrollCompletion.markSilentInitialScrollRetry(state);
|
|
2213
|
+
scrollToFallbackOffset(ctx, jiggleOffset);
|
|
2214
|
+
state.scheduledWork.frame(
|
|
2215
|
+
() => scrollToFallbackOffset(ctx, targetOffset),
|
|
2216
|
+
"checkFinishedScrollRetryFrame"
|
|
2217
|
+
);
|
|
2218
|
+
scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
|
|
2219
|
+
} else if (shouldRetryUnalignedEndScroll) {
|
|
2220
|
+
scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
|
|
2221
|
+
scheduleFallbackCheck(100);
|
|
2222
|
+
} else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
|
|
2223
|
+
finishScrollTo(ctx);
|
|
2224
|
+
} else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
|
|
2225
|
+
const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
|
|
2226
|
+
scrollToFallbackOffset(ctx, targetOffset);
|
|
2227
|
+
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
2228
|
+
} else {
|
|
2229
|
+
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
2230
|
+
}
|
|
2122
2231
|
}
|
|
2232
|
+
};
|
|
2233
|
+
scheduleFallbackCheck(initialDelay);
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
// src/core/doScrollTo.native.ts
|
|
2237
|
+
function doScrollTo(ctx, params) {
|
|
2238
|
+
const state = ctx.state;
|
|
2239
|
+
const { animated, horizontal, isInitialScroll, offset } = params;
|
|
2240
|
+
const isAnimated = !!animated;
|
|
2241
|
+
const { refScroller } = state;
|
|
2242
|
+
const scroller = refScroller.current;
|
|
2243
|
+
if (!scroller) {
|
|
2244
|
+
return;
|
|
2123
2245
|
}
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2246
|
+
const isHorizontal = !!horizontal;
|
|
2247
|
+
const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
|
|
2248
|
+
const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
|
|
2249
|
+
scroller.scrollTo({
|
|
2250
|
+
animated: isAnimated,
|
|
2251
|
+
x: isHorizontal ? nativeOffset : 0,
|
|
2252
|
+
y: isHorizontal ? 0 : offset
|
|
2253
|
+
});
|
|
2254
|
+
if (isInitialScroll) {
|
|
2255
|
+
initialScrollCompletion.markInitialScrollNativeDispatch(state);
|
|
2133
2256
|
}
|
|
2134
|
-
state.
|
|
2135
|
-
|
|
2136
|
-
state.scroll = newScroll;
|
|
2137
|
-
state.scrollTime = currentTime;
|
|
2138
|
-
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2139
|
-
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
2140
|
-
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
2141
|
-
if (didCancelMaintainScrollAtEnd) {
|
|
2142
|
-
finishMaintainScrollAtEnd(ctx);
|
|
2257
|
+
if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
|
|
2258
|
+
checkFinishedScroll(ctx);
|
|
2143
2259
|
}
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
|
|
2148
|
-
const scrollVelocity = getScrollVelocity(state);
|
|
2149
|
-
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
2150
|
-
const lastCalculated = state.scrollLastCalculate;
|
|
2151
|
-
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2152
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2153
|
-
if (shouldUpdate) {
|
|
2154
|
-
state.scrollLastCalculate = state.scroll;
|
|
2155
|
-
state.ignoreScrollFromMVCPIgnored = false;
|
|
2156
|
-
state.lastScrollDelta = scrollDelta;
|
|
2157
|
-
const runCalculateItems = () => {
|
|
2158
|
-
var _a4;
|
|
2159
|
-
const calculateItemsParams = {
|
|
2160
|
-
doMVCP: scrollingTo !== void 0,
|
|
2161
|
-
scrollVelocity
|
|
2162
|
-
};
|
|
2163
|
-
if (isLargeUserScrollJump) {
|
|
2164
|
-
calculateItemsParams.drawDistanceMode = "visible-first";
|
|
2165
|
-
}
|
|
2166
|
-
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
|
|
2167
|
-
checkThresholds(ctx, allowedEdge);
|
|
2168
|
-
};
|
|
2169
|
-
if (isLargeUserScrollJump) {
|
|
2170
|
-
state.mvcpAnchorLock = void 0;
|
|
2171
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
2172
|
-
state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
|
|
2173
|
-
state.scheduledWork.cancel("mvcpRecalculate");
|
|
2174
|
-
flushSync(runCalculateItems);
|
|
2175
|
-
scheduleFullDrawDistancePrewarm(ctx);
|
|
2176
|
-
} else {
|
|
2177
|
-
runCalculateItems();
|
|
2178
|
-
}
|
|
2179
|
-
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
2180
|
-
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
2181
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
2182
|
-
doMaintainScrollAtEnd(ctx);
|
|
2183
|
-
}
|
|
2184
|
-
state.dataChangeNeedsScrollUpdate = false;
|
|
2185
|
-
state.lastScrollDelta = 0;
|
|
2260
|
+
if (!isAnimated) {
|
|
2261
|
+
state.scroll = offset;
|
|
2262
|
+
checkFinishedScrollFallback(ctx);
|
|
2186
2263
|
}
|
|
2187
2264
|
}
|
|
2188
2265
|
|
|
@@ -2336,7 +2413,9 @@ function scrollTo(ctx, params) {
|
|
|
2336
2413
|
pinScrollTargetRenderRange(ctx, targetOffset, scrollTarget.index);
|
|
2337
2414
|
}
|
|
2338
2415
|
}
|
|
2339
|
-
|
|
2416
|
+
if (!animated || isInitialScroll) {
|
|
2417
|
+
state.scrollPending = targetOffset;
|
|
2418
|
+
}
|
|
2340
2419
|
syncInitialScrollNativeWatchdog(state, { isInitialScroll, requestedOffset: offset, targetOffset });
|
|
2341
2420
|
if (!isInitialScroll && !noScrollingTo && Math.abs(state.scroll - targetOffset) > 1) {
|
|
2342
2421
|
if (animated) {
|
|
@@ -2713,13 +2792,13 @@ function rearmBootstrapInitialScroll(ctx, options) {
|
|
|
2713
2792
|
queueBootstrapInitialScrollReevaluation(ctx.state);
|
|
2714
2793
|
}
|
|
2715
2794
|
function createInitialScrollAtEndTarget(options) {
|
|
2716
|
-
const { dataLength, footerSize, preserveForFooterLayout, stylePaddingEnd } = options;
|
|
2795
|
+
const { dataLength, footerSize, index, preserveForFooterLayout, stylePaddingEnd } = options;
|
|
2717
2796
|
return {
|
|
2718
2797
|
contentOffset: void 0,
|
|
2719
|
-
index: Math.max(0, dataLength - 1),
|
|
2798
|
+
index: index != null ? index : Math.max(0, dataLength - 1),
|
|
2720
2799
|
preserveForBottomPadding: true,
|
|
2721
2800
|
preserveForFooterLayout,
|
|
2722
|
-
viewOffset:
|
|
2801
|
+
viewOffset: getEndAlignedViewOffset(stylePaddingEnd, footerSize),
|
|
2723
2802
|
viewPosition: 1
|
|
2724
2803
|
};
|
|
2725
2804
|
}
|
|
@@ -2735,13 +2814,14 @@ function isRetargetableBottomAlignedInitialScrollTarget(target) {
|
|
|
2735
2814
|
function createRetargetedBottomAlignedInitialScroll(options) {
|
|
2736
2815
|
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingEnd, target } = options;
|
|
2737
2816
|
const preserveForFooterLayout = shouldPreserveInitialScrollForFooterLayout(target);
|
|
2817
|
+
const alignsToContentEnd = initialScrollAtEnd || isEndOfContentTarget(target, dataLength);
|
|
2738
2818
|
return {
|
|
2739
2819
|
...target,
|
|
2740
2820
|
contentOffset: void 0,
|
|
2741
2821
|
index: initialScrollAtEnd ? Math.max(0, dataLength - 1) : target.index,
|
|
2742
2822
|
preserveForBottomPadding: true,
|
|
2743
2823
|
preserveForFooterLayout,
|
|
2744
|
-
viewOffset:
|
|
2824
|
+
viewOffset: getEndAlignedViewOffset(stylePaddingEnd, alignsToContentEnd ? footerSize : 0),
|
|
2745
2825
|
viewPosition: 1
|
|
2746
2826
|
};
|
|
2747
2827
|
}
|
|
@@ -2755,7 +2835,7 @@ function clearPendingInitialScrollFooterLayout(ctx, options) {
|
|
|
2755
2835
|
}
|
|
2756
2836
|
const clearedFooterTarget = createInitialScrollAtEndTarget({
|
|
2757
2837
|
dataLength,
|
|
2758
|
-
footerSize: 0,
|
|
2838
|
+
footerSize: peek$(ctx, "footerSize") || 0,
|
|
2759
2839
|
preserveForFooterLayout: void 0,
|
|
2760
2840
|
stylePaddingEnd
|
|
2761
2841
|
});
|
|
@@ -2778,13 +2858,12 @@ function getObservedBootstrapInitialScrollOffset(state) {
|
|
|
2778
2858
|
return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
|
|
2779
2859
|
}
|
|
2780
2860
|
function getPreservedEndAnchorOffsetDiff(ctx) {
|
|
2781
|
-
var _a3;
|
|
2782
2861
|
const state = ctx.state;
|
|
2783
2862
|
const initialScroll = state.initialScroll;
|
|
2784
|
-
if (!state.didFinishInitialScroll ||
|
|
2863
|
+
if (!state.didFinishInitialScroll || state.scrollingTo || state.pendingScrollResolve || state.maintainingScrollAtEnd || state.isDragging || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
|
|
2785
2864
|
return;
|
|
2786
2865
|
}
|
|
2787
|
-
const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2866
|
+
const currentOffset = Platform.OS !== "web" && typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2788
2867
|
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
2789
2868
|
}
|
|
2790
2869
|
function schedulePreservedEndAnchorCorrection(ctx) {
|
|
@@ -2812,6 +2891,9 @@ function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
|
|
|
2812
2891
|
const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
|
|
2813
2892
|
if (hasObservedNativeScrollAfterRequest) {
|
|
2814
2893
|
activeCorrection.lastRequestTime = Date.now();
|
|
2894
|
+
if (Platform.OS === "web") {
|
|
2895
|
+
state.scroll = getObservedBootstrapInitialScrollOffset(state);
|
|
2896
|
+
}
|
|
2815
2897
|
requestAdjust(ctx, offsetDiff);
|
|
2816
2898
|
}
|
|
2817
2899
|
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
@@ -2934,10 +3016,10 @@ function handleBootstrapInitialScrollDataChange(ctx, options) {
|
|
|
2934
3016
|
function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
2935
3017
|
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingEnd } = options;
|
|
2936
3018
|
const state = ctx.state;
|
|
2937
|
-
|
|
3019
|
+
const initialScroll = state.initialScroll;
|
|
3020
|
+
if (!initialScrollAtEnd && !isEndOfContentTarget(initialScroll, dataLength)) {
|
|
2938
3021
|
return;
|
|
2939
3022
|
}
|
|
2940
|
-
const initialScroll = state.initialScroll;
|
|
2941
3023
|
if (isOffsetInitialScrollSession(state) || dataLength === 0 || !initialScroll) {
|
|
2942
3024
|
return;
|
|
2943
3025
|
}
|
|
@@ -2955,6 +3037,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2955
3037
|
const updatedInitialScroll = createInitialScrollAtEndTarget({
|
|
2956
3038
|
dataLength,
|
|
2957
3039
|
footerSize,
|
|
3040
|
+
index: initialScrollAtEnd ? void 0 : initialScroll.index,
|
|
2958
3041
|
preserveForFooterLayout: shouldPreserveInitialScrollForFooterLayout(initialScroll),
|
|
2959
3042
|
stylePaddingEnd
|
|
2960
3043
|
});
|
|
@@ -3191,6 +3274,11 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3191
3274
|
const state = ctx.state;
|
|
3192
3275
|
const previousInitialScrollDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
|
|
3193
3276
|
const shouldUseLatestInitialScroll = dataLength > 0 && (!state.hasHadNonEmptyData || didStartFreshData);
|
|
3277
|
+
if (didStartFreshData) {
|
|
3278
|
+
cancelImperativeScroll(state);
|
|
3279
|
+
state.maintainingScrollAtEnd = void 0;
|
|
3280
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
3281
|
+
}
|
|
3194
3282
|
if (dataLength > 0) {
|
|
3195
3283
|
state.hasHadNonEmptyData = true;
|
|
3196
3284
|
}
|
|
@@ -3909,7 +3997,7 @@ function getExpandedContainerPoolSize(dataLength, numContainers) {
|
|
|
3909
3997
|
}
|
|
3910
3998
|
|
|
3911
3999
|
// src/utils/findAvailableContainers.ts
|
|
3912
|
-
function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffered, pendingRemoval,
|
|
4000
|
+
function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffered, pendingRemoval, protectedKeys, reverseItemOrder = false) {
|
|
3913
4001
|
var _a3;
|
|
3914
4002
|
const numNeeded = needNewContainers.length;
|
|
3915
4003
|
if (numNeeded === 0) {
|
|
@@ -3918,16 +4006,27 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
3918
4006
|
const numContainers = peek$(ctx, "numContainers");
|
|
3919
4007
|
const state = ctx.state;
|
|
3920
4008
|
const { containerItemMetadata, stickyContainerPool } = state;
|
|
4009
|
+
const { data, getItemType } = state.props;
|
|
4010
|
+
const hasItemTypes = !!getItemType;
|
|
3921
4011
|
const shouldAvoidAssignedContainerReuse = state.props.recycleItems && !!state.props.positionComponentInternal;
|
|
3922
4012
|
const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
|
|
3923
|
-
const requests =
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
order
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
4013
|
+
const requests = new Array(numNeeded);
|
|
4014
|
+
const normalRequests = [];
|
|
4015
|
+
const stickyRequests = [];
|
|
4016
|
+
for (let order = 0; order < numNeeded; order++) {
|
|
4017
|
+
const itemIndex = needNewContainers[order];
|
|
4018
|
+
const itemType = getItemType == null ? void 0 : getItemType(data[itemIndex], itemIndex);
|
|
4019
|
+
const request = {
|
|
4020
|
+
isBuffered: itemIndex >= startBuffered && itemIndex <= endBuffered,
|
|
4021
|
+
isSticky: state.props.stickyHeaderIndicesSet.has(itemIndex),
|
|
4022
|
+
itemIndex,
|
|
4023
|
+
itemType: hasItemTypes ? itemType !== void 0 ? String(itemType) : "" : void 0,
|
|
4024
|
+
order,
|
|
4025
|
+
renderPriority: reverseItemOrder ? -itemIndex : itemIndex
|
|
4026
|
+
};
|
|
4027
|
+
requests[order] = request;
|
|
4028
|
+
(request.isSticky ? stickyRequests : normalRequests).push(request);
|
|
4029
|
+
}
|
|
3931
4030
|
const normalCandidates = [];
|
|
3932
4031
|
const stickyCandidates = [];
|
|
3933
4032
|
for (let containerIndex = 0; containerIndex < numContainers; containerIndex++) {
|
|
@@ -3983,7 +4082,7 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
3983
4082
|
}
|
|
3984
4083
|
};
|
|
3985
4084
|
const assignFromPool = (pendingRequests, candidates, allowCrossType) => {
|
|
3986
|
-
if (
|
|
4085
|
+
if (hasItemTypes) {
|
|
3987
4086
|
assignMatching(
|
|
3988
4087
|
pendingRequests,
|
|
3989
4088
|
candidates,
|
|
@@ -4007,6 +4106,11 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
4007
4106
|
}
|
|
4008
4107
|
assign(request, containerIndex);
|
|
4009
4108
|
}
|
|
4109
|
+
if (normalRequests.length > 1 || stickyRequests.length > 1) {
|
|
4110
|
+
const containerIndices = [];
|
|
4111
|
+
reorderPoolAssignments(normalRequests, allocations, containerIndices, hasItemTypes);
|
|
4112
|
+
reorderPoolAssignments(stickyRequests, allocations, containerIndices, hasItemTypes);
|
|
4113
|
+
}
|
|
4010
4114
|
if (pendingRemovalChanged) {
|
|
4011
4115
|
pendingRemoval.length = 0;
|
|
4012
4116
|
if (pendingRemovalSet) {
|
|
@@ -4036,12 +4140,53 @@ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffe
|
|
|
4036
4140
|
function comparatorByDistance(a, b) {
|
|
4037
4141
|
return b.distance - a.distance;
|
|
4038
4142
|
}
|
|
4143
|
+
function comparatorByRenderPriority(a, b) {
|
|
4144
|
+
return Number(b.isBuffered) - Number(a.isBuffered) || a.renderPriority - b.renderPriority;
|
|
4145
|
+
}
|
|
4146
|
+
function comparatorByIndex(a, b) {
|
|
4147
|
+
return a - b;
|
|
4148
|
+
}
|
|
4149
|
+
function reorderPoolAssignments(requests, allocations, containerIndices, groupByType) {
|
|
4150
|
+
if (requests.length >= 2) {
|
|
4151
|
+
if (groupByType) {
|
|
4152
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4153
|
+
for (const request of requests) {
|
|
4154
|
+
const group = groups.get(request.itemType);
|
|
4155
|
+
if (group) {
|
|
4156
|
+
group.push(request);
|
|
4157
|
+
} else {
|
|
4158
|
+
groups.set(request.itemType, [request]);
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
for (const group of groups.values()) {
|
|
4162
|
+
reorderPoolAssignments(group, allocations, containerIndices, false);
|
|
4163
|
+
}
|
|
4164
|
+
} else {
|
|
4165
|
+
containerIndices.length = 0;
|
|
4166
|
+
let indicesSorted = true;
|
|
4167
|
+
for (let i = 0; i < requests.length; i++) {
|
|
4168
|
+
const containerIndex = allocations[requests[i].order].containerIndex;
|
|
4169
|
+
if (i > 0 && containerIndex < containerIndices[i - 1]) {
|
|
4170
|
+
indicesSorted = false;
|
|
4171
|
+
}
|
|
4172
|
+
containerIndices.push(containerIndex);
|
|
4173
|
+
}
|
|
4174
|
+
if (!indicesSorted) {
|
|
4175
|
+
containerIndices.sort(comparatorByIndex);
|
|
4176
|
+
}
|
|
4177
|
+
requests.sort(comparatorByRenderPriority);
|
|
4178
|
+
for (let i = 0; i < requests.length; i++) {
|
|
4179
|
+
allocations[requests[i].order].containerIndex = containerIndices[i];
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4039
4184
|
|
|
4040
4185
|
// src/utils/setDidLayout.ts
|
|
4041
4186
|
function setDidLayout(ctx) {
|
|
4042
4187
|
const state = ctx.state;
|
|
4043
4188
|
state.queuedInitialLayout = true;
|
|
4044
|
-
|
|
4189
|
+
checkThresholds(ctx);
|
|
4045
4190
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4046
4191
|
if (state.pendingMaintainScrollAtEnd) {
|
|
4047
4192
|
doMaintainScrollAtEnd(ctx);
|
|
@@ -4269,9 +4414,9 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4269
4414
|
enableScrollForNextCalculateItemsInView,
|
|
4270
4415
|
idCache,
|
|
4271
4416
|
indexByKey,
|
|
4272
|
-
|
|
4417
|
+
positionRecalculationStartIndex,
|
|
4273
4418
|
positions,
|
|
4274
|
-
props: { alwaysRenderIndicesArr, alwaysRenderIndicesSet,
|
|
4419
|
+
props: { alwaysRenderIndicesArr, alwaysRenderIndicesSet, keyExtractor, onStickyHeaderChange },
|
|
4275
4420
|
scrollForNextCalculateItemsInView,
|
|
4276
4421
|
scrollLength,
|
|
4277
4422
|
sizes,
|
|
@@ -4387,21 +4532,21 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4387
4532
|
if (dataChanged) {
|
|
4388
4533
|
resetLayoutCachesForDataChange(state);
|
|
4389
4534
|
}
|
|
4390
|
-
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_e =
|
|
4391
|
-
const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 &&
|
|
4535
|
+
const startIndex = forceFullItemPositions || dataChanged ? 0 : (_e = positionRecalculationStartIndex != null ? positionRecalculationStartIndex : state.startBuffered) != null ? _e : 0;
|
|
4536
|
+
const optimizeForVisibleWindow = !forceFullItemPositions && !dataChanged && numColumns > 1 && positionRecalculationStartIndex !== void 0;
|
|
4392
4537
|
updateItemPositions(ctx, dataChanged, {
|
|
4393
4538
|
doMVCP,
|
|
4394
4539
|
// A changed size shifts every following position. The scrolling early-exit
|
|
4395
4540
|
// would leave the untouched suffix in the old coordinate space.
|
|
4396
|
-
forceFullUpdate: !!forceFullItemPositions ||
|
|
4541
|
+
forceFullUpdate: !!forceFullItemPositions || positionRecalculationStartIndex !== void 0,
|
|
4397
4542
|
optimizeForVisibleWindow,
|
|
4398
4543
|
scrollBottomBuffered,
|
|
4399
4544
|
scrollVelocity: speed,
|
|
4400
4545
|
startIndex
|
|
4401
4546
|
});
|
|
4402
4547
|
totalSize = getContentSize(ctx);
|
|
4403
|
-
if (
|
|
4404
|
-
state.
|
|
4548
|
+
if (positionRecalculationStartIndex !== void 0) {
|
|
4549
|
+
state.positionRecalculationStartIndex = void 0;
|
|
4405
4550
|
}
|
|
4406
4551
|
let protectedContainerKeys;
|
|
4407
4552
|
if (dataChanged && doMVCP && state.props.maintainVisibleContentPosition.data && state.didContainersLayout && state.idsInView.length > 0) {
|
|
@@ -4577,18 +4722,18 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4577
4722
|
set$(ctx, "activeStickyIndex", -1);
|
|
4578
4723
|
}
|
|
4579
4724
|
if (needNewContainers.length > 0) {
|
|
4580
|
-
const getRequiredItemType = getItemType ? (i) => {
|
|
4581
|
-
const itemType = getItemType(data[i], i);
|
|
4582
|
-
return itemType !== void 0 ? String(itemType) : "";
|
|
4583
|
-
} : void 0;
|
|
4584
4725
|
const availableContainerAllocations = findAvailableContainers(
|
|
4585
4726
|
ctx,
|
|
4586
4727
|
needNewContainers,
|
|
4587
4728
|
startBuffered,
|
|
4588
4729
|
endBuffered,
|
|
4589
4730
|
pendingRemoval,
|
|
4590
|
-
|
|
4591
|
-
|
|
4731
|
+
protectedContainerKeys,
|
|
4732
|
+
// Initial end alignment has no scroll velocity yet. Keep its
|
|
4733
|
+
// target-side rows first until the initial scroll settles.
|
|
4734
|
+
// After a pause velocity can be zero on the first movement;
|
|
4735
|
+
// use its displacement without treating initial insets as motion.
|
|
4736
|
+
hasActiveInitialScroll(state) ? (initialScroll == null ? void 0 : initialScroll.viewPosition) === 1 : (speed || (state.hasScrolled ? state.scroll - state.scrollPrev : 0)) < 0
|
|
4592
4737
|
);
|
|
4593
4738
|
for (const allocation of availableContainerAllocations) {
|
|
4594
4739
|
const i = allocation.itemIndex;
|
|
@@ -4735,6 +4880,7 @@ function maybeUpdateAnchoredEndSpace(ctx) {
|
|
|
4735
4880
|
const nextAnchorIndex = anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex;
|
|
4736
4881
|
let nextAnchorKey;
|
|
4737
4882
|
let isReady = true;
|
|
4883
|
+
let canUpdateSize = true;
|
|
4738
4884
|
let nextSize = 0;
|
|
4739
4885
|
if (anchoredEndSpace) {
|
|
4740
4886
|
const { anchorIndex, anchorMaxSize, anchorOffset = 0 } = anchoredEndSpace;
|
|
@@ -4756,25 +4902,30 @@ function maybeUpdateAnchoredEndSpace(ctx) {
|
|
|
4756
4902
|
contentBelowAnchor = Math.max(0, contentBelowAnchor - ctx.scrollAxisGap);
|
|
4757
4903
|
contentBelowAnchor += (ctx.values.get("footerSize") || 0) + getStylePaddingEnd(state.props);
|
|
4758
4904
|
isReady = !hasUnknownTailSize;
|
|
4759
|
-
|
|
4905
|
+
const knownSizeBound = Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset);
|
|
4906
|
+
nextSize = hasUnknownTailSize ? Math.min(previousSize || 0, knownSizeBound) : knownSizeBound;
|
|
4760
4907
|
} else if (anchorIndex >= 0) {
|
|
4761
4908
|
isReady = false;
|
|
4909
|
+
canUpdateSize = false;
|
|
4762
4910
|
}
|
|
4763
4911
|
}
|
|
4764
4912
|
const didSizeChange = previousSize !== nextSize && (previousSize !== void 0 || anchoredEndSpace !== void 0);
|
|
4765
4913
|
const didEffectiveSizeChange = (previousSize || 0) !== nextSize;
|
|
4914
|
+
const canApplySizeChange = canUpdateSize && (isReady || previousSize !== void 0);
|
|
4766
4915
|
const didReadyAnchorChange = previousReadyAnchorIndex !== nextAnchorIndex || previousReadyAnchorKey !== nextAnchorKey;
|
|
4767
|
-
|
|
4916
|
+
const didBecomeReady = isReady && state.anchoredEndSpacePendingReady;
|
|
4917
|
+
state.anchoredEndSpacePendingReady = !isReady;
|
|
4918
|
+
if (canApplySizeChange && didSizeChange) {
|
|
4919
|
+
set$(ctx, "anchoredEndSpaceSize", nextSize);
|
|
4920
|
+
(_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
|
|
4921
|
+
}
|
|
4922
|
+
if (canApplySizeChange && didEffectiveSizeChange) {
|
|
4923
|
+
updateContentMetricsState(ctx);
|
|
4924
|
+
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
4925
|
+
}
|
|
4926
|
+
if (isReady && (didSizeChange || didReadyAnchorChange || didBecomeReady)) {
|
|
4768
4927
|
state.anchoredEndSpaceReadyAnchorIndex = nextAnchorIndex;
|
|
4769
4928
|
state.anchoredEndSpaceReadyAnchorKey = nextAnchorKey;
|
|
4770
|
-
if (didSizeChange) {
|
|
4771
|
-
set$(ctx, "anchoredEndSpaceSize", nextSize);
|
|
4772
|
-
(_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
|
|
4773
|
-
}
|
|
4774
|
-
if (didEffectiveSizeChange) {
|
|
4775
|
-
updateContentMetricsState(ctx);
|
|
4776
|
-
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
4777
|
-
}
|
|
4778
4929
|
(_b = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onReady) == null ? void 0 : _b.call(anchoredEndSpace, { anchorIndex: nextAnchorIndex, anchorKey: nextAnchorKey, size: nextSize });
|
|
4779
4930
|
}
|
|
4780
4931
|
return nextSize;
|
|
@@ -4878,6 +5029,7 @@ function updateItemSizesBatch(ctx, measurements) {
|
|
|
4878
5029
|
var _a3;
|
|
4879
5030
|
const state = ctx.state;
|
|
4880
5031
|
const result = {};
|
|
5032
|
+
const previousTotalSize = state.totalSize;
|
|
4881
5033
|
for (const measurement of measurements) {
|
|
4882
5034
|
const ownsMeasuredItem = measurement.containerId === void 0 || peek$(ctx, `containerItemKey${measurement.containerId}`) === measurement.itemKey;
|
|
4883
5035
|
if (ownsMeasuredItem) {
|
|
@@ -4888,6 +5040,9 @@ function updateItemSizesBatch(ctx, measurements) {
|
|
|
4888
5040
|
mergeItemSizeUpdateResult(result, nextResult);
|
|
4889
5041
|
}
|
|
4890
5042
|
}
|
|
5043
|
+
if (state.totalSize !== previousTotalSize) {
|
|
5044
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
5045
|
+
}
|
|
4891
5046
|
flushItemSizeUpdates(ctx, result);
|
|
4892
5047
|
}
|
|
4893
5048
|
function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
@@ -4926,12 +5081,12 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4926
5081
|
}
|
|
4927
5082
|
let needsRecalculate = !didContainersLayout;
|
|
4928
5083
|
let shouldMaintainScrollAtEnd = false;
|
|
4929
|
-
let
|
|
5084
|
+
let positionRecalculationStartIndex;
|
|
4930
5085
|
const prevSizeKnown = state.sizesKnown.get(itemKey);
|
|
4931
|
-
const diff = updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem);
|
|
5086
|
+
const diff = updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem, false);
|
|
4932
5087
|
const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
|
|
4933
5088
|
if (diff !== 0) {
|
|
4934
|
-
|
|
5089
|
+
positionRecalculationStartIndex = positionRecalculationStartIndex !== void 0 ? Math.min(positionRecalculationStartIndex, index) : index;
|
|
4935
5090
|
const { startBuffered, endBuffered } = state;
|
|
4936
5091
|
needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
|
|
4937
5092
|
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
@@ -4948,8 +5103,8 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4948
5103
|
size
|
|
4949
5104
|
});
|
|
4950
5105
|
}
|
|
4951
|
-
if (
|
|
4952
|
-
state.
|
|
5106
|
+
if (positionRecalculationStartIndex !== void 0) {
|
|
5107
|
+
state.positionRecalculationStartIndex = state.positionRecalculationStartIndex !== void 0 ? Math.min(state.positionRecalculationStartIndex, positionRecalculationStartIndex) : positionRecalculationStartIndex;
|
|
4953
5108
|
}
|
|
4954
5109
|
updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
|
|
4955
5110
|
if (didContainersLayout || checkAllSizesKnown(state, state.startBuffered, state.endBuffered)) {
|
|
@@ -4966,7 +5121,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4966
5121
|
didMeasureUserScrollAnchorResetItem
|
|
4967
5122
|
};
|
|
4968
5123
|
}
|
|
4969
|
-
function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
5124
|
+
function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem, notifyTotalSize = true) {
|
|
4970
5125
|
var _a3, _b;
|
|
4971
5126
|
const state = ctx.state;
|
|
4972
5127
|
const {
|
|
@@ -4989,7 +5144,16 @@ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4989
5144
|
fixedItemSize,
|
|
4990
5145
|
itemType
|
|
4991
5146
|
} : void 0;
|
|
4992
|
-
const prevSize = getItemSize(
|
|
5147
|
+
const prevSize = getItemSize(
|
|
5148
|
+
ctx,
|
|
5149
|
+
itemKey,
|
|
5150
|
+
index,
|
|
5151
|
+
itemData,
|
|
5152
|
+
void 0,
|
|
5153
|
+
void 0,
|
|
5154
|
+
notifyTotalSize,
|
|
5155
|
+
resolvedItemSize
|
|
5156
|
+
);
|
|
4993
5157
|
const rawSize = horizontal ? sizeObj.width : sizeObj.height;
|
|
4994
5158
|
const prevSizeKnown = sizesKnown.get(itemKey);
|
|
4995
5159
|
if (Platform.OS !== "web" && prevSizeKnown !== void 0 && isNativeLayoutNoise(rawSize - prevSizeKnown)) {
|
|
@@ -5014,7 +5178,7 @@ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
5014
5178
|
}
|
|
5015
5179
|
}
|
|
5016
5180
|
if (!prevSize || Math.abs(prevSize - size) > 0.1) {
|
|
5017
|
-
setSize(ctx, itemKey, size);
|
|
5181
|
+
setSize(ctx, itemKey, size, notifyTotalSize);
|
|
5018
5182
|
return size - prevSize;
|
|
5019
5183
|
}
|
|
5020
5184
|
return 0;
|
|
@@ -5165,10 +5329,16 @@ function useValue$(key, params) {
|
|
|
5165
5329
|
var _a3;
|
|
5166
5330
|
return (_a3 = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a3 : 0;
|
|
5167
5331
|
};
|
|
5168
|
-
const
|
|
5332
|
+
const initialValue = getNewValue();
|
|
5333
|
+
const animValue = useAnimatedValue(initialValue);
|
|
5334
|
+
const lastValue = React2.useRef(initialValue);
|
|
5169
5335
|
React2.useLayoutEffect(() => {
|
|
5170
5336
|
const syncCurrentValue = () => {
|
|
5171
|
-
|
|
5337
|
+
const nextValue = getNewValue();
|
|
5338
|
+
if (lastValue.current !== nextValue) {
|
|
5339
|
+
lastValue.current = nextValue;
|
|
5340
|
+
animValue.setValue(nextValue);
|
|
5341
|
+
}
|
|
5172
5342
|
};
|
|
5173
5343
|
const unsubscribe = listen$(ctx, key, syncCurrentValue);
|
|
5174
5344
|
syncCurrentValue();
|
|
@@ -6083,6 +6253,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
6083
6253
|
renderScrollComponent,
|
|
6084
6254
|
onLayoutFooter,
|
|
6085
6255
|
onInternalScrollBeginDrag,
|
|
6256
|
+
onInternalScrollEndDrag,
|
|
6086
6257
|
onInternalScrollEnd,
|
|
6087
6258
|
scrollAdjustHandler,
|
|
6088
6259
|
snapToIndices,
|
|
@@ -6154,7 +6325,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
6154
6325
|
SnapOrScroll,
|
|
6155
6326
|
{
|
|
6156
6327
|
...rest,
|
|
6157
|
-
...Platform.OS === "web" ? ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, useWindowScroll } : {} : { onScrollBeginDrag: onInternalScrollBeginDrag },
|
|
6328
|
+
...Platform.OS === "web" ? ScrollComponent === ListComponentScrollView ? { onInternalScrollEnd, useWindowScroll } : {} : { onScrollBeginDrag: onInternalScrollBeginDrag, onScrollEndDrag: onInternalScrollEndDrag },
|
|
6158
6329
|
contentContainerStyle: [
|
|
6159
6330
|
horizontal ? { height: "100%" } : {},
|
|
6160
6331
|
contentContainerStyle,
|
|
@@ -6273,7 +6444,7 @@ function checkResetContainers(ctx, dataProp, { didColumnsChange = false } = {})
|
|
|
6273
6444
|
for (const key in state.averageSizes) {
|
|
6274
6445
|
delete state.averageSizes[key];
|
|
6275
6446
|
}
|
|
6276
|
-
state.
|
|
6447
|
+
state.positionRecalculationStartIndex = 0;
|
|
6277
6448
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
6278
6449
|
}
|
|
6279
6450
|
calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
|
|
@@ -6437,7 +6608,7 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
6437
6608
|
set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
|
|
6438
6609
|
}
|
|
6439
6610
|
if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onLayout) {
|
|
6440
|
-
doMaintainScrollAtEnd(ctx);
|
|
6611
|
+
doMaintainScrollAtEnd(ctx, { immediate: true });
|
|
6441
6612
|
}
|
|
6442
6613
|
checkThresholds(ctx);
|
|
6443
6614
|
if (state) {
|
|
@@ -6670,14 +6841,17 @@ function scrollToEnd(ctx, options) {
|
|
|
6670
6841
|
if (index === -1) {
|
|
6671
6842
|
return false;
|
|
6672
6843
|
}
|
|
6673
|
-
const paddingBottom = state.props
|
|
6844
|
+
const paddingBottom = getStylePaddingEnd(state.props);
|
|
6674
6845
|
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
6675
6846
|
scrollToIndex(ctx, {
|
|
6676
6847
|
...options,
|
|
6677
6848
|
index,
|
|
6678
|
-
viewOffset:
|
|
6849
|
+
viewOffset: getEndAlignedViewOffset(paddingBottom, footerSize) + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6679
6850
|
viewPosition: 1
|
|
6680
6851
|
});
|
|
6852
|
+
if (state.scrollingTo) {
|
|
6853
|
+
state.scrollingTo.isScrollToEnd = true;
|
|
6854
|
+
}
|
|
6681
6855
|
return true;
|
|
6682
6856
|
}
|
|
6683
6857
|
|
|
@@ -6875,7 +7049,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6875
7049
|
for (const key in state.averageSizes) {
|
|
6876
7050
|
delete state.averageSizes[key];
|
|
6877
7051
|
}
|
|
6878
|
-
state.
|
|
7052
|
+
state.positionRecalculationStartIndex = 0;
|
|
6879
7053
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
6880
7054
|
state.pendingTotalSize = void 0;
|
|
6881
7055
|
state.totalSize = 0;
|
|
@@ -7269,10 +7443,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7269
7443
|
onMetricsChange,
|
|
7270
7444
|
onLayout: onLayoutProp,
|
|
7271
7445
|
onLoad,
|
|
7446
|
+
onReady,
|
|
7272
7447
|
onMomentumScrollEnd,
|
|
7273
7448
|
onRefresh,
|
|
7274
7449
|
onScroll: onScrollProp,
|
|
7275
7450
|
onScrollBeginDrag,
|
|
7451
|
+
onScrollEndDrag,
|
|
7276
7452
|
onStartReached,
|
|
7277
7453
|
onStartReachedThreshold = 0.5,
|
|
7278
7454
|
onStickyHeaderChange,
|
|
@@ -7341,17 +7517,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7341
7517
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7342
7518
|
index: Math.max(0, dataProp.length - 1),
|
|
7343
7519
|
preserveForBottomPadding: true,
|
|
7344
|
-
viewOffset:
|
|
7520
|
+
viewOffset: getEndAlignedViewOffset(stylePaddingEndState),
|
|
7345
7521
|
viewPosition: 1
|
|
7346
7522
|
} : hasInitialScrollIndex ? typeof initialScrollIndexProp === "object" ? {
|
|
7347
7523
|
index: (_b = initialScrollIndexProp.index) != null ? _b : 0,
|
|
7348
7524
|
preserveForBottomPadding: initialScrollIndexProp.viewOffset === void 0 && initialScrollIndexProp.viewPosition === 1 ? true : void 0,
|
|
7349
|
-
viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 ?
|
|
7525
|
+
viewOffset: (_c = initialScrollIndexProp.viewOffset) != null ? _c : initialScrollIndexProp.viewPosition === 1 ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
|
|
7350
7526
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7351
7527
|
} : {
|
|
7352
7528
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7353
7529
|
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7354
|
-
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ?
|
|
7530
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? getEndAlignedViewOffset(stylePaddingEndState) : 0,
|
|
7355
7531
|
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7356
7532
|
} : initialScrollUsesOffsetOnly ? {
|
|
7357
7533
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
@@ -7411,6 +7587,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7411
7587
|
endReachedSnapshot: void 0,
|
|
7412
7588
|
firstFullyOnScreenIndex: -1,
|
|
7413
7589
|
freshDataTransitionEpoch: 0,
|
|
7590
|
+
handledDataChangeEpoch: 0,
|
|
7591
|
+
handledFreshDataTransitionEpoch: 0,
|
|
7414
7592
|
hasHadNonEmptyData: dataProp.length > 0,
|
|
7415
7593
|
idCache: [],
|
|
7416
7594
|
idsInView: [],
|
|
@@ -7427,11 +7605,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7427
7605
|
lastLayout: void 0,
|
|
7428
7606
|
lastScrollDelta: 0,
|
|
7429
7607
|
loadStartTime: Date.now(),
|
|
7430
|
-
minIndexSizeChanged: 0,
|
|
7431
7608
|
nativeContentInset: void 0,
|
|
7432
7609
|
nativeMarginTop: 0,
|
|
7433
7610
|
pendingDataComparison: void 0,
|
|
7434
7611
|
pendingNativeMVCPAdjust: void 0,
|
|
7612
|
+
positionRecalculationStartIndex: 0,
|
|
7435
7613
|
positions: [],
|
|
7436
7614
|
props: {},
|
|
7437
7615
|
queuedCalculateItemsInView: 0,
|
|
@@ -7470,8 +7648,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7470
7648
|
refState.current = ctx.state;
|
|
7471
7649
|
}
|
|
7472
7650
|
const state = refState.current;
|
|
7473
|
-
const handledDataChangeEpochRef = React2.useRef(state.dataChangeEpoch);
|
|
7474
|
-
const handledFreshDataTransitionEpochRef = React2.useRef(state.freshDataTransitionEpoch);
|
|
7475
7651
|
const isFirstLocal = state.isFirst;
|
|
7476
7652
|
const previousAdaptiveRender = state.props.adaptiveRender;
|
|
7477
7653
|
const previousHideItemsUntilMeasured = state.props.hideItemsUntilMeasured;
|
|
@@ -7536,8 +7712,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7536
7712
|
onItemSizeChanged,
|
|
7537
7713
|
onLoad,
|
|
7538
7714
|
onMomentumScrollEnd,
|
|
7715
|
+
onReady,
|
|
7539
7716
|
onScroll: throttleScrollFn,
|
|
7540
7717
|
onScrollBeginDrag,
|
|
7718
|
+
onScrollEndDrag,
|
|
7541
7719
|
onStartReached,
|
|
7542
7720
|
onStartReachedThreshold,
|
|
7543
7721
|
onStickyHeaderChange,
|
|
@@ -7626,10 +7804,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7626
7804
|
useDevChecks(props);
|
|
7627
7805
|
}
|
|
7628
7806
|
React2.useLayoutEffect(() => {
|
|
7629
|
-
const didDataChange =
|
|
7630
|
-
const didStartFreshData =
|
|
7631
|
-
|
|
7632
|
-
|
|
7807
|
+
const didDataChange = state.handledDataChangeEpoch !== dataChangeEpoch;
|
|
7808
|
+
const didStartFreshData = state.handledFreshDataTransitionEpoch !== freshDataTransitionEpoch;
|
|
7809
|
+
state.handledDataChangeEpoch = dataChangeEpoch;
|
|
7810
|
+
state.handledFreshDataTransitionEpoch = freshDataTransitionEpoch;
|
|
7633
7811
|
if (didStartFreshData) {
|
|
7634
7812
|
resetInitialRenderState(ctx, {
|
|
7635
7813
|
resetInitialScroll: !!initialScrollProp,
|
|
@@ -7833,17 +8011,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7833
8011
|
onScroll: (event) => onScroll(ctx, event),
|
|
7834
8012
|
onScrollBeginDrag: (event) => {
|
|
7835
8013
|
var _a4, _b2;
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
cancelImperativeScroll(state);
|
|
7839
|
-
}
|
|
7840
|
-
if (maintainingScrollAtEnd) {
|
|
7841
|
-
finishMaintainScrollAtEnd(ctx);
|
|
7842
|
-
}
|
|
8014
|
+
state.isDragging = true;
|
|
8015
|
+
interruptMaintainScrollAtEnd(ctx);
|
|
7843
8016
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
7844
8017
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
7845
8018
|
},
|
|
7846
|
-
onScrollEnd: () => prepareReachedEdgeForNextUserScroll(ctx)
|
|
8019
|
+
onScrollEnd: () => prepareReachedEdgeForNextUserScroll(ctx),
|
|
8020
|
+
onScrollEndDrag: (event) => {
|
|
8021
|
+
var _a4, _b2;
|
|
8022
|
+
state.isDragging = false;
|
|
8023
|
+
(_b2 = (_a4 = state.props).onScrollEndDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
8024
|
+
}
|
|
7847
8025
|
}),
|
|
7848
8026
|
[]
|
|
7849
8027
|
);
|
|
@@ -7867,6 +8045,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7867
8045
|
ListHeaderComponent,
|
|
7868
8046
|
onInternalScrollBeginDrag: fns.onScrollBeginDrag,
|
|
7869
8047
|
onInternalScrollEnd: fns.onScrollEnd,
|
|
8048
|
+
onInternalScrollEndDrag: fns.onScrollEndDrag,
|
|
7870
8049
|
onLayout,
|
|
7871
8050
|
onLayoutFooter,
|
|
7872
8051
|
onMomentumScrollEnd: fns.onMomentumScrollEnd,
|