feat: keyboard shortcuts for primary actions (#2030)
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user