fix: improve plaintext editor performance on mobile (#1855)

This commit is contained in:
Aman Harwara
2022-10-21 11:49:23 +05:30
committed by GitHub
parent 143b528b73
commit f71e6fe703
2 changed files with 39 additions and 98 deletions

View File

@@ -1,34 +0,0 @@
import { classNames } from '@/Utils/ConcatenateClassNames'
import { ComponentPropsWithoutRef, ForwardedRef, forwardRef } from 'react'
// Based on: https://css-tricks.com/auto-growing-inputs-textareas/#aa-other-ideas
const AutoresizingNoteViewTextarea = forwardRef(
(
{ value, className, ...textareaProps }: ComponentPropsWithoutRef<'textarea'>,
ref: ForwardedRef<HTMLTextAreaElement>,
) => {
return (
<div className="relative inline-grid min-h-[75vh] w-full grid-rows-1 items-stretch md:block md:flex-grow">
<pre
id="textarea-mobile-resizer"
className={classNames(
'editable font-editor break-word whitespace-pre-wrap',
'invisible [grid-area:1_/_1] md:hidden',
className,
)}
aria-hidden
>
{value}{' '}
</pre>
<textarea
value={value}
className={classNames('editable font-editor [grid-area:1_/_1] md:h-full md:min-h-0', className)}
{...textareaProps}
ref={ref}
></textarea>
</div>
)
},
)
export default AutoresizingNoteViewTextarea

View File

@@ -13,12 +13,11 @@ import {
NoteViewController,
PayloadEmitSource,
WebAppEvent,
Platform,
EditorLineHeight,
EditorFontSize,
NoteType,
} from '@standardnotes/snjs'
import { debounce, isDesktopApplication, isIOS } from '@/Utils'
import { debounce, isDesktopApplication } from '@/Utils'
import { EditorEventSource } from '../../Types/EditorEventSource'
import { confirmDialog, KeyboardModifier, KeyboardKey } from '@standardnotes/ui-services'
import { STRING_DELETE_PLACEHOLDER_ATTEMPT, STRING_DELETE_LOCKED_ATTEMPT, StringDeleteNote } from '@/Constants/Strings'
@@ -39,7 +38,6 @@ import { reloadFont } from './FontFunctions'
import { NoteViewProps } from './NoteViewProps'
import IndicatorCircle from '../IndicatorCircle/IndicatorCircle'
import { classNames } from '@/Utils/ConcatenateClassNames'
import AutoresizingNoteViewTextarea from './AutoresizingTextarea'
import MobileItemsListButton from '../NoteGroupView/MobileItemsListButton'
import LinkedItemBubblesContainer from '../LinkedItems/LinkedItemBubblesContainer'
import NoteStatusIndicator, { NoteStatus } from './NoteStatusIndicator'
@@ -50,7 +48,6 @@ import NoteViewFileDropTarget from './NoteViewFileDropTarget'
const MinimumStatusDuration = 400
const TextareaDebounce = 100
const NoteEditingDisabledText = 'Note editing disabled.'
const StickyHeaderScrollThresholdInPx = 20
function sortAlphabetically(array: SNComponent[]): SNComponent[] {
return array.sort((a, b) => (a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1))
@@ -83,8 +80,6 @@ type State = {
rightResizerWidth: number
rightResizerOffset: number
shouldStickyHeader: boolean
monospaceFont?: boolean
lineHeight?: EditorLineHeight
fontSize?: EditorFontSize
@@ -134,8 +129,6 @@ class NoteView extends PureComponent<NoteViewProps, State> {
this.textAreaChangeDebounceSave = debounce(this.textAreaChangeDebounceSave, TextareaDebounce)
this.handleWindowScroll = debounce(this.handleWindowScroll, 10)
this.state = {
availableStackComponents: [],
editorStateDidLoad: false,
@@ -155,23 +148,18 @@ class NoteView extends PureComponent<NoteViewProps, State> {
leftResizerOffset: 0,
rightResizerWidth: 0,
rightResizerOffset: 0,
shouldStickyHeader: false,
editorFeatureIdentifier: this.controller.item.editorIdentifier,
noteType: this.controller.item.noteType,
}
this.noteViewElementRef = createRef<HTMLDivElement>()
this.editorContentRef = createRef<HTMLDivElement>()
window.addEventListener('scroll', this.handleWindowScroll)
}
override deinit() {
super.deinit()
;(this.controller as unknown) = undefined
window.removeEventListener('scroll', this.handleWindowScroll)
this.removeComponentStreamObserver?.()
;(this.removeComponentStreamObserver as unknown) = undefined
@@ -932,12 +920,6 @@ class NoteView extends PureComponent<NoteViewProps, State> {
}
}
handleWindowScroll = () => {
this.setState({
shouldStickyHeader: window.scrollY > StickyHeaderScrollThresholdInPx,
})
}
override render() {
if (this.state.showProtectedWarning || !this.application.isAuthorizedToRenderItem(this.note)) {
return (
@@ -951,7 +933,11 @@ class NoteView extends PureComponent<NoteViewProps, State> {
}
return (
<div aria-label="Note" className="section editor sn-component" ref={this.noteViewElementRef}>
<div
aria-label="Note"
className="section editor sn-component max-h-screen md:max-h-full"
ref={this.noteViewElementRef}
>
{this.note && (
<NoteViewFileDropTarget
note={this.note}
@@ -983,15 +969,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
{this.note && (
<div
id="editor-title-bar"
className={classNames(
'content-title-bar section-title-bar z-editor-title-bar w-full bg-default',
this.state.shouldStickyHeader && 'fixed top-0',
this.state.shouldStickyHeader
? isIOS() || this.application.platform === Platform.Ios
? 'pt-safe-top'
: 'pt-4'
: '',
)}
className="content-title-bar section-title-bar z-editor-title-bar w-full bg-default pt-4"
>
<div className="mb-2 flex flex-wrap items-start justify-between gap-2 md:mb-0 md:flex-nowrap md:gap-4 xl:items-center">
<div className={classNames(this.state.noteLocked && 'locked', 'flex flex-grow items-center')}>
@@ -1017,36 +995,32 @@ class NoteView extends PureComponent<NoteViewProps, State> {
updateSavingIndicator={this.state.updateSavingIndicator}
/>
</div>
{!this.state.shouldStickyHeader && (
<div className="flex items-center gap-3">
<LinkedItemsButton
filesController={this.viewControllerManager.filesController}
linkingController={this.viewControllerManager.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<ChangeEditorButton
application={this.application}
viewControllerManager={this.viewControllerManager}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<PinNoteButton
notesController={this.viewControllerManager.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<NotesOptionsPanel
application={this.application}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
linkingController={this.viewControllerManager.linkingController}
historyModalController={this.viewControllerManager.historyModalController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</div>
)}
<div className="flex items-center gap-3">
<LinkedItemsButton
filesController={this.viewControllerManager.filesController}
linkingController={this.viewControllerManager.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<ChangeEditorButton
application={this.application}
viewControllerManager={this.viewControllerManager}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<PinNoteButton
notesController={this.viewControllerManager.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<NotesOptionsPanel
application={this.application}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
linkingController={this.viewControllerManager.linkingController}
historyModalController={this.viewControllerManager.historyModalController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</div>
</div>
{!this.state.shouldStickyHeader && (
<LinkedItemBubblesContainer linkingController={this.viewControllerManager.linkingController} />
)}
<LinkedItemBubblesContainer linkingController={this.viewControllerManager.linkingController} />
</div>
)}
@@ -1082,12 +1056,8 @@ class NoteView extends PureComponent<NoteViewProps, State> {
)}
{this.state.editorStateDidLoad && !this.state.editorComponentViewer && !this.state.textareaUnloading && (
<AutoresizingNoteViewTextarea
<textarea
autoComplete="off"
className={classNames(
this.state.lineHeight && `leading-${this.state.lineHeight.toLowerCase()}`,
this.state.fontSize && PlaintextFontSizeMapping[this.state.fontSize],
)}
dir="auto"
id={ElementIds.NoteTextEditor}
onChange={this.onTextAreaChange}
@@ -1096,7 +1066,12 @@ class NoteView extends PureComponent<NoteViewProps, State> {
ref={(ref) => ref && this.onSystemEditorLoad(ref)}
spellCheck={this.state.spellcheck}
value={this.state.editorText}
/>
className={classNames(
'editable font-editor flex-grow',
this.state.lineHeight && `leading-${this.state.lineHeight.toLowerCase()}`,
this.state.fontSize && PlaintextFontSizeMapping[this.state.fontSize],
)}
></textarea>
)}
{this.state.marginResizersEnabled && this.editorContentRef.current ? (