chore: fix note options menu visibility in plain editor on mobile [skip e2e]

This commit is contained in:
Aman Harwara
2023-10-29 14:00:45 +05:30
parent 12ccd22d78
commit 0f73ea8c4e
4 changed files with 66 additions and 38 deletions

View File

@@ -29,7 +29,7 @@ import {
VaultUserServiceEvent,
} from '@standardnotes/snjs'
import { confirmDialog, DELETE_NOTE_KEYBOARD_COMMAND, KeyboardKey } from '@standardnotes/ui-services'
import { ChangeEventHandler, createRef, CSSProperties, KeyboardEventHandler, RefObject } from 'react'
import { ChangeEventHandler, createRef, CSSProperties, FocusEvent, KeyboardEventHandler, RefObject } from 'react'
import { SuperEditor } from '../SuperEditor/SuperEditor'
import IndicatorCircle from '../IndicatorCircle/IndicatorCircle'
import LinkedItemBubblesContainer from '../LinkedItems/LinkedItemBubblesContainer'
@@ -826,7 +826,10 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
this.setState({ plainEditorFocused: true })
}
onPlainBlur = () => {
onPlainBlur = (event: FocusEvent) => {
if (event.relatedTarget?.id === ElementIds.NoteOptionsButton) {
return
}
this.setState({ plainEditorFocused: false })
}
@@ -937,30 +940,33 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
{pluralize(this.state.conflictedNotes.length, 'conflict', 'conflicts')}
</Button>
)}
{renderHeaderOptions && (
<div className="note-view-options-buttons flex items-center gap-3">
{!this.state.readonly && (
<>
<LinkedItemsButton
linkingController={this.application.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<ChangeEditorButton
noteViewController={this.controller}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<PinNoteButton
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</>
)}
<NotesOptionsPanel
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</div>
)}
<div className="note-view-options-buttons flex items-center gap-3">
{!this.state.readonly && renderHeaderOptions && (
<>
<LinkedItemsButton
linkingController={this.application.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<ChangeEditorButton
noteViewController={this.controller}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<PinNoteButton
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</>
)}
<NotesOptionsPanel
notesController={this.application.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
onButtonBlur={() => {
this.setState({
plainEditorFocused: false,
})
}}
/>
</div>
</div>
<div className="mb-1 mt-2.5 md:hidden">
<CollaborationInfoHUD item={this.note} />

View File

@@ -16,7 +16,16 @@ import {
PrefDefaults,
} from '@standardnotes/snjs'
import { TAB_COMMAND } from '@standardnotes/ui-services'
import { ChangeEventHandler, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'
import {
ChangeEventHandler,
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useRef,
useState,
FocusEvent,
} from 'react'
import { NoteViewController } from '../Controller/NoteViewController'
type Props = {
@@ -25,7 +34,7 @@ type Props = {
controller: NoteViewController
locked: boolean
onFocus: () => void
onBlur: () => void
onBlur: (event: FocusEvent) => void
}
export type PlainEditorInterface = {
@@ -106,13 +115,16 @@ export const PlainEditor = forwardRef<PlainEditorInterface, Props>(
onFocus()
}, [application, isAdjustingMobileCursor, lastEditorFocusEventSource, onFocus])
const onContentBlur = useCallback(() => {
if (lastEditorFocusEventSource.current) {
application.notifyWebEvent(WebAppEvent.EditorFocused, { eventSource: lastEditorFocusEventSource })
}
lastEditorFocusEventSource.current = undefined
onBlur()
}, [application, lastEditorFocusEventSource, onBlur])
const onContentBlur = useCallback(
(event: FocusEvent) => {
if (lastEditorFocusEventSource.current) {
application.notifyWebEvent(WebAppEvent.EditorFocused, { eventSource: lastEditorFocusEventSource })
}
lastEditorFocusEventSource.current = undefined
onBlur(event)
},
[application, lastEditorFocusEventSource, onBlur],
)
const scrollMobileCursorIntoViewAfterWebviewResize = useCallback(() => {
if (needsAdjustMobileCursor.current) {

View File

@@ -1,17 +1,19 @@
import { useCallback, useRef, useState } from 'react'
import { FocusEvent, useCallback, useRef, useState } from 'react'
import { observer } from 'mobx-react-lite'
import NotesOptions from './NotesOptions'
import { NotesController } from '@/Controllers/NotesController/NotesController'
import Popover from '../Popover/Popover'
import RoundIconButton from '../Button/RoundIconButton'
import Menu from '../Menu/Menu'
import { ElementIds } from '@/Constants/ElementIDs'
type Props = {
notesController: NotesController
onClickPreprocessing?: () => Promise<void>
onButtonBlur?: (event: FocusEvent) => void
}
const NotesOptionsPanel = ({ notesController, onClickPreprocessing }: Props) => {
const NotesOptionsPanel = ({ notesController, onClickPreprocessing, onButtonBlur }: Props) => {
const [isOpen, setIsOpen] = useState(false)
const buttonRef = useRef<HTMLButtonElement>(null)
@@ -30,7 +32,14 @@ const NotesOptionsPanel = ({ notesController, onClickPreprocessing }: Props) =>
return (
<>
<RoundIconButton label="Note options menu" onClick={toggleMenu} ref={buttonRef} icon="more" />
<RoundIconButton
id={ElementIds.NoteOptionsButton}
label="Note options menu"
onClick={toggleMenu}
onBlur={onButtonBlur}
ref={buttonRef}
icon="more"
/>
<Popover
title="Note options"
disableClickOutside={disableClickOutside}

View File

@@ -8,6 +8,7 @@ export const ElementIds = {
NavigationColumn: 'navigation',
NoteTextEditor: 'note-text-editor',
NoteTitleEditor: 'note-title-editor',
NoteOptionsButton: 'note-options-button',
RootId: 'app-group-root',
NoteStatusTooltip: 'note-status-tooltip',
ItemLinkAutocompleteInput: 'item-link-autocomplete-input',