Open first search candidate on pressing "enter" key
This commit is contained in:
parent
db523f0684
commit
01efed8ec3
9 changed files with 218 additions and 14 deletions
|
@ -424,8 +424,8 @@ story.add('Search: all results', () => (
|
||||||
messageResults: {
|
messageResults: {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
results: [
|
results: [
|
||||||
{ id: 'msg1', conversationId: 'foo' },
|
{ id: 'msg1', type: 'outgoing', conversationId: 'foo' },
|
||||||
{ id: 'msg2', conversationId: 'bar' },
|
{ id: 'msg2', type: 'incoming', conversationId: 'bar' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
primarySendsSms: false,
|
primarySendsSms: false,
|
||||||
|
|
|
@ -39,6 +39,7 @@ import {
|
||||||
getWidthFromPreferredWidth,
|
getWidthFromPreferredWidth,
|
||||||
} from '../util/leftPaneWidth';
|
} from '../util/leftPaneWidth';
|
||||||
import type { LookupConversationWithoutUuidActionsType } from '../util/lookupConversationWithoutUuid';
|
import type { LookupConversationWithoutUuidActionsType } from '../util/lookupConversationWithoutUuid';
|
||||||
|
import type { OpenConversationInternalType } from '../state/ducks/conversations';
|
||||||
|
|
||||||
import { ConversationList } from './ConversationList';
|
import { ConversationList } from './ConversationList';
|
||||||
import { ContactCheckboxDisabledReason } from './conversationList/ContactCheckbox';
|
import { ContactCheckboxDisabledReason } from './conversationList/ContactCheckbox';
|
||||||
|
@ -99,11 +100,7 @@ export type PropsType = {
|
||||||
closeMaximumGroupSizeModal: () => void;
|
closeMaximumGroupSizeModal: () => void;
|
||||||
closeRecommendedGroupSizeModal: () => void;
|
closeRecommendedGroupSizeModal: () => void;
|
||||||
createGroup: () => void;
|
createGroup: () => void;
|
||||||
openConversationInternal: (_: {
|
openConversationInternal: OpenConversationInternalType;
|
||||||
conversationId: string;
|
|
||||||
messageId?: string;
|
|
||||||
switchToAssociatedView?: boolean;
|
|
||||||
}) => void;
|
|
||||||
savePreferredLeftPaneWidth: (_: number) => void;
|
savePreferredLeftPaneWidth: (_: number) => void;
|
||||||
searchInConversation: (conversationId: string) => unknown;
|
searchInConversation: (conversationId: string) => unknown;
|
||||||
setComposeSearchTerm: (composeSearchTerm: string) => void;
|
setComposeSearchTerm: (composeSearchTerm: string) => void;
|
||||||
|
@ -332,7 +329,8 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const numericIndex = keyboardKeyToNumericIndex(event.key);
|
const numericIndex = keyboardKeyToNumericIndex(event.key);
|
||||||
if (commandOrCtrl && isNumber(numericIndex)) {
|
const openedByNumber = commandOrCtrl && isNumber(numericIndex);
|
||||||
|
if (openedByNumber) {
|
||||||
conversationToOpen =
|
conversationToOpen =
|
||||||
helper.getConversationAndMessageAtIndex(numericIndex);
|
helper.getConversationAndMessageAtIndex(numericIndex);
|
||||||
} else {
|
} else {
|
||||||
|
@ -366,6 +364,9 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
if (conversationToOpen) {
|
if (conversationToOpen) {
|
||||||
const { conversationId, messageId } = conversationToOpen;
|
const { conversationId, messageId } = conversationToOpen;
|
||||||
openConversationInternal({ conversationId, messageId });
|
openConversationInternal({ conversationId, messageId });
|
||||||
|
if (openedByNumber) {
|
||||||
|
clearSearch();
|
||||||
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
@ -391,6 +392,7 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
showInbox,
|
showInbox,
|
||||||
startComposing,
|
startComposing,
|
||||||
startSearch,
|
startSearch,
|
||||||
|
clearSearch,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const requiresFullWidth = helper.requiresFullWidth();
|
const requiresFullWidth = helper.requiresFullWidth();
|
||||||
|
@ -558,6 +560,7 @@ export const LeftPane: React.FC<PropsType> = ({
|
||||||
setComposeSearchTerm(event.target.value);
|
setComposeSearchTerm(event.target.value);
|
||||||
},
|
},
|
||||||
updateSearchTerm,
|
updateSearchTerm,
|
||||||
|
openConversationInternal,
|
||||||
})}
|
})}
|
||||||
<div className="module-left-pane__dialogs">
|
<div className="module-left-pane__dialogs">
|
||||||
{renderExpiredBuildDialog({
|
{renderExpiredBuildDialog({
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import type { ConversationType } from '../state/ducks/conversations';
|
import type {
|
||||||
|
ConversationType,
|
||||||
|
OpenConversationInternalType,
|
||||||
|
} from '../state/ducks/conversations';
|
||||||
import type { LocalizerType } from '../types/Util';
|
import type { LocalizerType } from '../types/Util';
|
||||||
import { Avatar, AvatarSize } from './Avatar';
|
import { Avatar, AvatarSize } from './Avatar';
|
||||||
import { SearchInput } from './SearchInput';
|
import { SearchInput } from './SearchInput';
|
||||||
|
@ -17,6 +20,11 @@ type PropsType = {
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
startSearchCounter: number;
|
startSearchCounter: number;
|
||||||
updateSearchTerm: (searchTerm: string) => void;
|
updateSearchTerm: (searchTerm: string) => void;
|
||||||
|
openConversationInternal: OpenConversationInternalType;
|
||||||
|
onEnterKeyDown?: (
|
||||||
|
clearSearch: () => void,
|
||||||
|
openConversationInternal: OpenConversationInternalType
|
||||||
|
) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LeftPaneSearchInput = ({
|
export const LeftPaneSearchInput = ({
|
||||||
|
@ -28,6 +36,8 @@ export const LeftPaneSearchInput = ({
|
||||||
searchTerm,
|
searchTerm,
|
||||||
startSearchCounter,
|
startSearchCounter,
|
||||||
updateSearchTerm,
|
updateSearchTerm,
|
||||||
|
openConversationInternal,
|
||||||
|
onEnterKeyDown,
|
||||||
}: PropsType): JSX.Element => {
|
}: PropsType): JSX.Element => {
|
||||||
const inputRef = useRef<null | HTMLInputElement>(null);
|
const inputRef = useRef<null | HTMLInputElement>(null);
|
||||||
|
|
||||||
|
@ -91,6 +101,13 @@ export const LeftPaneSearchInput = ({
|
||||||
clearSearch();
|
clearSearch();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
onKeyDown={event => {
|
||||||
|
if (onEnterKeyDown && event.key === 'Enter') {
|
||||||
|
onEnterKeyDown(clearSearch, openConversationInternal);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
}}
|
||||||
onChange={event => {
|
onChange={event => {
|
||||||
changeValue(event.currentTarget.value);
|
changeValue(event.currentTarget.value);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -12,7 +12,10 @@ import type { Row } from '../ConversationList';
|
||||||
import { RowType } from '../ConversationList';
|
import { RowType } from '../ConversationList';
|
||||||
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||||
import type { LocalizerType } from '../../types/Util';
|
import type { LocalizerType } from '../../types/Util';
|
||||||
import type { ConversationType } from '../../state/ducks/conversations';
|
import type {
|
||||||
|
ConversationType,
|
||||||
|
OpenConversationInternalType,
|
||||||
|
} from '../../state/ducks/conversations';
|
||||||
import { LeftPaneSearchInput } from '../LeftPaneSearchInput';
|
import { LeftPaneSearchInput } from '../LeftPaneSearchInput';
|
||||||
import type { LeftPaneSearchPropsType } from './LeftPaneSearchHelper';
|
import type { LeftPaneSearchPropsType } from './LeftPaneSearchHelper';
|
||||||
import { LeftPaneSearchHelper } from './LeftPaneSearchHelper';
|
import { LeftPaneSearchHelper } from './LeftPaneSearchHelper';
|
||||||
|
@ -81,11 +84,13 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
||||||
clearSearch,
|
clearSearch,
|
||||||
i18n,
|
i18n,
|
||||||
updateSearchTerm,
|
updateSearchTerm,
|
||||||
|
openConversationInternal,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
clearConversationSearch: () => unknown;
|
clearConversationSearch: () => unknown;
|
||||||
clearSearch: () => unknown;
|
clearSearch: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
updateSearchTerm: (searchTerm: string) => unknown;
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
openConversationInternal: OpenConversationInternalType;
|
||||||
}>): ReactChild | null {
|
}>): ReactChild | null {
|
||||||
if (!this.searchConversation) {
|
if (!this.searchConversation) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -100,6 +105,7 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<LeftPaneArchivePropsTy
|
||||||
searchTerm={this.searchTerm}
|
searchTerm={this.searchTerm}
|
||||||
startSearchCounter={this.startSearchCounter}
|
startSearchCounter={this.startSearchCounter}
|
||||||
updateSearchTerm={updateSearchTerm}
|
updateSearchTerm={updateSearchTerm}
|
||||||
|
openConversationInternal={openConversationInternal}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import type {
|
||||||
ReplaceAvatarActionType,
|
ReplaceAvatarActionType,
|
||||||
SaveAvatarToDiskActionType,
|
SaveAvatarToDiskActionType,
|
||||||
} from '../../types/Avatar';
|
} from '../../types/Avatar';
|
||||||
|
import type { OpenConversationInternalType } from '../../state/ducks/conversations';
|
||||||
|
|
||||||
export enum FindDirection {
|
export enum FindDirection {
|
||||||
Up,
|
Up,
|
||||||
|
@ -42,6 +43,7 @@ export abstract class LeftPaneHelper<T> {
|
||||||
event: ChangeEvent<HTMLInputElement>
|
event: ChangeEvent<HTMLInputElement>
|
||||||
) => unknown;
|
) => unknown;
|
||||||
updateSearchTerm: (searchTerm: string) => unknown;
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
openConversationInternal: OpenConversationInternalType;
|
||||||
}>
|
}>
|
||||||
): null | ReactChild {
|
): null | ReactChild {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -7,7 +7,10 @@ import React from 'react';
|
||||||
|
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import type { ToFindType } from './LeftPaneHelper';
|
import type { ToFindType } from './LeftPaneHelper';
|
||||||
import type { ConversationType } from '../../state/ducks/conversations';
|
import type {
|
||||||
|
ConversationType,
|
||||||
|
OpenConversationInternalType,
|
||||||
|
} from '../../state/ducks/conversations';
|
||||||
import { LeftPaneHelper } from './LeftPaneHelper';
|
import { LeftPaneHelper } from './LeftPaneHelper';
|
||||||
import { getConversationInDirection } from './getConversationInDirection';
|
import { getConversationInDirection } from './getConversationInDirection';
|
||||||
import type { Row } from '../ConversationList';
|
import type { Row } from '../ConversationList';
|
||||||
|
@ -83,11 +86,13 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
|
||||||
clearSearch,
|
clearSearch,
|
||||||
i18n,
|
i18n,
|
||||||
updateSearchTerm,
|
updateSearchTerm,
|
||||||
|
openConversationInternal,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
clearConversationSearch: () => unknown;
|
clearConversationSearch: () => unknown;
|
||||||
clearSearch: () => unknown;
|
clearSearch: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
updateSearchTerm: (searchTerm: string) => unknown;
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
openConversationInternal: OpenConversationInternalType;
|
||||||
}>): ReactChild {
|
}>): ReactChild {
|
||||||
return (
|
return (
|
||||||
<LeftPaneSearchInput
|
<LeftPaneSearchInput
|
||||||
|
@ -99,6 +104,7 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
|
||||||
searchTerm={this.searchTerm}
|
searchTerm={this.searchTerm}
|
||||||
startSearchCounter={this.startSearchCounter}
|
startSearchCounter={this.startSearchCounter}
|
||||||
updateSearchTerm={updateSearchTerm}
|
updateSearchTerm={updateSearchTerm}
|
||||||
|
openConversationInternal={openConversationInternal}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,10 @@ import type { Row } from '../ConversationList';
|
||||||
import { RowType } from '../ConversationList';
|
import { RowType } from '../ConversationList';
|
||||||
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
import type { PropsData as ConversationListItemPropsType } from '../conversationList/ConversationListItem';
|
||||||
import { handleKeydownForSearch } from './handleKeydownForSearch';
|
import { handleKeydownForSearch } from './handleKeydownForSearch';
|
||||||
import type { ConversationType } from '../../state/ducks/conversations';
|
import type {
|
||||||
|
ConversationType,
|
||||||
|
OpenConversationInternalType,
|
||||||
|
} from '../../state/ducks/conversations';
|
||||||
import { LeftPaneSearchInput } from '../LeftPaneSearchInput';
|
import { LeftPaneSearchInput } from '../LeftPaneSearchInput';
|
||||||
|
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
|
@ -35,6 +38,7 @@ export type LeftPaneSearchPropsType = {
|
||||||
messageResults: MaybeLoadedSearchResultsType<{
|
messageResults: MaybeLoadedSearchResultsType<{
|
||||||
id: string;
|
id: string;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
type: string;
|
||||||
}>;
|
}>;
|
||||||
searchConversationName?: string;
|
searchConversationName?: string;
|
||||||
primarySendsSms: boolean;
|
primarySendsSms: boolean;
|
||||||
|
@ -58,6 +62,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
private readonly messageResults: MaybeLoadedSearchResultsType<{
|
private readonly messageResults: MaybeLoadedSearchResultsType<{
|
||||||
id: string;
|
id: string;
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
type: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
private readonly searchConversationName?: string;
|
private readonly searchConversationName?: string;
|
||||||
|
@ -94,6 +99,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
this.searchDisabled = searchDisabled;
|
this.searchDisabled = searchDisabled;
|
||||||
this.searchTerm = searchTerm;
|
this.searchTerm = searchTerm;
|
||||||
this.startSearchCounter = startSearchCounter;
|
this.startSearchCounter = startSearchCounter;
|
||||||
|
this.onEnterKeyDown = this.onEnterKeyDown.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
override getSearchInput({
|
override getSearchInput({
|
||||||
|
@ -101,11 +107,13 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
clearSearch,
|
clearSearch,
|
||||||
i18n,
|
i18n,
|
||||||
updateSearchTerm,
|
updateSearchTerm,
|
||||||
|
openConversationInternal,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
clearConversationSearch: () => unknown;
|
clearConversationSearch: () => unknown;
|
||||||
clearSearch: () => unknown;
|
clearSearch: () => unknown;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
updateSearchTerm: (searchTerm: string) => unknown;
|
updateSearchTerm: (searchTerm: string) => unknown;
|
||||||
|
openConversationInternal: OpenConversationInternalType;
|
||||||
}>): ReactChild {
|
}>): ReactChild {
|
||||||
return (
|
return (
|
||||||
<LeftPaneSearchInput
|
<LeftPaneSearchInput
|
||||||
|
@ -117,6 +125,8 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
searchTerm={this.searchTerm}
|
searchTerm={this.searchTerm}
|
||||||
startSearchCounter={this.startSearchCounter}
|
startSearchCounter={this.startSearchCounter}
|
||||||
updateSearchTerm={updateSearchTerm}
|
updateSearchTerm={updateSearchTerm}
|
||||||
|
openConversationInternal={openConversationInternal}
|
||||||
|
onEnterKeyDown={this.onEnterKeyDown}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -298,10 +308,28 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is currently unimplemented. See DESKTOP-1170.
|
|
||||||
getConversationAndMessageAtIndex(
|
getConversationAndMessageAtIndex(
|
||||||
_conversationIndex: number
|
conversationIndex: number
|
||||||
): undefined | { conversationId: string; messageId?: string } {
|
): undefined | { conversationId: string; messageId?: string } {
|
||||||
|
if (conversationIndex < 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let pointer = conversationIndex;
|
||||||
|
for (const list of this.allResults()) {
|
||||||
|
if (list.isLoading) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pointer < list.results.length) {
|
||||||
|
const result = list.results[pointer];
|
||||||
|
return result.type === 'incoming' || result.type === 'outgoing' // message
|
||||||
|
? {
|
||||||
|
conversationId: result.conversationId,
|
||||||
|
messageId: result.id,
|
||||||
|
}
|
||||||
|
: { conversationId: result.id };
|
||||||
|
}
|
||||||
|
pointer -= list.results.length;
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,6 +360,18 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
private isLoading(): boolean {
|
private isLoading(): boolean {
|
||||||
return this.allResults().some(results => results.isLoading);
|
return this.allResults().some(results => results.isLoading);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onEnterKeyDown(
|
||||||
|
clearSearch: () => unknown,
|
||||||
|
openConversationInternal: OpenConversationInternalType
|
||||||
|
): void {
|
||||||
|
const conversation = this.getConversationAndMessageAtIndex(0);
|
||||||
|
if (!conversation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openConversationInternal(conversation);
|
||||||
|
clearSearch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRowCountForLoadedSearchResults(
|
function getRowCountForLoadedSearchResults(
|
||||||
|
|
|
@ -347,6 +347,12 @@ export type ConversationsStateType = {
|
||||||
messagesByConversation: MessagesByConversationType;
|
messagesByConversation: MessagesByConversationType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type OpenConversationInternalType = (_: {
|
||||||
|
conversationId: string;
|
||||||
|
messageId?: string;
|
||||||
|
switchToAssociatedView?: boolean;
|
||||||
|
}) => void;
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
export const getConversationCallMode = (
|
export const getConversationCallMode = (
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { LeftPaneSearchHelper } from '../../../components/leftPane/LeftPaneSearc
|
||||||
describe('LeftPaneSearchHelper', () => {
|
describe('LeftPaneSearchHelper', () => {
|
||||||
const fakeMessage = () => ({
|
const fakeMessage = () => ({
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
|
type: 'outgoing',
|
||||||
conversationId: uuid(),
|
conversationId: uuid(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -547,4 +548,127 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getConversationAndMessageAtIndex', () => {
|
||||||
|
it('returns correct conversation at given index', () => {
|
||||||
|
const expected = getDefaultConversation();
|
||||||
|
const helper = new LeftPaneSearchHelper({
|
||||||
|
conversationResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [expected, getDefaultConversation()],
|
||||||
|
},
|
||||||
|
contactResults: { isLoading: false, results: [] },
|
||||||
|
messageResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [fakeMessage(), fakeMessage(), fakeMessage()],
|
||||||
|
},
|
||||||
|
searchTerm: 'foo',
|
||||||
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
|
});
|
||||||
|
assert.strictEqual(
|
||||||
|
helper.getConversationAndMessageAtIndex(0)?.conversationId,
|
||||||
|
expected.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct contact at given index', () => {
|
||||||
|
const expected = getDefaultConversation();
|
||||||
|
const helper = new LeftPaneSearchHelper({
|
||||||
|
conversationResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [getDefaultConversation(), getDefaultConversation()],
|
||||||
|
},
|
||||||
|
contactResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [expected],
|
||||||
|
},
|
||||||
|
messageResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [fakeMessage(), fakeMessage(), fakeMessage()],
|
||||||
|
},
|
||||||
|
searchTerm: 'foo',
|
||||||
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
|
});
|
||||||
|
assert.strictEqual(
|
||||||
|
helper.getConversationAndMessageAtIndex(2)?.conversationId,
|
||||||
|
expected.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct message at given index', () => {
|
||||||
|
const expected = fakeMessage();
|
||||||
|
const helper = new LeftPaneSearchHelper({
|
||||||
|
conversationResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [getDefaultConversation(), getDefaultConversation()],
|
||||||
|
},
|
||||||
|
contactResults: { isLoading: false, results: [] },
|
||||||
|
messageResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [fakeMessage(), fakeMessage(), expected],
|
||||||
|
},
|
||||||
|
searchTerm: 'foo',
|
||||||
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
|
});
|
||||||
|
assert.strictEqual(
|
||||||
|
helper.getConversationAndMessageAtIndex(4)?.messageId,
|
||||||
|
expected.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct message at given index skipping not loaded results', () => {
|
||||||
|
const expected = fakeMessage();
|
||||||
|
const helper = new LeftPaneSearchHelper({
|
||||||
|
conversationResults: { isLoading: true },
|
||||||
|
contactResults: { isLoading: true },
|
||||||
|
messageResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [fakeMessage(), expected, fakeMessage()],
|
||||||
|
},
|
||||||
|
searchTerm: 'foo',
|
||||||
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
|
});
|
||||||
|
assert.strictEqual(
|
||||||
|
helper.getConversationAndMessageAtIndex(1)?.messageId,
|
||||||
|
expected.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns undefined if search candidate with given index does not exist', () => {
|
||||||
|
const helper = new LeftPaneSearchHelper({
|
||||||
|
conversationResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [getDefaultConversation(), getDefaultConversation()],
|
||||||
|
},
|
||||||
|
contactResults: { isLoading: false, results: [] },
|
||||||
|
messageResults: {
|
||||||
|
isLoading: false,
|
||||||
|
results: [fakeMessage(), fakeMessage(), fakeMessage()],
|
||||||
|
},
|
||||||
|
searchTerm: 'foo',
|
||||||
|
primarySendsSms: false,
|
||||||
|
searchConversation: undefined,
|
||||||
|
searchDisabled: false,
|
||||||
|
startSearchCounter: 0,
|
||||||
|
});
|
||||||
|
assert.isUndefined(
|
||||||
|
helper.getConversationAndMessageAtIndex(100)?.messageId
|
||||||
|
);
|
||||||
|
assert.isUndefined(
|
||||||
|
helper.getConversationAndMessageAtIndex(-100)?.messageId
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue