@legendapp/list 3.3.9 → 3.3.11
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 +13 -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.js +543 -476
- package/react-native.mjs +543 -476
- package/react-native.web.d.ts +1 -0
- package/react-native.web.js +357 -258
- package/react-native.web.mjs +357 -258
- package/react.d.ts +1 -0
- package/react.js +357 -258
- package/react.mjs +357 -258
package/react-native.js
CHANGED
|
@@ -1014,6 +1014,7 @@ function supersedeInitialScroll(ctx) {
|
|
|
1014
1014
|
function finishInitialScroll(ctx, options) {
|
|
1015
1015
|
var _a3, _b, _c;
|
|
1016
1016
|
const state = ctx.state;
|
|
1017
|
+
const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
|
|
1017
1018
|
if ((options == null ? void 0 : options.resolvedOffset) !== void 0) {
|
|
1018
1019
|
syncInitialScrollOffset(state, options.resolvedOffset);
|
|
1019
1020
|
} else if ((options == null ? void 0 : options.syncObservedOffset) && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset") {
|
|
@@ -1023,9 +1024,13 @@ function finishInitialScroll(ctx, options) {
|
|
|
1023
1024
|
}
|
|
1024
1025
|
}
|
|
1025
1026
|
const complete = () => {
|
|
1026
|
-
var _a4, _b2, _c2, _d, _e;
|
|
1027
|
-
|
|
1028
|
-
|
|
1027
|
+
var _a4, _b2, _c2, _d, _e, _f;
|
|
1028
|
+
if (freshDataTransitionEpoch !== state.freshDataTransitionEpoch) {
|
|
1029
|
+
(_a4 = options == null ? void 0 : options.onFinished) == null ? void 0 : _a4.call(options);
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
const shouldReleaseDeferredPublicOnScroll = Platform.OS === "web" && ((_b2 = state.initialScrollSession) == null ? void 0 : _b2.kind) === "bootstrap";
|
|
1033
|
+
const finalScrollOffset = (_e = (_d = (_c2 = options == null ? void 0 : options.resolvedOffset) != null ? _c2 : state.scrollPending) != null ? _d : state.scroll) != null ? _e : 0;
|
|
1029
1034
|
initialScrollWatchdog.clear(state);
|
|
1030
1035
|
if ((options == null ? void 0 : options.preserveTarget) && state.initialScroll) {
|
|
1031
1036
|
state.clearPreservedInitialScrollOnNextFinish = void 0;
|
|
@@ -1054,7 +1059,7 @@ function finishInitialScroll(ctx, options) {
|
|
|
1054
1059
|
if (shouldReleaseDeferredPublicOnScroll) {
|
|
1055
1060
|
releaseDeferredPublicOnScroll(ctx, finalScrollOffset);
|
|
1056
1061
|
}
|
|
1057
|
-
(
|
|
1062
|
+
(_f = options == null ? void 0 : options.onFinished) == null ? void 0 : _f.call(options);
|
|
1058
1063
|
};
|
|
1059
1064
|
if (options == null ? void 0 : options.waitForCompletionFrame) {
|
|
1060
1065
|
requestAnimationFrame(complete);
|
|
@@ -1338,246 +1343,21 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
|
1338
1343
|
return clampedOffset;
|
|
1339
1344
|
}
|
|
1340
1345
|
|
|
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
1346
|
// src/core/scrollRequestTracker.ts
|
|
1572
1347
|
function getScrollRequestTracker(ctx) {
|
|
1573
1348
|
if (!ctx.scrollRequestTracker) {
|
|
1574
1349
|
let currentToken = 0;
|
|
1575
|
-
|
|
1350
|
+
let waitingToken;
|
|
1351
|
+
const start = (resolve, isInternal = false) => {
|
|
1576
1352
|
const state = ctx.state;
|
|
1353
|
+
if (!isInternal && (state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd)) {
|
|
1354
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1355
|
+
}
|
|
1577
1356
|
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1578
1357
|
const token = ++currentToken;
|
|
1579
1358
|
settlePendingImperativeScroll(state);
|
|
1580
1359
|
state.pendingScrollResolve = resolve;
|
|
1360
|
+
waitingToken = token;
|
|
1581
1361
|
return token;
|
|
1582
1362
|
};
|
|
1583
1363
|
const runNow = (token, resolve, run) => {
|
|
@@ -1585,6 +1365,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1585
1365
|
if (token !== currentToken) {
|
|
1586
1366
|
return;
|
|
1587
1367
|
}
|
|
1368
|
+
waitingToken = void 0;
|
|
1588
1369
|
const didStartScroll = run();
|
|
1589
1370
|
if (!didStartScroll || !state.scrollingTo) {
|
|
1590
1371
|
if (state.pendingScrollResolve === resolve) {
|
|
@@ -1595,6 +1376,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1595
1376
|
};
|
|
1596
1377
|
ctx.scrollRequestTracker = {
|
|
1597
1378
|
isCurrent: (token) => token === currentToken,
|
|
1379
|
+
isWaitingToRun: () => waitingToken === currentToken && !!ctx.state.pendingScrollResolve,
|
|
1598
1380
|
runNow,
|
|
1599
1381
|
runNowIfIdle: (run) => {
|
|
1600
1382
|
const state = ctx.state;
|
|
@@ -1602,7 +1384,7 @@ function getScrollRequestTracker(ctx) {
|
|
|
1602
1384
|
return Promise.resolve();
|
|
1603
1385
|
}
|
|
1604
1386
|
return new Promise((resolve) => {
|
|
1605
|
-
const token = start(resolve);
|
|
1387
|
+
const token = start(resolve, true);
|
|
1606
1388
|
runNow(token, resolve, run);
|
|
1607
1389
|
});
|
|
1608
1390
|
},
|
|
@@ -1666,96 +1448,15 @@ function requestAdjust(ctx, positionDiff, source) {
|
|
|
1666
1448
|
}
|
|
1667
1449
|
}
|
|
1668
1450
|
|
|
1669
|
-
// src/core/
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
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
|
-
// src/core/mvcp.ts
|
|
1751
|
-
var MVCP_POSITION_EPSILON = 0.1;
|
|
1752
|
-
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
1753
|
-
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
1754
|
-
var NATIVE_END_CLAMP_EPSILON = 1;
|
|
1755
|
-
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
1756
|
-
if (!enableMVCPAnchorLock) {
|
|
1757
|
-
state.mvcpAnchorLock = void 0;
|
|
1758
|
-
return void 0;
|
|
1451
|
+
// src/core/mvcp.ts
|
|
1452
|
+
var MVCP_POSITION_EPSILON = 0.1;
|
|
1453
|
+
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
1454
|
+
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
1455
|
+
var NATIVE_END_CLAMP_EPSILON = 1;
|
|
1456
|
+
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
1457
|
+
if (!enableMVCPAnchorLock) {
|
|
1458
|
+
state.mvcpAnchorLock = void 0;
|
|
1459
|
+
return void 0;
|
|
1759
1460
|
}
|
|
1760
1461
|
const lock = state.mvcpAnchorLock;
|
|
1761
1462
|
if (!lock) {
|
|
@@ -2045,144 +1746,494 @@ function prepareMVCP(ctx, dataChanged, adjustmentSource) {
|
|
|
2045
1746
|
};
|
|
2046
1747
|
}
|
|
2047
1748
|
}
|
|
2048
|
-
|
|
2049
|
-
// src/platform/flushSync.native.ts
|
|
2050
|
-
var flushSync = (fn) => {
|
|
2051
|
-
fn();
|
|
2052
|
-
};
|
|
2053
|
-
|
|
2054
|
-
// src/utils/getScrollVelocity.ts
|
|
2055
|
-
var MAX_SCROLL_VELOCITY_WINDOW_MS = 1e3;
|
|
2056
|
-
var SCROLL_VELOCITY_HALF_LIFE_MS = 200;
|
|
2057
|
-
var getScrollVelocity = (state) => {
|
|
2058
|
-
const { scrollHistory } = state;
|
|
2059
|
-
const newestIndex = scrollHistory.length - 1;
|
|
2060
|
-
if (newestIndex < 1) {
|
|
2061
|
-
return 0;
|
|
2062
|
-
}
|
|
2063
|
-
const newest = scrollHistory[newestIndex];
|
|
2064
|
-
if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
2065
|
-
return 0;
|
|
1749
|
+
|
|
1750
|
+
// src/platform/flushSync.native.ts
|
|
1751
|
+
var flushSync = (fn) => {
|
|
1752
|
+
fn();
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
// src/utils/getScrollVelocity.ts
|
|
1756
|
+
var MAX_SCROLL_VELOCITY_WINDOW_MS = 1e3;
|
|
1757
|
+
var SCROLL_VELOCITY_HALF_LIFE_MS = 200;
|
|
1758
|
+
var getScrollVelocity = (state) => {
|
|
1759
|
+
const { scrollHistory } = state;
|
|
1760
|
+
const newestIndex = scrollHistory.length - 1;
|
|
1761
|
+
if (newestIndex < 1) {
|
|
1762
|
+
return 0;
|
|
1763
|
+
}
|
|
1764
|
+
const newest = scrollHistory[newestIndex];
|
|
1765
|
+
if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
1766
|
+
return 0;
|
|
1767
|
+
}
|
|
1768
|
+
let direction = 0;
|
|
1769
|
+
let weightedVelocity = 0;
|
|
1770
|
+
let totalWeight = 0;
|
|
1771
|
+
for (let i = newestIndex; i > 0; i--) {
|
|
1772
|
+
const current = scrollHistory[i];
|
|
1773
|
+
const previous = scrollHistory[i - 1];
|
|
1774
|
+
const scrollDiff = current.scroll - previous.scroll;
|
|
1775
|
+
const timeDiff = current.time - previous.time;
|
|
1776
|
+
const deltaSign = Math.sign(scrollDiff);
|
|
1777
|
+
if (deltaSign !== 0) {
|
|
1778
|
+
if (direction === 0) {
|
|
1779
|
+
direction = deltaSign;
|
|
1780
|
+
} else if (deltaSign !== direction) {
|
|
1781
|
+
break;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
|
|
1785
|
+
break;
|
|
1786
|
+
}
|
|
1787
|
+
if (scrollDiff === 0 || timeDiff <= 0) {
|
|
1788
|
+
continue;
|
|
1789
|
+
}
|
|
1790
|
+
const age = newest.time - current.time;
|
|
1791
|
+
const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
|
|
1792
|
+
weightedVelocity += scrollDiff / timeDiff * weight;
|
|
1793
|
+
totalWeight += weight;
|
|
1794
|
+
}
|
|
1795
|
+
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
1796
|
+
};
|
|
1797
|
+
|
|
1798
|
+
// src/utils/isInMVCPActiveMode.native.ts
|
|
1799
|
+
function isInMVCPActiveMode(state) {
|
|
1800
|
+
return state.dataChangeNeedsScrollUpdate;
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
// src/core/updateScroll.ts
|
|
1804
|
+
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
1805
|
+
var _a3;
|
|
1806
|
+
const state = ctx.state;
|
|
1807
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
1808
|
+
const prevScroll = state.scroll;
|
|
1809
|
+
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
1810
|
+
state.hasScrolled = true;
|
|
1811
|
+
}
|
|
1812
|
+
const currentTime = Date.now();
|
|
1813
|
+
state.lastBatchingAction = currentTime;
|
|
1814
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
1815
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
1816
|
+
if (adjustChanged) {
|
|
1817
|
+
scrollHistory.length = 0;
|
|
1818
|
+
}
|
|
1819
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
1820
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
1821
|
+
if (!adjustChanged) {
|
|
1822
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
if (scrollHistory.length > 5) {
|
|
1826
|
+
scrollHistory.shift();
|
|
1827
|
+
}
|
|
1828
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
1829
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
1830
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
1831
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
state.scrollPrev = prevScroll;
|
|
1836
|
+
state.scrollPrevTime = state.scrollTime;
|
|
1837
|
+
state.scroll = newScroll;
|
|
1838
|
+
state.scrollTime = currentTime;
|
|
1839
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1840
|
+
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
1841
|
+
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
1842
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
1843
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1844
|
+
}
|
|
1845
|
+
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
1846
|
+
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1847
|
+
const scrollLength = state.scrollLength;
|
|
1848
|
+
const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
|
|
1849
|
+
const scrollVelocity = getScrollVelocity(state);
|
|
1850
|
+
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
1851
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
1852
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1853
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1854
|
+
if (shouldUpdate) {
|
|
1855
|
+
state.scrollLastCalculate = state.scroll;
|
|
1856
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
1857
|
+
state.lastScrollDelta = scrollDelta;
|
|
1858
|
+
const runCalculateItems = () => {
|
|
1859
|
+
var _a4;
|
|
1860
|
+
const calculateItemsParams = {
|
|
1861
|
+
doMVCP: scrollingTo !== void 0,
|
|
1862
|
+
scrollVelocity
|
|
1863
|
+
};
|
|
1864
|
+
if (isLargeUserScrollJump) {
|
|
1865
|
+
calculateItemsParams.drawDistanceMode = "visible-first";
|
|
1866
|
+
}
|
|
1867
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
|
|
1868
|
+
checkThresholds(ctx, allowedEdge);
|
|
1869
|
+
};
|
|
1870
|
+
if (isLargeUserScrollJump) {
|
|
1871
|
+
state.mvcpAnchorLock = void 0;
|
|
1872
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
1873
|
+
state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
|
|
1874
|
+
state.scheduledWork.cancel("mvcpRecalculate");
|
|
1875
|
+
flushSync(runCalculateItems);
|
|
1876
|
+
scheduleFullDrawDistancePrewarm(ctx);
|
|
1877
|
+
} else {
|
|
1878
|
+
runCalculateItems();
|
|
1879
|
+
}
|
|
1880
|
+
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
1881
|
+
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
1882
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1883
|
+
doMaintainScrollAtEnd(ctx);
|
|
1884
|
+
}
|
|
1885
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
1886
|
+
state.lastScrollDelta = 0;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1891
|
+
function interruptMaintainScrollAtEnd(ctx) {
|
|
1892
|
+
var _a3;
|
|
1893
|
+
const { state } = ctx;
|
|
1894
|
+
const maintaining = state.maintainingScrollAtEnd;
|
|
1895
|
+
const cancelActiveScroll = !!(maintaining === "animated" || maintaining === "instant" || maintaining && ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isScrollToEnd));
|
|
1896
|
+
if (cancelActiveScroll) {
|
|
1897
|
+
cancelImperativeScroll(state);
|
|
1898
|
+
}
|
|
1899
|
+
if (maintaining || state.pendingMaintainScrollAtEnd) {
|
|
1900
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1901
|
+
}
|
|
1902
|
+
return cancelActiveScroll;
|
|
1903
|
+
}
|
|
1904
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1905
|
+
var _a3;
|
|
1906
|
+
const { state } = ctx;
|
|
1907
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1908
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1909
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1910
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1911
|
+
if (currentPadding !== nextPadding) {
|
|
1912
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1913
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1914
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1915
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1916
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1920
|
+
var _a3, _b, _c, _d, _e;
|
|
1921
|
+
const state = ctx.state;
|
|
1922
|
+
const {
|
|
1923
|
+
didContainersLayout,
|
|
1924
|
+
didFinishInitialScroll,
|
|
1925
|
+
pendingNativeMVCPAdjust,
|
|
1926
|
+
props: { maintainScrollAtEnd }
|
|
1927
|
+
} = state;
|
|
1928
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1929
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1930
|
+
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);
|
|
1931
|
+
if (shouldMaintainScrollAtEnd && !state.scrollingTo) {
|
|
1932
|
+
const scroller = state.refScroller.current;
|
|
1933
|
+
const nativeMax = (_c = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _c.call(scroller);
|
|
1934
|
+
const observed = (_d = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _d.call(scroller);
|
|
1935
|
+
if (nativeMax !== void 0 && observed !== void 0 && nativeMax < state.scroll - 1 && Math.abs(observed - nativeMax) <= 1) {
|
|
1936
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1937
|
+
state.scrollPending = observed;
|
|
1938
|
+
updateScroll(ctx, observed, true, { markHasScrolled: false });
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1942
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1943
|
+
return false;
|
|
1944
|
+
}
|
|
1945
|
+
if (pendingNativeMVCPAdjust) {
|
|
1946
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1947
|
+
return false;
|
|
1948
|
+
}
|
|
1949
|
+
if (shouldMaintainScrollAtEnd && (state.scrollingTo || state.pendingScrollResolve)) {
|
|
1950
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1951
|
+
(_e = state.maintainingScrollAtEnd) != null ? _e : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1952
|
+
return false;
|
|
1953
|
+
}
|
|
1954
|
+
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1955
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1956
|
+
const contentSize = getContentSize(ctx);
|
|
1957
|
+
if (contentSize < state.scrollLength) {
|
|
1958
|
+
state.scroll = 0;
|
|
1959
|
+
}
|
|
1960
|
+
if (!state.maintainingScrollAtEnd) {
|
|
1961
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1962
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1963
|
+
const scrollAtRequest = state.scroll;
|
|
1964
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1965
|
+
requestAnimationFrame(() => {
|
|
1966
|
+
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1967
|
+
return;
|
|
1968
|
+
}
|
|
1969
|
+
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1970
|
+
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1971
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1972
|
+
if (state.scrollingTo || state.pendingScrollResolve) {
|
|
1973
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1976
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1977
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1978
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1979
|
+
);
|
|
1980
|
+
void scrollPromise.then(() => {
|
|
1981
|
+
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1982
|
+
return;
|
|
1983
|
+
}
|
|
1984
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1985
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1986
|
+
doMaintainScrollAtEnd(ctx);
|
|
1987
|
+
} else {
|
|
1988
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1989
|
+
}
|
|
1990
|
+
});
|
|
1991
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1992
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1993
|
+
}
|
|
1994
|
+
});
|
|
1995
|
+
} else {
|
|
1996
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1997
|
+
}
|
|
1998
|
+
return true;
|
|
1999
|
+
}
|
|
2000
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2001
|
+
return false;
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
// src/core/finishScrollTo.ts
|
|
2005
|
+
function finishScrollTo(ctx) {
|
|
2006
|
+
var _a3, _b, _c;
|
|
2007
|
+
const state = ctx.state;
|
|
2008
|
+
if (state == null ? void 0 : state.scrollingTo) {
|
|
2009
|
+
cancelScrollCompletionChecks(state);
|
|
2010
|
+
const resolvePendingScroll = ((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) ? void 0 : state.pendingScrollResolve;
|
|
2011
|
+
if (resolvePendingScroll) {
|
|
2012
|
+
state.pendingScrollResolve = void 0;
|
|
2013
|
+
}
|
|
2014
|
+
const scrollingTo = state.scrollingTo;
|
|
2015
|
+
state.scrollHistory.length = 0;
|
|
2016
|
+
state.scrollingTo = void 0;
|
|
2017
|
+
state.scrollTargetPinnedRange = void 0;
|
|
2018
|
+
if (state.pendingTotalSize !== void 0) {
|
|
2019
|
+
addTotalSize(ctx, null, state.pendingTotalSize);
|
|
2020
|
+
}
|
|
2021
|
+
if (PlatformAdjustBreaksScroll) {
|
|
2022
|
+
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
2023
|
+
}
|
|
2024
|
+
if (scrollingTo.isInitialScroll || state.initialScroll) {
|
|
2025
|
+
const isOffsetSession = ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) === "offset";
|
|
2026
|
+
const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_c = state.initialScroll) == null ? void 0 : _c.viewPosition) === 1;
|
|
2027
|
+
finishInitialScroll(ctx, {
|
|
2028
|
+
onFinished: () => {
|
|
2029
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
2030
|
+
},
|
|
2031
|
+
preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
|
|
2032
|
+
recalculateItems: true,
|
|
2033
|
+
schedulePreservedTargetClear: shouldPreserveResizeTarget,
|
|
2034
|
+
syncObservedOffset: isOffsetSession,
|
|
2035
|
+
waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
|
|
2036
|
+
});
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
recalculateSettledScroll(ctx);
|
|
2040
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
2041
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
2042
|
+
state.maintainingScrollAtEnd = void 0;
|
|
2043
|
+
doMaintainScrollAtEnd(ctx);
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
// src/core/checkFinishedScroll.ts
|
|
2049
|
+
var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
|
|
2050
|
+
var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
|
|
2051
|
+
var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
|
|
2052
|
+
var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
|
|
2053
|
+
var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
|
|
2054
|
+
function checkFinishedScroll(ctx, options) {
|
|
2055
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
2056
|
+
if (options == null ? void 0 : options.onlyIfAligned) {
|
|
2057
|
+
if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
|
|
2065
|
+
}
|
|
2066
|
+
function hasScrollCompletionOwnership(state, options) {
|
|
2067
|
+
const { clampedTargetOffset, scrollingTo } = options;
|
|
2068
|
+
return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
|
|
2069
|
+
}
|
|
2070
|
+
function isSilentInitialDispatch(state, scrollingTo) {
|
|
2071
|
+
return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
|
|
2072
|
+
}
|
|
2073
|
+
function getInitialScrollWatchdogTargetOffset(state) {
|
|
2074
|
+
var _a3;
|
|
2075
|
+
return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
|
|
2076
|
+
}
|
|
2077
|
+
function isNativeInitialNonZeroTarget(state) {
|
|
2078
|
+
const targetOffset = getInitialScrollWatchdogTargetOffset(state);
|
|
2079
|
+
return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
|
|
2080
|
+
}
|
|
2081
|
+
function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
|
|
2082
|
+
var _a3, _b;
|
|
2083
|
+
if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
|
|
2084
|
+
return false;
|
|
2085
|
+
}
|
|
2086
|
+
if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
|
|
2087
|
+
return false;
|
|
2088
|
+
}
|
|
2089
|
+
const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
|
|
2090
|
+
if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
|
|
2091
|
+
return false;
|
|
2092
|
+
}
|
|
2093
|
+
if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
|
|
2094
|
+
return false;
|
|
2095
|
+
}
|
|
2096
|
+
return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
|
|
2097
|
+
}
|
|
2098
|
+
function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
2099
|
+
var _a3;
|
|
2100
|
+
const { state } = ctx;
|
|
2101
|
+
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;
|
|
2102
|
+
}
|
|
2103
|
+
function isEndAlignedLastItemTarget(ctx, scrollingTo) {
|
|
2104
|
+
return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
|
|
2105
|
+
}
|
|
2106
|
+
function getCurrentTargetOffset(ctx, scrollingTo) {
|
|
2107
|
+
var _a3;
|
|
2108
|
+
const index = scrollingTo.index;
|
|
2109
|
+
const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
|
|
2110
|
+
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);
|
|
2111
|
+
return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
|
|
2112
|
+
}
|
|
2113
|
+
function getResolvedScrollCompletionState(ctx, scrollingTo) {
|
|
2114
|
+
const { state } = ctx;
|
|
2115
|
+
const scroll = state.scrollPending;
|
|
2116
|
+
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
2117
|
+
const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
|
|
2118
|
+
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
2119
|
+
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
2120
|
+
const adjustedTargetOffset = clampedTargetOffset + adjust;
|
|
2121
|
+
const diff2 = Math.abs(scroll - adjustedTargetOffset);
|
|
2122
|
+
const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
|
|
2123
|
+
return {
|
|
2124
|
+
clampedTargetOffset,
|
|
2125
|
+
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
function checkFinishedScrollFrame(ctx) {
|
|
2129
|
+
const scrollingTo = ctx.state.scrollingTo;
|
|
2130
|
+
if (!scrollingTo) {
|
|
2131
|
+
return;
|
|
2066
2132
|
}
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
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;
|
|
2133
|
+
const { state } = ctx;
|
|
2134
|
+
const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
|
|
2135
|
+
if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
|
|
2136
|
+
clampedTargetOffset: completionState.clampedTargetOffset,
|
|
2137
|
+
scrollingTo
|
|
2138
|
+
})) {
|
|
2139
|
+
finishScrollTo(ctx);
|
|
2093
2140
|
}
|
|
2094
|
-
return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
|
|
2095
|
-
};
|
|
2096
|
-
|
|
2097
|
-
// src/utils/isInMVCPActiveMode.native.ts
|
|
2098
|
-
function isInMVCPActiveMode(state) {
|
|
2099
|
-
return state.dataChangeNeedsScrollUpdate;
|
|
2100
2141
|
}
|
|
2101
|
-
|
|
2102
|
-
// src/core/updateScroll.ts
|
|
2103
|
-
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
2142
|
+
function scrollToFallbackOffset(ctx, offset) {
|
|
2104
2143
|
var _a3;
|
|
2144
|
+
(_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
|
|
2145
|
+
animated: false,
|
|
2146
|
+
x: ctx.state.props.horizontal ? offset : 0,
|
|
2147
|
+
y: ctx.state.props.horizontal ? 0 : offset
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
function checkFinishedScrollFallback(ctx) {
|
|
2105
2151
|
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;
|
|
2152
|
+
if (state.scheduledWork.has("checkFinishedScrollFallback")) {
|
|
2153
|
+
return;
|
|
2117
2154
|
}
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2155
|
+
const scrollingTo = state.scrollingTo;
|
|
2156
|
+
const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
2157
|
+
const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
|
|
2158
|
+
const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
|
|
2159
|
+
const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
|
|
2160
|
+
const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
|
|
2161
|
+
let numChecks = 0;
|
|
2162
|
+
const scheduleFallbackCheck = (delay) => {
|
|
2163
|
+
state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
|
|
2164
|
+
};
|
|
2165
|
+
const checkHasScrolled = () => {
|
|
2166
|
+
var _a3, _b, _c, _d;
|
|
2167
|
+
const isStillScrollingTo = state.scrollingTo;
|
|
2168
|
+
if (isStillScrollingTo) {
|
|
2169
|
+
numChecks++;
|
|
2170
|
+
const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
|
|
2171
|
+
const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
|
|
2172
|
+
const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
|
|
2173
|
+
const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
|
|
2174
|
+
state,
|
|
2175
|
+
isStillScrollingTo
|
|
2176
|
+
);
|
|
2177
|
+
const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
|
|
2178
|
+
const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
|
|
2179
|
+
const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
|
|
2180
|
+
const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
|
|
2181
|
+
const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2182
|
+
const shouldRetryUnalignedEndScroll = Platform.OS !== "web" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2183
|
+
if (shouldRetrySilentInitialNativeScroll) {
|
|
2184
|
+
const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
|
|
2185
|
+
const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
|
|
2186
|
+
initialScrollCompletion.markSilentInitialScrollRetry(state);
|
|
2187
|
+
scrollToFallbackOffset(ctx, jiggleOffset);
|
|
2188
|
+
state.scheduledWork.frame(
|
|
2189
|
+
() => scrollToFallbackOffset(ctx, targetOffset),
|
|
2190
|
+
"checkFinishedScrollRetryFrame"
|
|
2191
|
+
);
|
|
2192
|
+
scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
|
|
2193
|
+
} else if (shouldRetryUnalignedEndScroll) {
|
|
2194
|
+
scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
|
|
2195
|
+
scheduleFallbackCheck(100);
|
|
2196
|
+
} else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
|
|
2197
|
+
finishScrollTo(ctx);
|
|
2198
|
+
} else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
|
|
2199
|
+
const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
|
|
2200
|
+
scrollToFallbackOffset(ctx, targetOffset);
|
|
2201
|
+
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
2202
|
+
} else {
|
|
2203
|
+
scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
|
|
2204
|
+
}
|
|
2122
2205
|
}
|
|
2206
|
+
};
|
|
2207
|
+
scheduleFallbackCheck(initialDelay);
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
// src/core/doScrollTo.native.ts
|
|
2211
|
+
function doScrollTo(ctx, params) {
|
|
2212
|
+
const state = ctx.state;
|
|
2213
|
+
const { animated, horizontal, isInitialScroll, offset } = params;
|
|
2214
|
+
const isAnimated = !!animated;
|
|
2215
|
+
const { refScroller } = state;
|
|
2216
|
+
const scroller = refScroller.current;
|
|
2217
|
+
if (!scroller) {
|
|
2218
|
+
return;
|
|
2123
2219
|
}
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2220
|
+
const isHorizontal = !!horizontal;
|
|
2221
|
+
const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
|
|
2222
|
+
const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
|
|
2223
|
+
scroller.scrollTo({
|
|
2224
|
+
animated: isAnimated,
|
|
2225
|
+
x: isHorizontal ? nativeOffset : 0,
|
|
2226
|
+
y: isHorizontal ? 0 : offset
|
|
2227
|
+
});
|
|
2228
|
+
if (isInitialScroll) {
|
|
2229
|
+
initialScrollCompletion.markInitialScrollNativeDispatch(state);
|
|
2133
2230
|
}
|
|
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);
|
|
2231
|
+
if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
|
|
2232
|
+
checkFinishedScroll(ctx);
|
|
2143
2233
|
}
|
|
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;
|
|
2234
|
+
if (!isAnimated) {
|
|
2235
|
+
state.scroll = offset;
|
|
2236
|
+
checkFinishedScrollFallback(ctx);
|
|
2186
2237
|
}
|
|
2187
2238
|
}
|
|
2188
2239
|
|
|
@@ -3191,6 +3242,11 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3191
3242
|
const state = ctx.state;
|
|
3192
3243
|
const previousInitialScrollDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
|
|
3193
3244
|
const shouldUseLatestInitialScroll = dataLength > 0 && (!state.hasHadNonEmptyData || didStartFreshData);
|
|
3245
|
+
if (didStartFreshData) {
|
|
3246
|
+
cancelImperativeScroll(state);
|
|
3247
|
+
state.maintainingScrollAtEnd = void 0;
|
|
3248
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
3249
|
+
}
|
|
3194
3250
|
if (dataLength > 0) {
|
|
3195
3251
|
state.hasHadNonEmptyData = true;
|
|
3196
3252
|
}
|
|
@@ -4735,6 +4791,7 @@ function maybeUpdateAnchoredEndSpace(ctx) {
|
|
|
4735
4791
|
const nextAnchorIndex = anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex;
|
|
4736
4792
|
let nextAnchorKey;
|
|
4737
4793
|
let isReady = true;
|
|
4794
|
+
let canUpdateSize = true;
|
|
4738
4795
|
let nextSize = 0;
|
|
4739
4796
|
if (anchoredEndSpace) {
|
|
4740
4797
|
const { anchorIndex, anchorMaxSize, anchorOffset = 0 } = anchoredEndSpace;
|
|
@@ -4756,25 +4813,30 @@ function maybeUpdateAnchoredEndSpace(ctx) {
|
|
|
4756
4813
|
contentBelowAnchor = Math.max(0, contentBelowAnchor - ctx.scrollAxisGap);
|
|
4757
4814
|
contentBelowAnchor += (ctx.values.get("footerSize") || 0) + getStylePaddingEnd(state.props);
|
|
4758
4815
|
isReady = !hasUnknownTailSize;
|
|
4759
|
-
|
|
4816
|
+
const knownSizeBound = Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset);
|
|
4817
|
+
nextSize = hasUnknownTailSize ? Math.min(previousSize || 0, knownSizeBound) : knownSizeBound;
|
|
4760
4818
|
} else if (anchorIndex >= 0) {
|
|
4761
4819
|
isReady = false;
|
|
4820
|
+
canUpdateSize = false;
|
|
4762
4821
|
}
|
|
4763
4822
|
}
|
|
4764
4823
|
const didSizeChange = previousSize !== nextSize && (previousSize !== void 0 || anchoredEndSpace !== void 0);
|
|
4765
4824
|
const didEffectiveSizeChange = (previousSize || 0) !== nextSize;
|
|
4825
|
+
const canApplySizeChange = canUpdateSize && (isReady || previousSize !== void 0);
|
|
4766
4826
|
const didReadyAnchorChange = previousReadyAnchorIndex !== nextAnchorIndex || previousReadyAnchorKey !== nextAnchorKey;
|
|
4767
|
-
|
|
4827
|
+
const didBecomeReady = isReady && state.anchoredEndSpacePendingReady;
|
|
4828
|
+
state.anchoredEndSpacePendingReady = !isReady;
|
|
4829
|
+
if (canApplySizeChange && didSizeChange) {
|
|
4830
|
+
set$(ctx, "anchoredEndSpaceSize", nextSize);
|
|
4831
|
+
(_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
|
|
4832
|
+
}
|
|
4833
|
+
if (canApplySizeChange && didEffectiveSizeChange) {
|
|
4834
|
+
updateContentMetricsState(ctx);
|
|
4835
|
+
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
4836
|
+
}
|
|
4837
|
+
if (isReady && (didSizeChange || didReadyAnchorChange || didBecomeReady)) {
|
|
4768
4838
|
state.anchoredEndSpaceReadyAnchorIndex = nextAnchorIndex;
|
|
4769
4839
|
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
4840
|
(_b = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onReady) == null ? void 0 : _b.call(anchoredEndSpace, { anchorIndex: nextAnchorIndex, anchorKey: nextAnchorKey, size: nextSize });
|
|
4779
4841
|
}
|
|
4780
4842
|
return nextSize;
|
|
@@ -6678,6 +6740,9 @@ function scrollToEnd(ctx, options) {
|
|
|
6678
6740
|
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6679
6741
|
viewPosition: 1
|
|
6680
6742
|
});
|
|
6743
|
+
if (state.scrollingTo) {
|
|
6744
|
+
state.scrollingTo.isScrollToEnd = true;
|
|
6745
|
+
}
|
|
6681
6746
|
return true;
|
|
6682
6747
|
}
|
|
6683
6748
|
|
|
@@ -7411,6 +7476,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7411
7476
|
endReachedSnapshot: void 0,
|
|
7412
7477
|
firstFullyOnScreenIndex: -1,
|
|
7413
7478
|
freshDataTransitionEpoch: 0,
|
|
7479
|
+
handledDataChangeEpoch: 0,
|
|
7480
|
+
handledFreshDataTransitionEpoch: 0,
|
|
7414
7481
|
hasHadNonEmptyData: dataProp.length > 0,
|
|
7415
7482
|
idCache: [],
|
|
7416
7483
|
idsInView: [],
|
|
@@ -7495,6 +7562,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7495
7562
|
if (shouldResetFreshDataLayout) {
|
|
7496
7563
|
state.freshDataTransitionEpoch += 1;
|
|
7497
7564
|
}
|
|
7565
|
+
const dataChangeEpoch = state.dataChangeEpoch;
|
|
7566
|
+
const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
|
|
7498
7567
|
const throttledOnScroll = useThrottledOnScroll(onScrollProp != null ? onScrollProp : noopOnScroll, scrollEventThrottle != null ? scrollEventThrottle : 0);
|
|
7499
7568
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? throttledOnScroll : onScrollProp;
|
|
7500
7569
|
const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_q = state.props.anchoredEndSpace) == null ? void 0 : _q.anchorIndex) !== (anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex);
|
|
@@ -7622,7 +7691,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7622
7691
|
useDevChecks(props);
|
|
7623
7692
|
}
|
|
7624
7693
|
React2.useLayoutEffect(() => {
|
|
7625
|
-
|
|
7694
|
+
const didDataChange = state.handledDataChangeEpoch !== dataChangeEpoch;
|
|
7695
|
+
const didStartFreshData = state.handledFreshDataTransitionEpoch !== freshDataTransitionEpoch;
|
|
7696
|
+
state.handledDataChangeEpoch = dataChangeEpoch;
|
|
7697
|
+
state.handledFreshDataTransitionEpoch = freshDataTransitionEpoch;
|
|
7698
|
+
if (didStartFreshData) {
|
|
7626
7699
|
resetInitialRenderState(ctx, {
|
|
7627
7700
|
resetInitialScroll: !!initialScrollProp,
|
|
7628
7701
|
resetLayout: true
|
|
@@ -7630,8 +7703,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7630
7703
|
}
|
|
7631
7704
|
handleInitialScrollDataChange(ctx, {
|
|
7632
7705
|
dataLength: dataProp.length,
|
|
7633
|
-
didDataChange
|
|
7634
|
-
didStartFreshData
|
|
7706
|
+
didDataChange,
|
|
7707
|
+
didStartFreshData,
|
|
7635
7708
|
initialScrollAtEnd,
|
|
7636
7709
|
latestInitialScroll: initialScrollProp,
|
|
7637
7710
|
latestInitialScrollSessionKind: initialScrollUsesOffsetOnly ? "offset" : "bootstrap",
|
|
@@ -7641,8 +7714,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7641
7714
|
}, [
|
|
7642
7715
|
dataProp.length,
|
|
7643
7716
|
dataKey,
|
|
7644
|
-
|
|
7645
|
-
|
|
7717
|
+
dataChangeEpoch,
|
|
7718
|
+
freshDataTransitionEpoch,
|
|
7646
7719
|
initialScrollAtEnd,
|
|
7647
7720
|
stylePaddingEndState,
|
|
7648
7721
|
usesBootstrapInitialScroll
|
|
@@ -7825,13 +7898,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7825
7898
|
onScroll: (event) => onScroll(ctx, event),
|
|
7826
7899
|
onScrollBeginDrag: (event) => {
|
|
7827
7900
|
var _a4, _b2;
|
|
7828
|
-
|
|
7829
|
-
if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
|
|
7830
|
-
cancelImperativeScroll(state);
|
|
7831
|
-
}
|
|
7832
|
-
if (maintainingScrollAtEnd) {
|
|
7833
|
-
finishMaintainScrollAtEnd(ctx);
|
|
7834
|
-
}
|
|
7901
|
+
interruptMaintainScrollAtEnd(ctx);
|
|
7835
7902
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
7836
7903
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
7837
7904
|
},
|