pl-fe: add keyboard shortcuts link to sidebar navigation

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2025-09-13 13:18:20 +02:00
parent bd31560793
commit 597e075511
4 changed files with 40 additions and 7 deletions

View File

@ -25,6 +25,7 @@ interface IDropdownMenuContent {
items?: Menu;
component?: React.FC<{ handleClose: () => any }>;
touchscreen?: boolean;
width?: React.CSSProperties['width'];
}
interface IDropdownMenu {
@ -38,11 +39,14 @@ interface IDropdownMenu {
placement?: Placement;
src?: string;
title?: string;
width?: React.CSSProperties['width'];
}
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
const DropdownMenuContent: React.FC<IDropdownMenuContent> = ({ handleClose, items, component: Component, touchscreen }) => {
const DropdownMenuContent: React.FC<IDropdownMenuContent> = ({ handleClose, items, component: Component, touchscreen, width }) => {
if (touchscreen) width = undefined;
const intl = useIntl();
const [tab, setTab] = useState<number>();
@ -149,12 +153,12 @@ const DropdownMenuContent: React.FC<IDropdownMenuContent> = ({ handleClose, item
return (
<div ref={ref}>
{items?.some(item => item?.items?.length) ? (
<ReactSwipeableViews animateHeight index={tab === undefined ? 0 : 1}>
<div className={clsx('max-w-full', { 'w-full': touchscreen })}>
<ReactSwipeableViews animateHeight index={tab === undefined ? 0 : 1} style={{ width }}>
<div className={clsx('max-w-full', { 'w-full': touchscreen })} style={{ width }}>
{Component && <Component handleClose={handleClose} />}
{(items?.length || touchscreen) && renderItems(items)}
</div>
<div className={clsx({ 'w-full': touchscreen, 'fit-content mr-auto': !touchscreen })}>
<div className={clsx({ 'w-full': touchscreen, 'fit-content mr-auto': !touchscreen })} style={{ width }}>
{tab !== undefined && (
<>
<HStack className='mx-2 my-1 text-gray-700 dark:text-gray-300' space={3} alignItems='center'>
@ -195,6 +199,7 @@ const DropdownMenu = (props: IDropdownMenu) => {
placement: initialPlacement = 'top',
src = require('@tabler/icons/outline/dots.svg'),
title = 'Menu',
width,
} = props;
const { openDropdownMenu, closeDropdownMenu } = useUiStore();
@ -381,7 +386,7 @@ const DropdownMenu = (props: IDropdownMenu) => {
}}
>
<div className={getClassName()}>
<DropdownMenuContent handleClose={handleClose} items={items} component={component} />
<DropdownMenuContent handleClose={handleClose} items={items} component={component} width={width} />
{/* Arrow */}
<div

View File

@ -18,6 +18,8 @@ import { usePendingUsersCount } from 'pl-fe/queries/admin/use-accounts';
import { usePendingReportsCount } from 'pl-fe/queries/admin/use-reports';
import { scheduledStatusesCountQueryOptions } from 'pl-fe/queries/statuses/scheduled-statuses';
import { useInteractionRequestsCount } from 'pl-fe/queries/statuses/use-interaction-requests';
import { useModalsStore } from 'pl-fe/stores/modals';
import sourceCode from 'pl-fe/utils/code';
import Account from './account';
import DropdownMenu, { Menu } from './dropdown-menu';
@ -38,6 +40,9 @@ const messages = defineMessages({
drafts: { id: 'navigation.drafts', defaultMessage: 'Drafts' },
conversations: { id: 'navigation.direct_messages', defaultMessage: 'Direct messages' },
interactionRequests: { id: 'navigation.interaction_requests', defaultMessage: 'Interaction requests' },
help: { id: 'navigation.help', defaultMessage: 'Help' },
keyboardShortcuts: { id: 'navigation.keyboard_shortcuts', defaultMessage: 'Keyboard shortcuts' },
sourceCode: { id: 'navigation.source_code', defaultMessage: 'Source code' },
});
interface ISidebarNavigation {
@ -49,6 +54,7 @@ interface ISidebarNavigation {
const SidebarNavigation: React.FC<ISidebarNavigation> = React.memo(({ shrink }) => {
const intl = useIntl();
const { unreadChatsCount } = useStatContext();
const { openModal } = useModalsStore();
const instance = useInstance();
const features = useFeatures();
@ -166,6 +172,26 @@ const SidebarNavigation: React.FC<ISidebarNavigation> = React.memo(({ shrink })
count: draftCount,
});
}
menu.push(null);
menu.push({
icon: require('@tabler/icons/outline/help-circle.svg'),
text: intl.formatMessage(messages.help),
items: [
{
action: () => openModal('HOTKEYS'),
icon: require('@tabler/icons/outline/keyboard.svg'),
text: intl.formatMessage(messages.keyboardShortcuts),
},
{
href: sourceCode.url,
target: '_blank',
icon: require('@tabler/icons/outline/code.svg'),
text: intl.formatMessage(messages.sourceCode),
},
],
});
}
return menu;
@ -326,7 +352,7 @@ const SidebarNavigation: React.FC<ISidebarNavigation> = React.memo(({ shrink })
)}
{menu.length > 0 && (
<DropdownMenu items={menu} placement='top'>
<DropdownMenu items={menu} placement='top' width='16rem'>
<SidebarNavigationLink
icon={require('@tabler/icons/outline/dots-circle-horizontal.svg')}
text={<FormattedMessage id='tabs_bar.more' defaultMessage='More' />}

View File

@ -164,7 +164,7 @@ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
}
return (
<DropdownMenu items={items}>
<DropdownMenu items={items} width='16rem'>
<Button
theme='muted'
size='xs'

View File

@ -1217,8 +1217,10 @@
"navigation.developers": "Developers",
"navigation.direct_messages": "Direct messages",
"navigation.drafts": "Drafts",
"navigation.help": "Help",
"navigation.home": "Home",
"navigation.interaction_requests": "Interaction requests",
"navigation.keyboard_shortcuts": "Keyboard shortcuts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation.sidebar": "Open sidebar",