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