From d72f89d77623dcf65d50d5abc47cb061118de5ce Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Fri, 8 Mar 2019 18:25:28 -0800 Subject: [PATCH] Render only visible conversations in left pane --- js/conversation_controller.js | 2 - package.json | 1 + stylesheets/_modules.scss | 4 +- ts/components/ConversationListItem.tsx | 4 +- ts/components/LeftPane.tsx | 59 ++++++++++++++++++++++---- yarn.lock | 8 ++++ 6 files changed, 65 insertions(+), 13 deletions(-) diff --git a/js/conversation_controller.js b/js/conversation_controller.js index e3eb312b8d..6f0c8f1a16 100644 --- a/js/conversation_controller.js +++ b/js/conversation_controller.js @@ -11,8 +11,6 @@ const conversations = new Whisper.ConversationCollection(); const inboxCollection = new (Backbone.Collection.extend({ initialize() { - this.on('change:timestamp change:name change:number', this.sort); - this.listenTo(conversations, 'add change:active_at', this.addActive); this.listenTo(conversations, 'reset', () => this.reset([])); diff --git a/package.json b/package.json index 9766c6d88f..f574233a48 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "dependencies": { "@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#36149a4b03ccf11ec18b9205e1bfd9056015cf07", "@sindresorhus/is": "0.8.0", + "@types/react-virtualized": "9.18.12", "backbone": "1.3.3", "blob-util": "1.3.0", "blueimp-canvas-to-blob": "3.14.0", diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss index 3e097a78c0..048fb1c594 100644 --- a/stylesheets/_modules.scss +++ b/stylesheets/_modules.scss @@ -2989,8 +2989,10 @@ .module-left-pane__list { flex-grow: 1; flex-shrink: 1; +} - overflow-y: scroll; +.module-left-pane__virtual-list { + outline: none; } // Module: Start New Conversation diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx index d9d6acd7ec..2e5ba37955 100644 --- a/ts/components/ConversationListItem.tsx +++ b/ts/components/ConversationListItem.tsx @@ -32,6 +32,7 @@ export type PropsData = { type PropsHousekeeping = { i18n: LocalizerType; + style?: Object; onClick?: (id: string) => void; }; @@ -176,7 +177,7 @@ export class ConversationListItem extends React.PureComponent { } public render() { - const { unreadCount, onClick, id, isSelected } = this.props; + const { unreadCount, onClick, id, isSelected, style } = this.props; return (
{ onClick(id); } }} + style={style} className={classNames( 'module-conversation-list-item', unreadCount > 0 ? 'module-conversation-list-item--has-unread' : null, diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index 8175f288b6..427ca107dc 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { AutoSizer, List } from 'react-virtualized'; import { ConversationListItem, @@ -23,11 +24,39 @@ export interface Props { renderMainHeader: () => JSX.Element; } +// from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5 +type RowRendererParams = { + index: number; + isScrolling: boolean; + isVisible: boolean; + key: string; + parent: Object; + style: Object; +}; + export class LeftPane extends React.Component { + public renderRow = ({ index, key, style }: RowRendererParams) => { + const { conversations, i18n, openConversationInternal } = this.props; + if (!conversations) { + return null; + } + const conversation = conversations[index]; + + return ( + + ); + }; + public renderList() { const { - conversations, i18n, + conversations, openConversationInternal, startNewConversation, searchResults, @@ -44,16 +73,28 @@ export class LeftPane extends React.Component { ); } + if (!conversations || !conversations.length) { + return null; + } + + // Note: conversations is not a known prop for List, but it is required to ensure that + // it re-renders when our conversation data changes. Otherwise it would just render + // on startup and scroll. return (
- {(conversations || []).map(conversation => ( - - ))} + + {({ height, width }) => ( + + )} +
); } diff --git a/yarn.lock b/yarn.lock index 30bf7e9a4b..b89af707d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -176,6 +176,14 @@ "@types/react" "*" redux "^4.0.0" +"@types/react-virtualized@9.18.12": + version "9.18.12" + resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.18.12.tgz#541e65c5e0b4629d6a1c6f339171c7943e016ecb" + integrity sha512-Msdpt9zvYlb5Ul4PA339QUkJ0/z2O+gaFxed1rG+2rZjbe6XdYo7jWfJe206KBnjj84DwPPIbPFQCtoGuNwNTQ== + dependencies: + "@types/prop-types" "*" + "@types/react" "*" + "@types/react@*", "@types/react@16.8.5": version "16.8.5" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.5.tgz#03b9a6597bc20f6eaaed43f377a160f7e41c2b90"