Fix timeline scrolling bug

This commit is contained in:
Evan Hahn 2022-02-07 17:00:04 -06:00 committed by GitHub
parent 59d323d815
commit fc3f8220df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 33 deletions

View File

@ -70,7 +70,7 @@ index 262776b..156cf0f 100644
this._cellHeightCache[key] = height;
this._cellWidthCache[key] = width;
diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js b/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js
index e1b959a..f084d6e 100644
index e1b959a..97d6ef9 100644
--- a/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js
+++ b/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js
@@ -132,6 +132,9 @@ var Grid = function (_React$PureComponent) {
@ -155,7 +155,7 @@ index e1b959a..f084d6e 100644
});
this._maybeCallOnScrollbarPresenceChange();
@@ -584,6 +616,70 @@ var Grid = function (_React$PureComponent) {
@@ -584,6 +616,65 @@ var Grid = function (_React$PureComponent) {
}
}
@ -180,36 +180,31 @@ index e1b959a..f084d6e 100644
+
+ if (scrollToColumn >= 0 && !this._hasScrolledToColumnTarget && scrollLeft + width <= totalColumnsWidth) {
+ const scrollRight = scrollLeft + width;
+ const maxScroll = totalColumnsWidth - width;
+ const targetColumn = instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(scrollToColumn);
+
+ // When scrolling to the rightmost column, we want to go all the way to the right
+ if (scrollToColumn >= columnCount - 1) {
+ this._hasScrolledToColumnTarget = scrollRight >= maxScroll;
+ let isVisible = false;
+ if (targetColumn.size <= width) {
+ const targetColumnRight = targetColumn.offset + targetColumn.size;
+ isVisible = (targetColumn.offset >= scrollLeft && targetColumnRight <= scrollRight);
+ } else {
+ let isVisible = false;
+ const targetColumn = instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(scrollToColumn);
+ if (targetColumn.size <= width) {
+ const targetColumnRight = targetColumn.offset + targetColumn.size;
+ isVisible = (targetColumn.offset >= scrollRight && targetColumnRight <= scrollRight);
+ } else {
+ isVisible = (targetColumn.offset >= scrollRight && targetColumn.offset <= scrollRight);
+ }
+ isVisible = (targetColumn.offset >= scrollLeft && targetColumn.offset <= scrollRight);
+ }
+
+ if (isVisible) {
+ this._hasScrolledToColumnTarget = (scrollLeft >= maxScroll || targetColumn.offset === scrollLeft);
+ }
+ if (isVisible) {
+ const maxScroll = totalColumnsWidth - width;
+ this._hasScrolledToColumnTarget = (scrollLeft >= maxScroll || targetColumn.offset === scrollLeft);
+ }
+ }
+ if (scrollToRow >= 0 && !this._hasScrolledToRowTarget && scrollTop + height <= totalRowsHeight) {
+ const scrollBottom = scrollTop + height;
+ const targetRow = instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(scrollToRow);
+ const maxScroll = totalRowsHeight - height;
+
+ // When scrolling to bottom row, we want to go all the way to the bottom
+ if (scrollToRow >= rowCount - 1) {
+ if (scrollToRow === rowCount - 1) {
+ this._hasScrolledToRowTarget = scrollTop >= maxScroll;
+ } else {
+ let isVisible = false;
+ const targetRow = instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(scrollToRow);
+ if (targetRow.size <= height) {
+ const targetRowBottom = targetRow.offset + targetRow.size;
+ isVisible = (targetRow.offset >= scrollTop && targetRowBottom <= scrollBottom);
@ -226,7 +221,7 @@ index e1b959a..f084d6e 100644
// Special case where the previous size was 0:
// In this case we don't show any windowed cells at all.
// So we should always recalculate offset afterwards.
@@ -594,6 +690,8 @@ var Grid = function (_React$PureComponent) {
@@ -594,6 +685,8 @@ var Grid = function (_React$PureComponent) {
if (this._recomputeScrollLeftFlag) {
this._recomputeScrollLeftFlag = false;
this._updateScrollLeftForScrollToColumn(this.props);
@ -235,7 +230,7 @@ index e1b959a..f084d6e 100644
} else {
(0, _updateScrollIndexHelper2.default)({
cellSizeAndPositionManager: instanceProps.columnSizeAndPositionManager,
@@ -616,6 +714,8 @@ var Grid = function (_React$PureComponent) {
@@ -616,6 +709,8 @@ var Grid = function (_React$PureComponent) {
if (this._recomputeScrollTopFlag) {
this._recomputeScrollTopFlag = false;
this._updateScrollTopForScrollToRow(this.props);
@ -244,7 +239,7 @@ index e1b959a..f084d6e 100644
} else {
(0, _updateScrollIndexHelper2.default)({
cellSizeAndPositionManager: instanceProps.rowSizeAndPositionManager,
@@ -635,19 +735,50 @@ var Grid = function (_React$PureComponent) {
@@ -635,19 +730,50 @@ var Grid = function (_React$PureComponent) {
});
}
@ -299,7 +294,7 @@ index e1b959a..f084d6e 100644
});
}
@@ -750,6 +881,7 @@ var Grid = function (_React$PureComponent) {
@@ -750,6 +876,7 @@ var Grid = function (_React$PureComponent) {
}, containerProps, {
'aria-label': this.props['aria-label'],
'aria-readonly': this.props['aria-readonly'],
@ -307,7 +302,7 @@ index e1b959a..f084d6e 100644
className: (0, _classnames2.default)('ReactVirtualized__Grid', className),
id: id,
onScroll: this._onScroll,
@@ -909,6 +1041,11 @@ var Grid = function (_React$PureComponent) {
@@ -909,6 +1036,11 @@ var Grid = function (_React$PureComponent) {
visibleRowIndices: visibleRowIndices
});
@ -319,7 +314,7 @@ index e1b959a..f084d6e 100644
// update the indices
this._columnStartIndex = columnStartIndex;
this._columnStopIndex = columnStopIndex;
@@ -962,7 +1099,11 @@ var Grid = function (_React$PureComponent) {
@@ -962,7 +1094,11 @@ var Grid = function (_React$PureComponent) {
var scrollLeft = _ref6.scrollLeft,
scrollTop = _ref6.scrollTop,
totalColumnsWidth = _ref6.totalColumnsWidth,
@ -332,7 +327,7 @@ index e1b959a..f084d6e 100644
this._onScrollMemoizer({
callback: function callback(_ref7) {
@@ -973,19 +1114,26 @@ var Grid = function (_React$PureComponent) {
@@ -973,19 +1109,26 @@ var Grid = function (_React$PureComponent) {
onScroll = _props7.onScroll,
width = _props7.width;
@ -362,7 +357,7 @@ index e1b959a..f084d6e 100644
}
});
}
@@ -1325,6 +1473,15 @@ var Grid = function (_React$PureComponent) {
@@ -1325,6 +1468,15 @@ var Grid = function (_React$PureComponent) {
var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize();
var scrollBarSize = instanceProps.scrollbarSizeMeasured && totalColumnsWidth > width ? instanceProps.scrollbarSize : 0;

View File

@ -1,4 +1,4 @@
// Copyright 2019-2021 Signal Messenger, LLC
// Copyright 2019-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -10,6 +10,7 @@ import type {
import { AutoSizer, Grid } from 'react-virtualized';
import {
chunk,
clamp,
debounce,
findLast,
flatMap,
@ -99,8 +100,8 @@ export const EmojiPicker = React.memo(
const debounceSearchChange = React.useMemo(
() =>
debounce((query: string) => {
setSearchText(query);
setScrollToRow(0);
setSearchText(query);
}, 200),
[setSearchText, setScrollToRow]
);
@ -155,9 +156,9 @@ export const EmojiPicker = React.memo(
React.useEffect(() => {
const handler = (event: KeyboardEvent) => {
if (searchMode && event.key === 'Escape') {
setScrollToRow(0);
setSearchText('');
setSearchMode(false);
setScrollToRow(0);
event.preventDefault();
event.stopPropagation();
@ -210,6 +211,8 @@ export const EmojiPicker = React.memo(
return [...chunk(firstRecent, COL_COUNT), ...chunks];
}, [firstRecent, renderableCategories, searchText]);
const rowCount = emojiGrid.length;
const catRowEnds = React.useMemo(() => {
const rowEnds: Array<number> = [
Math.ceil(firstRecent.length / COL_COUNT) - 1,
@ -354,7 +357,7 @@ export const EmojiPicker = React.memo(
)
)}
</header>
{emojiGrid.length > 0 ? (
{rowCount > 0 ? (
<div>
<AutoSizer>
{({ width, height }) => (
@ -366,9 +369,12 @@ export const EmojiPicker = React.memo(
columnCount={COL_COUNT}
columnWidth={38}
rowHeight={getRowHeight}
rowCount={emojiGrid.length}
rowCount={rowCount}
cellRenderer={cellRenderer}
scrollToRow={scrollToRow}
// In some cases, `scrollToRow` can be too high for a short period
// during state changes. This ensures that the value is never too
// large.
scrollToRow={clamp(scrollToRow, 0, rowCount - 1)}
scrollToAlignment="start"
onSectionRendered={onSectionRendered}
/>