Extract ListView controller from ConversationList

This commit is contained in:
Alvaro 2022-11-14 11:48:51 -07:00 committed by GitHub
parent 1b901522c2
commit 6b42a69947
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 31 deletions

View file

@ -4365,12 +4365,6 @@ button.module-image__border-overlay:focus {
padding-right: 10px;
}
&--scroll-behavior {
&-default {
@include smooth-scroll;
}
}
&__item {
&--archive-button {
@include button-reset;

View file

@ -0,0 +1,10 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.ListView {
&--scroll-behavior {
&-default {
@include smooth-scroll;
}
}
}

View file

@ -2,9 +2,8 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { ReactNode } from 'react';
import React, { useRef, useEffect, useCallback } from 'react';
import React, { useCallback } from 'react';
import type { ListRowRenderer } from 'react-virtualized';
import { List } from 'react-virtualized';
import classNames from 'classnames';
import { get, pick } from 'lodash';
@ -33,6 +32,7 @@ import { SearchResultsLoadingFakeHeader as SearchResultsLoadingFakeHeaderCompone
import { SearchResultsLoadingFakeRow as SearchResultsLoadingFakeRowComponent } from './conversationList/SearchResultsLoadingFakeRow';
import { UsernameSearchResultListItem } from './conversationList/UsernameSearchResultListItem';
import { GroupListItem } from './conversationList/GroupListItem';
import { ListView } from './ListView';
export enum RowType {
ArchiveButton = 'ArchiveButton',
@ -203,17 +203,8 @@ export const ConversationList: React.FC<PropsType> = ({
showConversation,
theme,
}) => {
const listRef = useRef<null | List>(null);
useEffect(() => {
const list = listRef.current;
if (shouldRecomputeRowHeights && list) {
list.recomputeRowHeights();
}
});
const calculateRowHeight = useCallback(
({ index }: { index: number }): number => {
(index: number): number => {
const row = getRow(index);
if (!row) {
assertDev(false, `Expected a row at index ${index}`);
@ -472,25 +463,20 @@ export const ConversationList: React.FC<PropsType> = ({
const widthBreakpoint = getConversationListWidthBreakpoint(width);
return (
<List
<ListView
className={classNames(
'module-conversation-list',
`module-conversation-list--scroll-behavior-${scrollBehavior}`,
`module-conversation-list--width-${widthBreakpoint}`
)}
width={width}
height={height}
ref={listRef}
rowCount={rowCount}
rowHeight={calculateRowHeight}
calculateRowHeight={calculateRowHeight}
rowRenderer={renderRow}
scrollToIndex={scrollToRowIndex}
style={{
// See `<Timeline>` for an explanation of this `any` cast.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
overflowY: scrollable ? ('overlay' as any) : 'hidden',
}}
tabIndex={-1}
width={width}
shouldRecomputeRowHeights={shouldRecomputeRowHeights}
scrollable={scrollable}
scrollBehavior={scrollBehavior}
/>
);
};

View file

@ -0,0 +1,70 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import classNames from 'classnames';
import React, { useEffect, useRef } from 'react';
import type { Index, ListRowRenderer } from 'react-virtualized';
import { List } from 'react-virtualized';
import { ScrollBehavior } from '../types/Util';
type Props = {
width: number;
height: number;
rowCount: number;
calculateRowHeight: (index: number) => number;
rowRenderer: ListRowRenderer;
scrollToIndex?: number;
scrollable?: boolean;
className?: string;
shouldRecomputeRowHeights?: boolean;
scrollBehavior?: ScrollBehavior;
};
/**
* Thin wrapper around react-virtualized List. Simplified API and provides common
* defaults.
*/
export const ListView = ({
width,
height,
rowCount,
calculateRowHeight,
rowRenderer,
scrollToIndex,
className,
scrollable = true,
shouldRecomputeRowHeights = false,
scrollBehavior = ScrollBehavior.Default,
}: Props): JSX.Element => {
const listRef = useRef<null | List>(null);
useEffect(() => {
const list = listRef.current;
if (shouldRecomputeRowHeights && list) {
list.recomputeRowHeights();
}
});
return (
<List
className={classNames(
'ListView',
`ListView--scroll-behavior-${scrollBehavior}`,
className
)}
width={width}
height={height}
ref={listRef}
rowCount={rowCount}
rowHeight={(index: Index) => calculateRowHeight(index.index)}
rowRenderer={rowRenderer}
scrollToIndex={scrollToIndex}
style={{
// See `<Timeline>` for an explanation of this `any` cast.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
overflowY: scrollable ? ('overlay' as any) : 'hidden',
}}
tabIndex={-1}
/>
);
};

View file

@ -9052,10 +9052,10 @@
},
{
"rule": "React-useRef",
"path": "ts/components/ConversationList.tsx",
"path": "ts/components/ListView.tsx",
"line": " const listRef = useRef<null | List>(null);",
"reasonCategory": "usageTrusted",
"updated": "2021-07-30T16:57:33.618Z"
"updated": "2022-11-11T17:11:07.659Z"
},
{
"rule": "React-useRef",