diff --git a/web/chat/chat-thread-list.css b/web/chat/chat-thread-list.css
--- a/web/chat/chat-thread-list.css
+++ b/web/chat/chat-thread-list.css
@@ -15,9 +15,6 @@
top: -7px;
left: 30px;
}
-.thread:first-child {
- padding-top: 6px;
-}
.activeThread,
.threadListSidebar:hover {
@@ -265,6 +262,7 @@
display: flex;
flex-direction: column;
overflow: auto;
+ flex: 1;
}
div.createNewThread {
diff --git a/web/chat/chat-thread-list.react.js b/web/chat/chat-thread-list.react.js
--- a/web/chat/chat-thread-list.react.js
+++ b/web/chat/chat-thread-list.react.js
@@ -1,7 +1,10 @@
// @flow
import invariant from 'invariant';
+import _sum from 'lodash/fp/sum.js';
import * as React from 'react';
+import AutoSizer from 'react-virtualized-auto-sizer';
+import { VariableSizeList } from 'react-window';
import { emptyItemText } from 'lib/shared/thread-utils.js';
@@ -14,6 +17,25 @@
import { useSelector } from '../redux/redux-utils.js';
import { useOnClickNewThread } from '../selectors/thread-selectors.js';
+const sizes = {
+ search: 68,
+ thread: 81,
+ sidebars: { sidebar: 32, seeMore: 22, spacer: 6 },
+};
+
+const getThreadItemSize = item => {
+ const sidebarHeight = _sum(item.sidebars.map(s => sizes.sidebars[s.type]));
+ return sizes.thread + sidebarHeight;
+};
+
+const renderItem = ({ index, data, style }) => {
+ return (
+
+ {index === 0 ? data[0] : }
+
+ );
+};
+
function ChatThreadList(): React.Node {
const threadListContext = React.useContext(ThreadListContext);
invariant(
@@ -33,31 +55,81 @@
const communityID = useSelector(state => state.communityPickerStore.chat);
- const threadComponents: React.Node[] = React.useMemo(() => {
- const threads = threadList
- .filter(
+ const search = React.useMemo(
+ () => (
+
+ ),
+ [searchText, setSearchText],
+ );
+
+ const threadListContainerRef = React.useRef();
+
+ const threads = React.useMemo(
+ () =>
+ threadList.filter(
item =>
!communityID ||
item.threadInfo.community === communityID ||
item.threadInfo.id === communityID,
- )
- .map(item => );
- if (threads.length === 0 && isBackground) {
- threads.push();
+ ),
+ [communityID, threadList],
+ );
+
+ React.useEffect(() => {
+ if (threadListContainerRef.current) {
+ threadListContainerRef.current.resetAfterIndex(0, false);
+ }
+ }, [threads]);
+
+ const threadListContainer = React.useMemo(() => {
+ if (isBackground && threads.length === 0) {
+ return (
+ <>
+ {search}
+
+ >
+ );
}
- return threads;
- }, [threadList, isBackground, communityID]);
+
+ const items = [search, ...threads];
+
+ const itemKey = index =>
+ index === 0 ? 'search' : items[index].threadInfo.id;
+
+ const itemSize = index => {
+ if (index === 0) {
+ return sizes.search;
+ }
+
+ return getThreadItemSize(items[index]);
+ };
+
+ return (
+
+ {({ height }) => (
+
+ {renderItem}
+
+ )}
+
+ );
+ }, [isBackground, search, threads]);
return (
<>
-
+ {threadListContainer}