chore: fix note options menu visibility in plain editor on mobile [skip e2e]
This commit is contained in:
@@ -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} />
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user