feat: Added "Find in note" option to note options/context menu for Super notes
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
||||
PIN_NOTE_COMMAND,
|
||||
SHOW_HIDDEN_OPTIONS_KEYBOARD_COMMAND,
|
||||
STAR_NOTE_COMMAND,
|
||||
SUPER_SHOW_MARKDOWN_PREVIEW,
|
||||
} from '@standardnotes/ui-services'
|
||||
import ChangeEditorOption from './ChangeEditorOption'
|
||||
import ListedActionsOption from './Listed/ListedActionsOption'
|
||||
@@ -24,7 +23,6 @@ import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/Keyboard
|
||||
import { NoteAttributes } from './NoteAttributes'
|
||||
import { SpellcheckOptions } from './SpellcheckOptions'
|
||||
import { NoteSizeWarning } from './NoteSizeWarning'
|
||||
import { useCommandService } from '../CommandProvider'
|
||||
import { iconClass } from './ClassNames'
|
||||
import SuperNoteOptions from './SuperNoteOptions'
|
||||
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||
@@ -48,12 +46,6 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
|
||||
const [altKeyDown, setAltKeyDown] = useState(false)
|
||||
const { toggleAppPane } = useResponsiveAppPane()
|
||||
const commandService = useCommandService()
|
||||
|
||||
const markdownShortcut = useMemo(
|
||||
() => commandService.keyboardShortcutForCommand(SUPER_SHOW_MARKDOWN_PREVIEW),
|
||||
[commandService],
|
||||
)
|
||||
|
||||
const toggleOn = (condition: (note: SNNote) => boolean) => {
|
||||
const notesMatchingAttribute = notes.filter(condition)
|
||||
@@ -213,10 +205,6 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
[application],
|
||||
)
|
||||
|
||||
const enableSuperMarkdownPreview = useCallback(() => {
|
||||
commandService.triggerCommand(SUPER_SHOW_MARKDOWN_PREVIEW)
|
||||
}, [commandService])
|
||||
|
||||
const toggleLineWidthModal = useCallback(() => {
|
||||
application.keyboardService.triggerCommand(CHANGE_EDITOR_WIDTH_COMMAND)
|
||||
}, [application.keyboardService])
|
||||
@@ -468,13 +456,7 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
|
||||
{notes.length === 1 && (
|
||||
<>
|
||||
{notes[0].noteType === NoteType.Super && (
|
||||
<SuperNoteOptions
|
||||
note={notes[0]}
|
||||
markdownShortcut={markdownShortcut}
|
||||
enableSuperMarkdownPreview={enableSuperMarkdownPreview}
|
||||
/>
|
||||
)}
|
||||
{notes[0].noteType === NoteType.Super && <SuperNoteOptions closeMenu={closeMenu} />}
|
||||
|
||||
{!areSomeNotesInSharedVault && (
|
||||
<MenuSection>
|
||||
|
||||
@@ -1,20 +1,42 @@
|
||||
import { SNNote } from '@standardnotes/snjs'
|
||||
import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
|
||||
import Icon from '../Icon/Icon'
|
||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||
import MenuItem from '../Menu/MenuItem'
|
||||
import { iconClass } from './ClassNames'
|
||||
import MenuSection from '../Menu/MenuSection'
|
||||
import { SUPER_SHOW_MARKDOWN_PREVIEW, SUPER_TOGGLE_SEARCH } from '@standardnotes/ui-services'
|
||||
import { useMemo, useCallback } from 'react'
|
||||
import { useCommandService } from '../CommandProvider'
|
||||
|
||||
type Props = {
|
||||
note: SNNote
|
||||
markdownShortcut?: PlatformedKeyboardShortcut
|
||||
enableSuperMarkdownPreview: () => void
|
||||
closeMenu: () => void
|
||||
}
|
||||
|
||||
const SuperNoteOptions = ({ markdownShortcut, enableSuperMarkdownPreview }: Props) => {
|
||||
const SuperNoteOptions = ({ closeMenu }: Props) => {
|
||||
const commandService = useCommandService()
|
||||
|
||||
const markdownShortcut = useMemo(
|
||||
() => commandService.keyboardShortcutForCommand(SUPER_SHOW_MARKDOWN_PREVIEW),
|
||||
[commandService],
|
||||
)
|
||||
|
||||
const findShortcut = useMemo(() => commandService.keyboardShortcutForCommand(SUPER_TOGGLE_SEARCH), [commandService])
|
||||
|
||||
const enableSuperMarkdownPreview = useCallback(() => {
|
||||
commandService.triggerCommand(SUPER_SHOW_MARKDOWN_PREVIEW)
|
||||
}, [commandService])
|
||||
|
||||
const findInNote = useCallback(() => {
|
||||
commandService.triggerCommand(SUPER_TOGGLE_SEARCH)
|
||||
closeMenu()
|
||||
}, [closeMenu, commandService])
|
||||
|
||||
return (
|
||||
<MenuSection>
|
||||
<MenuItem onClick={findInNote}>
|
||||
<Icon type="search" className={iconClass} />
|
||||
Find in note
|
||||
{findShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={findShortcut} />}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={enableSuperMarkdownPreview}>
|
||||
<Icon type="markdown" className={iconClass} />
|
||||
Show Markdown
|
||||
|
||||
@@ -14,8 +14,11 @@ import {
|
||||
import { classNames } from '@standardnotes/utils'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { useSuperSearchContext } from './Context'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
|
||||
export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog: () => void }) => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
const { query, results, currentResultIndex, isCaseSensitive, isReplaceMode, dispatch, dispatchReplaceEvent } =
|
||||
useSuperSearchContext()
|
||||
|
||||
@@ -53,22 +56,27 @@ export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog
|
||||
|
||||
return (
|
||||
<div
|
||||
className="absolute right-6 top-13 z-10 flex select-none rounded border border-border bg-default"
|
||||
className={classNames(
|
||||
'absolute left-2 right-6 top-2 z-10 flex select-none rounded border border-border bg-default md:left-auto',
|
||||
editor.isEditable() ? 'md:top-13' : 'md:top-3',
|
||||
)}
|
||||
ref={setElement}
|
||||
>
|
||||
<button
|
||||
className="focus:ring-none border-r border-border px-1 hover:bg-contrast focus:shadow-inner focus:shadow-info"
|
||||
onClick={() => {
|
||||
dispatch({ type: 'toggle-replace-mode' })
|
||||
}}
|
||||
title={`Toggle Replace Mode (${toggleReplaceShortcut})`}
|
||||
>
|
||||
{isReplaceMode ? (
|
||||
<ArrowDownIcon className="h-4 w-4 fill-text" />
|
||||
) : (
|
||||
<ArrowRightIcon className="h-4 w-4 fill-text" />
|
||||
)}
|
||||
</button>
|
||||
{editor.isEditable() && (
|
||||
<button
|
||||
className="focus:ring-none border-r border-border px-1 hover:bg-contrast focus:shadow-inner focus:shadow-info"
|
||||
onClick={() => {
|
||||
dispatch({ type: 'toggle-replace-mode' })
|
||||
}}
|
||||
title={`Toggle Replace Mode (${toggleReplaceShortcut})`}
|
||||
>
|
||||
{isReplaceMode ? (
|
||||
<ArrowDownIcon className="h-4 w-4 fill-text" />
|
||||
) : (
|
||||
<ArrowRightIcon className="h-4 w-4 fill-text" />
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
<div
|
||||
className="flex flex-col gap-2 px-2 py-2"
|
||||
onKeyDown={(event) => {
|
||||
@@ -171,7 +179,7 @@ export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog
|
||||
</button>
|
||||
</div>
|
||||
{isReplaceMode && (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex flex-wrap items-center gap-2 md:flex-nowrap">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Replace"
|
||||
|
||||
@@ -28,26 +28,15 @@ export const SearchPlugin = () => {
|
||||
const resultsRef = useStateRef(results)
|
||||
|
||||
useEffect(() => {
|
||||
const isFocusInEditor = () => {
|
||||
if (!document.activeElement || !document.activeElement.closest('.blocks-editor')) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return application.keyboardService.addCommandHandlers([
|
||||
{
|
||||
command: SUPER_TOGGLE_SEARCH,
|
||||
category: 'Super notes',
|
||||
description: 'Search in current note',
|
||||
onKeyDown: (event) => {
|
||||
if (!isFocusInEditor()) {
|
||||
return
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
dispatch({ type: 'toggle-search' })
|
||||
editor.focus()
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -55,7 +44,7 @@ export const SearchPlugin = () => {
|
||||
category: 'Super notes',
|
||||
description: 'Search and replace in current note',
|
||||
onKeyDown: (event) => {
|
||||
if (!isFocusInEditor()) {
|
||||
if (!editor.isEditable()) {
|
||||
return
|
||||
}
|
||||
event.preventDefault()
|
||||
@@ -66,9 +55,6 @@ export const SearchPlugin = () => {
|
||||
{
|
||||
command: SUPER_SEARCH_TOGGLE_CASE_SENSITIVE,
|
||||
onKeyDown() {
|
||||
if (!isFocusInEditor()) {
|
||||
return
|
||||
}
|
||||
dispatch({
|
||||
type: 'toggle-case-sensitive',
|
||||
})
|
||||
@@ -79,9 +65,6 @@ export const SearchPlugin = () => {
|
||||
category: 'Super notes',
|
||||
description: 'Go to next search result',
|
||||
onKeyDown(event) {
|
||||
if (!isFocusInEditor()) {
|
||||
return
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
dispatch({
|
||||
@@ -94,9 +77,6 @@ export const SearchPlugin = () => {
|
||||
category: 'Super notes',
|
||||
description: 'Go to previous search result',
|
||||
onKeyDown(event) {
|
||||
if (!isFocusInEditor()) {
|
||||
return
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
dispatch({
|
||||
|
||||
Reference in New Issue
Block a user