Files
standardnotes-app-web/packages/web/src/javascripts/Components/Footer/PreferencesButton.tsx
Aman Harwara efba7c682d feat: Added command palette for quick actions and switching between items (#2933) [skip e2e]
* wip: command palette

* use code instead of key

* show recent items above commands

* refactor

* fix command

* add placeholder

* Tab/Shift-Tab to switch tabs

* Fix test

* Add menu item to general account menu

* if shortcut_id is available, use that as the id

* make toggle fn more stable

* small naming changes

* fix name

* Close open modals and popovers when opening command palette

* use stable ids + make sure selectedNotesCount only changes when the count actually changes

* display all commands, even ones in recents list
2025-09-25 10:06:09 -03:00

77 lines
2.9 KiB
TypeScript

import { compareSemVersions, StatusServiceEvent } from '@standardnotes/snjs'
import { keyboardStringForShortcut, OPEN_PREFERENCES_COMMAND } from '@standardnotes/ui-services'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useApplication } from '../ApplicationProvider'
import { useKeyboardService } from '../KeyboardServiceProvider'
import Icon from '../Icon/Icon'
import StyledTooltip from '../StyledTooltip/StyledTooltip'
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
import RoundIconButton from '../Button/RoundIconButton'
import CountBubble from '../Preferences/PreferencesComponents/CountBubble'
type Props = {
openPreferences: (openWhatsNew: boolean) => void
}
const PreferencesButton = ({ openPreferences }: Props) => {
const application = useApplication()
const keyboardService = useKeyboardService()
const shortcut = useMemo(
() => keyboardStringForShortcut(keyboardService.keyboardShortcutForCommand(OPEN_PREFERENCES_COMMAND)),
[keyboardService],
)
const [changelogLastReadVersion, setChangelogLastReadVersion] = useState(() =>
application.changelogService.getLastReadVersion(),
)
const isChangelogUnread = useMemo(() => {
return changelogLastReadVersion && !application.isNativeMobileWeb()
? compareSemVersions(application.version, changelogLastReadVersion) > 0
: false
}, [application, changelogLastReadVersion])
useEffect(
() => application.changelogService.addLastReadChangeListener(setChangelogLastReadVersion),
[application.changelogService],
)
const onClick = useCallback(() => {
openPreferences(isChangelogUnread)
}, [isChangelogUnread, openPreferences])
const [bubbleCount, setBubbleCount] = useState<string | undefined>()
useEffect(() => {
return application.status.addEventObserver((event, message) => {
if (event !== StatusServiceEvent.PreferencesBubbleCountChanged) {
return
}
setBubbleCount(message)
})
}, [application.status])
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
if (isMobileScreen) {
return (
<div className="relative">
<RoundIconButton className="ml-2.5 bg-default" onClick={onClick} label="Go to preferences" icon="tune" />
<CountBubble position="right" count={bubbleCount} />
</div>
)
}
return (
<StyledTooltip label={`Open preferences (${shortcut})`}>
<button onClick={onClick} className="group relative flex h-full w-8 cursor-pointer items-center justify-center">
<div className="relative h-5">
<Icon type="tune" className="rounded group-hover:text-info" />
<CountBubble position="right" count={bubbleCount} />
</div>
{isChangelogUnread && <div className="absolute right-0.5 top-0.5 h-2 w-2 rounded-full bg-info" />}
</button>
</StyledTooltip>
)
}
export default PreferencesButton