feat: Added "Find in note" option to note options/context menu for Super notes

This commit is contained in:
Aman Harwara
2024-02-17 19:20:16 +05:30
parent 85c401fa6e
commit 47745cb79c
4 changed files with 53 additions and 61 deletions

View File

@@ -8,7 +8,6 @@ import {
PIN_NOTE_COMMAND, PIN_NOTE_COMMAND,
SHOW_HIDDEN_OPTIONS_KEYBOARD_COMMAND, SHOW_HIDDEN_OPTIONS_KEYBOARD_COMMAND,
STAR_NOTE_COMMAND, STAR_NOTE_COMMAND,
SUPER_SHOW_MARKDOWN_PREVIEW,
} from '@standardnotes/ui-services' } from '@standardnotes/ui-services'
import ChangeEditorOption from './ChangeEditorOption' import ChangeEditorOption from './ChangeEditorOption'
import ListedActionsOption from './Listed/ListedActionsOption' import ListedActionsOption from './Listed/ListedActionsOption'
@@ -24,7 +23,6 @@ import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/Keyboard
import { NoteAttributes } from './NoteAttributes' import { NoteAttributes } from './NoteAttributes'
import { SpellcheckOptions } from './SpellcheckOptions' import { SpellcheckOptions } from './SpellcheckOptions'
import { NoteSizeWarning } from './NoteSizeWarning' import { NoteSizeWarning } from './NoteSizeWarning'
import { useCommandService } from '../CommandProvider'
import { iconClass } from './ClassNames' import { iconClass } from './ClassNames'
import SuperNoteOptions from './SuperNoteOptions' import SuperNoteOptions from './SuperNoteOptions'
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem' import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
@@ -48,12 +46,6 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
const [altKeyDown, setAltKeyDown] = useState(false) const [altKeyDown, setAltKeyDown] = useState(false)
const { toggleAppPane } = useResponsiveAppPane() const { toggleAppPane } = useResponsiveAppPane()
const commandService = useCommandService()
const markdownShortcut = useMemo(
() => commandService.keyboardShortcutForCommand(SUPER_SHOW_MARKDOWN_PREVIEW),
[commandService],
)
const toggleOn = (condition: (note: SNNote) => boolean) => { const toggleOn = (condition: (note: SNNote) => boolean) => {
const notesMatchingAttribute = notes.filter(condition) const notesMatchingAttribute = notes.filter(condition)
@@ -213,10 +205,6 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
[application], [application],
) )
const enableSuperMarkdownPreview = useCallback(() => {
commandService.triggerCommand(SUPER_SHOW_MARKDOWN_PREVIEW)
}, [commandService])
const toggleLineWidthModal = useCallback(() => { const toggleLineWidthModal = useCallback(() => {
application.keyboardService.triggerCommand(CHANGE_EDITOR_WIDTH_COMMAND) application.keyboardService.triggerCommand(CHANGE_EDITOR_WIDTH_COMMAND)
}, [application.keyboardService]) }, [application.keyboardService])
@@ -468,13 +456,7 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
{notes.length === 1 && ( {notes.length === 1 && (
<> <>
{notes[0].noteType === NoteType.Super && ( {notes[0].noteType === NoteType.Super && <SuperNoteOptions closeMenu={closeMenu} />}
<SuperNoteOptions
note={notes[0]}
markdownShortcut={markdownShortcut}
enableSuperMarkdownPreview={enableSuperMarkdownPreview}
/>
)}
{!areSomeNotesInSharedVault && ( {!areSomeNotesInSharedVault && (
<MenuSection> <MenuSection>

View File

@@ -1,20 +1,42 @@
import { SNNote } from '@standardnotes/snjs'
import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
import Icon from '../Icon/Icon' import Icon from '../Icon/Icon'
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator' import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
import MenuItem from '../Menu/MenuItem' import MenuItem from '../Menu/MenuItem'
import { iconClass } from './ClassNames' import { iconClass } from './ClassNames'
import MenuSection from '../Menu/MenuSection' 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 = { type Props = {
note: SNNote closeMenu: () => void
markdownShortcut?: PlatformedKeyboardShortcut
enableSuperMarkdownPreview: () => 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 ( return (
<MenuSection> <MenuSection>
<MenuItem onClick={findInNote}>
<Icon type="search" className={iconClass} />
Find in note
{findShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={findShortcut} />}
</MenuItem>
<MenuItem onClick={enableSuperMarkdownPreview}> <MenuItem onClick={enableSuperMarkdownPreview}>
<Icon type="markdown" className={iconClass} /> <Icon type="markdown" className={iconClass} />
Show Markdown Show Markdown

View File

@@ -14,8 +14,11 @@ import {
import { classNames } from '@standardnotes/utils' import { classNames } from '@standardnotes/utils'
import { useCallback, useMemo, useState } from 'react' import { useCallback, useMemo, useState } from 'react'
import { useSuperSearchContext } from './Context' import { useSuperSearchContext } from './Context'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog: () => void }) => { export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog: () => void }) => {
const [editor] = useLexicalComposerContext()
const { query, results, currentResultIndex, isCaseSensitive, isReplaceMode, dispatch, dispatchReplaceEvent } = const { query, results, currentResultIndex, isCaseSensitive, isReplaceMode, dispatch, dispatchReplaceEvent } =
useSuperSearchContext() useSuperSearchContext()
@@ -53,22 +56,27 @@ export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog
return ( return (
<div <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} ref={setElement}
> >
<button {editor.isEditable() && (
className="focus:ring-none border-r border-border px-1 hover:bg-contrast focus:shadow-inner focus:shadow-info" <button
onClick={() => { className="focus:ring-none border-r border-border px-1 hover:bg-contrast focus:shadow-inner focus:shadow-info"
dispatch({ type: 'toggle-replace-mode' }) onClick={() => {
}} dispatch({ type: 'toggle-replace-mode' })
title={`Toggle Replace Mode (${toggleReplaceShortcut})`} }}
> title={`Toggle Replace Mode (${toggleReplaceShortcut})`}
{isReplaceMode ? ( >
<ArrowDownIcon className="h-4 w-4 fill-text" /> {isReplaceMode ? (
) : ( <ArrowDownIcon className="h-4 w-4 fill-text" />
<ArrowRightIcon className="h-4 w-4 fill-text" /> ) : (
)} <ArrowRightIcon className="h-4 w-4 fill-text" />
</button> )}
</button>
)}
<div <div
className="flex flex-col gap-2 px-2 py-2" className="flex flex-col gap-2 px-2 py-2"
onKeyDown={(event) => { onKeyDown={(event) => {
@@ -171,7 +179,7 @@ export const SearchDialog = ({ open, closeDialog }: { open: boolean; closeDialog
</button> </button>
</div> </div>
{isReplaceMode && ( {isReplaceMode && (
<div className="flex items-center gap-2"> <div className="flex flex-wrap items-center gap-2 md:flex-nowrap">
<input <input
type="text" type="text"
placeholder="Replace" placeholder="Replace"

View File

@@ -28,26 +28,15 @@ export const SearchPlugin = () => {
const resultsRef = useStateRef(results) const resultsRef = useStateRef(results)
useEffect(() => { useEffect(() => {
const isFocusInEditor = () => {
if (!document.activeElement || !document.activeElement.closest('.blocks-editor')) {
return false
}
return true
}
return application.keyboardService.addCommandHandlers([ return application.keyboardService.addCommandHandlers([
{ {
command: SUPER_TOGGLE_SEARCH, command: SUPER_TOGGLE_SEARCH,
category: 'Super notes', category: 'Super notes',
description: 'Search in current note', description: 'Search in current note',
onKeyDown: (event) => { onKeyDown: (event) => {
if (!isFocusInEditor()) {
return
}
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
dispatch({ type: 'toggle-search' }) dispatch({ type: 'toggle-search' })
editor.focus()
}, },
}, },
{ {
@@ -55,7 +44,7 @@ export const SearchPlugin = () => {
category: 'Super notes', category: 'Super notes',
description: 'Search and replace in current note', description: 'Search and replace in current note',
onKeyDown: (event) => { onKeyDown: (event) => {
if (!isFocusInEditor()) { if (!editor.isEditable()) {
return return
} }
event.preventDefault() event.preventDefault()
@@ -66,9 +55,6 @@ export const SearchPlugin = () => {
{ {
command: SUPER_SEARCH_TOGGLE_CASE_SENSITIVE, command: SUPER_SEARCH_TOGGLE_CASE_SENSITIVE,
onKeyDown() { onKeyDown() {
if (!isFocusInEditor()) {
return
}
dispatch({ dispatch({
type: 'toggle-case-sensitive', type: 'toggle-case-sensitive',
}) })
@@ -79,9 +65,6 @@ export const SearchPlugin = () => {
category: 'Super notes', category: 'Super notes',
description: 'Go to next search result', description: 'Go to next search result',
onKeyDown(event) { onKeyDown(event) {
if (!isFocusInEditor()) {
return
}
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
dispatch({ dispatch({
@@ -94,9 +77,6 @@ export const SearchPlugin = () => {
category: 'Super notes', category: 'Super notes',
description: 'Go to previous search result', description: 'Go to previous search result',
onKeyDown(event) { onKeyDown(event) {
if (!isFocusInEditor()) {
return
}
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
dispatch({ dispatch({