feat: keyboard shortcuts for primary actions (#2030)
This commit is contained in:
@@ -2,7 +2,7 @@ import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback, useRef, useState } from 'react'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
|
||||
import { NotesController } from '@/Controllers/NotesController'
|
||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||
import Popover from '../Popover/Popover'
|
||||
import { IconType } from '@standardnotes/snjs'
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||
import { CHANGE_EDITOR_COMMAND, KeyboardKey } from '@standardnotes/ui-services'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { SNNote } from '@standardnotes/snjs'
|
||||
import { FunctionComponent, useCallback, useRef, useState } from 'react'
|
||||
import { FunctionComponent, useCallback, useMemo, useRef, useState } from 'react'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import ChangeEditorMenu from '@/Components/ChangeEditor/ChangeEditorMenu'
|
||||
import Popover from '../Popover/Popover'
|
||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||
|
||||
type ChangeEditorOptionProps = {
|
||||
application: WebApplication
|
||||
@@ -27,6 +28,11 @@ const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
setIsOpen((isOpen) => !isOpen)
|
||||
}, [])
|
||||
|
||||
const shortcut = useMemo(
|
||||
() => application.keyboardService.keyboardShortcutForCommand(CHANGE_EDITOR_COMMAND),
|
||||
[application],
|
||||
)
|
||||
|
||||
return (
|
||||
<div ref={menuContainerRef}>
|
||||
<button
|
||||
@@ -43,7 +49,10 @@ const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
<Icon type="dashboard" className={`${iconClassName} mr-2 text-neutral`} />
|
||||
Change note type
|
||||
</div>
|
||||
<Icon type="chevron-right" className="text-neutral" />
|
||||
<div className="flex">
|
||||
{shortcut && <KeyboardShortcutIndicator className={'mr-2'} shortcut={shortcut} />}
|
||||
<Icon type="chevron-right" className="text-neutral" />
|
||||
</div>
|
||||
</button>
|
||||
<Popover
|
||||
align="start"
|
||||
|
||||
@@ -3,14 +3,19 @@ import Switch from '@/Components/Switch/Switch'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useState, useEffect, useMemo, useCallback, FunctionComponent } from 'react'
|
||||
import { Platform, SNApplication, SNComponent, SNNote } from '@standardnotes/snjs'
|
||||
import { KeyboardModifier } from '@standardnotes/ui-services'
|
||||
import {
|
||||
OPEN_NOTE_HISTORY_COMMAND,
|
||||
PIN_NOTE_COMMAND,
|
||||
SHOW_HIDDEN_OPTIONS_KEYBOARD_COMMAND,
|
||||
STAR_NOTE_COMMAND,
|
||||
} from '@standardnotes/ui-services'
|
||||
import ChangeEditorOption from './ChangeEditorOption'
|
||||
import { BYTES_IN_ONE_MEGABYTE } from '@/Constants/Constants'
|
||||
import ListedActionsOption from './ListedActionsOption'
|
||||
import AddTagOption from './AddTagOption'
|
||||
import { addToast, dismissToast, ToastType } from '@standardnotes/toast'
|
||||
import { NotesOptionsProps } from './NotesOptionsProps'
|
||||
import { NotesController } from '@/Controllers/NotesController'
|
||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||
import { formatDateForContextMenu } from '@/Utils/DateUtils'
|
||||
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
||||
@@ -21,6 +26,7 @@ import { downloadSelectedNotesOnAndroid } from '@/NativeMobileWeb/DownloadSelect
|
||||
import ProtectedUnauthorizedLabel from '../ProtectedItemOverlay/ProtectedUnauthorizedLabel'
|
||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||
|
||||
type DeletePermanentlyButtonProps = {
|
||||
onClick: () => void
|
||||
@@ -216,8 +222,8 @@ const NotesOptions = ({
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const removeAltKeyObserver = application.io.addKeyObserver({
|
||||
modifiers: [KeyboardModifier.Alt],
|
||||
const removeAltKeyObserver = application.keyboardService.addCommandHandler({
|
||||
command: SHOW_HIDDEN_OPTIONS_KEYBOARD_COMMAND,
|
||||
onKeyDown: () => {
|
||||
setAltKeyDown(true)
|
||||
},
|
||||
@@ -274,6 +280,21 @@ const NotesOptions = ({
|
||||
historyModalController.openModal(notesController.firstSelectedNote)
|
||||
}, [historyModalController, notesController.firstSelectedNote])
|
||||
|
||||
const historyShortcut = useMemo(
|
||||
() => application.keyboardService.keyboardShortcutForCommand(OPEN_NOTE_HISTORY_COMMAND),
|
||||
[application],
|
||||
)
|
||||
|
||||
const pinShortcut = useMemo(
|
||||
() => application.keyboardService.keyboardShortcutForCommand(PIN_NOTE_COMMAND),
|
||||
[application],
|
||||
)
|
||||
|
||||
const starShortcut = useMemo(
|
||||
() => application.keyboardService.keyboardShortcutForCommand(STAR_NOTE_COMMAND),
|
||||
[application],
|
||||
)
|
||||
|
||||
const unauthorized = notes.some((note) => !application.isAuthorizedToRenderItem(note))
|
||||
if (unauthorized) {
|
||||
return <ProtectedUnauthorizedLabel />
|
||||
@@ -295,8 +316,13 @@ const NotesOptions = ({
|
||||
{notes.length === 1 && (
|
||||
<>
|
||||
<button className={classNames(defaultClassNames, firstItemClass)} onClick={openRevisionHistoryModal}>
|
||||
<Icon type="history" className={iconClass} />
|
||||
Note history
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span className="flex">
|
||||
<Icon type="history" className={iconClass} />
|
||||
Note history
|
||||
</span>
|
||||
{historyShortcut && <KeyboardShortcutIndicator className={''} shortcut={historyShortcut} />}
|
||||
</div>
|
||||
</button>
|
||||
<HorizontalSeparator classes="my-2" />
|
||||
</>
|
||||
@@ -364,8 +390,13 @@ const NotesOptions = ({
|
||||
notesController.setStarSelectedNotes(!starred)
|
||||
}}
|
||||
>
|
||||
<Icon type="star" className={iconClass} />
|
||||
{starred ? 'Unstar' : 'Star'}
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span className="flex">
|
||||
<Icon type="star" className={iconClass} />
|
||||
{starred ? 'Unstar' : 'Star'}
|
||||
</span>
|
||||
{starShortcut && <KeyboardShortcutIndicator className={''} shortcut={starShortcut} />}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{unpinned && (
|
||||
@@ -375,8 +406,13 @@ const NotesOptions = ({
|
||||
notesController.setPinSelectedNotes(true)
|
||||
}}
|
||||
>
|
||||
<Icon type="pin" className={iconClass} />
|
||||
Pin to top
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span className="flex">
|
||||
<Icon type="pin" className={iconClass} />
|
||||
Pin to top
|
||||
</span>
|
||||
{pinShortcut && <KeyboardShortcutIndicator className={''} shortcut={pinShortcut} />}
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
{pinned && (
|
||||
@@ -386,8 +422,13 @@ const NotesOptions = ({
|
||||
notesController.setPinSelectedNotes(false)
|
||||
}}
|
||||
>
|
||||
<Icon type="unpin" className={iconClass} />
|
||||
Unpin
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span className="flex">
|
||||
<Icon type="unpin" className={iconClass} />
|
||||
Unpin
|
||||
</span>
|
||||
{pinShortcut && <KeyboardShortcutIndicator className={''} shortcut={pinShortcut} />}
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback, useRef, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import NotesOptions from './NotesOptions'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { NotesController } from '@/Controllers/NotesController'
|
||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
|
||||
import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalController'
|
||||
import Popover from '../Popover/Popover'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalController'
|
||||
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
|
||||
import { NotesController } from '@/Controllers/NotesController'
|
||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||
import { LinkingController } from '@/Controllers/LinkingController'
|
||||
|
||||
export type NotesOptionsProps = {
|
||||
|
||||
Reference in New Issue
Block a user