import { KeyboardKey, KeyboardModifier } from '@/Services/IOService' import { WebApplication } from '@/UIModels/Application' import { AppState } from '@/UIModels/AppState' import { PANEL_NAME_NOTES } from '@/Constants' import { PrefKey } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { FunctionComponent } from 'preact' import { useEffect, useRef, useState } from 'preact/hooks' import { NoAccountWarning } from '@/Components/NoAccountWarning' import { NotesList } from '@/Components/NotesList' import { NotesListOptionsMenu } from '@/Components/NotesList/NotesListOptionsMenu' import { SearchOptions } from '@/Components/SearchOptions' import { PanelSide, ResizeFinishCallback, PanelResizer, PanelResizeType } from '@/Components/PanelResizer' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' type Props = { application: WebApplication appState: AppState } export const NotesView: FunctionComponent = observer(({ application, appState }) => { const notesViewPanelRef = useRef(null) const displayOptionsMenuRef = useRef(null) const { completedFullSync, createNewNote, displayOptions, noteFilterText, optionsSubtitle, panelTitle, renderedNotes, selectedNotes, setNoteFilterText, searchBarElement, selectNextNote, selectPreviousNote, onFilterEnter, handleFilterTextChanged, clearFilterText, paginate, panelWidth, } = appState.notesView const [showDisplayOptionsMenu, setShowDisplayOptionsMenu] = useState(false) const [focusedSearch, setFocusedSearch] = useState(false) const [closeDisplayOptMenuOnBlur] = useCloseOnBlur(displayOptionsMenuRef, setShowDisplayOptionsMenu) useEffect(() => { handleFilterTextChanged() }, [noteFilterText, handleFilterTextChanged]) useEffect(() => { /** * In the browser we're not allowed to override cmd/ctrl + n, so we have to * use Control modifier as well. These rules don't apply to desktop, but * probably better to be consistent. */ const newNoteKeyObserver = application.io.addKeyObserver({ key: 'n', modifiers: [KeyboardModifier.Meta, KeyboardModifier.Ctrl], onKeyDown: (event) => { event.preventDefault() createNewNote().catch(console.error) }, }) const nextNoteKeyObserver = application.io.addKeyObserver({ key: KeyboardKey.Down, elements: [document.body, ...(searchBarElement ? [searchBarElement] : [])], onKeyDown: () => { if (searchBarElement === document.activeElement) { searchBarElement?.blur() } selectNextNote() }, }) const previousNoteKeyObserver = application.io.addKeyObserver({ key: KeyboardKey.Up, element: document.body, onKeyDown: () => { selectPreviousNote() }, }) const searchKeyObserver = application.io.addKeyObserver({ key: 'f', modifiers: [KeyboardModifier.Meta, KeyboardModifier.Shift], onKeyDown: () => { if (searchBarElement) { searchBarElement.focus() } }, }) return () => { newNoteKeyObserver() nextNoteKeyObserver() previousNoteKeyObserver() searchKeyObserver() } }, [application.io, createNewNote, searchBarElement, selectNextNote, selectPreviousNote]) const onNoteFilterTextChange = (e: Event) => { setNoteFilterText((e.target as HTMLInputElement).value) } const onSearchFocused = () => setFocusedSearch(true) const onSearchBlurred = () => setFocusedSearch(false) const onNoteFilterKeyUp = (e: KeyboardEvent) => { if (e.key === KeyboardKey.Enter) { onFilterEnter() } } const panelResizeFinishCallback: ResizeFinishCallback = (width, _lastLeft, _isMaxWidth, isCollapsed) => { application.setPreference(PrefKey.NotesPanelWidth, width).catch(console.error) appState.noteTags.reloadTagsContainerMaxWidth() appState.panelDidResize(PANEL_NAME_NOTES, isCollapsed) } const panelWidthEventCallback = () => { appState.noteTags.reloadTagsContainerMaxWidth() } const toggleDisplayOptionsMenu = () => { setShowDisplayOptionsMenu(!showDisplayOptionsMenu) } return (
{panelTitle}
{noteFilterText && ( )}
{(focusedSearch || noteFilterText) && (
)}
Options
{optionsSubtitle}
{showDisplayOptionsMenu && ( )}
{completedFullSync && !renderedNotes.length ?

No notes.

: null} {!completedFullSync && !renderedNotes.length ? (

Loading notes...

) : null} {renderedNotes.length ? ( ) : null}
{notesViewPanelRef.current && ( )}
) })