From f740a211cecf0d2e83a5f32abc80464552ba0440 Mon Sep 17 00:00:00 2001 From: Ammar Ahmed <40239442+ammarahm-ed@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:14:14 +0500 Subject: [PATCH] Fix selection scrolls to incorrect position on focus and press enter on mobile (#6838) * mobile: fix keep-in-view overscrolling * mobile: fix editor status flickers too much * mobile: fix setting startingOffset * mobile: set sticky state if not set already --- .../src/components/statusbar.tsx | 41 ++++++++++++++++--- .../extensions/keep-in-view/keep-in-view.ts | 4 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/packages/editor-mobile/src/components/statusbar.tsx b/packages/editor-mobile/src/components/statusbar.tsx index c014ce393..fdf27a289 100644 --- a/packages/editor-mobile/src/components/statusbar.tsx +++ b/packages/editor-mobile/src/components/statusbar.tsx @@ -62,9 +62,12 @@ function StatusBar({ }; }, [tab.id, statusBar]); + const scrollState = useRef({ + isMovingUp: false, + startingOffset: 0 + }); const onScroll = React.useCallback((event: Event) => { const currentOffset = (event.target as HTMLElement)?.scrollTop; - post("editor-event:scroll", currentOffset); if (currentOffset < 200) { if (stickyRef.current) { stickyRef.current = false; @@ -76,11 +79,39 @@ function StatusBar({ } if (Date.now() - lastStickyChangeTime.current < 300) return; if (currentOffset > prevScroll.current) { - setSticky(false); - stickyRef.current = false; + if ( + !scrollState.current.startingOffset || + scrollState.current.isMovingUp + ) { + scrollState.current.startingOffset = currentOffset; + } + scrollState.current.isMovingUp = false; } else { - setSticky(true); - stickyRef.current = true; + if ( + !scrollState.current.startingOffset || + !scrollState.current.isMovingUp + ) { + scrollState.current.startingOffset = currentOffset; + } + scrollState.current.isMovingUp = true; + } + + if (scrollState.current.isMovingUp) { + if (currentOffset < scrollState.current.startingOffset - 50) { + if (!stickyRef.current) { + stickyRef.current = true; + setSticky(true); + } + scrollState.current.startingOffset = 0; + } + } else { + if (currentOffset > scrollState.current.startingOffset + 50) { + if (stickyRef.current) { + stickyRef.current = false; + setSticky(false); + } + scrollState.current.startingOffset = 0; + } } lastStickyChangeTime.current = Date.now(); prevScroll.current = currentOffset; diff --git a/packages/editor/src/extensions/keep-in-view/keep-in-view.ts b/packages/editor/src/extensions/keep-in-view/keep-in-view.ts index b3809d976..8d862ae8a 100644 --- a/packages/editor/src/extensions/keep-in-view/keep-in-view.ts +++ b/packages/editor/src/extensions/keep-in-view/keep-in-view.ts @@ -82,9 +82,7 @@ export function keepLastLineInView( ) return; - const isPopupVisible = document.getElementsByClassName( - "editor-mobile-toolbar-popup" - ); + const isPopupVisible = document.querySelector(".editor-mobile-toolbar-popup"); const node = editor.state.selection.$from; if (node.pos > editor.state.doc.nodeSize) return;