diff --git a/packages/pl-fe/src/features/ui/components/modals/hotkeys-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/hotkeys-modal.tsx index e334db37d..caa9a884f 100644 --- a/packages/pl-fe/src/features/ui/components/modals/hotkeys-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/hotkeys-modal.tsx @@ -1,3 +1,4 @@ +import clsx from 'clsx'; import React from 'react'; import { FormattedMessage } from 'react-intl'; @@ -12,8 +13,8 @@ const Hotkey: React.FC<{ children: React.ReactNode }> = ({ children }) => ( ); -const TableCell: React.FC<{ children: React.ReactNode }> = ({ children }) => ( - +const TableCell: React.FC<{ className?: string; children: React.ReactNode }> = ({ className, children }) => ( + {children} ); @@ -21,6 +22,111 @@ const TableCell: React.FC<{ children: React.ReactNode }> = ({ children }) => ( const HotkeysModal: React.FC = ({ onClose }) => { const features = useFeatures(); + const hotkeys = [ + { + key: r, + label: , + }, + { + key: m, + label: , + }, + { + key: p, + label: , + }, + { + key: f, + label: , + }, + features.emojiReacts && { + key: e, + label: , + }, + { + key: b, + label: , + }, + { + key: <>enter, o, + label: , + }, + { + key: a, + label: , + }, + features.spoilers && { + key: x, + label: , + }, + features.spoilers && { + key: h, + label: , + }, + { + key: <>up, k, + label: , + }, + { + key: <>down, j, + label: , + }, + { + key: n, + label: , + }, + { + key: <>alt + n, + label: , + }, + { + key: backspace, + label: , + }, + { + key: <>s, /, + label: , + }, + { + key: esc, + label: , + }, + { + key: <>g + h, + label: , + }, + { + key: <>g + n, + label: , + }, + { + key: <>g + f, + label: , + }, + { + key: <>g + p, + label: , + }, + { + key: <>g + b, + label: , + }, + { + key: <>g + m, + label: , + }, + features.followRequests && { + key: <>g + r, + label: , + }, + { + key: ?, + label: , + }, + ].filter(hotkey => hotkey !== false); + + const columnSize = Math.ceil(hotkeys.length / 3); + return ( } @@ -35,40 +141,12 @@ const HotkeysModal: React.FC = ({ onClose }) => { - - r - - - - m - - - - p - - - - f - - - {features.emojiReacts && ( - - e - + {hotkeys.slice(0, columnSize).map((hotkey, i) => ( + + {hotkey.key} + {hotkey.label} - )} - - b - - - - enter, o - - - - a - - + ))} @@ -78,46 +156,12 @@ const HotkeysModal: React.FC = ({ onClose }) => { - {features.spoilers && ( - - x - + {hotkeys.slice(columnSize, columnSize * 2).map((hotkey, i) => ( + + {hotkey.key} + {hotkey.label} - )} - {features.spoilers && ( - - h - - - )} - - up, k - - - - down, j - - - - n - - - - alt + n - - - - backspace - - - - s, / - - - - esc - - + ))}
@@ -127,40 +171,12 @@ const HotkeysModal: React.FC = ({ onClose }) => { - - g + h - - - - g + n - - - - g + f - - - - g + p - - - - g + b - - - - g + m - - - {features.followRequests && ( - - g + r - + {hotkeys.slice(columnSize * 2).map((hotkey, i) => ( + + {hotkey.key} + {hotkey.label} - )} - - ? - - + ))}
diff --git a/packages/pl-fe/src/features/ui/util/global-hotkeys.tsx b/packages/pl-fe/src/features/ui/util/global-hotkeys.tsx index 039d07ea9..fe3f84342 100644 --- a/packages/pl-fe/src/features/ui/util/global-hotkeys.tsx +++ b/packages/pl-fe/src/features/ui/util/global-hotkeys.tsx @@ -1,9 +1,9 @@ -import React, { useRef } from 'react'; +import React, { useMemo, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { resetCompose } from 'pl-fe/actions/compose'; import { FOCUS_EDITOR_COMMAND } from 'pl-fe/features/compose/editor/plugins/focus-plugin'; -import { useAppSelector, useAppDispatch, useOwnAccount } from 'pl-fe/hooks'; +import { useAppDispatch, useOwnAccount } from 'pl-fe/hooks'; import { useModalsStore } from 'pl-fe/stores'; import { HotKeys } from '../components/hotkeys'; @@ -46,111 +46,120 @@ const GlobalHotkeys: React.FC = ({ children, node }) => { const history = useHistory(); const dispatch = useAppDispatch(); - const me = useAppSelector(state => state.me); const { account } = useOwnAccount(); const { openModal } = useModalsStore(); - const handleHotkeyNew = (e?: KeyboardEvent) => { - e?.preventDefault(); - - const element = node.current?.querySelector('div[data-lexical-editor="true"]') as HTMLTextAreaElement; - - if (element) { - ((element as any).__lexicalEditor as LexicalEditor).dispatchCommand(FOCUS_EDITOR_COMMAND, undefined); - } else { - openModal('COMPOSE'); - } - }; - - const handleHotkeySearch = (e?: KeyboardEvent) => { - e?.preventDefault(); - if (!node.current) return; - - const element = node.current.querySelector('input#search') as HTMLInputElement; - - if (element?.checkVisibility()) { - element.focus(); - } else { - history.push('/search'); - } - }; - - const handleHotkeyForceNew = (e?: KeyboardEvent) => { - handleHotkeyNew(e); - dispatch(resetCompose()); - }; - - const handleHotkeyBack = () => { - if (window.history && window.history.length === 1) { - history.push('/'); - } else { - history.goBack(); - } - }; - const setHotkeysRef: React.LegacyRef = (c: any) => { hotkeys.current = c; - if (!me || !hotkeys.current) return; + if (!account || !hotkeys.current) return; // @ts-ignore hotkeys.current.__mousetrap__.stopCallback = (_e, element) => ['TEXTAREA', 'SELECT', 'INPUT', 'EM-EMOJI-PICKER'].includes(element.tagName) || !!element.closest('[contenteditable]'); }; - const handleHotkeyToggleHelp = () => { - openModal('HOTKEYS'); - }; + const handlers = useMemo(() => { + const handleHotkeyNew = (e?: KeyboardEvent) => { + e?.preventDefault(); - const handleHotkeyGoToHome = () => { - history.push('/'); - }; + const element = node.current?.querySelector('div[data-lexical-editor="true"]') as HTMLTextAreaElement; - const handleHotkeyGoToNotifications = () => { - history.push('/notifications'); - }; + if (element) { + ((element as any).__lexicalEditor as LexicalEditor).dispatchCommand(FOCUS_EDITOR_COMMAND, undefined); + } else { + openModal('COMPOSE'); + } + }; - const handleHotkeyGoToFavourites = () => { - if (!account) return; - history.push(`/@${account.username}/favorites`); - }; + const handleHotkeySearch = (e?: KeyboardEvent) => { + e?.preventDefault(); + if (!node.current) return; - const handleHotkeyGoToProfile = () => { - if (!account) return; - history.push(`/@${account.username}`); - }; + const element = node.current.querySelector('input#search') as HTMLInputElement; - const handleHotkeyGoToBlocked = () => { - history.push('/blocks'); - }; + if (element?.checkVisibility()) { + element.focus(); + } else { + history.push('/search'); + } + }; - const handleHotkeyGoToMuted = () => { - history.push('/mutes'); - }; + const handleHotkeyForceNew = (e?: KeyboardEvent) => { + handleHotkeyNew(e); + dispatch(resetCompose()); + }; - const handleHotkeyGoToRequests = () => { - history.push('/follow_requests'); - }; + const handleHotkeyBack = () => { + if (window.history && window.history.length === 1) { + history.push('/'); + } else { + history.goBack(); + } + }; - type HotkeyHandlers = { [key: string]: (keyEvent?: KeyboardEvent) => void }; + const handleHotkeyToggleHelp = () => { + openModal('HOTKEYS'); + }; + + const handleHotkeyGoToHome = () => { + history.push('/'); + }; + + const handleHotkeyGoToNotifications = () => { + history.push('/notifications'); + }; + + const handleHotkeyGoToFavourites = () => { + if (!account) return; + history.push(`/@${account.username}/favorites`); + }; + + const handleHotkeyGoToProfile = () => { + if (!account) return; + history.push(`/@${account.username}`); + }; + + const handleHotkeyGoToBlocked = () => { + history.push('/blocks'); + }; + + const handleHotkeyGoToMuted = () => { + history.push('/mutes'); + }; + + const handleHotkeyGoToRequests = () => { + history.push('/follow_requests'); + }; + + type HotkeyHandlers = { [key: string]: (keyEvent?: KeyboardEvent) => void }; + + let handlers: HotkeyHandlers = { + help: handleHotkeyToggleHelp, + search: handleHotkeySearch, + back: handleHotkeyBack, + }; + + if (account) { + handlers = { + ...handlers, + new: handleHotkeyNew, + forceNew: handleHotkeyForceNew, + goToHome: handleHotkeyGoToHome, + goToNotifications: handleHotkeyGoToNotifications, + goToFavourites: handleHotkeyGoToFavourites, + goToProfile: handleHotkeyGoToProfile, + goToBlocked: handleHotkeyGoToBlocked, + goToMuted: handleHotkeyGoToMuted, + goToRequests: handleHotkeyGoToRequests, + }; + } + return handlers; + }, [account?.id]); - const handlers: HotkeyHandlers = { - help: handleHotkeyToggleHelp, - new: handleHotkeyNew, - search: handleHotkeySearch, - forceNew: handleHotkeyForceNew, - back: handleHotkeyBack, - goToHome: handleHotkeyGoToHome, - goToNotifications: handleHotkeyGoToNotifications, - goToFavourites: handleHotkeyGoToFavourites, - goToProfile: handleHotkeyGoToProfile, - goToBlocked: handleHotkeyGoToBlocked, - goToMuted: handleHotkeyGoToMuted, - goToRequests: handleHotkeyGoToRequests, - }; return ( - + {children} );