Left Search: Fix <Esc> hotkey behavior (#1977)
This commit is contained in:
parent
bc9fd31ed3
commit
c738eaf13b
@ -8,6 +8,7 @@ import { LeftColumnContent, SettingsScreens } from '../../types';
|
|||||||
|
|
||||||
import { IS_MAC_OS, IS_PWA, LAYERS_ANIMATION_NAME } from '../../util/environment';
|
import { IS_MAC_OS, IS_PWA, LAYERS_ANIMATION_NAME } from '../../util/environment';
|
||||||
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
||||||
|
import { selectCurrentChat } from '../../global/selectors';
|
||||||
import useFoldersReducer from '../../hooks/reducers/useFoldersReducer';
|
import useFoldersReducer from '../../hooks/reducers/useFoldersReducer';
|
||||||
import { useResize } from '../../hooks/useResize';
|
import { useResize } from '../../hooks/useResize';
|
||||||
import { useHotkeys } from '../../hooks/useHotkeys';
|
import { useHotkeys } from '../../hooks/useHotkeys';
|
||||||
@ -24,12 +25,13 @@ import './LeftColumn.scss';
|
|||||||
type StateProps = {
|
type StateProps = {
|
||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
searchDate?: number;
|
searchDate?: number;
|
||||||
activeChatFolder: number;
|
isFirstChatFolderActive: boolean;
|
||||||
shouldSkipHistoryAnimations?: boolean;
|
shouldSkipHistoryAnimations?: boolean;
|
||||||
leftColumnWidth?: number;
|
leftColumnWidth?: number;
|
||||||
currentUserId?: string;
|
currentUserId?: string;
|
||||||
hasPasscode?: boolean;
|
hasPasscode?: boolean;
|
||||||
nextSettingsScreen?: SettingsScreens;
|
nextSettingsScreen?: SettingsScreens;
|
||||||
|
isChatOpen: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
@ -49,12 +51,13 @@ const RESET_TRANSITION_DELAY_MS = 250;
|
|||||||
const LeftColumn: FC<StateProps> = ({
|
const LeftColumn: FC<StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
searchDate,
|
searchDate,
|
||||||
activeChatFolder,
|
isFirstChatFolderActive,
|
||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
leftColumnWidth,
|
leftColumnWidth,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
hasPasscode,
|
hasPasscode,
|
||||||
nextSettingsScreen,
|
nextSettingsScreen,
|
||||||
|
isChatOpen,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
setGlobalSearchQuery,
|
setGlobalSearchQuery,
|
||||||
@ -276,14 +279,15 @@ const LeftColumn: FC<StateProps> = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content === LeftColumnContent.ChatList && activeChatFolder === 0) {
|
if (content === LeftColumnContent.ChatList && isFirstChatFolderActive) {
|
||||||
setContent(LeftColumnContent.GlobalSearch);
|
setContent(LeftColumnContent.GlobalSearch);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fullReset();
|
fullReset();
|
||||||
}, [
|
}, [
|
||||||
content, activeChatFolder, settingsScreen, setGlobalSearchQuery, setGlobalSearchDate, setGlobalSearchChatId,
|
content, isFirstChatFolderActive, settingsScreen, setGlobalSearchQuery, setGlobalSearchDate, setGlobalSearchChatId,
|
||||||
resetChatCreation, hasPasscode,
|
resetChatCreation, hasPasscode,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -301,10 +305,10 @@ const LeftColumn: FC<StateProps> = ({
|
|||||||
}, [content, searchQuery, setGlobalSearchQuery]);
|
}, [content, searchQuery, setGlobalSearchQuery]);
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => (content !== LeftColumnContent.ChatList || activeChatFolder === 0
|
() => (content !== LeftColumnContent.ChatList || (isFirstChatFolderActive && !isChatOpen)
|
||||||
? captureEscKeyListener(() => handleReset())
|
? captureEscKeyListener(() => handleReset())
|
||||||
: undefined),
|
: undefined),
|
||||||
[activeChatFolder, content, handleReset],
|
[isFirstChatFolderActive, content, handleReset, isChatOpen],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleHotkeySearch = useCallback((e: KeyboardEvent) => {
|
const handleHotkeySearch = useCallback((e: KeyboardEvent) => {
|
||||||
@ -462,15 +466,18 @@ export default memo(withGlobal(
|
|||||||
},
|
},
|
||||||
} = global;
|
} = global;
|
||||||
|
|
||||||
|
const isChatOpen = Boolean(selectCurrentChat(global)?.id);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
searchDate: date,
|
searchDate: date,
|
||||||
activeChatFolder,
|
isFirstChatFolderActive: activeChatFolder === 0,
|
||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
leftColumnWidth,
|
leftColumnWidth,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
hasPasscode,
|
hasPasscode,
|
||||||
nextSettingsScreen,
|
nextSettingsScreen,
|
||||||
|
isChatOpen,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(LeftColumn));
|
)(LeftColumn));
|
||||||
|
|||||||
@ -39,6 +39,7 @@ type StateProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SAVED_MESSAGES_HOTKEY = '0';
|
const SAVED_MESSAGES_HOTKEY = '0';
|
||||||
|
const FIRST_FOLDER_INDEX = 0;
|
||||||
|
|
||||||
const ChatFolders: FC<OwnProps & StateProps> = ({
|
const ChatFolders: FC<OwnProps & StateProps> = ({
|
||||||
foldersDispatch,
|
foldersDispatch,
|
||||||
@ -68,7 +69,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
}
|
}
|
||||||
}, [lastSyncTime, loadChatFolders]);
|
}, [lastSyncTime, loadChatFolders]);
|
||||||
|
|
||||||
const defaultFolder = useMemo(() => {
|
const allChatsFolder = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
id: ALL_FOLDER_ID,
|
id: ALL_FOLDER_ID,
|
||||||
title: orderedFolderIds?.[0] === ALL_FOLDER_ID ? lang('FilterAllChatsShort') : lang('FilterAllChats'),
|
title: orderedFolderIds?.[0] === ALL_FOLDER_ID ? lang('FilterAllChatsShort') : lang('FilterAllChats'),
|
||||||
@ -79,15 +80,17 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
return orderedFolderIds
|
return orderedFolderIds
|
||||||
? orderedFolderIds.map((id) => {
|
? orderedFolderIds.map((id) => {
|
||||||
if (id === ALL_FOLDER_ID) {
|
if (id === ALL_FOLDER_ID) {
|
||||||
return defaultFolder;
|
return allChatsFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
return chatFoldersById[id] || {};
|
return chatFoldersById[id] || {};
|
||||||
}).filter(Boolean)
|
}).filter(Boolean)
|
||||||
: undefined;
|
: undefined;
|
||||||
}, [chatFoldersById, defaultFolder, orderedFolderIds]);
|
}, [chatFoldersById, allChatsFolder, orderedFolderIds]);
|
||||||
|
|
||||||
const allFolderIndex = displayedFolders?.findIndex((folder) => folder.id === 0);
|
const allChatsFolderIndex = displayedFolders?.findIndex((folder) => folder.id === ALL_FOLDER_ID);
|
||||||
const isInAllFolder = allFolderIndex === activeChatFolder;
|
const isInAllChatsFolder = allChatsFolderIndex === activeChatFolder;
|
||||||
|
const isInFirstFolder = FIRST_FOLDER_INDEX === activeChatFolder;
|
||||||
|
|
||||||
const folderCountersById = useFolderManagerForUnreadCounters();
|
const folderCountersById = useFolderManagerForUnreadCounters();
|
||||||
const folderTabs = useMemo(() => {
|
const folderTabs = useMemo(() => {
|
||||||
@ -119,9 +122,9 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (activeChatFolder >= folderTabs.length) {
|
if (activeChatFolder >= folderTabs.length) {
|
||||||
setActiveChatFolder(allFolderIndex);
|
setActiveChatFolder(FIRST_FOLDER_INDEX);
|
||||||
}
|
}
|
||||||
}, [activeChatFolder, allFolderIndex, folderTabs, setActiveChatFolder]);
|
}, [activeChatFolder, folderTabs, setActiveChatFolder]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!transitionRef.current || !IS_TOUCH_ENV || !folderTabs || !folderTabs.length) {
|
if (!transitionRef.current || !IS_TOUCH_ENV || !folderTabs || !folderTabs.length) {
|
||||||
@ -144,17 +147,17 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
}, [activeChatFolder, folderTabs, setActiveChatFolder]);
|
}, [activeChatFolder, folderTabs, setActiveChatFolder]);
|
||||||
|
|
||||||
const isNotInAllTabRef = useRef();
|
const isNotInFirstFolderRef = useRef();
|
||||||
isNotInAllTabRef.current = !isInAllFolder;
|
isNotInFirstFolderRef.current = !isInFirstFolder;
|
||||||
useEffect(() => (isNotInAllTabRef.current ? captureEscKeyListener(() => {
|
useEffect(() => (isNotInFirstFolderRef.current ? captureEscKeyListener(() => {
|
||||||
if (isNotInAllTabRef.current) {
|
if (isNotInFirstFolderRef.current) {
|
||||||
setActiveChatFolder(allFolderIndex);
|
setActiveChatFolder(FIRST_FOLDER_INDEX);
|
||||||
}
|
}
|
||||||
}) : undefined), [activeChatFolder, allFolderIndex, setActiveChatFolder]);
|
}) : undefined), [activeChatFolder, setActiveChatFolder]);
|
||||||
|
|
||||||
useHistoryBack({
|
useHistoryBack({
|
||||||
isActive: !isInAllFolder,
|
isActive: !isInFirstFolder,
|
||||||
onBack: () => setActiveChatFolder(allFolderIndex, { forceOnHeavyAnimation: true }),
|
onBack: () => setActiveChatFolder(FIRST_FOLDER_INDEX, { forceOnHeavyAnimation: true }),
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -191,7 +194,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
|||||||
const activeFolder = Object.values(chatFoldersById)
|
const activeFolder = Object.values(chatFoldersById)
|
||||||
.find(({ id }) => id === folderTabs![activeChatFolder].id);
|
.find(({ id }) => id === folderTabs![activeChatFolder].id);
|
||||||
|
|
||||||
if (!activeFolder || isInAllFolder) {
|
if (!activeFolder || isInAllChatsFolder) {
|
||||||
return (
|
return (
|
||||||
<ChatList
|
<ChatList
|
||||||
folderType="all"
|
folderType="all"
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
import React, { memo, useCallback, useMemo } from '../../../lib/teact/teact';
|
import React, {
|
||||||
|
memo, useCallback, useEffect, useMemo,
|
||||||
|
} from '../../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
import type { ISettings } from '../../../types';
|
import type { ISettings } from '../../../types';
|
||||||
@ -29,6 +31,7 @@ import useLang from '../../../hooks/useLang';
|
|||||||
import useConnectionStatus from '../../../hooks/useConnectionStatus';
|
import useConnectionStatus from '../../../hooks/useConnectionStatus';
|
||||||
import { useHotkeys } from '../../../hooks/useHotkeys';
|
import { useHotkeys } from '../../../hooks/useHotkeys';
|
||||||
import { getPromptInstall } from '../../../util/installPrompt';
|
import { getPromptInstall } from '../../../util/installPrompt';
|
||||||
|
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||||
|
|
||||||
import DropdownMenu from '../../ui/DropdownMenu';
|
import DropdownMenu from '../../ui/DropdownMenu';
|
||||||
import MenuItem from '../../ui/MenuItem';
|
import MenuItem from '../../ui/MenuItem';
|
||||||
@ -235,6 +238,8 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
|||||||
|| content === LeftColumnContent.Contacts
|
|| content === LeftColumnContent.Contacts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => (isSearchFocused ? captureEscKeyListener(() => onReset()) : undefined), [isSearchFocused, onReset]);
|
||||||
|
|
||||||
const searchInputPlaceholder = content === LeftColumnContent.Contacts
|
const searchInputPlaceholder = content === LeftColumnContent.Contacts
|
||||||
? lang('SearchFriends')
|
? lang('SearchFriends')
|
||||||
: lang('Search');
|
: lang('Search');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user