mobile: fix scroll into view on keyboard shown (#2762)

This commit is contained in:
Ammar Ahmed
2023-06-19 19:04:53 +05:00
committed by GitHub
parent f0a4a61e1d
commit 6c9c99681e
8 changed files with 56 additions and 22 deletions

View File

@@ -226,7 +226,7 @@ const AppSection = ({
{EditorOverlay ? (
<EditorOverlay editorId={editorId || ""} editor={editor} />
) : null}
<ReadonlyButton editor={editor} />
{editorId === "" ? <ReadonlyButton editor={editor} /> : null}
</>
) : null;
};

View File

@@ -153,6 +153,7 @@ export const useEditorEvents = (
useEffect(() => {
const handleKeyboardDidShow: KeyboardEventListener = () => {
editor.commands.keyboardShown(true);
editor.postMessage(EditorEvents.keyboardShown, undefined);
};
const handleKeyboardDidHide: KeyboardEventListener = () => {
editor.commands.keyboardShown(false);
@@ -164,7 +165,7 @@ export const useEditorEvents = (
return () => {
subscriptions.forEach((subscription) => subscription.remove());
};
}, [editor.commands]);
}, [editor.commands, editor.postMessage]);
useEffect(() => {
editor.commands.setSettings({

View File

@@ -646,6 +646,7 @@ export const useEditor = (
onContentChanged,
editorId: editorId,
markImageLoaded,
overlay
overlay,
postMessage
};
};

View File

@@ -49,7 +49,8 @@ export const EditorEvents: { [name: string]: string } = {
theme: "native:theme",
titleplaceholder: "native:titleplaceholder",
logger: "native:logger",
status: "native:status"
status: "native:status",
keyboardShown: "native:keyboardShown"
};
export function randId(prefix: string) {

View File

@@ -25,7 +25,6 @@ import {
usePermissionHandler,
useTiptap
} from "@notesnook/editor";
import { keepLastLineInView } from "@notesnook/editor/dist/extensions/keep-in-view/keep-in-view";
import { Theme, useTheme } from "@notesnook/theme";
import {
forwardRef,
@@ -44,9 +43,6 @@ import StatusBar from "./statusbar";
import Tags from "./tags";
import Title from "./title";
function isIOSBrowser() {
return __PLATFORM__ !== "android";
}
const Tiptap = ({
editorTheme,
toolbarTheme,
@@ -73,17 +69,6 @@ const Tiptap = ({
onUpdate: ({ editor }) => {
global.editorController.contentChange(editor as Editor);
},
onSelectionUpdate: (props) => {
if (props.transaction.docChanged) {
if (isIOSBrowser()) {
setTimeout(() => {
keepLastLineInView(props.editor, 80, 1);
}, 1);
} else {
props.transaction.scrollIntoView();
}
}
},
onOpenAttachmentPicker: (editor, type) => {
global.editorController.openFilePicker(type);
return true;

View File

@@ -50,6 +50,36 @@ type Timers = {
wordCounter: NodeJS.Timeout | null;
};
function isInViewport(element: any) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
function scrollIntoView(editor: Editor) {
setTimeout(() => {
const node = editor?.state.selection.$from;
const dom = node ? editor?.view?.domAtPos(node.pos) : null;
let domNode = dom?.node;
if (domNode) {
if (domNode.nodeType === Node.TEXT_NODE && domNode.parentNode) {
domNode = domNode.parentNode;
}
if (isInViewport(domNode)) return;
(domNode as HTMLElement).scrollIntoView({
behavior: "smooth",
block: "end"
});
}
}, 100);
}
export type EditorController = {
selectionChange: (editor: Editor) => void;
titleChange: (title: string) => void;
@@ -161,6 +191,11 @@ export function useEditorController(update: () => void): EditorController {
break;
case "native:status":
break;
case "native:keyboardShown":
if (editor?.current) {
scrollIntoView(editor?.current as any);
}
break;
default:
break;
}

View File

@@ -19,12 +19,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { Editor, Extension, posToDOMRect } from "@tiptap/core";
type KeepInViewOptions = {
scrollIntoViewOnWindowResize: boolean;
};
let onWindowResize: ((this: Window, ev: UIEvent) => void) | undefined =
undefined;
export const KeepInView = Extension.create({
export const KeepInView = Extension.create<KeepInViewOptions>({
name: "keepinview",
addOptions() {
return {
scrollIntoViewOnWindowResize: true
};
},
onCreate() {
if (!this.options.scrollIntoViewOnWindowResize) return;
onWindowResize = () => {
keepLastLineInView(this.editor);
};

View File

@@ -238,7 +238,9 @@ const useTiptap = (
Codemark,
MathInline,
MathBlock,
KeepInView,
KeepInView.configure({
scrollIntoViewOnWindowResize: !isMobile
}),
DateTime.configure({ dateFormat, timeFormat }),
KeyMap,
WebClipNode