Various search UI improvements
This commit is contained in:
parent
630394d91d
commit
a9cb621eb6
25 changed files with 835 additions and 577 deletions
|
@ -12,28 +12,54 @@ import type { Row } from '../ConversationList';
|
|||
import { RowType } from '../ConversationList';
|
||||
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||
import type { LocalizerType } from '../../types/Util';
|
||||
import type { ConversationType } from '../../state/ducks/conversations';
|
||||
import { LeftPaneSearchInput } from '../LeftPaneSearchInput';
|
||||
import type { LeftPaneSearchPropsType } from './LeftPaneSearchHelper';
|
||||
import { LeftPaneSearchHelper } from './LeftPaneSearchHelper';
|
||||
|
||||
export type LeftPaneArchivePropsType = {
|
||||
type LeftPaneArchiveBasePropsType = {
|
||||
archivedConversations: ReadonlyArray<ConversationListItemPropsType>;
|
||||
searchConversation: undefined | ConversationType;
|
||||
searchTerm: string;
|
||||
};
|
||||
|
||||
export type LeftPaneArchivePropsType =
|
||||
| LeftPaneArchiveBasePropsType
|
||||
| (LeftPaneArchiveBasePropsType & LeftPaneSearchPropsType);
|
||||
|
||||
/* eslint-disable class-methods-use-this */
|
||||
|
||||
export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsType> {
|
||||
private readonly archivedConversations: ReadonlyArray<ConversationListItemPropsType>;
|
||||
|
||||
constructor({ archivedConversations }: Readonly<LeftPaneArchivePropsType>) {
|
||||
private readonly searchConversation: undefined | ConversationType;
|
||||
|
||||
private readonly searchTerm: string;
|
||||
|
||||
private readonly searchHelper: undefined | LeftPaneSearchHelper;
|
||||
|
||||
constructor(props: Readonly<LeftPaneArchivePropsType>) {
|
||||
super();
|
||||
|
||||
this.archivedConversations = archivedConversations;
|
||||
this.archivedConversations = props.archivedConversations;
|
||||
this.searchConversation = props.searchConversation;
|
||||
this.searchTerm = props.searchTerm;
|
||||
|
||||
if ('conversationResults' in props) {
|
||||
this.searchHelper = new LeftPaneSearchHelper(props);
|
||||
}
|
||||
}
|
||||
|
||||
getHeaderContents({
|
||||
clearSearch,
|
||||
i18n,
|
||||
showInbox,
|
||||
updateSearchTerm,
|
||||
}: Readonly<{
|
||||
clearSearch: () => void;
|
||||
i18n: LocalizerType;
|
||||
showInbox: () => void;
|
||||
updateSearchTerm: (query: string) => void;
|
||||
}>): ReactChild {
|
||||
return (
|
||||
<div className="module-left-pane__header__contents">
|
||||
|
@ -45,7 +71,24 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
type="button"
|
||||
/>
|
||||
<div className="module-left-pane__header__contents__text">
|
||||
{i18n('archivedConversations')}
|
||||
{this.searchConversation ? (
|
||||
<LeftPaneSearchInput
|
||||
i18n={i18n}
|
||||
onChangeValue={newValue => {
|
||||
updateSearchTerm(newValue);
|
||||
}}
|
||||
onClear={() => {
|
||||
clearSearch();
|
||||
}}
|
||||
ref={el => {
|
||||
el?.focus();
|
||||
}}
|
||||
searchConversation={this.searchConversation}
|
||||
value={this.searchTerm}
|
||||
/>
|
||||
) : (
|
||||
i18n('archivedConversations')
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -55,7 +98,13 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
return showInbox;
|
||||
}
|
||||
|
||||
getPreRowsNode({ i18n }: Readonly<{ i18n: LocalizerType }>): ReactChild {
|
||||
getPreRowsNode({
|
||||
i18n,
|
||||
}: Readonly<{ i18n: LocalizerType }>): ReactChild | null {
|
||||
if (this.searchHelper) {
|
||||
return this.searchHelper.getPreRowsNode({ i18n });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="module-left-pane__archive-helper-text">
|
||||
{i18n('archiveHelperText')}
|
||||
|
@ -64,10 +113,16 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
}
|
||||
|
||||
getRowCount(): number {
|
||||
return this.archivedConversations.length;
|
||||
return (
|
||||
this.searchHelper?.getRowCount() ?? this.archivedConversations.length
|
||||
);
|
||||
}
|
||||
|
||||
getRow(rowIndex: number): undefined | Row {
|
||||
if (this.searchHelper) {
|
||||
return this.searchHelper.getRow(rowIndex);
|
||||
}
|
||||
|
||||
const conversation = this.archivedConversations[rowIndex];
|
||||
return conversation
|
||||
? {
|
||||
|
@ -80,6 +135,10 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
getRowIndexToScrollTo(
|
||||
selectedConversationId: undefined | string
|
||||
): undefined | number {
|
||||
if (this.searchHelper) {
|
||||
return this.searchHelper.getRowIndexToScrollTo(selectedConversationId);
|
||||
}
|
||||
|
||||
if (!selectedConversationId) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -92,7 +151,12 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
getConversationAndMessageAtIndex(
|
||||
conversationIndex: number
|
||||
): undefined | { conversationId: string } {
|
||||
const { archivedConversations } = this;
|
||||
const { archivedConversations, searchHelper } = this;
|
||||
|
||||
if (searchHelper) {
|
||||
return searchHelper.getConversationAndMessageAtIndex(conversationIndex);
|
||||
}
|
||||
|
||||
const conversation =
|
||||
archivedConversations[conversationIndex] || last(archivedConversations);
|
||||
return conversation ? { conversationId: conversation.id } : undefined;
|
||||
|
@ -101,8 +165,16 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
getConversationAndMessageInDirection(
|
||||
toFind: Readonly<ToFindType>,
|
||||
selectedConversationId: undefined | string,
|
||||
_selectedMessageId: unknown
|
||||
selectedMessageId: unknown
|
||||
): undefined | { conversationId: string } {
|
||||
if (this.searchHelper) {
|
||||
return this.searchHelper.getConversationAndMessageInDirection(
|
||||
toFind,
|
||||
selectedConversationId,
|
||||
selectedMessageId
|
||||
);
|
||||
}
|
||||
|
||||
return getConversationInDirection(
|
||||
this.archivedConversations,
|
||||
toFind,
|
||||
|
@ -110,7 +182,51 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
|||
);
|
||||
}
|
||||
|
||||
shouldRecomputeRowHeights(_old: unknown): boolean {
|
||||
shouldRecomputeRowHeights(old: Readonly<LeftPaneArchivePropsType>): boolean {
|
||||
const hasSearchingChanged =
|
||||
'conversationResults' in old !== Boolean(this.searchHelper);
|
||||
if (hasSearchingChanged) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('conversationResults' in old && this.searchHelper) {
|
||||
return this.searchHelper.shouldRecomputeRowHeights(old);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onKeyDown(
|
||||
event: KeyboardEvent,
|
||||
{
|
||||
searchInConversation,
|
||||
selectedConversationId,
|
||||
}: Readonly<{
|
||||
searchInConversation: (conversationId: string) => unknown;
|
||||
selectedConversationId: undefined | string;
|
||||
}>
|
||||
): void {
|
||||
if (!selectedConversationId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { ctrlKey, metaKey, shiftKey, key } = event;
|
||||
const commandKey = window.platform === 'darwin' && metaKey;
|
||||
const controlKey = window.platform !== 'darwin' && ctrlKey;
|
||||
const commandOrCtrl = commandKey || controlKey;
|
||||
const commandAndCtrl = commandKey && ctrlKey;
|
||||
|
||||
if (
|
||||
commandOrCtrl &&
|
||||
!commandAndCtrl &&
|
||||
shiftKey &&
|
||||
key.toLowerCase() === 'f' &&
|
||||
this.archivedConversations.some(({ id }) => id === selectedConversationId)
|
||||
) {
|
||||
searchInConversation(selectedConversationId);
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue