Improve left pane UI when loading search results
This commit is contained in:
parent
f05d45ac9b
commit
d81aaf654f
15 changed files with 420 additions and 93 deletions
|
@ -10,6 +10,14 @@ import { PropsData as ConversationListItemPropsType } from '../conversationList/
|
|||
|
||||
import { Intl } from '../Intl';
|
||||
import { Emojify } from '../conversation/Emojify';
|
||||
import { assert } from '../../util/assert';
|
||||
|
||||
// The "correct" thing to do is to measure the size of the left pane and render enough
|
||||
// search results for the container height. But (1) that's slow (2) the list is
|
||||
// virtualized (3) 99 rows is over 6000px tall, taller than most monitors (4) it's fine
|
||||
// if, in some extremely tall window, we have some empty space. So we just hard-code a
|
||||
// fairly big number.
|
||||
const SEARCH_RESULTS_FAKE_ROW_COUNT = 99;
|
||||
|
||||
type MaybeLoadedSearchResultsType<T> =
|
||||
| { isLoading: true }
|
||||
|
@ -106,9 +114,14 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
}
|
||||
|
||||
getRowCount(): number {
|
||||
if (this.isLoading()) {
|
||||
// 1 for the header.
|
||||
return 1 + SEARCH_RESULTS_FAKE_ROW_COUNT;
|
||||
}
|
||||
|
||||
return this.allResults().reduce(
|
||||
(result: number, searchResults) =>
|
||||
result + getRowCountForSearchResult(searchResults),
|
||||
result + getRowCountForLoadedSearchResults(searchResults),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
@ -124,11 +137,21 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
getRow(rowIndex: number): undefined | Row {
|
||||
const { conversationResults, contactResults, messageResults } = this;
|
||||
|
||||
const conversationRowCount = getRowCountForSearchResult(
|
||||
if (this.isLoading()) {
|
||||
if (rowIndex === 0) {
|
||||
return { type: RowType.SearchResultsLoadingFakeHeader };
|
||||
}
|
||||
if (rowIndex + 1 <= SEARCH_RESULTS_FAKE_ROW_COUNT) {
|
||||
return { type: RowType.SearchResultsLoadingFakeRow };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const conversationRowCount = getRowCountForLoadedSearchResults(
|
||||
conversationResults
|
||||
);
|
||||
const contactRowCount = getRowCountForSearchResult(contactResults);
|
||||
const messageRowCount = getRowCountForSearchResult(messageResults);
|
||||
const contactRowCount = getRowCountForLoadedSearchResults(contactResults);
|
||||
const messageRowCount = getRowCountForLoadedSearchResults(messageResults);
|
||||
|
||||
if (rowIndex < conversationRowCount) {
|
||||
if (rowIndex === 0) {
|
||||
|
@ -137,9 +160,10 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
i18nKey: 'conversationsHeader',
|
||||
};
|
||||
}
|
||||
if (conversationResults.isLoading) {
|
||||
return { type: RowType.Spinner };
|
||||
}
|
||||
assert(
|
||||
!conversationResults.isLoading,
|
||||
"We shouldn't get here with conversation results still loading"
|
||||
);
|
||||
const conversation = conversationResults.results[rowIndex - 1];
|
||||
return conversation
|
||||
? {
|
||||
|
@ -157,9 +181,10 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
i18nKey: 'contactsHeader',
|
||||
};
|
||||
}
|
||||
if (contactResults.isLoading) {
|
||||
return { type: RowType.Spinner };
|
||||
}
|
||||
assert(
|
||||
!contactResults.isLoading,
|
||||
"We shouldn't get here with contact results still loading"
|
||||
);
|
||||
const conversation = contactResults.results[localIndex - 1];
|
||||
return conversation
|
||||
? {
|
||||
|
@ -180,9 +205,10 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
i18nKey: 'messagesHeader',
|
||||
};
|
||||
}
|
||||
if (messageResults.isLoading) {
|
||||
return { type: RowType.Spinner };
|
||||
}
|
||||
assert(
|
||||
!messageResults.isLoading,
|
||||
"We shouldn't get here with message results still loading"
|
||||
);
|
||||
const message = messageResults.results[localIndex - 1];
|
||||
return message
|
||||
? {
|
||||
|
@ -192,11 +218,23 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
: undefined;
|
||||
}
|
||||
|
||||
isScrollable(): boolean {
|
||||
return !this.isLoading();
|
||||
}
|
||||
|
||||
shouldRecomputeRowHeights(old: Readonly<LeftPaneSearchPropsType>): boolean {
|
||||
const oldIsLoading = new LeftPaneSearchHelper(old).isLoading();
|
||||
const newIsLoading = this.isLoading();
|
||||
if (oldIsLoading && newIsLoading) {
|
||||
return false;
|
||||
}
|
||||
if (oldIsLoading !== newIsLoading) {
|
||||
return true;
|
||||
}
|
||||
return searchResultKeys.some(
|
||||
key =>
|
||||
getRowCountForSearchResult(old[key]) !==
|
||||
getRowCountForSearchResult(this[key])
|
||||
getRowCountForLoadedSearchResults(old[key]) !==
|
||||
getRowCountForLoadedSearchResults(this[key])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -221,20 +259,27 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<
|
|||
private allResults() {
|
||||
return [this.conversationResults, this.contactResults, this.messageResults];
|
||||
}
|
||||
|
||||
private isLoading(): boolean {
|
||||
return this.allResults().some(results => results.isLoading);
|
||||
}
|
||||
}
|
||||
|
||||
function getRowCountForSearchResult(
|
||||
function getRowCountForLoadedSearchResults(
|
||||
searchResults: Readonly<MaybeLoadedSearchResultsType<unknown>>
|
||||
): number {
|
||||
let hasHeader: boolean;
|
||||
let resultRows: number;
|
||||
// It's possible to call this helper with invalid results (e.g., ones that are loading).
|
||||
// We could change the parameter of this function, but that adds a bunch of redundant
|
||||
// checks that are, in the author's opinion, less clear.
|
||||
if (searchResults.isLoading) {
|
||||
hasHeader = true;
|
||||
resultRows = 1; // For the spinner.
|
||||
} else {
|
||||
const resultCount = searchResults.results.length;
|
||||
hasHeader = Boolean(resultCount);
|
||||
resultRows = resultCount;
|
||||
assert(
|
||||
false,
|
||||
'getRowCountForLoadedSearchResults: Expected this to be called with loaded search results. Returning 0'
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const resultRows = searchResults.results.length;
|
||||
const hasHeader = Boolean(resultRows);
|
||||
return (hasHeader ? 1 : 0) + resultRows;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue