Skip to content

Commit

Permalink
Fix keyboard search when left pane is narrow
Browse files Browse the repository at this point in the history
This PR fixes Cmd+f/Ctrl+f functionality in the left pane.
Using a keyboard to search across all
conversations should now automatically change the left pane width
to accommodate the search input component.

Resolves: #6281
  • Loading branch information
veekas committed Feb 22, 2023
1 parent 3d735ac commit 28bcd47
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 23 deletions.
24 changes: 12 additions & 12 deletions ts/components/LeftPane.stories.tsx
Expand Up @@ -104,7 +104,7 @@ const defaultModeSpecificProps = {
pinnedConversations,
conversations: defaultConversations,
archivedConversations: defaultArchivedConversations,
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
};

const emptySearchResultsGroup = { isLoading: false, results: [] };
Expand Down Expand Up @@ -278,7 +278,7 @@ export function InboxNoConversations(): JSX.Element {
pinnedConversations: [],
conversations: [],
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand All @@ -299,7 +299,7 @@ export function InboxOnlyPinnedConversations(): JSX.Element {
pinnedConversations,
conversations: [],
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand All @@ -320,7 +320,7 @@ export function InboxOnlyNonPinnedConversations(): JSX.Element {
pinnedConversations: [],
conversations: defaultConversations,
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand All @@ -341,7 +341,7 @@ export function InboxOnlyArchivedConversations(): JSX.Element {
pinnedConversations: [],
conversations: [],
archivedConversations: defaultArchivedConversations,
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand All @@ -362,7 +362,7 @@ export function InboxPinnedAndArchivedConversations(): JSX.Element {
pinnedConversations,
conversations: [],
archivedConversations: defaultArchivedConversations,
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand All @@ -383,7 +383,7 @@ export function InboxNonPinnedAndArchivedConversations(): JSX.Element {
pinnedConversations: [],
conversations: defaultConversations,
archivedConversations: defaultArchivedConversations,
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand All @@ -404,7 +404,7 @@ export function InboxPinnedAndNonPinnedConversations(): JSX.Element {
pinnedConversations,
conversations: defaultConversations,
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
},
})}
/>
Expand Down Expand Up @@ -946,7 +946,7 @@ export function CaptchaDialogRequired(): JSX.Element {
pinnedConversations,
conversations: defaultConversations,
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
searchTerm: '',
},
challengeStatus: 'required',
Expand All @@ -969,7 +969,7 @@ export function CaptchaDialogPending(): JSX.Element {
pinnedConversations,
conversations: defaultConversations,
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
searchTerm: '',
},
challengeStatus: 'pending',
Expand All @@ -991,7 +991,7 @@ export const _CrashReportDialog = (): JSX.Element => (
pinnedConversations,
conversations: defaultConversations,
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
searchTerm: '',
},
crashReportCount: 42,
Expand Down Expand Up @@ -1163,7 +1163,7 @@ export function SearchingConversation(): JSX.Element {
pinnedConversations: [],
conversations: defaultConversations,
archivedConversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
searchConversation: getDefaultConversation(),
searchTerm: '',
},
Expand Down
10 changes: 5 additions & 5 deletions ts/components/leftPane/LeftPaneInboxHelper.tsx
Expand Up @@ -24,7 +24,7 @@ export type LeftPaneInboxPropsType = {
conversations: ReadonlyArray<ConversationListItemPropsType>;
archivedConversations: ReadonlyArray<ConversationListItemPropsType>;
pinnedConversations: ReadonlyArray<ConversationListItemPropsType>;
isAboutToSearchInAConversation: boolean;
isAboutToSearch: boolean;
startSearchCounter: number;
searchDisabled: boolean;
searchTerm: string;
Expand All @@ -38,7 +38,7 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>

private readonly pinnedConversations: ReadonlyArray<ConversationListItemPropsType>;

private readonly isAboutToSearchInAConversation: boolean;
private readonly isAboutToSearch: boolean;

private readonly startSearchCounter: number;

Expand All @@ -52,7 +52,7 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
conversations,
archivedConversations,
pinnedConversations,
isAboutToSearchInAConversation,
isAboutToSearch,
startSearchCounter,
searchDisabled,
searchTerm,
Expand All @@ -63,7 +63,7 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
this.conversations = conversations;
this.archivedConversations = archivedConversations;
this.pinnedConversations = pinnedConversations;
this.isAboutToSearchInAConversation = isAboutToSearchInAConversation;
this.isAboutToSearch = isAboutToSearch;
this.startSearchCounter = startSearchCounter;
this.searchDisabled = searchDisabled;
this.searchTerm = searchTerm;
Expand Down Expand Up @@ -245,7 +245,7 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
!this.conversations.length &&
!this.pinnedConversations.length &&
!this.archivedConversations.length;
return hasNoConversations || this.isAboutToSearchInAConversation;
return hasNoConversations || this.isAboutToSearch;
}

shouldRecomputeRowHeights(old: Readonly<LeftPaneInboxPropsType>): boolean {
Expand Down
6 changes: 4 additions & 2 deletions ts/state/ducks/search.ts
Expand Up @@ -57,6 +57,7 @@ export type MessageSearchResultLookupType = ReadonlyDeep<{
export type SearchStateType = ReadonlyDeep<{
startSearchCounter: number;
searchConversationId?: string;
globalSearch?: boolean;
contactIds: Array<string>;
conversationIds: Array<string>;
query: string;
Expand Down Expand Up @@ -94,7 +95,7 @@ type UpdateSearchTermActionType = ReadonlyDeep<{
}>;
type StartSearchActionType = ReadonlyDeep<{
type: 'SEARCH_START';
payload: null;
payload: { globalSearch: boolean };
}>;
type ClearSearchActionType = ReadonlyDeep<{
type: 'SEARCH_CLEAR';
Expand Down Expand Up @@ -137,7 +138,7 @@ export const actions = {
function startSearch(): StartSearchActionType {
return {
type: 'SEARCH_START',
payload: null,
payload: { globalSearch: true },
};
}
function clearSearch(): ClearSearchActionType {
Expand Down Expand Up @@ -341,6 +342,7 @@ export function reducer(
return {
...state,
searchConversationId: undefined,
globalSearch: true,
startSearchCounter: state.startSearchCounter + 1,
};
}
Expand Down
17 changes: 17 additions & 0 deletions ts/state/selectors/search.ts
Expand Up @@ -54,6 +54,23 @@ export const getIsSearchingInAConversation = createSelector(
Boolean
);

export const getSearchGlobalValue = createSelector(
getSearch,
(state: SearchStateType): boolean | undefined => state.globalSearch
);

export const getIsSearchingGlobally = createSelector(
getSearchGlobalValue,
Boolean
);

export const getIsSearching = createSelector(
getIsSearchingInAConversation,
getIsSearchingGlobally,
(isSearchingInAConversation, isSearchingGlobally): boolean =>
isSearchingInAConversation || isSearchingGlobally
);

export const getSearchConversation = createSelector(
getSearchConversationId,
getConversationLookup,
Expand Down
4 changes: 2 additions & 2 deletions ts/state/smart/LeftPane.tsx
Expand Up @@ -16,7 +16,7 @@ import { isDone as isRegistrationDone } from '../../util/registration';

import { ComposerStep, OneTimeModalState } from '../ducks/conversationsEnums';
import {
getIsSearchingInAConversation,
getIsSearching,
getQuery,
getSearchConversation,
getSearchResults,
Expand Down Expand Up @@ -152,7 +152,7 @@ const getModeSpecificProps = (
}
return {
mode: LeftPaneMode.Inbox,
isAboutToSearchInAConversation: getIsSearchingInAConversation(state),
isAboutToSearch: getIsSearching(state),
searchConversation: getSearchConversation(state),
searchDisabled: state.network.challengeStatus !== 'idle',
searchTerm: getQuery(state),
Expand Down
57 changes: 57 additions & 0 deletions ts/test-both/state/selectors/search_test.ts
Expand Up @@ -14,6 +14,8 @@ import type { MessageSearchResultType } from '../../../state/ducks/search';
import { getEmptyState as getEmptySearchState } from '../../../state/ducks/search';
import { getEmptyState as getEmptyUserState } from '../../../state/ducks/user';
import {
getIsSearching,
getIsSearchingGlobally,
getIsSearchingInAConversation,
getMessageSearchResultSelector,
getSearchResults,
Expand Down Expand Up @@ -93,6 +95,61 @@ describe('both/state/selectors/search', () => {
});
});

describe('#getIsSearchingGlobally', () => {
it('returns false if not searching', () => {
const state = getEmptyRootState();

assert.isFalse(getIsSearchingGlobally(state));
});

it('returns true if searching globally', () => {
const state = {
...getEmptyRootState(),
search: {
...getEmptySearchState(),
globalSearch: true,
},
};

assert.isTrue(getIsSearchingGlobally(state));
});
});

describe('#getIsSearching', () => {
it('returns false if not searching in any manner', () => {
const state = getEmptyRootState();

assert.isFalse(getIsSearching(state));
});

it('returns true if searching in a conversation', () => {
const state = {
...getEmptyRootState(),
search: {
...getEmptySearchState(),
searchConversationId: 'abc123',
searchConversationName: 'Test Conversation',
globalSearch: false,
},
};

assert.isTrue(getIsSearching(state));
});

it('returns true if searching globally', () => {
const state = {
...getEmptyRootState(),
search: {
...getEmptySearchState(),
searchConversationId: undefined,
globalSearch: true,
},
};

assert.isTrue(getIsSearchingGlobally(state));
});
});

describe('#getMessageSearchResultSelector', () => {
it('returns undefined if message not found in lookup', () => {
const state = getEmptyRootState();
Expand Down
4 changes: 2 additions & 2 deletions ts/test-node/components/leftPane/LeftPaneInboxHelper_test.tsx
Expand Up @@ -14,7 +14,7 @@ describe('LeftPaneInboxHelper', () => {
const defaultProps: LeftPaneInboxPropsType = {
archivedConversations: [],
conversations: [],
isAboutToSearchInAConversation: false,
isAboutToSearch: false,
pinnedConversations: [],
searchConversation: undefined,
searchDisabled: false,
Expand Down Expand Up @@ -616,7 +616,7 @@ describe('LeftPaneInboxHelper', () => {
it("returns true if we're about to search in a conversation", () => {
const helper = new LeftPaneInboxHelper({
...defaultProps,
isAboutToSearchInAConversation: true,
isAboutToSearch: true,
});

assert.isTrue(helper.requiresFullWidth());
Expand Down

0 comments on commit 28bcd47

Please sign in to comment.