feat: keyboard shortcuts for primary actions (#2030)

This commit is contained in:
Mo
2022-11-18 09:01:48 -06:00
committed by GitHub
parent 0309912f98
commit f49ba6bd4d
67 changed files with 1296 additions and 555 deletions

View File

@@ -1,8 +1,10 @@
import { WebApplication } from '@/Application/Application'
import { FunctionComponent, MouseEventHandler, useCallback } from 'react'
import { FunctionComponent, MouseEventHandler, useCallback, useMemo } from 'react'
import Switch from '@/Components/Switch/Switch'
import { isMobileScreen } from '@/Utils'
import { classNames } from '@/Utils/ConcatenateClassNames'
import { TOGGLE_FOCUS_MODE_COMMAND } from '@standardnotes/ui-services'
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
type Props = {
application: WebApplication
@@ -22,6 +24,11 @@ const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onCl
[onToggle, isEnabled, onClose],
)
const shortcut = useMemo(
() => application.keyboardService.keyboardShortcutForCommand(TOGGLE_FOCUS_MODE_COMMAND),
[application],
)
const isMobile = application.isNativeMobileWeb() || isMobileScreen()
if (isMobile) {
@@ -37,8 +44,11 @@ const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onCl
)}
onClick={toggle}
>
<div className="flex items-center">Focused Writing</div>
<Switch className="px-0" checked={isEnabled} />
<div className="flex items-center">Focus Mode</div>
<div className="flex">
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
<Switch className="px-0" checked={isEnabled} />
</div>
</button>
)
}

View File

