Skip to content

Commit

Permalink
fix: Correct behavior for CMD/CTRL+k shortcut in new navigation setti…
Browse files Browse the repository at this point in the history
…ngs (WPB-10006) (#17690)

* fix: Correct behavior for CMD/CTRL+k shortcut in new navigation settings (WPB-10006)

* more refactoring

* fix test
  • Loading branch information
thisisamir98 authored Jul 15, 2024
1 parent 8a7df3b commit 1c39586
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 37 deletions.
35 changes: 29 additions & 6 deletions src/script/page/LeftSidebar/LeftSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
*/

import React, {useEffect} from 'react';
import React, {useEffect, useRef, useState} from 'react';

import {amplify} from 'amplify';
import cx from 'classnames';
Expand All @@ -42,27 +42,50 @@ type LeftSidebarProps = {
const LeftSidebar: React.FC<LeftSidebarProps> = ({listViewModel, selfUser, isActivatedAccount}) => {
const {conversationRepository, propertiesRepository} = listViewModel;
const repositories = listViewModel.contentViewModel.repositories;
const inputRef = useRef<HTMLInputElement | null>(null);

const [isConversationFilterFocused, setIsConversationFilterFocused] = useState<boolean>(false);
const listState = useAppState(state => state.listState);

const switchList = (list: ListState) => listViewModel.switchList(list);

const {setCurrentTab} = useSidebarStore();

useEffect(() => {
amplify.subscribe(WebAppEvents.SHORTCUT.START, () => {
function openCreateGroupModal() {
amplify.publish(WebAppEvents.CONVERSATION.CREATE_GROUP, 'conversation_details');
});
}

async function jumpToRecentSearch() {
switchList(ListState.CONVERSATIONS);

amplify.subscribe(WebAppEvents.SHORTCUT.SEARCH, () => {
setCurrentTab(SidebarTabs.RECENT);
switchList(ListState.START_UI);
});
setIsConversationFilterFocused(true);
}

amplify.subscribe(WebAppEvents.SHORTCUT.START, openCreateGroupModal);

amplify.subscribe(WebAppEvents.SHORTCUT.SEARCH, jumpToRecentSearch);

return () => {
amplify.unsubscribe(WebAppEvents.SHORTCUT.START, openCreateGroupModal);
amplify.unsubscribe(WebAppEvents.SHORTCUT.SEARCH, jumpToRecentSearch);
};
}, []);

useEffect(() => {
if (isConversationFilterFocused) {
inputRef.current?.focus();
}
}, [inputRef, isConversationFilterFocused]);

return (
<aside id="left-column" className={cx('left-column', {'left-column--light-theme': !isActivatedAccount})}>
{[ListState.CONVERSATIONS, ListState.START_UI, ListState.PREFERENCES, ListState.ARCHIVE].includes(listState) && (
<Conversations
inputRef={inputRef}
isConversationFilterFocused={isConversationFilterFocused}
setIsConversationFilterFocused={setIsConversationFilterFocused}
selfUser={selfUser}
listViewModel={listViewModel}
searchRepository={repositories.search}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
*/

import {KeyboardEvent, useEffect, useRef} from 'react';
import {forwardRef, ForwardRefRenderFunction, KeyboardEvent} from 'react';

import {amplify} from 'amplify';

Expand Down Expand Up @@ -55,22 +55,23 @@ interface ConversationHeaderProps {
onSearchEnterClick: (event: KeyboardEvent<HTMLInputElement>) => void;
}

export const ConversationHeader = ({
currentTab,
selfUser,
showSearchInput = false,
searchValue = '',
setSearchValue,
currentFolder,
searchInputPlaceholder,
setIsConversationFilterFocused,
onSearchEnterClick,
}: ConversationHeaderProps) => {
export const ConversationHeaderComponent: ForwardRefRenderFunction<HTMLInputElement, ConversationHeaderProps> = (
{
currentTab,
selfUser,
showSearchInput = false,
searchValue = '',
setSearchValue,
currentFolder,
searchInputPlaceholder,
setIsConversationFilterFocused,
onSearchEnterClick,
},
inputRef,
) => {
const {canCreateGroupConversation} = generatePermissionHelpers(selfUser.teamRole());
const isFolderView = currentTab === SidebarTabs.FOLDER;

const inputRef = useRef<HTMLInputElement | null>(null);

const conversationsHeaderTitle: Partial<Record<SidebarTabs, string>> = {
[SidebarTabs.RECENT]: t('conversationViewAllConversations'),
[SidebarTabs.FAVORITES]: t('conversationLabelFavorites'),
Expand All @@ -81,12 +82,6 @@ export const ConversationHeader = ({
[SidebarTabs.CONNECT]: t('searchConnect'),
};

useEffect(() => {
amplify.subscribe(WebAppEvents.SHORTCUT.SEARCH, () => {
inputRef?.current?.focus();
});
}, []);

const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Escape') {
setSearchValue('');
Expand Down Expand Up @@ -141,3 +136,5 @@ export const ConversationHeader = ({
</>
);
};

export const ConversationHeader = forwardRef(ConversationHeaderComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ describe('Conversations', () => {
preferenceNotificationRepository: {notifications: observable([])} as any,
propertiesRepository: {getPreference: jest.fn(), savePreference: jest.fn()} as any,
selfUser: new User(),
inputRef: {current: null},
isConversationFilterFocused: false,
setIsConversationFilterFocused: () => undefined,
integrationRepository: {integrations: observable([])} as any,
searchRepository: {search: jest.fn()} as any,
teamRepository: {getTeam: jest.fn()} as any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,22 @@ type ConversationsProps = {
searchRepository: SearchRepository;
teamRepository: TeamRepository;
userRepository: UserRepository;
inputRef: React.MutableRefObject<HTMLInputElement | null>;
isConversationFilterFocused: boolean;
setIsConversationFilterFocused: (isFocused: boolean) => void;
};

const Conversations: React.FC<ConversationsProps> = ({
inputRef,
integrationRepository,
searchRepository,
teamRepository,
userRepository,
propertiesRepository,
conversationRepository,
preferenceNotificationRepository,
isConversationFilterFocused,
setIsConversationFilterFocused,
listViewModel,
conversationState = container.resolve(ConversationState),
teamState = container.resolve(TeamState),
Expand All @@ -101,7 +107,6 @@ const Conversations: React.FC<ConversationsProps> = ({
}) => {
const {currentTab, status: sidebarStatus, setStatus: setSidebarStatus, setCurrentTab} = useSidebarStore();
const [conversationsFilter, setConversationsFilter] = useState<string>('');
const [isConversationFilterFocused, setIsConversationFilterFocused] = useState(false);
const {classifiedDomains, isTeam} = useKoSubscribableChildren(teamState, ['classifiedDomains', 'isTeam']);
const {connectRequests} = useKoSubscribableChildren(userState, ['connectRequests']);

Expand Down Expand Up @@ -316,14 +321,15 @@ const Conversations: React.FC<ConversationsProps> = ({
id="conversations"
headerElement={
<ConversationHeader
ref={inputRef}
currentFolder={currentFolder}
currentTab={currentTab}
selfUser={selfUser}
showSearchInput={(showSearchInput && currentTabConversations.length !== 0) || !!conversationsFilter}
searchValue={conversationsFilter}
setSearchValue={setConversationsFilter}
searchInputPlaceholder={searchInputPlaceholder}
setIsConversationFilterFocused={setIsConversationFilterFocused}
setIsConversationFilterFocused={value => setIsConversationFilterFocused(value)}
onSearchEnterClick={handleEnterSearchClick}
/>
}
Expand Down
2 changes: 1 addition & 1 deletion src/script/page/LeftSidebar/panels/Conversations/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const useSidebarStore = create<SidebarStore>()(
{
name: 'sidebar-store',
storage: createJSONStorage(() => localStorage),
partialize: state => ({status: state.status}),
partialize: state => ({status: state.status, currentTab: state.currentTab}),
},
),
);
Expand Down
14 changes: 6 additions & 8 deletions src/script/router/routerBindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ import {navigate} from './Router';

import {useAppMainState, ViewType} from '../page/state';

export const createNavigate =
(link: string): React.MouseEventHandler =>
(event: React.MouseEvent<Element, MouseEvent>) => {
// The order here matters, setting the view before calling navigate() would not save the history
navigate(link);
setResponsiveView();
event.preventDefault();
};
export const createNavigate = (link: string) => (event?: React.MouseEvent<Element, MouseEvent>) => {
// The order here matters, setting the view before calling navigate() would not save the history
navigate(link);
setResponsiveView();
event?.preventDefault();
};

export const createNavigateKeyboard =
(link: string, setIsResponsive = false): React.KeyboardEventHandler =>
Expand Down

0 comments on commit 1c39586

Please sign in to comment.