@legendapp/list 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/react-native.js +1166 -1148
- package/react-native.mjs +1166 -1148
- package/react-native.web.js +1336 -1322
- package/react-native.web.mjs +1336 -1322
- package/react.js +1336 -1322
- package/react.mjs +1336 -1322
- package/section-list.d.ts +19 -2
- package/section-list.js +47 -26
- package/section-list.mjs +47 -26
package/react-native.mjs
CHANGED
|
@@ -1981,18 +1981,29 @@ function shouldFinishInitialZeroTargetScroll(ctx) {
|
|
|
1981
1981
|
const { state } = ctx;
|
|
1982
1982
|
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;
|
|
1983
1983
|
}
|
|
1984
|
-
function
|
|
1984
|
+
function isEndAlignedLastItemTarget(ctx, scrollingTo) {
|
|
1985
|
+
return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
|
|
1986
|
+
}
|
|
1987
|
+
function getCurrentTargetOffset(ctx, scrollingTo) {
|
|
1985
1988
|
var _a3;
|
|
1989
|
+
const index = scrollingTo.index;
|
|
1990
|
+
const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
|
|
1991
|
+
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);
|
|
1992
|
+
return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
|
|
1993
|
+
}
|
|
1994
|
+
function getResolvedScrollCompletionState(ctx, scrollingTo) {
|
|
1986
1995
|
const { state } = ctx;
|
|
1987
1996
|
const scroll = state.scrollPending;
|
|
1988
1997
|
const adjust = state.scrollAdjustHandler.getAdjust();
|
|
1989
|
-
const clampedTargetOffset = (
|
|
1998
|
+
const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
|
|
1990
1999
|
const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
|
|
1991
2000
|
const diff1 = Math.abs(scroll - clampedTargetOffset);
|
|
1992
|
-
const
|
|
2001
|
+
const adjustedTargetOffset = clampedTargetOffset + adjust;
|
|
2002
|
+
const diff2 = Math.abs(scroll - adjustedTargetOffset);
|
|
2003
|
+
const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
|
|
1993
2004
|
return {
|
|
1994
2005
|
clampedTargetOffset,
|
|
1995
|
-
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 ||
|
|
2006
|
+
isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
|
|
1996
2007
|
};
|
|
1997
2008
|
}
|
|
1998
2009
|
function checkFinishedScrollFrame(ctx) {
|
|
@@ -2049,6 +2060,7 @@ function checkFinishedScrollFallback(ctx) {
|
|
|
2049
2060
|
const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
|
|
2050
2061
|
const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
|
|
2051
2062
|
const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2063
|
+
const shouldRetryUnalignedEndScroll = Platform.OS === "ios" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
|
|
2052
2064
|
if (shouldRetrySilentInitialNativeScroll) {
|
|
2053
2065
|
const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
|
|
2054
2066
|
const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
|
|
@@ -2058,6 +2070,9 @@ function checkFinishedScrollFallback(ctx) {
|
|
|
2058
2070
|
scrollToFallbackOffset(ctx, targetOffset);
|
|
2059
2071
|
});
|
|
2060
2072
|
scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
|
|
2073
|
+
} else if (shouldRetryUnalignedEndScroll) {
|
|
2074
|
+
scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
|
|
2075
|
+
scheduleFallbackCheck(100);
|
|
2061
2076
|
} else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
|
|
2062
2077
|
finishScrollTo(ctx);
|
|
2063
2078
|
} else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
|
|
@@ -2100,733 +2115,1162 @@ function doScrollTo(ctx, params) {
|
|
|
2100
2115
|
}
|
|
2101
2116
|
}
|
|
2102
2117
|
|
|
2103
|
-
// src/core/
|
|
2104
|
-
function
|
|
2105
|
-
|
|
2106
|
-
|
|
2118
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
2119
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
2120
|
+
const state = ctx.state;
|
|
2121
|
+
const {
|
|
2122
|
+
didContainersLayout,
|
|
2123
|
+
pendingNativeMVCPAdjust,
|
|
2124
|
+
refScroller,
|
|
2125
|
+
props: { maintainScrollAtEnd }
|
|
2126
|
+
} = state;
|
|
2127
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
2128
|
+
const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
|
|
2129
|
+
if (pendingNativeMVCPAdjust) {
|
|
2130
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
2131
|
+
return false;
|
|
2107
2132
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
const
|
|
2111
|
-
|
|
2133
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
2134
|
+
if (shouldMaintainScrollAtEnd) {
|
|
2135
|
+
const contentSize = getContentSize(ctx);
|
|
2136
|
+
if (contentSize < state.scrollLength) {
|
|
2137
|
+
state.scroll = 0;
|
|
2138
|
+
}
|
|
2139
|
+
if (!state.maintainingScrollAtEnd) {
|
|
2140
|
+
state.maintainingScrollAtEnd = true;
|
|
2141
|
+
requestAnimationFrame(() => {
|
|
2142
|
+
if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
|
|
2143
|
+
const scroller = refScroller.current;
|
|
2144
|
+
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
2145
|
+
const currentContentSize = getContentSize(ctx);
|
|
2146
|
+
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
2147
|
+
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
2148
|
+
scroller == null ? void 0 : scroller.scrollTo({
|
|
2149
|
+
animated: maintainScrollAtEnd.animated,
|
|
2150
|
+
x: nativeOffset,
|
|
2151
|
+
y: 0
|
|
2152
|
+
});
|
|
2153
|
+
} else {
|
|
2154
|
+
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
2155
|
+
animated: maintainScrollAtEnd.animated
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
setTimeout(
|
|
2159
|
+
() => {
|
|
2160
|
+
state.maintainingScrollAtEnd = false;
|
|
2161
|
+
},
|
|
2162
|
+
maintainScrollAtEnd.animated ? 500 : 0
|
|
2163
|
+
);
|
|
2164
|
+
} else {
|
|
2165
|
+
state.maintainingScrollAtEnd = false;
|
|
2166
|
+
}
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2169
|
+
return true;
|
|
2112
2170
|
}
|
|
2113
|
-
return
|
|
2171
|
+
return false;
|
|
2114
2172
|
}
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
const
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2173
|
+
|
|
2174
|
+
// src/utils/requestAdjust.ts
|
|
2175
|
+
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
2176
|
+
const state = ctx.state;
|
|
2177
|
+
if (Math.abs(positionDiff) > 0.1) {
|
|
2178
|
+
const needsScrollWorkaround = Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
|
|
2179
|
+
const doit = () => {
|
|
2180
|
+
if (needsScrollWorkaround) {
|
|
2181
|
+
scrollTo(ctx, {
|
|
2182
|
+
noScrollingTo: true,
|
|
2183
|
+
offset: state.scroll
|
|
2184
|
+
});
|
|
2185
|
+
} else {
|
|
2186
|
+
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
2187
|
+
if (state.adjustingFromInitialMount) {
|
|
2188
|
+
state.adjustingFromInitialMount--;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2192
|
+
state.scroll += positionDiff;
|
|
2193
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2194
|
+
const readyToRender = peek$(ctx, "readyToRender");
|
|
2195
|
+
if (readyToRender) {
|
|
2196
|
+
doit();
|
|
2197
|
+
if (Platform.OS !== "web") {
|
|
2198
|
+
const threshold = state.scroll - positionDiff / 2;
|
|
2199
|
+
if (!state.ignoreScrollFromMVCP) {
|
|
2200
|
+
state.ignoreScrollFromMVCP = {};
|
|
2201
|
+
}
|
|
2202
|
+
if (positionDiff > 0) {
|
|
2203
|
+
state.ignoreScrollFromMVCP.lt = threshold;
|
|
2204
|
+
} else {
|
|
2205
|
+
state.ignoreScrollFromMVCP.gt = threshold;
|
|
2206
|
+
}
|
|
2207
|
+
if (state.ignoreScrollFromMVCPTimeout) {
|
|
2208
|
+
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
2209
|
+
}
|
|
2210
|
+
const delay = needsScrollWorkaround ? 250 : 100;
|
|
2211
|
+
state.ignoreScrollFromMVCPTimeout = setTimeout(() => {
|
|
2212
|
+
var _a3;
|
|
2213
|
+
state.ignoreScrollFromMVCP = void 0;
|
|
2214
|
+
const shouldForceUpdate = state.ignoreScrollFromMVCPIgnored && state.scrollProcessingEnabled !== false;
|
|
2215
|
+
if (shouldForceUpdate) {
|
|
2216
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
2217
|
+
state.scrollPending = state.scroll;
|
|
2218
|
+
(_a3 = state.reprocessCurrentScroll) == null ? void 0 : _a3.call(state);
|
|
2219
|
+
}
|
|
2220
|
+
}, delay);
|
|
2221
|
+
}
|
|
2222
|
+
} else {
|
|
2223
|
+
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
2224
|
+
requestAnimationFrame(doit);
|
|
2225
|
+
}
|
|
2131
2226
|
}
|
|
2132
2227
|
}
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
} = scrollTarget;
|
|
2144
|
-
const {
|
|
2145
|
-
props: { horizontal }
|
|
2146
|
-
} = state;
|
|
2147
|
-
if (state.animFrameCheckFinishedScroll) {
|
|
2148
|
-
cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
|
|
2228
|
+
|
|
2229
|
+
// src/core/mvcp.ts
|
|
2230
|
+
var MVCP_POSITION_EPSILON = 0.1;
|
|
2231
|
+
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
2232
|
+
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
2233
|
+
var NATIVE_END_CLAMP_EPSILON = 1;
|
|
2234
|
+
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
2235
|
+
if (!enableMVCPAnchorLock) {
|
|
2236
|
+
state.mvcpAnchorLock = void 0;
|
|
2237
|
+
return void 0;
|
|
2149
2238
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2239
|
+
const lock = state.mvcpAnchorLock;
|
|
2240
|
+
if (!lock) {
|
|
2241
|
+
return void 0;
|
|
2152
2242
|
}
|
|
2153
|
-
const
|
|
2154
|
-
const
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2243
|
+
const isExpired = now > lock.expiresAt;
|
|
2244
|
+
const isMissing = state.indexByKey.get(lock.id) === void 0;
|
|
2245
|
+
if (isExpired || isMissing || !mvcpData) {
|
|
2246
|
+
state.mvcpAnchorLock = void 0;
|
|
2247
|
+
return void 0;
|
|
2248
|
+
}
|
|
2249
|
+
return lock;
|
|
2250
|
+
}
|
|
2251
|
+
function updateAnchorLock(state, params) {
|
|
2252
|
+
if (Platform.OS === "web") {
|
|
2253
|
+
const { anchorId, anchorPosition, dataChanged, now, positionDiff } = params;
|
|
2254
|
+
const enableMVCPAnchorLock = !!dataChanged || !!state.mvcpAnchorLock;
|
|
2255
|
+
const mvcpData = state.props.maintainVisibleContentPosition.data;
|
|
2256
|
+
if (!enableMVCPAnchorLock || !mvcpData || state.scrollingTo || !anchorId || anchorPosition === void 0) {
|
|
2257
|
+
return;
|
|
2161
2258
|
}
|
|
2162
|
-
const
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2259
|
+
const existingLock = state.mvcpAnchorLock;
|
|
2260
|
+
const quietPasses = !dataChanged && Math.abs(positionDiff) <= MVCP_POSITION_EPSILON && (existingLock == null ? void 0 : existingLock.id) === anchorId ? existingLock.quietPasses + 1 : 0;
|
|
2261
|
+
if (!dataChanged && quietPasses >= MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE) {
|
|
2262
|
+
state.mvcpAnchorLock = void 0;
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
state.mvcpAnchorLock = {
|
|
2266
|
+
expiresAt: now + MVCP_ANCHOR_LOCK_TTL_MS,
|
|
2267
|
+
id: anchorId,
|
|
2268
|
+
position: anchorPosition,
|
|
2269
|
+
quietPasses
|
|
2168
2270
|
};
|
|
2169
2271
|
}
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
if (
|
|
2173
|
-
|
|
2174
|
-
} else {
|
|
2175
|
-
state.scroll = offset;
|
|
2272
|
+
}
|
|
2273
|
+
function shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget) {
|
|
2274
|
+
if (!dataChanged || Platform.OS === "web" || !state.props.maintainVisibleContentPosition.data || scrollTarget !== void 0 || positionDiff >= -MVCP_POSITION_EPSILON) {
|
|
2275
|
+
return false;
|
|
2176
2276
|
}
|
|
2277
|
+
const distanceFromEnd = prevTotalSize - prevScroll - state.scrollLength;
|
|
2278
|
+
return distanceFromEnd < Math.abs(positionDiff) - MVCP_POSITION_EPSILON;
|
|
2177
2279
|
}
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
if (dataLength <= 0) {
|
|
2182
|
-
return -1;
|
|
2280
|
+
function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
|
|
2281
|
+
if (Math.abs(unresolvedAmount) <= MVCP_POSITION_EPSILON) {
|
|
2282
|
+
return 0;
|
|
2183
2283
|
}
|
|
2184
|
-
|
|
2185
|
-
|
|
2284
|
+
const maxScroll = Math.max(0, totalSize - state.scrollLength);
|
|
2285
|
+
const clampDelta = maxScroll - state.scroll;
|
|
2286
|
+
if (unresolvedAmount < 0) {
|
|
2287
|
+
return Math.max(unresolvedAmount, Math.min(0, clampDelta));
|
|
2186
2288
|
}
|
|
2187
|
-
if (
|
|
2188
|
-
return 0;
|
|
2289
|
+
if (unresolvedAmount > 0) {
|
|
2290
|
+
return Math.min(unresolvedAmount, Math.max(0, clampDelta));
|
|
2189
2291
|
}
|
|
2190
|
-
return
|
|
2292
|
+
return 0;
|
|
2191
2293
|
}
|
|
2192
|
-
function
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
forceScroll,
|
|
2197
|
-
isInitialScroll,
|
|
2198
|
-
viewPosition
|
|
2199
|
-
}) {
|
|
2294
|
+
function getProgressTowardAmount(targetDelta, nativeDelta) {
|
|
2295
|
+
return targetDelta < 0 ? -nativeDelta : nativeDelta;
|
|
2296
|
+
}
|
|
2297
|
+
function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
|
|
2200
2298
|
const state = ctx.state;
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
const isLast = index === data.length - 1;
|
|
2206
|
-
if (isLast && viewPosition === void 0) {
|
|
2207
|
-
viewPosition = 1;
|
|
2208
|
-
}
|
|
2209
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
2210
|
-
scrollTo(ctx, {
|
|
2211
|
-
animated,
|
|
2212
|
-
forceScroll,
|
|
2213
|
-
index,
|
|
2214
|
-
isInitialScroll,
|
|
2215
|
-
itemSize,
|
|
2216
|
-
offset: firstIndexOffset,
|
|
2217
|
-
viewOffset,
|
|
2218
|
-
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2219
|
-
});
|
|
2220
|
-
}
|
|
2221
|
-
|
|
2222
|
-
// src/core/initialScroll.ts
|
|
2223
|
-
function dispatchInitialScroll(ctx, params) {
|
|
2224
|
-
const { forceScroll, resolvedOffset, target, waitForCompletionFrame } = params;
|
|
2225
|
-
const requestedIndex = target.index;
|
|
2226
|
-
const index = requestedIndex !== void 0 ? clampScrollIndex(requestedIndex, ctx.state.props.data.length) : void 0;
|
|
2227
|
-
const itemSize = getItemSizeAtIndex(ctx, index);
|
|
2228
|
-
scrollTo(ctx, {
|
|
2229
|
-
animated: false,
|
|
2230
|
-
forceScroll,
|
|
2231
|
-
index: index !== void 0 && index >= 0 ? index : void 0,
|
|
2232
|
-
isInitialScroll: true,
|
|
2233
|
-
itemSize,
|
|
2234
|
-
offset: resolvedOffset,
|
|
2235
|
-
precomputedWithViewOffset: true,
|
|
2236
|
-
viewOffset: target.viewOffset,
|
|
2237
|
-
viewPosition: target.viewPosition,
|
|
2238
|
-
waitForInitialScrollCompletionFrame: waitForCompletionFrame
|
|
2239
|
-
});
|
|
2240
|
-
}
|
|
2241
|
-
function setInitialScrollTarget(state, target, options) {
|
|
2242
|
-
var _a3;
|
|
2243
|
-
state.clearPreservedInitialScrollOnNextFinish = void 0;
|
|
2244
|
-
if (state.timeoutPreservedInitialScrollClear !== void 0) {
|
|
2245
|
-
clearTimeout(state.timeoutPreservedInitialScrollClear);
|
|
2246
|
-
state.timeoutPreservedInitialScrollClear = void 0;
|
|
2247
|
-
}
|
|
2248
|
-
state.initialScroll = target;
|
|
2249
|
-
if ((options == null ? void 0 : options.resetDidFinish) && state.didFinishInitialScroll) {
|
|
2250
|
-
state.didFinishInitialScroll = false;
|
|
2299
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2300
|
+
const remaining = remainingAfterManual - nativeDelta;
|
|
2301
|
+
if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
|
|
2302
|
+
requestAdjust(ctx, remaining, true);
|
|
2251
2303
|
}
|
|
2252
|
-
setInitialScrollSession(state, {
|
|
2253
|
-
kind: ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" ? "offset" : "bootstrap"
|
|
2254
|
-
});
|
|
2255
2304
|
}
|
|
2256
|
-
function
|
|
2257
|
-
var _a3, _b;
|
|
2305
|
+
function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
2258
2306
|
const state = ctx.state;
|
|
2259
|
-
|
|
2260
|
-
|
|
2307
|
+
const pending = state.pendingNativeMVCPAdjust;
|
|
2308
|
+
if (!pending || Math.abs(pending.manualApplied) > MVCP_POSITION_EPSILON) {
|
|
2309
|
+
return;
|
|
2261
2310
|
}
|
|
2262
|
-
const
|
|
2263
|
-
const
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
function getAdvanceableInitialScrollState(state, options) {
|
|
2267
|
-
const { didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
|
|
2268
|
-
const initialScroll = state.initialScroll;
|
|
2269
|
-
const isInitialScrollInProgress = !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll);
|
|
2270
|
-
const shouldWaitForInitialLayout = !!(options == null ? void 0 : options.requiresMeasuredLayout) && !queuedInitialLayout && !isInitialScrollInProgress;
|
|
2271
|
-
if (!initialScroll || shouldWaitForInitialLayout || didFinishInitialScroll || scrollingTo && !isInitialScrollInProgress) {
|
|
2272
|
-
return void 0;
|
|
2311
|
+
const totalSize = getContentSize(ctx);
|
|
2312
|
+
const predictedNativeClamp = getPredictedNativeClamp(state, pending.amount, totalSize);
|
|
2313
|
+
if (Math.abs(predictedNativeClamp) <= MVCP_POSITION_EPSILON) {
|
|
2314
|
+
return;
|
|
2273
2315
|
}
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2316
|
+
const manualDesired = pending.amount - predictedNativeClamp;
|
|
2317
|
+
if (Math.abs(manualDesired) <= MVCP_POSITION_EPSILON) {
|
|
2318
|
+
return;
|
|
2319
|
+
}
|
|
2320
|
+
pending.manualApplied = manualDesired;
|
|
2321
|
+
requestAdjust(ctx, manualDesired, true);
|
|
2322
|
+
pending.furthestProgressTowardAmount = 0;
|
|
2280
2323
|
}
|
|
2281
|
-
function
|
|
2282
|
-
var _a3, _b, _c;
|
|
2324
|
+
function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
2283
2325
|
const state = ctx.state;
|
|
2284
|
-
const
|
|
2285
|
-
|
|
2286
|
-
});
|
|
2287
|
-
if (!advanceableState) {
|
|
2326
|
+
const pending = state.pendingNativeMVCPAdjust;
|
|
2327
|
+
if (!pending) {
|
|
2288
2328
|
return false;
|
|
2289
2329
|
}
|
|
2290
|
-
const
|
|
2291
|
-
const
|
|
2292
|
-
const
|
|
2293
|
-
const
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
if (!(options == null ? void 0 : options.forceScroll) && !didOffsetChange && isInitialScrollInProgress && !didActiveInitialTargetChange) {
|
|
2298
|
-
return false;
|
|
2330
|
+
const remainingAfterManual = pending.amount - pending.manualApplied;
|
|
2331
|
+
const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
|
|
2332
|
+
const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
|
|
2333
|
+
const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
|
|
2334
|
+
if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
|
|
2335
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2336
|
+
return true;
|
|
2299
2337
|
}
|
|
2300
|
-
if (
|
|
2338
|
+
if (isWrongDirection) {
|
|
2339
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2301
2340
|
return false;
|
|
2302
2341
|
}
|
|
2303
|
-
if (
|
|
2304
|
-
|
|
2342
|
+
if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
|
|
2343
|
+
settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
|
|
2344
|
+
return true;
|
|
2305
2345
|
}
|
|
2306
|
-
const
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
return true;
|
|
2313
|
-
}
|
|
2314
|
-
function advanceOffsetInitialScroll(ctx, options) {
|
|
2315
|
-
var _a3, _b;
|
|
2316
|
-
const state = ctx.state;
|
|
2317
|
-
const advanceableState = getAdvanceableInitialScrollState(state);
|
|
2318
|
-
if (!advanceableState) {
|
|
2319
|
-
return false;
|
|
2346
|
+
const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
2347
|
+
const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
|
|
2348
|
+
const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
|
|
2349
|
+
if (isAtExpectedNativeClamp) {
|
|
2350
|
+
settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
|
|
2351
|
+
return true;
|
|
2320
2352
|
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2353
|
+
if (state.pendingMaintainScrollAtEnd && peek$(ctx, "isWithinMaintainScrollAtEndThreshold") && progressTowardAmount > MVCP_POSITION_EPSILON) {
|
|
2354
|
+
settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
|
|
2355
|
+
return true;
|
|
2356
|
+
}
|
|
2357
|
+
if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
|
|
2358
|
+
pending.furthestProgressTowardAmount = progressTowardAmount;
|
|
2325
2359
|
return false;
|
|
2326
2360
|
}
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
forceScroll,
|
|
2331
|
-
resolvedOffset,
|
|
2332
|
-
target: initialScroll
|
|
2333
|
-
});
|
|
2334
|
-
return true;
|
|
2335
|
-
}
|
|
2336
|
-
function advanceCurrentInitialScrollSession(ctx, options) {
|
|
2337
|
-
var _a3;
|
|
2338
|
-
return ((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" ? advanceOffsetInitialScroll(ctx, {
|
|
2339
|
-
forceScroll: options == null ? void 0 : options.forceScroll
|
|
2340
|
-
}) : advanceMeasuredInitialScroll(ctx, {
|
|
2341
|
-
forceScroll: options == null ? void 0 : options.forceScroll
|
|
2342
|
-
});
|
|
2343
|
-
}
|
|
2344
|
-
|
|
2345
|
-
// src/utils/checkAllSizesKnown.ts
|
|
2346
|
-
function isNullOrUndefined2(value) {
|
|
2347
|
-
return value === null || value === void 0;
|
|
2348
|
-
}
|
|
2349
|
-
function getMountedIndicesInRange(state, start, end) {
|
|
2350
|
-
if (!isNullOrUndefined2(end) && !isNullOrUndefined2(start) && start >= 0 && end >= 0) {
|
|
2351
|
-
return Array.from(state.containerItemKeys.keys()).map((key) => state.indexByKey.get(key)).filter((index) => index !== void 0 && index >= start && index <= end).sort((a, b) => a - b);
|
|
2361
|
+
if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
|
|
2362
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2363
|
+
return false;
|
|
2352
2364
|
}
|
|
2353
|
-
return
|
|
2354
|
-
}
|
|
2355
|
-
function getMountedBufferedIndices(state) {
|
|
2356
|
-
return getMountedIndicesInRange(state, state.startBuffered, state.endBuffered);
|
|
2357
|
-
}
|
|
2358
|
-
function getMountedNoBufferIndices(state) {
|
|
2359
|
-
return getMountedIndicesInRange(state, state.startNoBuffer, state.endNoBuffer);
|
|
2360
|
-
}
|
|
2361
|
-
function checkAllSizesKnown(state, indices) {
|
|
2362
|
-
return indices.length > 0 && indices.every((index) => {
|
|
2363
|
-
const key = getId(state, index);
|
|
2364
|
-
return key !== void 0 && state.sizesKnown.has(key);
|
|
2365
|
-
});
|
|
2365
|
+
return false;
|
|
2366
2366
|
}
|
|
2367
|
-
|
|
2368
|
-
// src/utils/requestAdjust.ts
|
|
2369
|
-
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
2367
|
+
function prepareMVCP(ctx, dataChanged) {
|
|
2370
2368
|
const state = ctx.state;
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2369
|
+
const { idsInView, positions, props } = state;
|
|
2370
|
+
const {
|
|
2371
|
+
maintainVisibleContentPosition: { data: mvcpData, size: mvcpScroll, shouldRestorePosition }
|
|
2372
|
+
} = props;
|
|
2373
|
+
const isWeb = Platform.OS === "web";
|
|
2374
|
+
const now = Date.now();
|
|
2375
|
+
const enableMVCPAnchorLock = isWeb && (!!dataChanged || !!state.mvcpAnchorLock);
|
|
2376
|
+
const scrollingTo = state.scrollingTo;
|
|
2377
|
+
const anchorLock = isWeb ? resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) : void 0;
|
|
2378
|
+
let prevPosition;
|
|
2379
|
+
let targetId;
|
|
2380
|
+
const idsInViewWithPositions = [];
|
|
2381
|
+
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
2382
|
+
const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
|
|
2383
|
+
const isEndAnchoredScrollTarget = scrollTarget !== void 0 && state.props.data.length > 0 && scrollTarget >= state.props.data.length - 1 && (scrollingToViewPosition != null ? scrollingToViewPosition : 0) > 0;
|
|
2384
|
+
const shouldMVCP = dataChanged ? mvcpData : mvcpScroll;
|
|
2385
|
+
const indexByKey = state.indexByKey;
|
|
2386
|
+
const prevScroll = state.scroll;
|
|
2387
|
+
const prevTotalSize = getContentSize(ctx);
|
|
2388
|
+
if (shouldMVCP) {
|
|
2389
|
+
if (!isWeb && state.pendingNativeMVCPAdjust && scrollTarget === void 0) {
|
|
2390
|
+
maybeApplyPredictedNativeMVCPAdjust(ctx);
|
|
2391
|
+
return void 0;
|
|
2392
|
+
}
|
|
2393
|
+
if (anchorLock && scrollTarget === void 0) {
|
|
2394
|
+
targetId = anchorLock.id;
|
|
2395
|
+
prevPosition = anchorLock.position;
|
|
2396
|
+
} else if (scrollTarget !== void 0) {
|
|
2397
|
+
if (!IsNewArchitecture && (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll)) {
|
|
2398
|
+
return void 0;
|
|
2399
|
+
}
|
|
2400
|
+
targetId = getId(state, scrollTarget);
|
|
2401
|
+
} else if (idsInView.length > 0 && state.didContainersLayout && !dataChanged) {
|
|
2402
|
+
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
2403
|
+
}
|
|
2404
|
+
if (dataChanged && idsInView.length > 0 && state.didContainersLayout) {
|
|
2405
|
+
for (let i = 0; i < idsInView.length; i++) {
|
|
2406
|
+
const id = idsInView[i];
|
|
2407
|
+
const index = indexByKey.get(id);
|
|
2408
|
+
if (index !== void 0) {
|
|
2409
|
+
const position = positions[index];
|
|
2410
|
+
if (position !== void 0) {
|
|
2411
|
+
idsInViewWithPositions.push({ id, position });
|
|
2412
|
+
}
|
|
2383
2413
|
}
|
|
2384
2414
|
}
|
|
2385
|
-
}
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2415
|
+
}
|
|
2416
|
+
if (targetId !== void 0 && prevPosition === void 0) {
|
|
2417
|
+
const targetIndex = indexByKey.get(targetId);
|
|
2418
|
+
if (targetIndex !== void 0) {
|
|
2419
|
+
prevPosition = positions[targetIndex];
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
return () => {
|
|
2423
|
+
let positionDiff = 0;
|
|
2424
|
+
let anchorIdForLock = anchorLock == null ? void 0 : anchorLock.id;
|
|
2425
|
+
let anchorPositionForLock;
|
|
2426
|
+
let skipTargetAnchor = false;
|
|
2427
|
+
const data = state.props.data;
|
|
2428
|
+
const shouldValidateLockedAnchor = isWeb && dataChanged && mvcpData && scrollTarget === void 0 && targetId !== void 0 && (anchorLock == null ? void 0 : anchorLock.id) === targetId && shouldRestorePosition !== void 0;
|
|
2429
|
+
if (shouldValidateLockedAnchor && targetId !== void 0) {
|
|
2430
|
+
const index = indexByKey.get(targetId);
|
|
2431
|
+
if (index !== void 0) {
|
|
2432
|
+
const item = data[index];
|
|
2433
|
+
skipTargetAnchor = item === void 0 || !shouldRestorePosition(item, index, data);
|
|
2434
|
+
if (skipTargetAnchor && (anchorLock == null ? void 0 : anchorLock.id) === targetId) {
|
|
2435
|
+
state.mvcpAnchorLock = void 0;
|
|
2436
|
+
}
|
|
2395
2437
|
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2438
|
+
}
|
|
2439
|
+
const shouldUseFallbackVisibleAnchor = dataChanged && mvcpData && scrollTarget === void 0 && (() => {
|
|
2440
|
+
if (targetId === void 0 || skipTargetAnchor) {
|
|
2441
|
+
return true;
|
|
2400
2442
|
}
|
|
2401
|
-
|
|
2402
|
-
|
|
2443
|
+
const targetIndex = indexByKey.get(targetId);
|
|
2444
|
+
return targetIndex === void 0 || positions[targetIndex] === void 0;
|
|
2445
|
+
})();
|
|
2446
|
+
if (shouldUseFallbackVisibleAnchor) {
|
|
2447
|
+
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
2448
|
+
const { id, position } = idsInViewWithPositions[i];
|
|
2449
|
+
const index = indexByKey.get(id);
|
|
2450
|
+
if (index !== void 0 && shouldRestorePosition) {
|
|
2451
|
+
const item = data[index];
|
|
2452
|
+
if (item === void 0 || !shouldRestorePosition(item, index, data)) {
|
|
2453
|
+
continue;
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
const newPosition = index !== void 0 ? positions[index] : void 0;
|
|
2457
|
+
if (newPosition !== void 0) {
|
|
2458
|
+
positionDiff = newPosition - position;
|
|
2459
|
+
anchorIdForLock = id;
|
|
2460
|
+
anchorPositionForLock = newPosition;
|
|
2461
|
+
break;
|
|
2462
|
+
}
|
|
2403
2463
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
(
|
|
2464
|
+
}
|
|
2465
|
+
if (!skipTargetAnchor && targetId !== void 0 && prevPosition !== void 0) {
|
|
2466
|
+
const targetIndex = indexByKey.get(targetId);
|
|
2467
|
+
const newPosition = targetIndex !== void 0 ? positions[targetIndex] : void 0;
|
|
2468
|
+
if (newPosition !== void 0) {
|
|
2469
|
+
const totalSize = getContentSize(ctx);
|
|
2470
|
+
let diff = newPosition - prevPosition;
|
|
2471
|
+
if (diff !== 0 && isEndAnchoredScrollTarget && state.scroll + state.scrollLength > totalSize) {
|
|
2472
|
+
if (diff > 0) {
|
|
2473
|
+
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
2474
|
+
} else {
|
|
2475
|
+
diff = 0;
|
|
2476
|
+
}
|
|
2413
2477
|
}
|
|
2414
|
-
|
|
2478
|
+
positionDiff = diff;
|
|
2479
|
+
anchorIdForLock = targetId;
|
|
2480
|
+
anchorPositionForLock = newPosition;
|
|
2481
|
+
}
|
|
2415
2482
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2483
|
+
if (scrollingToViewPosition && scrollingToViewPosition > 0) {
|
|
2484
|
+
const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
|
|
2485
|
+
const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
|
|
2486
|
+
if (newSize !== void 0 && prevSize !== void 0 && newSize !== prevSize) {
|
|
2487
|
+
const diff = newSize - prevSize;
|
|
2488
|
+
if (diff !== 0) {
|
|
2489
|
+
positionDiff += diff * scrollingToViewPosition;
|
|
2490
|
+
scrollingTo.itemSize = newSize;
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
updateAnchorLock(state, {
|
|
2495
|
+
anchorId: anchorIdForLock,
|
|
2496
|
+
anchorPosition: anchorPositionForLock,
|
|
2497
|
+
dataChanged,
|
|
2498
|
+
now,
|
|
2499
|
+
positionDiff
|
|
2500
|
+
});
|
|
2501
|
+
if (shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget)) {
|
|
2502
|
+
state.pendingNativeMVCPAdjust = {
|
|
2503
|
+
amount: positionDiff,
|
|
2504
|
+
furthestProgressTowardAmount: 0,
|
|
2505
|
+
manualApplied: 0,
|
|
2506
|
+
startScroll: prevScroll
|
|
2507
|
+
};
|
|
2508
|
+
maybeApplyPredictedNativeMVCPAdjust(ctx);
|
|
2509
|
+
return;
|
|
2510
|
+
}
|
|
2511
|
+
if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
|
|
2512
|
+
const shouldSkipAdjustForMaintainedEnd = state.maintainingScrollAtEnd && peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
2513
|
+
if (!shouldSkipAdjustForMaintainedEnd) {
|
|
2514
|
+
requestAdjust(ctx, positionDiff, dataChanged && mvcpData);
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
};
|
|
2420
2518
|
}
|
|
2421
2519
|
}
|
|
2422
2520
|
|
|
2423
|
-
// src/
|
|
2424
|
-
var
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
return ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
2431
|
-
}
|
|
2432
|
-
function isOffsetInitialScrollSession(state) {
|
|
2521
|
+
// src/platform/flushSync.native.ts
|
|
2522
|
+
var flushSync = (fn) => {
|
|
2523
|
+
fn();
|
|
2524
|
+
};
|
|
2525
|
+
|
|
2526
|
+
// src/core/updateScroll.ts
|
|
2527
|
+
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
2433
2528
|
var _a3;
|
|
2434
|
-
|
|
2435
|
-
}
|
|
2436
|
-
|
|
2437
|
-
if (
|
|
2438
|
-
|
|
2529
|
+
const state = ctx.state;
|
|
2530
|
+
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
2531
|
+
const prevScroll = state.scroll;
|
|
2532
|
+
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
2533
|
+
state.hasScrolled = true;
|
|
2439
2534
|
}
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2535
|
+
state.lastBatchingAction = Date.now();
|
|
2536
|
+
const currentTime = Date.now();
|
|
2537
|
+
const adjust = scrollAdjustHandler.getAdjust();
|
|
2538
|
+
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
2539
|
+
if (adjustChanged) {
|
|
2540
|
+
scrollHistory.length = 0;
|
|
2444
2541
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
const endOffset = offset + scrollLength;
|
|
2450
|
-
const visibleIndices = [];
|
|
2451
|
-
let index = requestedStartIndex !== void 0 ? Math.max(0, Math.min(dataLength - 1, requestedStartIndex)) : 0;
|
|
2452
|
-
while (index > 0) {
|
|
2453
|
-
const previousIndex = index - 1;
|
|
2454
|
-
const previousPosition = positions[previousIndex];
|
|
2455
|
-
if (previousPosition === void 0) {
|
|
2456
|
-
index = previousIndex;
|
|
2457
|
-
continue;
|
|
2458
|
-
}
|
|
2459
|
-
const previousSize = getSize(previousIndex);
|
|
2460
|
-
if (previousSize === void 0) {
|
|
2461
|
-
index = previousIndex;
|
|
2462
|
-
continue;
|
|
2463
|
-
}
|
|
2464
|
-
if (previousPosition + previousSize <= offset) {
|
|
2465
|
-
break;
|
|
2542
|
+
state.lastScrollAdjustForHistory = adjust;
|
|
2543
|
+
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
2544
|
+
if (!adjustChanged) {
|
|
2545
|
+
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
2466
2546
|
}
|
|
2467
|
-
index = previousIndex;
|
|
2468
2547
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2548
|
+
if (scrollHistory.length > 5) {
|
|
2549
|
+
scrollHistory.shift();
|
|
2550
|
+
}
|
|
2551
|
+
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
2552
|
+
const { lt, gt } = ignoreScrollFromMVCP;
|
|
2553
|
+
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
2554
|
+
state.ignoreScrollFromMVCPIgnored = true;
|
|
2555
|
+
return;
|
|
2473
2556
|
}
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2557
|
+
}
|
|
2558
|
+
state.scrollPrev = prevScroll;
|
|
2559
|
+
state.scrollPrevTime = state.scrollTime;
|
|
2560
|
+
state.scroll = newScroll;
|
|
2561
|
+
state.scrollTime = currentTime;
|
|
2562
|
+
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2563
|
+
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
2564
|
+
const scrollLength = state.scrollLength;
|
|
2565
|
+
const lastCalculated = state.scrollLastCalculate;
|
|
2566
|
+
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2567
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2568
|
+
if (shouldUpdate) {
|
|
2569
|
+
state.scrollLastCalculate = state.scroll;
|
|
2570
|
+
state.ignoreScrollFromMVCPIgnored = false;
|
|
2571
|
+
state.lastScrollDelta = scrollDelta;
|
|
2572
|
+
const runCalculateItems = () => {
|
|
2573
|
+
var _a4;
|
|
2574
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
2575
|
+
checkThresholds(ctx);
|
|
2576
|
+
};
|
|
2577
|
+
if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust) {
|
|
2578
|
+
state.mvcpAnchorLock = void 0;
|
|
2579
|
+
state.pendingNativeMVCPAdjust = void 0;
|
|
2580
|
+
state.userScrollAnchorResetKeys = /* @__PURE__ */ new Set();
|
|
2581
|
+
if (state.queuedMVCPRecalculate !== void 0) {
|
|
2582
|
+
cancelAnimationFrame(state.queuedMVCPRecalculate);
|
|
2583
|
+
state.queuedMVCPRecalculate = void 0;
|
|
2584
|
+
}
|
|
2585
|
+
flushSync(runCalculateItems);
|
|
2586
|
+
} else {
|
|
2587
|
+
runCalculateItems();
|
|
2477
2588
|
}
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2589
|
+
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
2590
|
+
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
2591
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
2592
|
+
doMaintainScrollAtEnd(ctx);
|
|
2482
2593
|
}
|
|
2594
|
+
state.dataChangeNeedsScrollUpdate = false;
|
|
2595
|
+
state.lastScrollDelta = 0;
|
|
2483
2596
|
}
|
|
2484
|
-
return visibleIndices;
|
|
2485
|
-
}
|
|
2486
|
-
function shouldAbortBootstrapReveal(options) {
|
|
2487
|
-
const {
|
|
2488
|
-
mountFrameCount,
|
|
2489
|
-
maxFrames = DEFAULT_BOOTSTRAP_REVEAL_MAX_FRAMES,
|
|
2490
|
-
maxPasses = DEFAULT_BOOTSTRAP_REVEAL_MAX_PASSES,
|
|
2491
|
-
passCount
|
|
2492
|
-
} = options;
|
|
2493
|
-
return mountFrameCount >= maxFrames || passCount >= maxPasses;
|
|
2494
2597
|
}
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
console.warn(BOOTSTRAP_REVEAL_ABORT_WARNING);
|
|
2598
|
+
|
|
2599
|
+
// src/core/scrollTo.ts
|
|
2600
|
+
function getAverageSizeSnapshot(state) {
|
|
2601
|
+
if (Object.keys(state.averageSizes).length === 0) {
|
|
2602
|
+
return void 0;
|
|
2501
2603
|
}
|
|
2502
|
-
|
|
2503
|
-
|
|
2604
|
+
const snapshot = {};
|
|
2605
|
+
for (const itemType in state.averageSizes) {
|
|
2606
|
+
const averages = state.averageSizes[itemType];
|
|
2607
|
+
snapshot[itemType] = averages.avg;
|
|
2608
|
+
}
|
|
2609
|
+
return snapshot;
|
|
2504
2610
|
}
|
|
2505
|
-
function
|
|
2611
|
+
function syncInitialScrollNativeWatchdog(state, options) {
|
|
2506
2612
|
var _a3;
|
|
2507
|
-
const
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
|
|
2613
|
+
const { isInitialScroll, requestedOffset, targetOffset } = options;
|
|
2614
|
+
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2615
|
+
const shouldWatchInitialNativeScroll = !state.didFinishInitialScroll && (isInitialScroll || !!existingWatchdog) && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
|
|
2616
|
+
const shouldClearInitialNativeScrollWatchdog = !state.didFinishInitialScroll && !!existingWatchdog && initialScrollWatchdog.isAtZeroTargetOffset(requestedOffset);
|
|
2617
|
+
if (shouldWatchInitialNativeScroll) {
|
|
2618
|
+
state.hasScrolled = false;
|
|
2619
|
+
initialScrollWatchdog.set(state, {
|
|
2620
|
+
startScroll: (_a3 = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _a3 : state.scroll,
|
|
2621
|
+
targetOffset
|
|
2622
|
+
});
|
|
2623
|
+
return;
|
|
2511
2624
|
}
|
|
2512
|
-
if (
|
|
2513
|
-
|
|
2625
|
+
if (shouldClearInitialNativeScrollWatchdog) {
|
|
2626
|
+
initialScrollWatchdog.clear(state);
|
|
2514
2627
|
}
|
|
2515
|
-
setInitialScrollSession(state, {
|
|
2516
|
-
bootstrap: null,
|
|
2517
|
-
kind: (_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind
|
|
2518
|
-
});
|
|
2519
|
-
}
|
|
2520
|
-
function startBootstrapInitialScrollSession(state, options) {
|
|
2521
|
-
var _a3, _b, _c;
|
|
2522
|
-
const previousBootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
2523
|
-
setInitialScrollSession(state, {
|
|
2524
|
-
bootstrap: {
|
|
2525
|
-
frameHandle: previousBootstrapInitialScroll == null ? void 0 : previousBootstrapInitialScroll.frameHandle,
|
|
2526
|
-
// Re-arming during the initial mount should spend from the same watchdog budget.
|
|
2527
|
-
mountFrameCount: (_a3 = previousBootstrapInitialScroll == null ? void 0 : previousBootstrapInitialScroll.mountFrameCount) != null ? _a3 : 0,
|
|
2528
|
-
passCount: 0,
|
|
2529
|
-
previousResolvedOffset: void 0,
|
|
2530
|
-
scroll: options.scroll,
|
|
2531
|
-
seedContentOffset: (_c = (_b = options.seedContentOffset) != null ? _b : previousBootstrapInitialScroll == null ? void 0 : previousBootstrapInitialScroll.seedContentOffset) != null ? _c : options.scroll,
|
|
2532
|
-
targetIndexSeed: options.targetIndexSeed,
|
|
2533
|
-
visibleIndices: void 0
|
|
2534
|
-
},
|
|
2535
|
-
kind: "bootstrap"
|
|
2536
|
-
});
|
|
2537
2628
|
}
|
|
2538
|
-
function
|
|
2539
|
-
var _a3
|
|
2540
|
-
const
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2629
|
+
function scrollTo(ctx, params) {
|
|
2630
|
+
var _a3;
|
|
2631
|
+
const state = ctx.state;
|
|
2632
|
+
const { noScrollingTo, forceScroll, ...scrollTarget } = params;
|
|
2633
|
+
const {
|
|
2634
|
+
animated,
|
|
2635
|
+
isInitialScroll,
|
|
2636
|
+
offset: scrollTargetOffset,
|
|
2637
|
+
precomputedWithViewOffset,
|
|
2638
|
+
waitForInitialScrollCompletionFrame
|
|
2639
|
+
} = scrollTarget;
|
|
2640
|
+
const {
|
|
2641
|
+
props: { horizontal }
|
|
2642
|
+
} = state;
|
|
2643
|
+
if (state.animFrameCheckFinishedScroll) {
|
|
2644
|
+
cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
|
|
2645
|
+
}
|
|
2646
|
+
if (state.timeoutCheckFinishedScrollFallback) {
|
|
2647
|
+
clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
|
|
2648
|
+
}
|
|
2649
|
+
const requestedOffset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
|
|
2650
|
+
const shouldPreserveRawInitialOffsetRequest = !!isInitialScroll && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset";
|
|
2651
|
+
const targetOffset = clampScrollOffset(ctx, requestedOffset, scrollTarget);
|
|
2652
|
+
const offset = shouldPreserveRawInitialOffsetRequest ? requestedOffset : targetOffset;
|
|
2653
|
+
state.scrollHistory.length = 0;
|
|
2654
|
+
if (!noScrollingTo) {
|
|
2655
|
+
if (isInitialScroll) {
|
|
2656
|
+
initialScrollCompletion.resetFlags(state);
|
|
2548
2657
|
}
|
|
2658
|
+
const averageSizeSnapshot = getAverageSizeSnapshot(state);
|
|
2659
|
+
state.scrollingTo = {
|
|
2660
|
+
...scrollTarget,
|
|
2661
|
+
...averageSizeSnapshot ? { averageSizeSnapshot } : {},
|
|
2662
|
+
targetOffset,
|
|
2663
|
+
waitForInitialScrollCompletionFrame
|
|
2664
|
+
};
|
|
2665
|
+
}
|
|
2666
|
+
state.scrollPending = targetOffset;
|
|
2667
|
+
syncInitialScrollNativeWatchdog(state, { isInitialScroll, requestedOffset: offset, targetOffset });
|
|
2668
|
+
if (!animated && !isInitialScroll && !noScrollingTo && Math.abs(state.scroll - targetOffset) > 1) {
|
|
2669
|
+
updateScroll(ctx, targetOffset, false, { markHasScrolled: false });
|
|
2670
|
+
}
|
|
2671
|
+
if (forceScroll || !isInitialScroll || Platform.OS === "android") {
|
|
2672
|
+
doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
|
|
2549
2673
|
} else {
|
|
2550
|
-
|
|
2551
|
-
bootstrapInitialScroll.previousResolvedOffset = void 0;
|
|
2552
|
-
bootstrapInitialScroll.scroll = (_a3 = options == null ? void 0 : options.scroll) != null ? _a3 : bootstrapInitialScroll.scroll;
|
|
2553
|
-
bootstrapInitialScroll.seedContentOffset = (_b = options == null ? void 0 : options.seedContentOffset) != null ? _b : bootstrapInitialScroll.seedContentOffset;
|
|
2554
|
-
bootstrapInitialScroll.targetIndexSeed = (_c = options == null ? void 0 : options.targetIndexSeed) != null ? _c : bootstrapInitialScroll.targetIndexSeed;
|
|
2555
|
-
bootstrapInitialScroll.visibleIndices = void 0;
|
|
2556
|
-
setInitialScrollSession(state, {
|
|
2557
|
-
bootstrap: bootstrapInitialScroll,
|
|
2558
|
-
kind: "bootstrap"
|
|
2559
|
-
});
|
|
2674
|
+
state.scroll = offset;
|
|
2560
2675
|
}
|
|
2561
2676
|
}
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2677
|
+
|
|
2678
|
+
// src/core/scrollToIndex.ts
|
|
2679
|
+
function clampScrollIndex(index, dataLength) {
|
|
2680
|
+
if (dataLength <= 0) {
|
|
2681
|
+
return -1;
|
|
2682
|
+
}
|
|
2683
|
+
if (index >= dataLength) {
|
|
2684
|
+
return dataLength - 1;
|
|
2685
|
+
}
|
|
2686
|
+
if (index < 0) {
|
|
2687
|
+
return 0;
|
|
2688
|
+
}
|
|
2689
|
+
return index;
|
|
2569
2690
|
}
|
|
2570
|
-
function
|
|
2691
|
+
function scrollToIndex(ctx, {
|
|
2692
|
+
index,
|
|
2693
|
+
viewOffset = 0,
|
|
2694
|
+
animated = true,
|
|
2695
|
+
forceScroll,
|
|
2696
|
+
isInitialScroll,
|
|
2697
|
+
viewPosition
|
|
2698
|
+
}) {
|
|
2571
2699
|
const state = ctx.state;
|
|
2572
|
-
const
|
|
2573
|
-
|
|
2574
|
-
|
|
2700
|
+
const { data } = state.props;
|
|
2701
|
+
index = clampScrollIndex(index, data.length);
|
|
2702
|
+
const itemSize = getItemSizeAtIndex(ctx, index);
|
|
2703
|
+
const firstIndexOffset = calculateOffsetForIndex(ctx, index);
|
|
2704
|
+
const isLast = index === data.length - 1;
|
|
2705
|
+
if (isLast && viewPosition === void 0) {
|
|
2706
|
+
viewPosition = 1;
|
|
2575
2707
|
}
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
return;
|
|
2588
|
-
}
|
|
2589
|
-
ensureBootstrapInitialScrollFrameTicker(ctx);
|
|
2590
|
-
};
|
|
2591
|
-
bootstrapInitialScroll.frameHandle = requestAnimationFrame(tick);
|
|
2708
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2709
|
+
scrollTo(ctx, {
|
|
2710
|
+
animated,
|
|
2711
|
+
forceScroll,
|
|
2712
|
+
index,
|
|
2713
|
+
isInitialScroll,
|
|
2714
|
+
itemSize,
|
|
2715
|
+
offset: firstIndexOffset,
|
|
2716
|
+
viewOffset,
|
|
2717
|
+
viewPosition: viewPosition != null ? viewPosition : 0
|
|
2718
|
+
});
|
|
2592
2719
|
}
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2720
|
+
|
|
2721
|
+
// src/core/initialScroll.ts
|
|
2722
|
+
function dispatchInitialScroll(ctx, params) {
|
|
2723
|
+
const { forceScroll, resolvedOffset, target, waitForCompletionFrame } = params;
|
|
2724
|
+
const requestedIndex = target.index;
|
|
2725
|
+
const index = requestedIndex !== void 0 ? clampScrollIndex(requestedIndex, ctx.state.props.data.length) : void 0;
|
|
2726
|
+
const itemSize = getItemSizeAtIndex(ctx, index);
|
|
2727
|
+
scrollTo(ctx, {
|
|
2728
|
+
animated: false,
|
|
2729
|
+
forceScroll,
|
|
2730
|
+
index: index !== void 0 && index >= 0 ? index : void 0,
|
|
2731
|
+
isInitialScroll: true,
|
|
2732
|
+
itemSize,
|
|
2733
|
+
offset: resolvedOffset,
|
|
2734
|
+
precomputedWithViewOffset: true,
|
|
2735
|
+
viewOffset: target.viewOffset,
|
|
2736
|
+
viewPosition: target.viewPosition,
|
|
2737
|
+
waitForInitialScrollCompletionFrame: waitForCompletionFrame
|
|
2738
|
+
});
|
|
2597
2739
|
}
|
|
2598
|
-
function
|
|
2599
|
-
|
|
2740
|
+
function setInitialScrollTarget(state, target, options) {
|
|
2741
|
+
var _a3;
|
|
2742
|
+
state.clearPreservedInitialScrollOnNextFinish = void 0;
|
|
2743
|
+
if (state.timeoutPreservedInitialScrollClear !== void 0) {
|
|
2744
|
+
clearTimeout(state.timeoutPreservedInitialScrollClear);
|
|
2745
|
+
state.timeoutPreservedInitialScrollClear = void 0;
|
|
2746
|
+
}
|
|
2747
|
+
state.initialScroll = target;
|
|
2748
|
+
if ((options == null ? void 0 : options.resetDidFinish) && state.didFinishInitialScroll) {
|
|
2749
|
+
state.didFinishInitialScroll = false;
|
|
2750
|
+
}
|
|
2751
|
+
setInitialScrollSession(state, {
|
|
2752
|
+
kind: ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" ? "offset" : "bootstrap"
|
|
2753
|
+
});
|
|
2754
|
+
}
|
|
2755
|
+
function resolveInitialScrollOffset(ctx, initialScroll) {
|
|
2756
|
+
var _a3, _b;
|
|
2757
|
+
const state = ctx.state;
|
|
2758
|
+
if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset") {
|
|
2759
|
+
return (_b = initialScroll.contentOffset) != null ? _b : 0;
|
|
2760
|
+
}
|
|
2761
|
+
const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
|
|
2762
|
+
const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
|
|
2763
|
+
return clampScrollOffset(ctx, resolvedOffset, initialScroll);
|
|
2764
|
+
}
|
|
2765
|
+
function getAdvanceableInitialScrollState(state, options) {
|
|
2766
|
+
const { didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
|
|
2767
|
+
const initialScroll = state.initialScroll;
|
|
2768
|
+
const isInitialScrollInProgress = !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll);
|
|
2769
|
+
const shouldWaitForInitialLayout = !!(options == null ? void 0 : options.requiresMeasuredLayout) && !queuedInitialLayout && !isInitialScrollInProgress;
|
|
2770
|
+
if (!initialScroll || shouldWaitForInitialLayout || didFinishInitialScroll || scrollingTo && !isInitialScrollInProgress) {
|
|
2771
|
+
return void 0;
|
|
2772
|
+
}
|
|
2600
2773
|
return {
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
viewOffset: -stylePaddingBottom - footerSize,
|
|
2606
|
-
viewPosition: 1
|
|
2774
|
+
initialScroll,
|
|
2775
|
+
isInitialScrollInProgress,
|
|
2776
|
+
queuedInitialLayout,
|
|
2777
|
+
scrollingTo
|
|
2607
2778
|
};
|
|
2608
2779
|
}
|
|
2609
|
-
function
|
|
2610
|
-
|
|
2611
|
-
}
|
|
2612
|
-
function shouldPreserveInitialScrollForFooterLayout(target) {
|
|
2613
|
-
return !!(target == null ? void 0 : target.preserveForFooterLayout);
|
|
2614
|
-
}
|
|
2615
|
-
function isRetargetableBottomAlignedInitialScrollTarget(target) {
|
|
2616
|
-
return !!(target && target.viewPosition === 1 && (shouldPreserveInitialScrollForBottomPadding(target) || shouldPreserveInitialScrollForFooterLayout(target)));
|
|
2617
|
-
}
|
|
2618
|
-
function createRetargetedBottomAlignedInitialScroll(options) {
|
|
2619
|
-
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingBottom, target } = options;
|
|
2620
|
-
const preserveForFooterLayout = shouldPreserveInitialScrollForFooterLayout(target);
|
|
2621
|
-
return {
|
|
2622
|
-
...target,
|
|
2623
|
-
contentOffset: void 0,
|
|
2624
|
-
index: initialScrollAtEnd ? Math.max(0, dataLength - 1) : target.index,
|
|
2625
|
-
preserveForBottomPadding: true,
|
|
2626
|
-
preserveForFooterLayout,
|
|
2627
|
-
viewOffset: -stylePaddingBottom - (preserveForFooterLayout ? footerSize : 0),
|
|
2628
|
-
viewPosition: 1
|
|
2629
|
-
};
|
|
2630
|
-
}
|
|
2631
|
-
function areEquivalentBootstrapInitialScrollTargets(current, next) {
|
|
2632
|
-
return current.index === next.index && current.preserveForBottomPadding === next.preserveForBottomPadding && current.preserveForFooterLayout === next.preserveForFooterLayout && current.viewOffset === next.viewOffset && current.viewPosition === next.viewPosition;
|
|
2633
|
-
}
|
|
2634
|
-
function clearPendingInitialScrollFooterLayout(ctx, options) {
|
|
2635
|
-
const { dataLength, stylePaddingBottom, target } = options;
|
|
2780
|
+
function advanceMeasuredInitialScroll(ctx, options) {
|
|
2781
|
+
var _a3, _b, _c;
|
|
2636
2782
|
const state = ctx.state;
|
|
2637
|
-
|
|
2638
|
-
|
|
2783
|
+
const advanceableState = getAdvanceableInitialScrollState(state, {
|
|
2784
|
+
requiresMeasuredLayout: true
|
|
2785
|
+
});
|
|
2786
|
+
if (!advanceableState) {
|
|
2787
|
+
return false;
|
|
2639
2788
|
}
|
|
2640
|
-
const
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2789
|
+
const { initialScroll, isInitialScrollInProgress, queuedInitialLayout } = advanceableState;
|
|
2790
|
+
const scrollingTo = isInitialScrollInProgress ? advanceableState.scrollingTo : void 0;
|
|
2791
|
+
const resolvedOffset = resolveInitialScrollOffset(ctx, initialScroll);
|
|
2792
|
+
const activeInitialTargetOffset = scrollingTo ? (_a3 = scrollingTo.targetOffset) != null ? _a3 : scrollingTo.offset : void 0;
|
|
2793
|
+
const didOffsetChange = initialScroll.contentOffset === void 0 || Math.abs(initialScroll.contentOffset - resolvedOffset) > 1;
|
|
2794
|
+
const didActiveInitialTargetChange = activeInitialTargetOffset !== void 0 && Math.abs(activeInitialTargetOffset - resolvedOffset) > 1;
|
|
2795
|
+
const isAlreadyAtDesiredInitialTarget = activeInitialTargetOffset !== void 0 && Math.abs(state.scroll - resolvedOffset) <= 1 && Math.abs(state.scrollPending - resolvedOffset) <= 1;
|
|
2796
|
+
if (!(options == null ? void 0 : options.forceScroll) && !didOffsetChange && isInitialScrollInProgress && !didActiveInitialTargetChange) {
|
|
2797
|
+
return false;
|
|
2798
|
+
}
|
|
2799
|
+
if ((options == null ? void 0 : options.forceScroll) && isAlreadyAtDesiredInitialTarget) {
|
|
2800
|
+
return false;
|
|
2801
|
+
}
|
|
2802
|
+
if (didOffsetChange && ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) !== "offset") {
|
|
2803
|
+
setInitialScrollTarget(state, { ...initialScroll, contentOffset: resolvedOffset });
|
|
2804
|
+
}
|
|
2805
|
+
const forceScroll = (_c = options == null ? void 0 : options.forceScroll) != null ? _c : !!queuedInitialLayout || isInitialScrollInProgress && didOffsetChange;
|
|
2806
|
+
dispatchInitialScroll(ctx, {
|
|
2807
|
+
forceScroll,
|
|
2808
|
+
resolvedOffset,
|
|
2809
|
+
target: initialScroll
|
|
2645
2810
|
});
|
|
2646
|
-
|
|
2647
|
-
}
|
|
2648
|
-
function clearFinishedViewportRetargetableInitialScroll(state) {
|
|
2649
|
-
clearPreservedInitialScrollTarget(state);
|
|
2811
|
+
return true;
|
|
2650
2812
|
}
|
|
2651
|
-
function
|
|
2813
|
+
function advanceOffsetInitialScroll(ctx, options) {
|
|
2814
|
+
var _a3, _b;
|
|
2652
2815
|
const state = ctx.state;
|
|
2653
|
-
|
|
2816
|
+
const advanceableState = getAdvanceableInitialScrollState(state);
|
|
2817
|
+
if (!advanceableState) {
|
|
2654
2818
|
return false;
|
|
2655
2819
|
}
|
|
2656
|
-
const
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2820
|
+
const { initialScroll, queuedInitialLayout } = advanceableState;
|
|
2821
|
+
const resolvedOffset = (_a3 = initialScroll.contentOffset) != null ? _a3 : 0;
|
|
2822
|
+
const isAlreadyAtDesiredInitialTarget = Math.abs(state.scroll - resolvedOffset) <= 1 && Math.abs(state.scrollPending - resolvedOffset) <= 1;
|
|
2823
|
+
if ((options == null ? void 0 : options.forceScroll) && isAlreadyAtDesiredInitialTarget) {
|
|
2824
|
+
return false;
|
|
2825
|
+
}
|
|
2826
|
+
const hasMeasuredScrollLayout = !!state.lastLayout && state.scrollLength > 0;
|
|
2827
|
+
const forceScroll = (_b = options == null ? void 0 : options.forceScroll) != null ? _b : hasMeasuredScrollLayout || !!queuedInitialLayout;
|
|
2828
|
+
dispatchInitialScroll(ctx, {
|
|
2829
|
+
forceScroll,
|
|
2830
|
+
resolvedOffset,
|
|
2831
|
+
target: initialScroll
|
|
2832
|
+
});
|
|
2833
|
+
return true;
|
|
2663
2834
|
}
|
|
2664
|
-
function
|
|
2835
|
+
function advanceCurrentInitialScrollSession(ctx, options) {
|
|
2665
2836
|
var _a3;
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2837
|
+
return ((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" ? advanceOffsetInitialScroll(ctx, {
|
|
2838
|
+
forceScroll: options == null ? void 0 : options.forceScroll
|
|
2839
|
+
}) : advanceMeasuredInitialScroll(ctx, {
|
|
2840
|
+
forceScroll: options == null ? void 0 : options.forceScroll
|
|
2841
|
+
});
|
|
2842
|
+
}
|
|
2843
|
+
|
|
2844
|
+
// src/utils/checkAllSizesKnown.ts
|
|
2845
|
+
function isNullOrUndefined2(value) {
|
|
2846
|
+
return value === null || value === void 0;
|
|
2847
|
+
}
|
|
2848
|
+
function getMountedIndicesInRange(state, start, end) {
|
|
2849
|
+
if (!isNullOrUndefined2(end) && !isNullOrUndefined2(start) && start >= 0 && end >= 0) {
|
|
2850
|
+
return Array.from(state.containerItemKeys.keys()).map((key) => state.indexByKey.get(key)).filter((index) => index !== void 0 && index >= start && index <= end).sort((a, b) => a - b);
|
|
2670
2851
|
}
|
|
2671
|
-
|
|
2672
|
-
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
2852
|
+
return [];
|
|
2673
2853
|
}
|
|
2674
|
-
function
|
|
2675
|
-
|
|
2854
|
+
function getMountedBufferedIndices(state) {
|
|
2855
|
+
return getMountedIndicesInRange(state, state.startBuffered, state.endBuffered);
|
|
2856
|
+
}
|
|
2857
|
+
function getMountedNoBufferIndices(state) {
|
|
2858
|
+
return getMountedIndicesInRange(state, state.startNoBuffer, state.endNoBuffer);
|
|
2859
|
+
}
|
|
2860
|
+
function checkAllSizesKnown(state, indices) {
|
|
2861
|
+
return indices.length > 0 && indices.every((index) => {
|
|
2862
|
+
const key = getId(state, index);
|
|
2863
|
+
return key !== void 0 && state.sizesKnown.has(key);
|
|
2864
|
+
});
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
// src/core/bootstrapInitialScroll.ts
|
|
2868
|
+
var DEFAULT_BOOTSTRAP_REVEAL_EPSILON = 1;
|
|
2869
|
+
var DEFAULT_BOOTSTRAP_REVEAL_MAX_FRAMES = 8;
|
|
2870
|
+
var DEFAULT_BOOTSTRAP_REVEAL_MAX_PASSES = 24;
|
|
2871
|
+
var BOOTSTRAP_REVEAL_ABORT_WARNING = "LegendList bootstrap initial scroll aborted after exceeding convergence bounds.";
|
|
2872
|
+
function getBootstrapInitialScrollSession(state) {
|
|
2873
|
+
var _a3;
|
|
2874
|
+
return ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
2875
|
+
}
|
|
2876
|
+
function isOffsetInitialScrollSession(state) {
|
|
2877
|
+
var _a3;
|
|
2878
|
+
return ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset";
|
|
2879
|
+
}
|
|
2880
|
+
function doVisibleIndicesMatch(previous, next) {
|
|
2881
|
+
if (!previous || previous.length !== next.length) {
|
|
2676
2882
|
return false;
|
|
2677
2883
|
}
|
|
2678
|
-
|
|
2679
|
-
|
|
2884
|
+
for (let i = 0; i < previous.length; i++) {
|
|
2885
|
+
if (previous[i] !== next[i]) {
|
|
2886
|
+
return false;
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2680
2889
|
return true;
|
|
2681
2890
|
}
|
|
2682
|
-
function
|
|
2683
|
-
const
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2891
|
+
function getBootstrapRevealVisibleIndices(options) {
|
|
2892
|
+
const { dataLength, getSize, offset, positions, scrollLength, startIndex: requestedStartIndex } = options;
|
|
2893
|
+
const endOffset = offset + scrollLength;
|
|
2894
|
+
const visibleIndices = [];
|
|
2895
|
+
let index = requestedStartIndex !== void 0 ? Math.max(0, Math.min(dataLength - 1, requestedStartIndex)) : 0;
|
|
2896
|
+
while (index > 0) {
|
|
2897
|
+
const previousIndex = index - 1;
|
|
2898
|
+
const previousPosition = positions[previousIndex];
|
|
2899
|
+
if (previousPosition === void 0) {
|
|
2900
|
+
index = previousIndex;
|
|
2901
|
+
continue;
|
|
2690
2902
|
}
|
|
2691
|
-
const
|
|
2692
|
-
if (
|
|
2693
|
-
|
|
2694
|
-
|
|
2903
|
+
const previousSize = getSize(previousIndex);
|
|
2904
|
+
if (previousSize === void 0) {
|
|
2905
|
+
index = previousIndex;
|
|
2906
|
+
continue;
|
|
2695
2907
|
}
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
activeCorrection.lastRequestTime = Date.now();
|
|
2699
|
-
requestAdjust(ctx, offsetDiff);
|
|
2908
|
+
if (previousPosition + previousSize <= offset) {
|
|
2909
|
+
break;
|
|
2700
2910
|
}
|
|
2701
|
-
|
|
2702
|
-
});
|
|
2703
|
-
}
|
|
2704
|
-
function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
|
|
2705
|
-
var _a3, _b;
|
|
2706
|
-
const state = ctx.state;
|
|
2707
|
-
const initialScroll = state.initialScroll;
|
|
2708
|
-
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
|
|
2709
|
-
return;
|
|
2911
|
+
index = previousIndex;
|
|
2710
2912
|
}
|
|
2711
|
-
|
|
2712
|
-
const
|
|
2713
|
-
if (
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2913
|
+
for (; index < dataLength; index++) {
|
|
2914
|
+
const position = positions[index];
|
|
2915
|
+
if (position === void 0) {
|
|
2916
|
+
continue;
|
|
2917
|
+
}
|
|
2918
|
+
const size = getSize(index);
|
|
2919
|
+
if (size === void 0) {
|
|
2920
|
+
continue;
|
|
2921
|
+
}
|
|
2922
|
+
if (position < endOffset && position + size > offset) {
|
|
2923
|
+
visibleIndices.push(index);
|
|
2924
|
+
} else if (visibleIndices.length > 0 && position >= endOffset) {
|
|
2925
|
+
break;
|
|
2723
2926
|
}
|
|
2724
2927
|
}
|
|
2928
|
+
return visibleIndices;
|
|
2725
2929
|
}
|
|
2726
|
-
function
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
clearBootstrapInitialScrollSession(state);
|
|
2735
|
-
finishInitialScroll(ctx, {
|
|
2736
|
-
resolvedOffset: offset
|
|
2737
|
-
});
|
|
2738
|
-
} else if (shouldFinishWithPreservedTarget) {
|
|
2739
|
-
clearBootstrapInitialScrollSession(state);
|
|
2740
|
-
finishInitialScroll(ctx, {
|
|
2741
|
-
preserveTarget: true,
|
|
2742
|
-
resolvedOffset: offset
|
|
2743
|
-
});
|
|
2744
|
-
} else {
|
|
2745
|
-
startBootstrapInitialScrollSession(state, {
|
|
2746
|
-
scroll: offset,
|
|
2747
|
-
seedContentOffset: Platform.OS === "web" ? 0 : offset,
|
|
2748
|
-
targetIndexSeed: target.index
|
|
2749
|
-
});
|
|
2750
|
-
ensureBootstrapInitialScrollFrameTicker(ctx);
|
|
2751
|
-
}
|
|
2930
|
+
function shouldAbortBootstrapReveal(options) {
|
|
2931
|
+
const {
|
|
2932
|
+
mountFrameCount,
|
|
2933
|
+
maxFrames = DEFAULT_BOOTSTRAP_REVEAL_MAX_FRAMES,
|
|
2934
|
+
maxPasses = DEFAULT_BOOTSTRAP_REVEAL_MAX_PASSES,
|
|
2935
|
+
passCount
|
|
2936
|
+
} = options;
|
|
2937
|
+
return mountFrameCount >= maxFrames || passCount >= maxPasses;
|
|
2752
2938
|
}
|
|
2753
|
-
function
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
const initialScroll = state.initialScroll;
|
|
2757
|
-
if (isOffsetInitialScrollSession(state) || !initialScroll) {
|
|
2758
|
-
return;
|
|
2939
|
+
function abortBootstrapRevealIfNeeded(ctx, options) {
|
|
2940
|
+
if (!shouldAbortBootstrapReveal(options)) {
|
|
2941
|
+
return false;
|
|
2759
2942
|
}
|
|
2760
|
-
|
|
2943
|
+
if (IS_DEV) {
|
|
2944
|
+
console.warn(BOOTSTRAP_REVEAL_ABORT_WARNING);
|
|
2945
|
+
}
|
|
2946
|
+
abortBootstrapInitialScroll(ctx);
|
|
2947
|
+
return true;
|
|
2948
|
+
}
|
|
2949
|
+
function clearBootstrapInitialScrollSession(state) {
|
|
2950
|
+
var _a3;
|
|
2761
2951
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
2762
|
-
const
|
|
2763
|
-
if (
|
|
2764
|
-
|
|
2765
|
-
return;
|
|
2952
|
+
const frameHandle = bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle;
|
|
2953
|
+
if (frameHandle !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
2954
|
+
cancelAnimationFrame(frameHandle);
|
|
2766
2955
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
return;
|
|
2956
|
+
if (bootstrapInitialScroll) {
|
|
2957
|
+
bootstrapInitialScroll.frameHandle = void 0;
|
|
2770
2958
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2959
|
+
setInitialScrollSession(state, {
|
|
2960
|
+
bootstrap: null,
|
|
2961
|
+
kind: (_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind
|
|
2962
|
+
});
|
|
2963
|
+
}
|
|
2964
|
+
function startBootstrapInitialScrollSession(state, options) {
|
|
2965
|
+
var _a3, _b, _c;
|
|
2966
|
+
const previousBootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
2967
|
+
setInitialScrollSession(state, {
|
|
2968
|
+
bootstrap: {
|
|
2969
|
+
frameHandle: previousBootstrapInitialScroll == null ? void 0 : previousBootstrapInitialScroll.frameHandle,
|
|
2970
|
+
// Re-arming during the initial mount should spend from the same watchdog budget.
|
|
2971
|
+
mountFrameCount: (_a3 = previousBootstrapInitialScroll == null ? void 0 : previousBootstrapInitialScroll.mountFrameCount) != null ? _a3 : 0,
|
|
2972
|
+
passCount: 0,
|
|
2973
|
+
previousResolvedOffset: void 0,
|
|
2974
|
+
scroll: options.scroll,
|
|
2975
|
+
seedContentOffset: (_c = (_b = options.seedContentOffset) != null ? _b : previousBootstrapInitialScroll == null ? void 0 : previousBootstrapInitialScroll.seedContentOffset) != null ? _c : options.scroll,
|
|
2976
|
+
targetIndexSeed: options.targetIndexSeed,
|
|
2977
|
+
visibleIndices: void 0
|
|
2978
|
+
},
|
|
2979
|
+
kind: "bootstrap"
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
function resetBootstrapInitialScrollSession(state, options) {
|
|
2983
|
+
var _a3, _b, _c;
|
|
2984
|
+
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
2985
|
+
if (!bootstrapInitialScroll) {
|
|
2986
|
+
if ((options == null ? void 0 : options.scroll) !== void 0) {
|
|
2987
|
+
startBootstrapInitialScrollSession(state, {
|
|
2988
|
+
scroll: options.scroll,
|
|
2989
|
+
seedContentOffset: options.seedContentOffset,
|
|
2990
|
+
targetIndexSeed: options.targetIndexSeed
|
|
2789
2991
|
});
|
|
2992
|
+
}
|
|
2993
|
+
} else {
|
|
2994
|
+
bootstrapInitialScroll.passCount = 0;
|
|
2995
|
+
bootstrapInitialScroll.previousResolvedOffset = void 0;
|
|
2996
|
+
bootstrapInitialScroll.scroll = (_a3 = options == null ? void 0 : options.scroll) != null ? _a3 : bootstrapInitialScroll.scroll;
|
|
2997
|
+
bootstrapInitialScroll.seedContentOffset = (_b = options == null ? void 0 : options.seedContentOffset) != null ? _b : bootstrapInitialScroll.seedContentOffset;
|
|
2998
|
+
bootstrapInitialScroll.targetIndexSeed = (_c = options == null ? void 0 : options.targetIndexSeed) != null ? _c : bootstrapInitialScroll.targetIndexSeed;
|
|
2999
|
+
bootstrapInitialScroll.visibleIndices = void 0;
|
|
3000
|
+
setInitialScrollSession(state, {
|
|
3001
|
+
bootstrap: bootstrapInitialScroll,
|
|
3002
|
+
kind: "bootstrap"
|
|
3003
|
+
});
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
function queueBootstrapInitialScrollReevaluation(state) {
|
|
3007
|
+
requestAnimationFrame(() => {
|
|
3008
|
+
var _a3;
|
|
3009
|
+
if (getBootstrapInitialScrollSession(state)) {
|
|
3010
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
3011
|
+
}
|
|
3012
|
+
});
|
|
3013
|
+
}
|
|
3014
|
+
function ensureBootstrapInitialScrollFrameTicker(ctx) {
|
|
3015
|
+
const state = ctx.state;
|
|
3016
|
+
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
3017
|
+
if (!bootstrapInitialScroll || bootstrapInitialScroll.frameHandle !== void 0) {
|
|
3018
|
+
return;
|
|
3019
|
+
}
|
|
3020
|
+
const tick = () => {
|
|
3021
|
+
const activeBootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
3022
|
+
if (!activeBootstrapInitialScroll) {
|
|
2790
3023
|
return;
|
|
2791
3024
|
}
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
seedContentOffset: shouldResetDidFinish && !bootstrapInitialScroll ? getObservedBootstrapInitialScrollOffset(state) : void 0,
|
|
2799
|
-
targetIndexSeed: updatedInitialScroll.index
|
|
2800
|
-
});
|
|
3025
|
+
activeBootstrapInitialScroll.frameHandle = void 0;
|
|
3026
|
+
activeBootstrapInitialScroll.mountFrameCount += 1;
|
|
3027
|
+
if (abortBootstrapRevealIfNeeded(ctx, {
|
|
3028
|
+
mountFrameCount: activeBootstrapInitialScroll.mountFrameCount,
|
|
3029
|
+
passCount: activeBootstrapInitialScroll.passCount
|
|
3030
|
+
})) {
|
|
2801
3031
|
return;
|
|
2802
3032
|
}
|
|
2803
|
-
|
|
2804
|
-
|
|
3033
|
+
ensureBootstrapInitialScrollFrameTicker(ctx);
|
|
3034
|
+
};
|
|
3035
|
+
bootstrapInitialScroll.frameHandle = requestAnimationFrame(tick);
|
|
3036
|
+
}
|
|
3037
|
+
function rearmBootstrapInitialScroll(ctx, options) {
|
|
3038
|
+
resetBootstrapInitialScrollSession(ctx.state, options);
|
|
3039
|
+
ensureBootstrapInitialScrollFrameTicker(ctx);
|
|
3040
|
+
queueBootstrapInitialScrollReevaluation(ctx.state);
|
|
3041
|
+
}
|
|
3042
|
+
function createInitialScrollAtEndTarget(options) {
|
|
3043
|
+
const { dataLength, footerSize, preserveForFooterLayout, stylePaddingBottom } = options;
|
|
3044
|
+
return {
|
|
3045
|
+
contentOffset: void 0,
|
|
3046
|
+
index: Math.max(0, dataLength - 1),
|
|
3047
|
+
preserveForBottomPadding: true,
|
|
3048
|
+
preserveForFooterLayout,
|
|
3049
|
+
viewOffset: -stylePaddingBottom - footerSize,
|
|
3050
|
+
viewPosition: 1
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
function shouldPreserveInitialScrollForBottomPadding(target) {
|
|
3054
|
+
return !!(target == null ? void 0 : target.preserveForBottomPadding);
|
|
3055
|
+
}
|
|
3056
|
+
function shouldPreserveInitialScrollForFooterLayout(target) {
|
|
3057
|
+
return !!(target == null ? void 0 : target.preserveForFooterLayout);
|
|
3058
|
+
}
|
|
3059
|
+
function isRetargetableBottomAlignedInitialScrollTarget(target) {
|
|
3060
|
+
return !!(target && target.viewPosition === 1 && (shouldPreserveInitialScrollForBottomPadding(target) || shouldPreserveInitialScrollForFooterLayout(target)));
|
|
3061
|
+
}
|
|
3062
|
+
function createRetargetedBottomAlignedInitialScroll(options) {
|
|
3063
|
+
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingBottom, target } = options;
|
|
3064
|
+
const preserveForFooterLayout = shouldPreserveInitialScrollForFooterLayout(target);
|
|
3065
|
+
return {
|
|
3066
|
+
...target,
|
|
3067
|
+
contentOffset: void 0,
|
|
3068
|
+
index: initialScrollAtEnd ? Math.max(0, dataLength - 1) : target.index,
|
|
3069
|
+
preserveForBottomPadding: true,
|
|
3070
|
+
preserveForFooterLayout,
|
|
3071
|
+
viewOffset: -stylePaddingBottom - (preserveForFooterLayout ? footerSize : 0),
|
|
3072
|
+
viewPosition: 1
|
|
3073
|
+
};
|
|
3074
|
+
}
|
|
3075
|
+
function areEquivalentBootstrapInitialScrollTargets(current, next) {
|
|
3076
|
+
return current.index === next.index && current.preserveForBottomPadding === next.preserveForBottomPadding && current.preserveForFooterLayout === next.preserveForFooterLayout && current.viewOffset === next.viewOffset && current.viewPosition === next.viewPosition;
|
|
3077
|
+
}
|
|
3078
|
+
function clearPendingInitialScrollFooterLayout(ctx, options) {
|
|
3079
|
+
const { dataLength, stylePaddingBottom, target } = options;
|
|
3080
|
+
const state = ctx.state;
|
|
3081
|
+
if (!shouldPreserveInitialScrollForFooterLayout(target)) {
|
|
2805
3082
|
return;
|
|
2806
3083
|
}
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
targetIndexSeed: initialScroll.index
|
|
2815
|
-
});
|
|
2816
|
-
}
|
|
3084
|
+
const clearedFooterTarget = createInitialScrollAtEndTarget({
|
|
3085
|
+
dataLength,
|
|
3086
|
+
footerSize: 0,
|
|
3087
|
+
preserveForFooterLayout: void 0,
|
|
3088
|
+
stylePaddingBottom
|
|
3089
|
+
});
|
|
3090
|
+
setInitialScrollTarget(state, clearedFooterTarget);
|
|
2817
3091
|
}
|
|
2818
|
-
function
|
|
2819
|
-
|
|
3092
|
+
function clearFinishedViewportRetargetableInitialScroll(state) {
|
|
3093
|
+
clearPreservedInitialScrollTarget(state);
|
|
3094
|
+
}
|
|
3095
|
+
function didFinishedInitialScrollMoveAwayFromTarget(ctx, target, epsilon = DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2820
3096
|
const state = ctx.state;
|
|
2821
|
-
if (!
|
|
2822
|
-
return;
|
|
3097
|
+
if (!state.didFinishInitialScroll) {
|
|
3098
|
+
return false;
|
|
2823
3099
|
}
|
|
3100
|
+
const currentOffset = getObservedBootstrapInitialScrollOffset(state);
|
|
3101
|
+
return Math.abs(currentOffset - resolveInitialScrollOffset(ctx, target)) > epsilon;
|
|
3102
|
+
}
|
|
3103
|
+
function getObservedBootstrapInitialScrollOffset(state) {
|
|
3104
|
+
var _a3, _b, _c, _d;
|
|
3105
|
+
const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
|
|
3106
|
+
return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
|
|
3107
|
+
}
|
|
3108
|
+
function getPreservedEndAnchorOffsetDiff(ctx) {
|
|
3109
|
+
var _a3;
|
|
3110
|
+
const state = ctx.state;
|
|
2824
3111
|
const initialScroll = state.initialScroll;
|
|
2825
|
-
if (
|
|
3112
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
|
|
2826
3113
|
return;
|
|
2827
3114
|
}
|
|
2828
|
-
const
|
|
2829
|
-
|
|
3115
|
+
const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
3116
|
+
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
3117
|
+
}
|
|
3118
|
+
function schedulePreservedEndAnchorCorrection(ctx) {
|
|
3119
|
+
if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
|
|
3120
|
+
return false;
|
|
3121
|
+
}
|
|
3122
|
+
const correction = {};
|
|
3123
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
3124
|
+
return true;
|
|
3125
|
+
}
|
|
3126
|
+
function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
|
|
3127
|
+
const state = ctx.state;
|
|
3128
|
+
state.preservedEndAnchorCorrection = correction;
|
|
3129
|
+
requestAnimationFrame(() => {
|
|
3130
|
+
var _a3;
|
|
3131
|
+
const activeCorrection = state.preservedEndAnchorCorrection;
|
|
3132
|
+
if (activeCorrection !== correction) {
|
|
3133
|
+
return;
|
|
3134
|
+
}
|
|
3135
|
+
const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
|
|
3136
|
+
if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
3137
|
+
state.preservedEndAnchorCorrection = void 0;
|
|
3138
|
+
return;
|
|
3139
|
+
}
|
|
3140
|
+
const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
|
|
3141
|
+
if (hasObservedNativeScrollAfterRequest) {
|
|
3142
|
+
activeCorrection.lastRequestTime = Date.now();
|
|
3143
|
+
requestAdjust(ctx, offsetDiff);
|
|
3144
|
+
}
|
|
3145
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
3146
|
+
});
|
|
3147
|
+
}
|
|
3148
|
+
function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
|
|
3149
|
+
var _a3, _b;
|
|
3150
|
+
const state = ctx.state;
|
|
3151
|
+
const initialScroll = state.initialScroll;
|
|
3152
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
|
|
3153
|
+
return;
|
|
3154
|
+
}
|
|
3155
|
+
if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
|
|
3156
|
+
const shouldKeepEndTargetAlive = isRetargetableBottomAlignedInitialScrollTarget(initialScroll) && peek$(ctx, "isAtEnd");
|
|
3157
|
+
if (!shouldKeepEndTargetAlive) {
|
|
3158
|
+
if (shouldPreserveInitialScrollForFooterLayout(initialScroll)) {
|
|
3159
|
+
clearPendingInitialScrollFooterLayout(ctx, {
|
|
3160
|
+
dataLength: state.props.data.length,
|
|
3161
|
+
stylePaddingBottom: (_b = state.props.stylePaddingBottom) != null ? _b : 0,
|
|
3162
|
+
target: initialScroll
|
|
3163
|
+
});
|
|
3164
|
+
} else {
|
|
3165
|
+
clearFinishedViewportRetargetableInitialScroll(state);
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
function startBootstrapInitialScrollOnMount(ctx, options) {
|
|
3171
|
+
var _a3, _b, _c;
|
|
3172
|
+
const { initialScrollAtEnd, target } = options;
|
|
3173
|
+
const state = ctx.state;
|
|
3174
|
+
const offset = resolveInitialScrollOffset(ctx, target);
|
|
3175
|
+
const shouldFinishAtOrigin = offset === 0 && !initialScrollAtEnd && (isOffsetInitialScrollSession(state) ? Math.abs((_a3 = target.contentOffset) != null ? _a3 : 0) <= 1 : target.index === 0 && ((_b = target.viewPosition) != null ? _b : 0) === 0 && Math.abs((_c = target.viewOffset) != null ? _c : 0) <= 1);
|
|
3176
|
+
const shouldFinishWithPreservedTarget = state.props.data.length === 0 && target.index !== void 0;
|
|
3177
|
+
if (shouldFinishAtOrigin) {
|
|
3178
|
+
clearBootstrapInitialScrollSession(state);
|
|
3179
|
+
finishInitialScroll(ctx, {
|
|
3180
|
+
resolvedOffset: offset
|
|
3181
|
+
});
|
|
3182
|
+
} else if (shouldFinishWithPreservedTarget) {
|
|
3183
|
+
clearBootstrapInitialScrollSession(state);
|
|
3184
|
+
finishInitialScroll(ctx, {
|
|
3185
|
+
preserveTarget: true,
|
|
3186
|
+
resolvedOffset: offset
|
|
3187
|
+
});
|
|
3188
|
+
} else {
|
|
3189
|
+
startBootstrapInitialScrollSession(state, {
|
|
3190
|
+
scroll: offset,
|
|
3191
|
+
seedContentOffset: Platform.OS === "web" ? 0 : offset,
|
|
3192
|
+
targetIndexSeed: target.index
|
|
3193
|
+
});
|
|
3194
|
+
ensureBootstrapInitialScrollFrameTicker(ctx);
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
function handleBootstrapInitialScrollDataChange(ctx, options) {
|
|
3198
|
+
const { dataLength, didDataChange, initialScrollAtEnd, previousDataLength, stylePaddingBottom } = options;
|
|
3199
|
+
const state = ctx.state;
|
|
3200
|
+
const initialScroll = state.initialScroll;
|
|
3201
|
+
if (isOffsetInitialScrollSession(state) || !initialScroll) {
|
|
3202
|
+
return;
|
|
3203
|
+
}
|
|
3204
|
+
const shouldResetDidFinish = !!(state.didFinishInitialScroll && previousDataLength === 0 && dataLength > 0 && initialScroll.index !== void 0);
|
|
3205
|
+
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
3206
|
+
const shouldClearFinishedResizePreservation = !initialScrollAtEnd && didDataChange && dataLength > 0 && state.didFinishInitialScroll && !bootstrapInitialScroll && !shouldResetDidFinish;
|
|
3207
|
+
if (shouldClearFinishedResizePreservation) {
|
|
3208
|
+
clearPreservedInitialScrollTarget(state);
|
|
3209
|
+
return;
|
|
3210
|
+
}
|
|
3211
|
+
const shouldRetargetBottomAligned = dataLength > 0 && (initialScrollAtEnd || isRetargetableBottomAlignedInitialScrollTarget(initialScroll));
|
|
3212
|
+
if (!didDataChange && !shouldResetDidFinish && !shouldRetargetBottomAligned) {
|
|
3213
|
+
return;
|
|
3214
|
+
}
|
|
3215
|
+
if (shouldRetargetBottomAligned) {
|
|
3216
|
+
const updatedInitialScroll = initialScrollAtEnd ? createInitialScrollAtEndTarget({
|
|
3217
|
+
dataLength,
|
|
3218
|
+
footerSize: peek$(ctx, "footerSize") || 0,
|
|
3219
|
+
preserveForFooterLayout: shouldPreserveInitialScrollForFooterLayout(initialScroll),
|
|
3220
|
+
stylePaddingBottom
|
|
3221
|
+
}) : createRetargetedBottomAlignedInitialScroll({
|
|
3222
|
+
dataLength,
|
|
3223
|
+
footerSize: peek$(ctx, "footerSize") || 0,
|
|
3224
|
+
initialScrollAtEnd,
|
|
3225
|
+
stylePaddingBottom,
|
|
3226
|
+
target: initialScroll
|
|
3227
|
+
});
|
|
3228
|
+
if (!shouldResetDidFinish && didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
|
|
3229
|
+
clearPendingInitialScrollFooterLayout(ctx, {
|
|
3230
|
+
dataLength,
|
|
3231
|
+
stylePaddingBottom,
|
|
3232
|
+
target: initialScroll
|
|
3233
|
+
});
|
|
3234
|
+
return;
|
|
3235
|
+
}
|
|
3236
|
+
if (!areEquivalentBootstrapInitialScrollTargets(initialScroll, updatedInitialScroll) || !!bootstrapInitialScroll || shouldResetDidFinish || didDataChange) {
|
|
3237
|
+
setInitialScrollTarget(state, updatedInitialScroll, {
|
|
3238
|
+
resetDidFinish: shouldResetDidFinish
|
|
3239
|
+
});
|
|
3240
|
+
rearmBootstrapInitialScroll(ctx, {
|
|
3241
|
+
scroll: resolveInitialScrollOffset(ctx, updatedInitialScroll),
|
|
3242
|
+
seedContentOffset: shouldResetDidFinish && !bootstrapInitialScroll ? getObservedBootstrapInitialScrollOffset(state) : void 0,
|
|
3243
|
+
targetIndexSeed: updatedInitialScroll.index
|
|
3244
|
+
});
|
|
3245
|
+
return;
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
if (!didDataChange) {
|
|
3249
|
+
return;
|
|
3250
|
+
}
|
|
3251
|
+
if (bootstrapInitialScroll || shouldResetDidFinish) {
|
|
3252
|
+
setInitialScrollTarget(state, initialScroll, {
|
|
3253
|
+
resetDidFinish: shouldResetDidFinish
|
|
3254
|
+
});
|
|
3255
|
+
rearmBootstrapInitialScroll(ctx, {
|
|
3256
|
+
scroll: resolveInitialScrollOffset(ctx, initialScroll),
|
|
3257
|
+
seedContentOffset: shouldResetDidFinish && !bootstrapInitialScroll ? getObservedBootstrapInitialScrollOffset(state) : void 0,
|
|
3258
|
+
targetIndexSeed: initialScroll.index
|
|
3259
|
+
});
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
3263
|
+
const { dataLength, footerSize, initialScrollAtEnd, stylePaddingBottom } = options;
|
|
3264
|
+
const state = ctx.state;
|
|
3265
|
+
if (!initialScrollAtEnd) {
|
|
3266
|
+
return;
|
|
3267
|
+
}
|
|
3268
|
+
const initialScroll = state.initialScroll;
|
|
3269
|
+
if (isOffsetInitialScrollSession(state) || dataLength === 0 || !initialScroll) {
|
|
3270
|
+
return;
|
|
3271
|
+
}
|
|
3272
|
+
const shouldProcessFooterLayout = !!getBootstrapInitialScrollSession(state) || shouldPreserveInitialScrollForFooterLayout(initialScroll);
|
|
3273
|
+
if (!shouldProcessFooterLayout) {
|
|
2830
3274
|
return;
|
|
2831
3275
|
}
|
|
2832
3276
|
if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
|
|
@@ -2985,405 +3429,113 @@ function abortBootstrapInitialScroll(ctx) {
|
|
|
2985
3429
|
const state = ctx.state;
|
|
2986
3430
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
2987
3431
|
const initialScroll = state.initialScroll;
|
|
2988
|
-
if (bootstrapInitialScroll && initialScroll && !isOffsetInitialScrollSession(state) && state.refScroller.current) {
|
|
2989
|
-
clearBootstrapInitialScrollSession(state);
|
|
2990
|
-
dispatchInitialScroll(ctx, {
|
|
2991
|
-
forceScroll: true,
|
|
2992
|
-
resolvedOffset: bootstrapInitialScroll.scroll,
|
|
2993
|
-
target: initialScroll,
|
|
2994
|
-
waitForCompletionFrame: Platform.OS === "web"
|
|
2995
|
-
});
|
|
2996
|
-
} else {
|
|
2997
|
-
finishBootstrapInitialScrollWithoutScroll(
|
|
2998
|
-
ctx,
|
|
2999
|
-
(_d = (_c = (_b = (_a3 = getBootstrapInitialScrollSession(state)) == null ? void 0 : _a3.scroll) != null ? _b : state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0
|
|
3000
|
-
);
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3003
|
-
|
|
3004
|
-
// src/core/initialScrollLifecycle.ts
|
|
3005
|
-
function retargetActiveInitialScrollAtEnd(ctx) {
|
|
3006
|
-
var _a3;
|
|
3007
|
-
const state = ctx.state;
|
|
3008
|
-
const initialScroll = state.initialScroll;
|
|
3009
|
-
if (state.didFinishInitialScroll) {
|
|
3010
|
-
return schedulePreservedEndAnchorCorrection(ctx);
|
|
3011
|
-
}
|
|
3012
|
-
if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
|
|
3013
|
-
return false;
|
|
3014
|
-
}
|
|
3015
|
-
return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
3016
|
-
}
|
|
3017
|
-
function handleInitialScrollLayoutReady(ctx) {
|
|
3018
|
-
var _a3;
|
|
3019
|
-
if (!ctx.state.initialScroll) {
|
|
3020
|
-
return;
|
|
3021
|
-
}
|
|
3022
|
-
const runScroll = () => advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
3023
|
-
runScroll();
|
|
3024
|
-
if (((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) !== "offset") {
|
|
3025
|
-
requestAnimationFrame(runScroll);
|
|
3026
|
-
}
|
|
3027
|
-
checkFinishedScroll(ctx, { onlyIfAligned: true });
|
|
3028
|
-
}
|
|
3029
|
-
function initializeInitialScrollOnMount(ctx, options) {
|
|
3030
|
-
var _a3, _b;
|
|
3031
|
-
const {
|
|
3032
|
-
alwaysDispatchInitialScroll,
|
|
3033
|
-
dataLength,
|
|
3034
|
-
hasFooterComponent,
|
|
3035
|
-
initialContentOffset,
|
|
3036
|
-
initialScrollAtEnd,
|
|
3037
|
-
useBootstrapInitialScroll
|
|
3038
|
-
} = options;
|
|
3039
|
-
const state = ctx.state;
|
|
3040
|
-
const initialScroll = state.initialScroll;
|
|
3041
|
-
const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
|
|
3042
|
-
const preserveForFooterLayout = useBootstrapInitialScroll && initialScrollAtEnd && hasFooterComponent;
|
|
3043
|
-
if (initialScroll && (initialScroll.contentOffset === void 0 || !!initialScroll.preserveForFooterLayout !== preserveForFooterLayout && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) !== "offset")) {
|
|
3044
|
-
setInitialScrollTarget(state, {
|
|
3045
|
-
...initialScroll,
|
|
3046
|
-
contentOffset: resolvedInitialContentOffset,
|
|
3047
|
-
preserveForFooterLayout
|
|
3048
|
-
});
|
|
3049
|
-
}
|
|
3050
|
-
if (useBootstrapInitialScroll && initialScroll && ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) !== "offset") {
|
|
3051
|
-
startBootstrapInitialScrollOnMount(ctx, {
|
|
3052
|
-
initialScrollAtEnd,
|
|
3053
|
-
target: state.initialScroll
|
|
3054
|
-
});
|
|
3055
|
-
return;
|
|
3056
|
-
}
|
|
3057
|
-
const hasPendingDataDependentInitialScroll = !!initialScroll && dataLength === 0 && !(resolvedInitialContentOffset === 0 && !initialScrollAtEnd);
|
|
3058
|
-
if (!alwaysDispatchInitialScroll && !resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
|
|
3059
|
-
if (initialScroll && !initialScrollAtEnd) {
|
|
3060
|
-
finishInitialScroll(ctx, {
|
|
3061
|
-
resolvedOffset: resolvedInitialContentOffset
|
|
3062
|
-
});
|
|
3063
|
-
} else {
|
|
3064
|
-
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
3065
|
-
}
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
function handleInitialScrollDataChange(ctx, options) {
|
|
3069
|
-
var _a3, _b, _c;
|
|
3070
|
-
const { dataLength, didDataChange, initialScrollAtEnd, stylePaddingBottom, useBootstrapInitialScroll } = options;
|
|
3071
|
-
const state = ctx.state;
|
|
3072
|
-
const previousDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
|
|
3073
|
-
if (state.initialScrollSession) {
|
|
3074
|
-
state.initialScrollSession.previousDataLength = dataLength;
|
|
3075
|
-
}
|
|
3076
|
-
setInitialScrollSession(state);
|
|
3077
|
-
if (useBootstrapInitialScroll) {
|
|
3078
|
-
handleBootstrapInitialScrollDataChange(ctx, {
|
|
3079
|
-
dataLength,
|
|
3080
|
-
didDataChange,
|
|
3081
|
-
initialScrollAtEnd,
|
|
3082
|
-
previousDataLength,
|
|
3083
|
-
stylePaddingBottom
|
|
3084
|
-
});
|
|
3085
|
-
return;
|
|
3086
|
-
}
|
|
3087
|
-
const shouldReplayFinishedOffsetInitialScroll = previousDataLength === 0 && dataLength > 0 && !!state.initialScroll && ((_c = ctx.state.initialScrollSession) == null ? void 0 : _c.kind) === "offset" && !!state.didFinishInitialScroll;
|
|
3088
|
-
if (previousDataLength !== 0 || dataLength === 0 || !state.initialScroll || !state.queuedInitialLayout || state.didFinishInitialScroll && !shouldReplayFinishedOffsetInitialScroll) {
|
|
3089
|
-
return;
|
|
3090
|
-
}
|
|
3091
|
-
if (shouldReplayFinishedOffsetInitialScroll) {
|
|
3092
|
-
state.didFinishInitialScroll = false;
|
|
3093
|
-
}
|
|
3094
|
-
advanceCurrentInitialScrollSession(ctx);
|
|
3095
|
-
}
|
|
3096
|
-
|
|
3097
|
-
// src/core/mvcp.ts
|
|
3098
|
-
var MVCP_POSITION_EPSILON = 0.1;
|
|
3099
|
-
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
3100
|
-
var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
|
|
3101
|
-
var NATIVE_END_CLAMP_EPSILON = 1;
|
|
3102
|
-
function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
|
|
3103
|
-
if (!enableMVCPAnchorLock) {
|
|
3104
|
-
state.mvcpAnchorLock = void 0;
|
|
3105
|
-
return void 0;
|
|
3106
|
-
}
|
|
3107
|
-
const lock = state.mvcpAnchorLock;
|
|
3108
|
-
if (!lock) {
|
|
3109
|
-
return void 0;
|
|
3110
|
-
}
|
|
3111
|
-
const isExpired = now > lock.expiresAt;
|
|
3112
|
-
const isMissing = state.indexByKey.get(lock.id) === void 0;
|
|
3113
|
-
if (isExpired || isMissing || !mvcpData) {
|
|
3114
|
-
state.mvcpAnchorLock = void 0;
|
|
3115
|
-
return void 0;
|
|
3116
|
-
}
|
|
3117
|
-
return lock;
|
|
3118
|
-
}
|
|
3119
|
-
function updateAnchorLock(state, params) {
|
|
3120
|
-
if (Platform.OS === "web") {
|
|
3121
|
-
const { anchorId, anchorPosition, dataChanged, now, positionDiff } = params;
|
|
3122
|
-
const enableMVCPAnchorLock = !!dataChanged || !!state.mvcpAnchorLock;
|
|
3123
|
-
const mvcpData = state.props.maintainVisibleContentPosition.data;
|
|
3124
|
-
if (!enableMVCPAnchorLock || !mvcpData || state.scrollingTo || !anchorId || anchorPosition === void 0) {
|
|
3125
|
-
return;
|
|
3126
|
-
}
|
|
3127
|
-
const existingLock = state.mvcpAnchorLock;
|
|
3128
|
-
const quietPasses = !dataChanged && Math.abs(positionDiff) <= MVCP_POSITION_EPSILON && (existingLock == null ? void 0 : existingLock.id) === anchorId ? existingLock.quietPasses + 1 : 0;
|
|
3129
|
-
if (!dataChanged && quietPasses >= MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE) {
|
|
3130
|
-
state.mvcpAnchorLock = void 0;
|
|
3131
|
-
return;
|
|
3132
|
-
}
|
|
3133
|
-
state.mvcpAnchorLock = {
|
|
3134
|
-
expiresAt: now + MVCP_ANCHOR_LOCK_TTL_MS,
|
|
3135
|
-
id: anchorId,
|
|
3136
|
-
position: anchorPosition,
|
|
3137
|
-
quietPasses
|
|
3138
|
-
};
|
|
3139
|
-
}
|
|
3140
|
-
}
|
|
3141
|
-
function shouldQueueNativeMVCPAdjust(dataChanged, state, positionDiff, prevTotalSize, prevScroll, scrollTarget) {
|
|
3142
|
-
if (!dataChanged || Platform.OS === "web" || !state.props.maintainVisibleContentPosition.data || scrollTarget !== void 0 || positionDiff >= -MVCP_POSITION_EPSILON) {
|
|
3143
|
-
return false;
|
|
3144
|
-
}
|
|
3145
|
-
const distanceFromEnd = prevTotalSize - prevScroll - state.scrollLength;
|
|
3146
|
-
return distanceFromEnd < Math.abs(positionDiff) - MVCP_POSITION_EPSILON;
|
|
3147
|
-
}
|
|
3148
|
-
function getPredictedNativeClamp(state, unresolvedAmount, totalSize) {
|
|
3149
|
-
if (Math.abs(unresolvedAmount) <= MVCP_POSITION_EPSILON) {
|
|
3150
|
-
return 0;
|
|
3151
|
-
}
|
|
3152
|
-
const maxScroll = Math.max(0, totalSize - state.scrollLength);
|
|
3153
|
-
const clampDelta = maxScroll - state.scroll;
|
|
3154
|
-
if (unresolvedAmount < 0) {
|
|
3155
|
-
return Math.max(unresolvedAmount, Math.min(0, clampDelta));
|
|
3156
|
-
}
|
|
3157
|
-
if (unresolvedAmount > 0) {
|
|
3158
|
-
return Math.min(unresolvedAmount, Math.max(0, clampDelta));
|
|
3159
|
-
}
|
|
3160
|
-
return 0;
|
|
3161
|
-
}
|
|
3162
|
-
function getProgressTowardAmount(targetDelta, nativeDelta) {
|
|
3163
|
-
return targetDelta < 0 ? -nativeDelta : nativeDelta;
|
|
3164
|
-
}
|
|
3165
|
-
function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
|
|
3166
|
-
const state = ctx.state;
|
|
3167
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
3168
|
-
const remaining = remainingAfterManual - nativeDelta;
|
|
3169
|
-
if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
|
|
3170
|
-
requestAdjust(ctx, remaining, true);
|
|
3171
|
-
}
|
|
3172
|
-
}
|
|
3173
|
-
function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
3174
|
-
const state = ctx.state;
|
|
3175
|
-
const pending = state.pendingNativeMVCPAdjust;
|
|
3176
|
-
if (!pending || Math.abs(pending.manualApplied) > MVCP_POSITION_EPSILON) {
|
|
3177
|
-
return;
|
|
3178
|
-
}
|
|
3179
|
-
const totalSize = getContentSize(ctx);
|
|
3180
|
-
const predictedNativeClamp = getPredictedNativeClamp(state, pending.amount, totalSize);
|
|
3181
|
-
if (Math.abs(predictedNativeClamp) <= MVCP_POSITION_EPSILON) {
|
|
3182
|
-
return;
|
|
3183
|
-
}
|
|
3184
|
-
const manualDesired = pending.amount - predictedNativeClamp;
|
|
3185
|
-
if (Math.abs(manualDesired) <= MVCP_POSITION_EPSILON) {
|
|
3186
|
-
return;
|
|
3187
|
-
}
|
|
3188
|
-
pending.manualApplied = manualDesired;
|
|
3189
|
-
requestAdjust(ctx, manualDesired, true);
|
|
3190
|
-
pending.furthestProgressTowardAmount = 0;
|
|
3191
|
-
}
|
|
3192
|
-
function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
3193
|
-
const state = ctx.state;
|
|
3194
|
-
const pending = state.pendingNativeMVCPAdjust;
|
|
3195
|
-
if (!pending) {
|
|
3196
|
-
return false;
|
|
3197
|
-
}
|
|
3198
|
-
const remainingAfterManual = pending.amount - pending.manualApplied;
|
|
3199
|
-
const nativeDelta = newScroll - (pending.startScroll + pending.manualApplied);
|
|
3200
|
-
const isWrongDirection = remainingAfterManual < 0 && nativeDelta > MVCP_POSITION_EPSILON || remainingAfterManual > 0 && nativeDelta < -MVCP_POSITION_EPSILON;
|
|
3201
|
-
const progressTowardAmount = getProgressTowardAmount(remainingAfterManual, nativeDelta);
|
|
3202
|
-
if (Math.abs(remainingAfterManual) <= MVCP_POSITION_EPSILON) {
|
|
3203
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
3204
|
-
return true;
|
|
3205
|
-
}
|
|
3206
|
-
if (isWrongDirection) {
|
|
3207
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
3208
|
-
return false;
|
|
3209
|
-
}
|
|
3210
|
-
if (progressTowardAmount + MVCP_POSITION_EPSILON >= Math.abs(remainingAfterManual)) {
|
|
3211
|
-
settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
|
|
3212
|
-
return true;
|
|
3213
|
-
}
|
|
3214
|
-
const expectedNativeClampScroll = Math.max(0, getContentSize(ctx) - state.scrollLength);
|
|
3215
|
-
const distanceToClamp = Math.abs(newScroll - expectedNativeClampScroll);
|
|
3216
|
-
const isAtExpectedNativeClamp = distanceToClamp <= NATIVE_END_CLAMP_EPSILON;
|
|
3217
|
-
if (isAtExpectedNativeClamp) {
|
|
3218
|
-
settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
|
|
3219
|
-
return true;
|
|
3220
|
-
}
|
|
3221
|
-
if (state.pendingMaintainScrollAtEnd && peek$(ctx, "isWithinMaintainScrollAtEndThreshold") && progressTowardAmount > MVCP_POSITION_EPSILON) {
|
|
3222
|
-
settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta);
|
|
3223
|
-
return true;
|
|
3224
|
-
}
|
|
3225
|
-
if (progressTowardAmount > pending.furthestProgressTowardAmount + MVCP_POSITION_EPSILON) {
|
|
3226
|
-
pending.furthestProgressTowardAmount = progressTowardAmount;
|
|
3227
|
-
return false;
|
|
3228
|
-
}
|
|
3229
|
-
if (pending.furthestProgressTowardAmount > MVCP_POSITION_EPSILON && progressTowardAmount < pending.furthestProgressTowardAmount - MVCP_POSITION_EPSILON) {
|
|
3230
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
3231
|
-
return false;
|
|
3232
|
-
}
|
|
3233
|
-
return false;
|
|
3234
|
-
}
|
|
3235
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
3236
|
-
const state = ctx.state;
|
|
3237
|
-
const { idsInView, positions, props } = state;
|
|
3238
|
-
const {
|
|
3239
|
-
maintainVisibleContentPosition: { data: mvcpData, size: mvcpScroll, shouldRestorePosition }
|
|
3240
|
-
} = props;
|
|
3241
|
-
const isWeb = Platform.OS === "web";
|
|
3242
|
-
const now = Date.now();
|
|
3243
|
-
const enableMVCPAnchorLock = isWeb && (!!dataChanged || !!state.mvcpAnchorLock);
|
|
3244
|
-
const scrollingTo = state.scrollingTo;
|
|
3245
|
-
const anchorLock = isWeb ? resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) : void 0;
|
|
3246
|
-
let prevPosition;
|
|
3247
|
-
let targetId;
|
|
3248
|
-
const idsInViewWithPositions = [];
|
|
3249
|
-
const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
|
|
3250
|
-
const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
|
|
3251
|
-
const isEndAnchoredScrollTarget = scrollTarget !== void 0 && state.props.data.length > 0 && scrollTarget >= state.props.data.length - 1 && (scrollingToViewPosition != null ? scrollingToViewPosition : 0) > 0;
|
|
3252
|
-
const shouldMVCP = dataChanged ? mvcpData : mvcpScroll;
|
|
3253
|
-
const indexByKey = state.indexByKey;
|
|
3254
|
-
const prevScroll = state.scroll;
|
|
3255
|
-
const prevTotalSize = getContentSize(ctx);
|
|
3256
|
-
if (shouldMVCP) {
|
|
3257
|
-
if (!isWeb && state.pendingNativeMVCPAdjust && scrollTarget === void 0) {
|
|
3258
|
-
maybeApplyPredictedNativeMVCPAdjust(ctx);
|
|
3259
|
-
return void 0;
|
|
3260
|
-
}
|
|
3261
|
-
if (anchorLock && scrollTarget === void 0) {
|
|
3262
|
-
targetId = anchorLock.id;
|
|
3263
|
-
prevPosition = anchorLock.position;
|
|
3264
|
-
} else if (scrollTarget !== void 0) {
|
|
3265
|
-
if (!IsNewArchitecture && (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll)) {
|
|
3266
|
-
return void 0;
|
|
3267
|
-
}
|
|
3268
|
-
targetId = getId(state, scrollTarget);
|
|
3269
|
-
} else if (idsInView.length > 0 && state.didContainersLayout && !dataChanged) {
|
|
3270
|
-
targetId = idsInView.find((id) => indexByKey.get(id) !== void 0);
|
|
3271
|
-
}
|
|
3272
|
-
if (dataChanged && idsInView.length > 0 && state.didContainersLayout) {
|
|
3273
|
-
for (let i = 0; i < idsInView.length; i++) {
|
|
3274
|
-
const id = idsInView[i];
|
|
3275
|
-
const index = indexByKey.get(id);
|
|
3276
|
-
if (index !== void 0) {
|
|
3277
|
-
const position = positions[index];
|
|
3278
|
-
if (position !== void 0) {
|
|
3279
|
-
idsInViewWithPositions.push({ id, position });
|
|
3280
|
-
}
|
|
3281
|
-
}
|
|
3282
|
-
}
|
|
3283
|
-
}
|
|
3284
|
-
if (targetId !== void 0 && prevPosition === void 0) {
|
|
3285
|
-
const targetIndex = indexByKey.get(targetId);
|
|
3286
|
-
if (targetIndex !== void 0) {
|
|
3287
|
-
prevPosition = positions[targetIndex];
|
|
3288
|
-
}
|
|
3289
|
-
}
|
|
3290
|
-
return () => {
|
|
3291
|
-
let positionDiff = 0;
|
|
3292
|
-
let anchorIdForLock = anchorLock == null ? void 0 : anchorLock.id;
|
|
3293
|
-
let anchorPositionForLock;
|
|
3294
|
-
let skipTargetAnchor = false;
|
|
3295
|
-
const data = state.props.data;
|
|
3296
|
-
const shouldValidateLockedAnchor = isWeb && dataChanged && mvcpData && scrollTarget === void 0 && targetId !== void 0 && (anchorLock == null ? void 0 : anchorLock.id) === targetId && shouldRestorePosition !== void 0;
|
|
3297
|
-
if (shouldValidateLockedAnchor && targetId !== void 0) {
|
|
3298
|
-
const index = indexByKey.get(targetId);
|
|
3299
|
-
if (index !== void 0) {
|
|
3300
|
-
const item = data[index];
|
|
3301
|
-
skipTargetAnchor = item === void 0 || !shouldRestorePosition(item, index, data);
|
|
3302
|
-
if (skipTargetAnchor && (anchorLock == null ? void 0 : anchorLock.id) === targetId) {
|
|
3303
|
-
state.mvcpAnchorLock = void 0;
|
|
3304
|
-
}
|
|
3305
|
-
}
|
|
3306
|
-
}
|
|
3307
|
-
const shouldUseFallbackVisibleAnchor = dataChanged && mvcpData && scrollTarget === void 0 && (() => {
|
|
3308
|
-
if (targetId === void 0 || skipTargetAnchor) {
|
|
3309
|
-
return true;
|
|
3310
|
-
}
|
|
3311
|
-
const targetIndex = indexByKey.get(targetId);
|
|
3312
|
-
return targetIndex === void 0 || positions[targetIndex] === void 0;
|
|
3313
|
-
})();
|
|
3314
|
-
if (shouldUseFallbackVisibleAnchor) {
|
|
3315
|
-
for (let i = 0; i < idsInViewWithPositions.length; i++) {
|
|
3316
|
-
const { id, position } = idsInViewWithPositions[i];
|
|
3317
|
-
const index = indexByKey.get(id);
|
|
3318
|
-
if (index !== void 0 && shouldRestorePosition) {
|
|
3319
|
-
const item = data[index];
|
|
3320
|
-
if (item === void 0 || !shouldRestorePosition(item, index, data)) {
|
|
3321
|
-
continue;
|
|
3322
|
-
}
|
|
3323
|
-
}
|
|
3324
|
-
const newPosition = index !== void 0 ? positions[index] : void 0;
|
|
3325
|
-
if (newPosition !== void 0) {
|
|
3326
|
-
positionDiff = newPosition - position;
|
|
3327
|
-
anchorIdForLock = id;
|
|
3328
|
-
anchorPositionForLock = newPosition;
|
|
3329
|
-
break;
|
|
3330
|
-
}
|
|
3331
|
-
}
|
|
3332
|
-
}
|
|
3333
|
-
if (!skipTargetAnchor && targetId !== void 0 && prevPosition !== void 0) {
|
|
3334
|
-
const targetIndex = indexByKey.get(targetId);
|
|
3335
|
-
const newPosition = targetIndex !== void 0 ? positions[targetIndex] : void 0;
|
|
3336
|
-
if (newPosition !== void 0) {
|
|
3337
|
-
const totalSize = getContentSize(ctx);
|
|
3338
|
-
let diff = newPosition - prevPosition;
|
|
3339
|
-
if (diff !== 0 && isEndAnchoredScrollTarget && state.scroll + state.scrollLength > totalSize) {
|
|
3340
|
-
if (diff > 0) {
|
|
3341
|
-
diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
|
|
3342
|
-
} else {
|
|
3343
|
-
diff = 0;
|
|
3344
|
-
}
|
|
3345
|
-
}
|
|
3346
|
-
positionDiff = diff;
|
|
3347
|
-
anchorIdForLock = targetId;
|
|
3348
|
-
anchorPositionForLock = newPosition;
|
|
3349
|
-
}
|
|
3350
|
-
}
|
|
3351
|
-
if (scrollingToViewPosition && scrollingToViewPosition > 0) {
|
|
3352
|
-
const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
|
|
3353
|
-
const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
|
|
3354
|
-
if (newSize !== void 0 && prevSize !== void 0 && newSize !== prevSize) {
|
|
3355
|
-
const diff = newSize - prevSize;
|
|
3356
|
-
if (diff !== 0) {
|
|
3357
|
-
positionDiff += diff * scrollingToViewPosition;
|
|
3358
|
-
scrollingTo.itemSize = newSize;
|
|
3359
|
-
}
|
|
3360
|
-
}
|
|
3361
|
-
}
|
|
3362
|
-
updateAnchorLock(state, {
|
|
3363
|
-
anchorId: anchorIdForLock,
|
|
3364
|
-
anchorPosition: anchorPositionForLock,
|
|
3365
|
-
dataChanged,
|
|
3366
|
-
now,
|
|
3367
|
-
positionDiff
|
|
3432
|
+
if (bootstrapInitialScroll && initialScroll && !isOffsetInitialScrollSession(state) && state.refScroller.current) {
|
|
3433
|
+
clearBootstrapInitialScrollSession(state);
|
|
3434
|
+
dispatchInitialScroll(ctx, {
|
|
3435
|
+
forceScroll: true,
|
|
3436
|
+
resolvedOffset: bootstrapInitialScroll.scroll,
|
|
3437
|
+
target: initialScroll,
|
|
3438
|
+
waitForCompletionFrame: Platform.OS === "web"
|
|
3439
|
+
});
|
|
3440
|
+
} else {
|
|
3441
|
+
finishBootstrapInitialScrollWithoutScroll(
|
|
3442
|
+
ctx,
|
|
3443
|
+
(_d = (_c = (_b = (_a3 = getBootstrapInitialScrollSession(state)) == null ? void 0 : _a3.scroll) != null ? _b : state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0
|
|
3444
|
+
);
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
// src/core/initialScrollLifecycle.ts
|
|
3449
|
+
function retargetActiveInitialScrollAtEnd(ctx) {
|
|
3450
|
+
var _a3;
|
|
3451
|
+
const state = ctx.state;
|
|
3452
|
+
const initialScroll = state.initialScroll;
|
|
3453
|
+
if (state.didFinishInitialScroll) {
|
|
3454
|
+
return schedulePreservedEndAnchorCorrection(ctx);
|
|
3455
|
+
}
|
|
3456
|
+
if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
|
|
3457
|
+
return false;
|
|
3458
|
+
}
|
|
3459
|
+
return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
3460
|
+
}
|
|
3461
|
+
function handleInitialScrollLayoutReady(ctx) {
|
|
3462
|
+
var _a3;
|
|
3463
|
+
if (!ctx.state.initialScroll) {
|
|
3464
|
+
return;
|
|
3465
|
+
}
|
|
3466
|
+
const runScroll = () => advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
3467
|
+
runScroll();
|
|
3468
|
+
if (((_a3 = ctx.state.initialScrollSession) == null ? void 0 : _a3.kind) !== "offset") {
|
|
3469
|
+
requestAnimationFrame(runScroll);
|
|
3470
|
+
}
|
|
3471
|
+
checkFinishedScroll(ctx, { onlyIfAligned: true });
|
|
3472
|
+
}
|
|
3473
|
+
function initializeInitialScrollOnMount(ctx, options) {
|
|
3474
|
+
var _a3, _b;
|
|
3475
|
+
const {
|
|
3476
|
+
alwaysDispatchInitialScroll,
|
|
3477
|
+
dataLength,
|
|
3478
|
+
hasFooterComponent,
|
|
3479
|
+
initialContentOffset,
|
|
3480
|
+
initialScrollAtEnd,
|
|
3481
|
+
useBootstrapInitialScroll
|
|
3482
|
+
} = options;
|
|
3483
|
+
const state = ctx.state;
|
|
3484
|
+
const initialScroll = state.initialScroll;
|
|
3485
|
+
const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
|
|
3486
|
+
const preserveForFooterLayout = useBootstrapInitialScroll && initialScrollAtEnd && hasFooterComponent;
|
|
3487
|
+
if (initialScroll && (initialScroll.contentOffset === void 0 || !!initialScroll.preserveForFooterLayout !== preserveForFooterLayout && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) !== "offset")) {
|
|
3488
|
+
setInitialScrollTarget(state, {
|
|
3489
|
+
...initialScroll,
|
|
3490
|
+
contentOffset: resolvedInitialContentOffset,
|
|
3491
|
+
preserveForFooterLayout
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
if (useBootstrapInitialScroll && initialScroll && ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) !== "offset") {
|
|
3495
|
+
startBootstrapInitialScrollOnMount(ctx, {
|
|
3496
|
+
initialScrollAtEnd,
|
|
3497
|
+
target: state.initialScroll
|
|
3498
|
+
});
|
|
3499
|
+
return;
|
|
3500
|
+
}
|
|
3501
|
+
const hasPendingDataDependentInitialScroll = !!initialScroll && dataLength === 0 && !(resolvedInitialContentOffset === 0 && !initialScrollAtEnd);
|
|
3502
|
+
if (!alwaysDispatchInitialScroll && !resolvedInitialContentOffset && !hasPendingDataDependentInitialScroll) {
|
|
3503
|
+
if (initialScroll && !initialScrollAtEnd) {
|
|
3504
|
+
finishInitialScroll(ctx, {
|
|
3505
|
+
resolvedOffset: resolvedInitialContentOffset
|
|
3368
3506
|
});
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3507
|
+
} else {
|
|
3508
|
+
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
function handleInitialScrollDataChange(ctx, options) {
|
|
3513
|
+
var _a3, _b, _c;
|
|
3514
|
+
const { dataLength, didDataChange, initialScrollAtEnd, stylePaddingBottom, useBootstrapInitialScroll } = options;
|
|
3515
|
+
const state = ctx.state;
|
|
3516
|
+
const previousDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
|
|
3517
|
+
if (state.initialScrollSession) {
|
|
3518
|
+
state.initialScrollSession.previousDataLength = dataLength;
|
|
3519
|
+
}
|
|
3520
|
+
setInitialScrollSession(state);
|
|
3521
|
+
if (useBootstrapInitialScroll) {
|
|
3522
|
+
handleBootstrapInitialScrollDataChange(ctx, {
|
|
3523
|
+
dataLength,
|
|
3524
|
+
didDataChange,
|
|
3525
|
+
initialScrollAtEnd,
|
|
3526
|
+
previousDataLength,
|
|
3527
|
+
stylePaddingBottom
|
|
3528
|
+
});
|
|
3529
|
+
return;
|
|
3530
|
+
}
|
|
3531
|
+
const shouldReplayFinishedOffsetInitialScroll = previousDataLength === 0 && dataLength > 0 && !!state.initialScroll && ((_c = ctx.state.initialScrollSession) == null ? void 0 : _c.kind) === "offset" && !!state.didFinishInitialScroll;
|
|
3532
|
+
if (previousDataLength !== 0 || dataLength === 0 || !state.initialScroll || !state.queuedInitialLayout || state.didFinishInitialScroll && !shouldReplayFinishedOffsetInitialScroll) {
|
|
3533
|
+
return;
|
|
3534
|
+
}
|
|
3535
|
+
if (shouldReplayFinishedOffsetInitialScroll) {
|
|
3536
|
+
state.didFinishInitialScroll = false;
|
|
3386
3537
|
}
|
|
3538
|
+
advanceCurrentInitialScrollSession(ctx);
|
|
3387
3539
|
}
|
|
3388
3540
|
|
|
3389
3541
|
// src/core/resetLayoutCachesForDataChange.ts
|
|
@@ -4669,62 +4821,6 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4669
4821
|
});
|
|
4670
4822
|
}
|
|
4671
4823
|
|
|
4672
|
-
// src/core/doMaintainScrollAtEnd.ts
|
|
4673
|
-
function doMaintainScrollAtEnd(ctx) {
|
|
4674
|
-
const state = ctx.state;
|
|
4675
|
-
const {
|
|
4676
|
-
didContainersLayout,
|
|
4677
|
-
pendingNativeMVCPAdjust,
|
|
4678
|
-
refScroller,
|
|
4679
|
-
props: { maintainScrollAtEnd }
|
|
4680
|
-
} = state;
|
|
4681
|
-
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
4682
|
-
const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
|
|
4683
|
-
if (pendingNativeMVCPAdjust) {
|
|
4684
|
-
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
4685
|
-
return false;
|
|
4686
|
-
}
|
|
4687
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
4688
|
-
if (shouldMaintainScrollAtEnd) {
|
|
4689
|
-
const contentSize = getContentSize(ctx);
|
|
4690
|
-
if (contentSize < state.scrollLength) {
|
|
4691
|
-
state.scroll = 0;
|
|
4692
|
-
}
|
|
4693
|
-
if (!state.maintainingScrollAtEnd) {
|
|
4694
|
-
state.maintainingScrollAtEnd = true;
|
|
4695
|
-
requestAnimationFrame(() => {
|
|
4696
|
-
if (peek$(ctx, "isWithinMaintainScrollAtEndThreshold")) {
|
|
4697
|
-
const scroller = refScroller.current;
|
|
4698
|
-
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
4699
|
-
const currentContentSize = getContentSize(ctx);
|
|
4700
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
4701
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
4702
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
4703
|
-
animated: maintainScrollAtEnd.animated,
|
|
4704
|
-
x: nativeOffset,
|
|
4705
|
-
y: 0
|
|
4706
|
-
});
|
|
4707
|
-
} else {
|
|
4708
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
4709
|
-
animated: maintainScrollAtEnd.animated
|
|
4710
|
-
});
|
|
4711
|
-
}
|
|
4712
|
-
setTimeout(
|
|
4713
|
-
() => {
|
|
4714
|
-
state.maintainingScrollAtEnd = false;
|
|
4715
|
-
},
|
|
4716
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
4717
|
-
);
|
|
4718
|
-
} else {
|
|
4719
|
-
state.maintainingScrollAtEnd = false;
|
|
4720
|
-
}
|
|
4721
|
-
});
|
|
4722
|
-
}
|
|
4723
|
-
return true;
|
|
4724
|
-
}
|
|
4725
|
-
return false;
|
|
4726
|
-
}
|
|
4727
|
-
|
|
4728
4824
|
// src/core/checkResetContainers.ts
|
|
4729
4825
|
function checkResetContainers(ctx, dataProp, { didColumnsChange = false } = {}) {
|
|
4730
4826
|
const state = ctx.state;
|
|
@@ -4905,84 +5001,6 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
4905
5001
|
setCanRender(true);
|
|
4906
5002
|
}
|
|
4907
5003
|
|
|
4908
|
-
// src/platform/flushSync.native.ts
|
|
4909
|
-
var flushSync = (fn) => {
|
|
4910
|
-
fn();
|
|
4911
|
-
};
|
|
4912
|
-
|
|
4913
|
-
// src/core/updateScroll.ts
|
|
4914
|
-
function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
4915
|
-
var _a3;
|
|
4916
|
-
const state = ctx.state;
|
|
4917
|
-
const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
|
|
4918
|
-
const prevScroll = state.scroll;
|
|
4919
|
-
if ((options == null ? void 0 : options.markHasScrolled) !== false) {
|
|
4920
|
-
state.hasScrolled = true;
|
|
4921
|
-
}
|
|
4922
|
-
state.lastBatchingAction = Date.now();
|
|
4923
|
-
const currentTime = Date.now();
|
|
4924
|
-
const adjust = scrollAdjustHandler.getAdjust();
|
|
4925
|
-
const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
|
|
4926
|
-
if (adjustChanged) {
|
|
4927
|
-
scrollHistory.length = 0;
|
|
4928
|
-
}
|
|
4929
|
-
state.lastScrollAdjustForHistory = adjust;
|
|
4930
|
-
if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
|
|
4931
|
-
if (!adjustChanged) {
|
|
4932
|
-
scrollHistory.push({ scroll: newScroll, time: currentTime });
|
|
4933
|
-
}
|
|
4934
|
-
}
|
|
4935
|
-
if (scrollHistory.length > 5) {
|
|
4936
|
-
scrollHistory.shift();
|
|
4937
|
-
}
|
|
4938
|
-
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
4939
|
-
const { lt, gt } = ignoreScrollFromMVCP;
|
|
4940
|
-
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
4941
|
-
state.ignoreScrollFromMVCPIgnored = true;
|
|
4942
|
-
return;
|
|
4943
|
-
}
|
|
4944
|
-
}
|
|
4945
|
-
state.scrollPrev = prevScroll;
|
|
4946
|
-
state.scrollPrevTime = state.scrollTime;
|
|
4947
|
-
state.scroll = newScroll;
|
|
4948
|
-
state.scrollTime = currentTime;
|
|
4949
|
-
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
4950
|
-
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
4951
|
-
const scrollLength = state.scrollLength;
|
|
4952
|
-
const lastCalculated = state.scrollLastCalculate;
|
|
4953
|
-
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
4954
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
4955
|
-
if (shouldUpdate) {
|
|
4956
|
-
state.scrollLastCalculate = state.scroll;
|
|
4957
|
-
state.ignoreScrollFromMVCPIgnored = false;
|
|
4958
|
-
state.lastScrollDelta = scrollDelta;
|
|
4959
|
-
const runCalculateItems = () => {
|
|
4960
|
-
var _a4;
|
|
4961
|
-
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
4962
|
-
checkThresholds(ctx);
|
|
4963
|
-
};
|
|
4964
|
-
if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust) {
|
|
4965
|
-
state.mvcpAnchorLock = void 0;
|
|
4966
|
-
state.pendingNativeMVCPAdjust = void 0;
|
|
4967
|
-
state.userScrollAnchorResetKeys = /* @__PURE__ */ new Set();
|
|
4968
|
-
if (state.queuedMVCPRecalculate !== void 0) {
|
|
4969
|
-
cancelAnimationFrame(state.queuedMVCPRecalculate);
|
|
4970
|
-
state.queuedMVCPRecalculate = void 0;
|
|
4971
|
-
}
|
|
4972
|
-
flushSync(runCalculateItems);
|
|
4973
|
-
} else {
|
|
4974
|
-
runCalculateItems();
|
|
4975
|
-
}
|
|
4976
|
-
const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
|
|
4977
|
-
if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
|
|
4978
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
4979
|
-
doMaintainScrollAtEnd(ctx);
|
|
4980
|
-
}
|
|
4981
|
-
state.dataChangeNeedsScrollUpdate = false;
|
|
4982
|
-
state.lastScrollDelta = 0;
|
|
4983
|
-
}
|
|
4984
|
-
}
|
|
4985
|
-
|
|
4986
5004
|
// src/core/onScroll.ts
|
|
4987
5005
|
function trackInitialScrollNativeProgress(state, newScroll) {
|
|
4988
5006
|
const initialNativeScrollWatchdog = initialScrollWatchdog.get(state);
|