@@ -1,76 +1,48 @@
import { WebApplication } from '@/Application/Application'
import { memo, useEffect, useState } from 'react'
import { ApplicationEvent, PrefKey } from '@standardnotes/snjs'
import { TOGGLE_LIST_PANE_KEYBOARD_COMMAND, TOGGLE_NAVIGATION_PANE_KEYBOARD_COMMAND } from '@standardnotes/ui-services'
import { useMemo } from 'react'
import MenuItem from '../Menu/MenuItem'
import { MenuItemType } from '../Menu/MenuItemType'
import { PANEL_NAME_NAVIGATION, PANEL_NAME_NOTES } from '@/Constants/Constants'
import { PrefDefaults } from '@/Constants/PrefDefaults'
import { observer } from 'mobx-react-lite'
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
import { useCommandService } from '../ApplicationView/CommandProvider'
type Props = {
application: WebApplication
}
const PanelSettingsSection = () => {
const { isListPaneCollapsed, isNavigationPaneCollapsed, toggleListPane, toggleNavigationPane } =
useResponsiveAppPane()
const WidthForCollapsedPanel = 5
const MinimumNavPanelWidth = PrefDefaults[PrefKey.TagsPanelWidth]
const MinimumNotesPanelWidth = PrefDefaults[PrefKey.NotesPanelWidth]
const commandService = useCommandService()
const PanelSettingsSection = ({ application }: Props) => {
const [currentNavPanelWidth, setCurrentNavPanelWidth] = useState(
application.getPreference(PrefKey.TagsPanelWidth, MinimumNavPanelWidth),
const navigationShortcut = useMemo(
() => commandService.keyboardShortcutForCommand(TOGGLE_NAVIGATION_PANE_KEYBOARD_COMMAND),
[commandService],
)
const [currentItemsPanelWidth, setCurrentItemsPanelWidth] = useState(
application.getPreference(PrefKey.NotesPanelWidth, MinimumNotesPanelWidth),
const listShortcut = useMemo(
() => commandService.keyboardShortcutForCommand(TOGGLE_LIST_PANE_KEYBOARD_COMMAND),
[commandService],
)
const toggleNavigationPanel = () => {
const isCollapsed = currentNavPanelWidth <= WidthForCollapsedPanel
if (isCollapsed) {
void application.setPreference(PrefKey.TagsPanelWidth, MinimumNavPanelWidth)
} else {
void application.setPreference(PrefKey.TagsPanelWidth, WidthForCollapsedPanel)
}
application.publishPanelDidResizeEvent(PANEL_NAME_NAVIGATION, !isCollapsed)
}
const toggleItemsListPanel = () => {
const isCollapsed = currentItemsPanelWidth <= WidthForCollapsedPanel
if (isCollapsed) {
void application.setPreference(PrefKey.NotesPanelWidth, MinimumNotesPanelWidth)
} else {
void application.setPreference(PrefKey.NotesPanelWidth, WidthForCollapsedPanel)
}
application.publishPanelDidResizeEvent(PANEL_NAME_NOTES, !isCollapsed)
}
useEffect(() => {
const removeObserver = application.addEventObserver(async () => {
setCurrentNavPanelWidth(application.getPreference(PrefKey.TagsPanelWidth, MinimumNavPanelWidth))
setCurrentItemsPanelWidth(application.getPreference(PrefKey.NotesPanelWidth, MinimumNotesPanelWidth))
}, ApplicationEvent.PreferencesChanged)
return removeObserver
}, [application])
return (
<div className="hidden md:block pointer-coarse:md-only:hidden pointer-coarse:lg-only:hidden">
<MenuItem
type={MenuItemType.SwitchButton}
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
checked={currentNavPanelWidth > WidthForCollapsedPanel}
onChange={toggleNavigationPanel}
checked={isNavigationPaneCollapsed}
onChange={toggleNavigationPane}
shortcut={navigationShortcut}
>
Show navigation panel
Show Tags Panel
</MenuItem>
<MenuItem
type={MenuItemType.SwitchButton}
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
checked={currentItemsPanelWidth > WidthForCollapsedPanel}
onChange={toggleItemsListPanel}
checked={isListPaneCollapsed}
onChange={toggleListPane}
shortcut={listShortcut}
>
Show list panel
Show Notes Panel
</MenuItem>
</div>
)
}
export default memo(PanelSettingsSection)
export default observer(PanelSettingsSection)

View File

@@ -23,27 +23,13 @@ import PanelSettingsSection from './PanelSettingsSection'
import { PrefDefaults } from '@/Constants/PrefDefaults'
import { classNames } from '@/Utils/ConcatenateClassNames'
const focusModeAnimationDuration = 1255
export const focusModeAnimationDuration = 1255
type MenuProps = {
quickSettingsMenuController: QuickSettingsController
application: WebApplication
}
const toggleFocusMode = (enabled: boolean) => {
if (enabled) {
document.body.classList.add('focus-mode')
} else {
if (document.body.classList.contains('focus-mode')) {
document.body.classList.add('disable-focus-mode')
document.body.classList.remove('focus-mode')
setTimeout(() => {
document.body.classList.remove('disable-focus-mode')
}, focusModeAnimationDuration)
}
}
}
const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSettingsMenuController }) => {
const { closeQuickSettingsMenu, focusModeEnabled, setFocusModeEnabled } = quickSettingsMenuController
const [themes, setThemes] = useState<ThemeItem[]>([])
@@ -71,10 +57,6 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
const prefsButtonRef = useRef<HTMLButtonElement>(null)
const defaultThemeButtonRef = useRef<HTMLButtonElement>(null)
useEffect(() => {
toggleFocusMode(focusModeEnabled)
}, [focusModeEnabled])
const reloadThemes = useCallback(() => {
const themes = application.items
.getDisplayableComponents()
@@ -210,13 +192,14 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
{themes.map((theme) => (
<ThemesMenuButton item={theme} application={application} key={theme.component?.uuid ?? theme.identifier} />
))}
<HorizontalSeparator classes="my-2" />
<FocusModeSwitch
application={application}
onToggle={setFocusModeEnabled}
onClose={closeQuickSettingsMenu}
isEnabled={focusModeEnabled}
/>
<PanelSettingsSection application={application} />
<PanelSettingsSection />
</div>
)
}