From 263640d47628320c1ad1a3c5f27bba20ab31f135 Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Sat, 5 Mar 2022 19:49:26 +0530 Subject: [PATCH] fix: toolbar change editor menu not updating (#909) * fix: toolbar change editor menu not updating * refactor: rename isOpen prop to isVisible * style: use better variable naming scheme --- .../components/ChangeEditorButton.tsx | 53 ++++--------- .../NotesOptions/ChangeEditorOption.tsx | 74 ++++++------------- .../changeEditor/ChangeEditorMenu.tsx | 41 +++++++--- 3 files changed, 66 insertions(+), 102 deletions(-) diff --git a/app/assets/javascripts/components/ChangeEditorButton.tsx b/app/assets/javascripts/components/ChangeEditorButton.tsx index c080c35ec..0523dc878 100644 --- a/app/assets/javascripts/components/ChangeEditorButton.tsx +++ b/app/assets/javascripts/components/ChangeEditorButton.tsx @@ -7,14 +7,11 @@ import { DisclosurePanel, } from '@reach/disclosure'; import VisuallyHidden from '@reach/visually-hidden'; -import { ComponentArea, SNComponent } from '@standardnotes/snjs'; import { observer } from 'mobx-react-lite'; import { FunctionComponent } from 'preact'; -import { useEffect, useRef, useState } from 'preact/hooks'; +import { useRef, useState } from 'preact/hooks'; import { Icon } from './Icon'; import { ChangeEditorMenu } from './NotesOptions/changeEditor/ChangeEditorMenu'; -import { createEditorMenuGroups } from './NotesOptions/changeEditor/createEditorMenuGroups'; -import { EditorMenuGroup } from './NotesOptions/ChangeEditorOption'; import { useCloseOnBlur } from './utils'; type Props = { @@ -26,7 +23,8 @@ type Props = { export const ChangeEditorButton: FunctionComponent = observer( ({ application, appState, onClickPreprocessing }) => { const note = Object.values(appState.notes.selectedNotes)[0]; - const [open, setOpen] = useState(false); + const [isOpen, setIsOpen] = useState(false); + const [isVisible, setIsVisible] = useState(false); const [position, setPosition] = useState({ top: 0, right: 0, @@ -35,28 +33,7 @@ export const ChangeEditorButton: FunctionComponent = observer( const buttonRef = useRef(null); const panelRef = useRef(null); const containerRef = useRef(null); - const [closeOnBlur] = useCloseOnBlur(containerRef, setOpen); - const [editors] = useState(() => - application.componentManager - .componentsForArea(ComponentArea.Editor) - .sort((a, b) => { - return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; - }) - ); - const [editorMenuGroups, setEditorMenuGroups] = useState( - [] - ); - const [currentEditor, setCurrentEditor] = useState(); - - useEffect(() => { - setEditorMenuGroups(createEditorMenuGroups(application, editors)); - }, [application, editors]); - - useEffect(() => { - if (note) { - setCurrentEditor(application.componentManager.editorForNote(note)); - } - }, [application, note]); + const [closeOnBlur] = useCloseOnBlur(containerRef, setIsOpen); const toggleChangeEditorMenu = async () => { const rect = buttonRef.current?.getBoundingClientRect(); @@ -81,22 +58,25 @@ export const ChangeEditorButton: FunctionComponent = observer( right: document.body.clientWidth - rect.right, }); - const newOpenState = !open; + const newOpenState = !isOpen; if (newOpenState && onClickPreprocessing) { await onClickPreprocessing(); } - setOpen(newOpenState); + setIsOpen(newOpenState); + setTimeout(() => { + setIsVisible(newOpenState); + }); } }; return (
- + { if (event.key === 'Escape') { - setOpen(false); + setIsOpen(false); } }} onBlur={closeOnBlur} @@ -109,7 +89,7 @@ export const ChangeEditorButton: FunctionComponent = observer( { if (event.key === 'Escape') { - setOpen(false); + setIsOpen(false); buttonRef.current?.focus(); } }} @@ -121,17 +101,14 @@ export const ChangeEditorButton: FunctionComponent = observer( className="sn-dropdown sn-dropdown--animated min-w-68 max-h-120 max-w-xs flex flex-col overflow-y-auto fixed" onBlur={closeOnBlur} > - {open && ( + {isOpen && ( { - setOpen(false); + setIsOpen(false); }} /> )} diff --git a/app/assets/javascripts/components/NotesOptions/ChangeEditorOption.tsx b/app/assets/javascripts/components/NotesOptions/ChangeEditorOption.tsx index fb90c0623..a8ba28a68 100644 --- a/app/assets/javascripts/components/NotesOptions/ChangeEditorOption.tsx +++ b/app/assets/javascripts/components/NotesOptions/ChangeEditorOption.tsx @@ -6,16 +6,10 @@ import { DisclosureButton, DisclosurePanel, } from '@reach/disclosure'; -import { - ComponentArea, - IconType, - SNComponent, - SNNote, -} from '@standardnotes/snjs'; +import { IconType, SNComponent, SNNote } from '@standardnotes/snjs'; import { FunctionComponent } from 'preact'; import { useEffect, useRef, useState } from 'preact/hooks'; import { Icon } from '../Icon'; -import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups'; import { ChangeEditorMenu } from './changeEditor/ChangeEditorMenu'; import { calculateSubmenuStyle, @@ -49,74 +43,53 @@ export const ChangeEditorOption: FunctionComponent = ({ closeOnBlur, note, }) => { - const [changeEditorMenuOpen, setChangeEditorMenuOpen] = useState(false); - const [changeEditorMenuVisible, setChangeEditorMenuVisible] = useState(false); + const [isOpen, setIsOpen] = useState(false); + const [isVisible, setIsVisible] = useState(false); const [menuStyle, setMenuStyle] = useState({ right: 0, bottom: 0, maxHeight: 'auto', }); - const changeEditorMenuRef = useRef(null); - const changeEditorButtonRef = useRef(null); - const [editors] = useState(() => - application.componentManager - .componentsForArea(ComponentArea.Editor) - .sort((a, b) => { - return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; - }) - ); - const [editorMenuGroups, setEditorMenuGroups] = useState( - [] - ); - const [selectedEditor, setSelectedEditor] = useState(() => - application.componentManager.editorForNote(note) - ); - - useEffect(() => { - setEditorMenuGroups(createEditorMenuGroups(application, editors)); - }, [application, editors]); - - useEffect(() => { - setSelectedEditor(application.componentManager.editorForNote(note)); - }, [application, note]); + const menuRef = useRef(null); + const buttonRef = useRef(null); const toggleChangeEditorMenu = () => { - if (!changeEditorMenuOpen) { - const menuStyle = calculateSubmenuStyle(changeEditorButtonRef.current); + if (!isOpen) { + const menuStyle = calculateSubmenuStyle(buttonRef.current); if (menuStyle) { setMenuStyle(menuStyle); } } - setChangeEditorMenuOpen(!changeEditorMenuOpen); + setIsOpen(!isOpen); }; useEffect(() => { - if (changeEditorMenuOpen) { + if (isOpen) { setTimeout(() => { const newMenuStyle = calculateSubmenuStyle( - changeEditorButtonRef.current, - changeEditorMenuRef.current + buttonRef.current, + menuRef.current ); if (newMenuStyle) { setMenuStyle(newMenuStyle); - setChangeEditorMenuVisible(true); + setIsVisible(true); } }); } - }, [changeEditorMenuOpen]); + }, [isOpen]); return ( - + { if (event.key === KeyboardKey.Escape) { - setChangeEditorMenuOpen(false); + setIsOpen(false); } }} onBlur={closeOnBlur} - ref={changeEditorButtonRef} + ref={buttonRef} className="sn-dropdown-item justify-between" >
@@ -126,11 +99,11 @@ export const ChangeEditorOption: FunctionComponent = ({ { if (event.key === KeyboardKey.Escape) { - setChangeEditorMenuOpen(false); - changeEditorButtonRef.current?.focus(); + setIsOpen(false); + buttonRef.current?.focus(); } }} style={{ @@ -139,17 +112,14 @@ export const ChangeEditorOption: FunctionComponent = ({ }} className="sn-dropdown flex flex-col max-h-120 min-w-68 fixed overflow-y-auto" > - {changeEditorMenuOpen && ( + {isOpen && ( { - setChangeEditorMenuOpen(false); + setIsOpen(false); }} /> )} diff --git a/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx b/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx index b6578bdba..7ca59b382 100644 --- a/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx +++ b/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx @@ -19,19 +19,19 @@ import { TransactionalMutation, } from '@standardnotes/snjs'; import { Fragment, FunctionComponent } from 'preact'; -import { StateUpdater, useCallback } from 'preact/hooks'; +import { useCallback, useEffect, useState } from 'preact/hooks'; import { EditorMenuItem, EditorMenuGroup } from '../ChangeEditorOption'; -import { PLAIN_EDITOR_NAME } from './createEditorMenuGroups'; +import { + createEditorMenuGroups, + PLAIN_EDITOR_NAME, +} from './createEditorMenuGroups'; type ChangeEditorMenuProps = { application: WebApplication; closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void; closeMenu: () => void; - groups: EditorMenuGroup[]; - isOpen: boolean; - currentEditor: SNComponent | undefined; + isVisible: boolean; note: SNNote; - setSelectedEditor: StateUpdater; }; const getGroupId = (group: EditorMenuGroup) => @@ -41,12 +41,29 @@ export const ChangeEditorMenu: FunctionComponent = ({ application, closeOnBlur, closeMenu, - groups, - isOpen, - currentEditor, - setSelectedEditor, + isVisible, note, }) => { + const [editors] = useState(() => + application.componentManager + .componentsForArea(ComponentArea.Editor) + .sort((a, b) => { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }) + ); + const [groups, setGroups] = useState([]); + const [currentEditor, setCurrentEditor] = useState(); + + useEffect(() => { + setGroups(createEditorMenuGroups(application, editors)); + }, [application, editors]); + + useEffect(() => { + if (note) { + setCurrentEditor(application.componentManager.editorForNote(note)); + } + }, [application, note]); + const premiumModal = usePremiumModal(); const isSelectedEditor = useCallback( @@ -138,7 +155,7 @@ export const ChangeEditorMenu: FunctionComponent = ({ /** Dirtying can happen above */ application.sync(); - setSelectedEditor(application.componentManager.editorForNote(note)); + setCurrentEditor(application.componentManager.editorForNote(note)); }; const selectEditor = async (itemToBeSelected: EditorMenuItem) => { @@ -179,7 +196,7 @@ export const ChangeEditorMenu: FunctionComponent = ({ {groups .filter((group) => group.items && group.items.length)