diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index 25a3d9e8b96..4f9abd9212b 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -150,11 +150,13 @@ export class LeftPane extends React.Component { } conversationIndex -= pinnedConversations.length + 2; - } else { + } else if (index < pinnedConversations.length) { return { index, type: RowType.PinnedConversation, }; + } else { + conversationIndex = 0; } } @@ -610,13 +612,34 @@ export class LeftPane extends React.Component { } componentDidUpdate(oldProps: PropsType): void { - const { pinnedConversations: oldPinned } = oldProps; - const { pinnedConversations: pinned } = this.props; + const { + conversations: oldConversations = [], + pinnedConversations: oldPinnedConversations = [], + archivedConversations: oldArchivedConversations = [], + showArchived: oldShowArchived, + } = oldProps; + const { + conversations: newConversations = [], + pinnedConversations: newPinnedConversations = [], + archivedConversations: newArchivedConversations = [], + showArchived: newShowArchived, + } = this.props; - const oldLength = (oldPinned && oldPinned.length) || 0; - const newLength = (pinned && pinned.length) || 0; + const oldHasArchivedConversations = Boolean( + oldArchivedConversations.length + ); + const newHasArchivedConversations = Boolean( + newArchivedConversations.length + ); - if (oldLength !== newLength) { + // This could probably be optimized further, but we want to be extra-careful that our + // heights are correct. + if ( + oldConversations.length !== newConversations.length || + oldPinnedConversations.length !== newPinnedConversations.length || + oldHasArchivedConversations !== newHasArchivedConversations || + oldShowArchived !== newShowArchived + ) { this.recomputeRowHeights(); } } diff --git a/ts/test/components/LeftPane_test.tsx b/ts/test/components/LeftPane_test.tsx index a51e235259d..0372180a979 100644 --- a/ts/test/components/LeftPane_test.tsx +++ b/ts/test/components/LeftPane_test.tsx @@ -34,6 +34,86 @@ describe('LeftPane', () => { describe('getRowFromIndex', () => { let leftPane: LeftPane; + describe('with pinned, non-pinned, and archived chats', () => { + it('returns headers, conversations, and an archived button', () => { + leftPane = new LeftPane({ + ...defaultProps, + pinnedConversations: [ + { + id: 'philly-convo', + isPinned: true, + isSelected: false, + lastUpdated: Date.now(), + title: 'Philip Glass', + type: 'direct', + }, + { + id: 'robbo-convo', + isPinned: true, + isSelected: false, + lastUpdated: Date.now(), + title: 'Robert Moog', + type: 'direct', + }, + ], + conversations: [ + { + id: 'etta-convo', + isSelected: false, + lastUpdated: Date.now(), + title: 'Etta James', + type: 'direct', + }, + { + id: 'kimbra-convo', + isPinned: false, + isSelected: false, + lastUpdated: Date.now(), + title: 'Kimbra', + type: 'direct', + }, + ], + archivedConversations: [ + { + id: 'jerry-convo', + isSelected: false, + lastUpdated: Date.now(), + title: 'Jerry Jordan', + type: 'direct', + }, + ], + }); + + expect(leftPane.getRowFromIndex(0)).to.eql({ + headerType: HeaderType.Pinned, + type: RowType.Header, + }); + expect(leftPane.getRowFromIndex(1)).to.eql({ + index: 0, + type: RowType.PinnedConversation, + }); + expect(leftPane.getRowFromIndex(2)).to.eql({ + index: 1, + type: RowType.PinnedConversation, + }); + expect(leftPane.getRowFromIndex(3)).to.eql({ + headerType: HeaderType.Chats, + type: RowType.Header, + }); + expect(leftPane.getRowFromIndex(4)).to.eql({ + index: 0, + type: RowType.Conversation, + }); + expect(leftPane.getRowFromIndex(5)).to.eql({ + index: 1, + type: RowType.Conversation, + }); + expect(leftPane.getRowFromIndex(6)).to.eql({ + type: RowType.ArchiveButton, + }); + }); + }); + describe('given only pinned chats', () => { beforeEach(function beforeEach() { const props: PropsType = { @@ -158,6 +238,65 @@ describe('LeftPane', () => { }); }); }); + + describe('given only pinned and archived chats', () => { + it('shows the pinned chats with no headers', () => { + leftPane = new LeftPane({ + ...defaultProps, + pinnedConversations: [ + { + id: 'philly-convo', + isPinned: true, + isSelected: false, + lastUpdated: Date.now(), + title: 'Philip Glass', + type: 'direct', + }, + ], + archivedConversations: [ + { + id: 'fred-convo', + isSelected: false, + lastUpdated: Date.now(), + title: 'Fred Willard', + type: 'direct', + }, + ], + }); + + expect(leftPane.getRowFromIndex(0)).to.eql({ + index: 0, + type: RowType.PinnedConversation, + }); + + expect(leftPane.getRowFromIndex(1)).to.eql({ + type: RowType.ArchiveButton, + }); + }); + }); + + describe("given only archived conversations, which we're not showing", () => { + it('returns a single row, the archive button', () => { + leftPane = new LeftPane({ + ...defaultProps, + archivedConversations: [ + { + id: 'jerry-convo', + isSelected: false, + lastUpdated: Date.now(), + title: 'Jerry Jordan', + type: 'direct', + }, + ], + showArchived: false, + }); + + expect(leftPane.getRowFromIndex(0)).to.eql({ + type: RowType.ArchiveButton, + }); + }); + }); + describe('given not showing archive with archived conversation', () => { beforeEach(function beforeEach() { const props: PropsType = {