diff --git a/Libraries/Lists/VirtualizeUtils.js b/Libraries/Lists/VirtualizeUtils.js index 6e50e62b9ca..85d50539db6 100644 --- a/Libraries/Lists/VirtualizeUtils.js +++ b/Libraries/Lists/VirtualizeUtils.js @@ -25,12 +25,13 @@ export function elementsThatOverlapOffsets( offset: number, ... }, + zoomScale: number, ): Array { const out = []; let outLength = 0; for (let ii = 0; ii < itemCount; ii++) { const frame = getFrameMetrics(ii); - const trailingOffset = frame.offset + frame.length; + const trailingOffset = (frame.offset + frame.length) * zoomScale; for (let kk = 0; kk < offsets.length; kk++) { if (out[kk] == null && trailingOffset >= offsets[kk]) { out[kk] = ii; @@ -104,6 +105,7 @@ export function computeWindowedRenderLimits( offset: number, velocity: number, visibleLength: number, + zoomScale: number, ... }, ): { @@ -115,7 +117,7 @@ export function computeWindowedRenderLimits( if (itemCount === 0) { return prev; } - const {offset, velocity, visibleLength} = scrollMetrics; + const {offset, velocity, visibleLength, zoomScale} = scrollMetrics; // Start with visible area, then compute maximum overscan region by expanding from there, biased // in the direction of scroll. Total overscan area is capped, which should cap memory consumption @@ -136,7 +138,8 @@ export function computeWindowedRenderLimits( ); const overscanEnd = Math.max(0, visibleEnd + leadFactor * overscanLength); - const lastItemOffset = getFrameMetricsApprox(itemCount - 1).offset; + const lastItemOffset = + getFrameMetricsApprox(itemCount - 1).offset * zoomScale; if (lastItemOffset < overscanBegin) { // Entire list is before our overscan window return { @@ -150,6 +153,7 @@ export function computeWindowedRenderLimits( [overscanBegin, visibleBegin, visibleEnd, overscanEnd], itemCount, getFrameMetricsApprox, + zoomScale, ); overscanFirst = overscanFirst == null ? 0 : overscanFirst; first = first == null ? Math.max(0, overscanFirst) : first; diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 86f45354e36..fdf63b3198d 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -1228,6 +1228,7 @@ class VirtualizedList extends React.PureComponent { timestamp: 0, velocity: 0, visibleLength: 0, + zoomScale: 1, }; _scrollRef: ?React.ElementRef = null; _sentEndForContentLength = 0; @@ -1624,6 +1625,9 @@ class VirtualizedList extends React.PureComponent { ); this._hasWarned.perf = true; } + + const zoomScale = e.nativeEvent.zoomScale; + this._scrollMetrics = { contentLength, dt, @@ -1632,6 +1636,7 @@ class VirtualizedList extends React.PureComponent { timestamp, velocity, visibleLength, + zoomScale, }; this._updateViewableItems(this.props.data); if (!this.props) { diff --git a/Libraries/Lists/VirtualizedListContext.js b/Libraries/Lists/VirtualizedListContext.js index d51a79244a0..308f6a20d19 100644 --- a/Libraries/Lists/VirtualizedListContext.js +++ b/Libraries/Lists/VirtualizedListContext.js @@ -47,6 +47,7 @@ type Context = $ReadOnly<{ timestamp: number, velocity: number, visibleLength: number, + zoomScale: number, }, horizontal: ?boolean, getOutermostParentListRef: () => VirtualizedList, diff --git a/Libraries/Lists/__tests__/VirtualizeUtils-test.js b/Libraries/Lists/__tests__/VirtualizeUtils-test.js index 88eb4f068c4..c700d599100 100644 --- a/Libraries/Lists/__tests__/VirtualizeUtils-test.js +++ b/Libraries/Lists/__tests__/VirtualizeUtils-test.js @@ -48,9 +48,9 @@ describe('elementsThatOverlapOffsets', function () { offset: 100 * index, }; } - expect(elementsThatOverlapOffsets(offsets, 100, getFrameMetrics)).toEqual([ - 0, 2, 3, 4, - ]); + expect( + elementsThatOverlapOffsets(offsets, 100, getFrameMetrics, 1), + ).toEqual([0, 2, 3, 4]); }); it('handles variable length', function () { const offsets = [150, 250, 900]; @@ -62,7 +62,7 @@ describe('elementsThatOverlapOffsets', function () { {offset: 950, length: 150}, ]; expect( - elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]), + elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1), ).toEqual([1, 1, 3]); }); it('handles out of bounds', function () { @@ -73,7 +73,7 @@ describe('elementsThatOverlapOffsets', function () { {offset: 250, length: 100}, ]; expect( - elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]), + elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1), ).toEqual([1]); }); it('errors on non-increasing offsets', function () { @@ -84,7 +84,7 @@ describe('elementsThatOverlapOffsets', function () { {offset: 250, length: 100}, ]; expect(() => { - elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii]); + elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1); }).toThrowErrorMatchingSnapshot(); }); }); diff --git a/Libraries/Lists/__tests__/VirtualizedList-test.js b/Libraries/Lists/__tests__/VirtualizedList-test.js index 9f902f180c7..5354df93f7f 100644 --- a/Libraries/Lists/__tests__/VirtualizedList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedList-test.js @@ -384,7 +384,7 @@ describe('VirtualizedList', () => { const instance = component.getInstance(); - instance._onLayout({nativeEvent: {layout}}); + instance._onLayout({nativeEvent: {layout, zoomScale: 1}}); const initialContentHeight = props.initialNumToRender * ITEM_HEIGHT; @@ -1490,7 +1490,7 @@ it('calls _onCellLayout properly', () => { ); const cell = virtualList._cellRefs.i4; const event = { - nativeEvent: {layout: {x: 0, y: 0, width: 50, height: 50}}, + nativeEvent: {layout: {x: 0, y: 0, width: 50, height: 50}, zoomScale: 1}, }; cell._onLayout(event); expect(mock).toHaveBeenCalledWith(event, 'i4', 3); @@ -1544,7 +1544,9 @@ function simulateLayout(component, args) { function simulateViewportLayout(component, dimensions) { lastViewportLayout = dimensions; - component.getInstance()._onLayout({nativeEvent: {layout: dimensions}}); + component + .getInstance() + ._onLayout({nativeEvent: {layout: dimensions}, zoomScale: 1}); } function simulateContentLayout(component, dimensions) { @@ -1558,7 +1560,7 @@ function simulateCellLayout(component, items, itemIndex, dimensions) { const instance = component.getInstance(); const cellKey = instance._keyExtractor(items[itemIndex], itemIndex); instance._onCellLayout( - {nativeEvent: {layout: dimensions}}, + {nativeEvent: {layout: dimensions, zoomScale: 1}}, cellKey, itemIndex, ); @@ -1570,6 +1572,7 @@ function simulateScroll(component, position) { contentOffset: position, contentSize: lastContentLayout, layoutMeasurement: lastViewportLayout, + zoomScale: 1, }, }); }