import './shortcuts.css'; import { Menu, MenuItem } from '@szhsin/react-menu'; import { memo } from 'preact/compat'; import { useMemo, useRef } from 'preact/hooks'; import { useHotkeys } from 'react-hotkeys-hook'; import { useNavigate } from 'react-router-dom'; import { useSnapshot } from 'valtio'; import { SHORTCUTS_META } from '../components/shortcuts-settings'; import { api } from '../utils/api'; import states from '../utils/states'; import AsyncText from './AsyncText'; import Icon from './icon'; import Link from './link'; import MenuLink from './menu-link'; function Shortcuts() { const { instance } = api(); const snapStates = useSnapshot(states); const { shortcuts, settings } = snapStates; if (!shortcuts.length) { return null; } if ( settings.shortcutsViewMode === 'multi-column' || (!settings.shortcutsViewMode && settings.shortcutsColumnsMode) ) { return null; } const menuRef = useRef(); const formattedShortcuts = useMemo( () => shortcuts .map((pin, i) => { const { type, ...data } = pin; if (!SHORTCUTS_META[type]) return null; let { id, path, title, subtitle, icon } = SHORTCUTS_META[type]; if (typeof id === 'function') { id = id(data, i); } if (typeof path === 'function') { path = path( { ...data, instance: data.instance || instance, }, i, ); } if (typeof title === 'function') { title = title(data, i); } if (typeof subtitle === 'function') { subtitle = subtitle(data, i); } if (typeof icon === 'function') { icon = icon(data, i); } return { id, path, title, subtitle, icon, }; }) .filter(Boolean), [shortcuts], ); const navigate = useNavigate(); useHotkeys(['1', '2', '3', '4', '5', '6', '7', '8', '9'], (e, handler) => { const index = parseInt(handler.keys[0], 10) - 1; if (index < formattedShortcuts.length) { const { path } = formattedShortcuts[index]; if (path) { navigate(path); menuRef.current?.closeMenu?.(); } } }); return (
{snapStates.settings.shortcutsViewMode === 'tab-menu-bar' ? ( ) : ( { e.preventDefault(); states.showShortcutsSettings = true; }} onTransitionStart={(e) => { // Close menu if the button disappears try { const { target } = e; if (getComputedStyle(target).pointerEvents === 'none') { menuRef.current?.closeMenu?.(); } } catch (e) {} }} > } > {formattedShortcuts.map(({ path, title, subtitle, icon }, i) => { return ( {' '} {title} {subtitle && ( <> {' '} {subtitle} )} {i + 1} ); })} )}
); } export default memo(Shortcuts);