1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-18 09:35:20 +02:00
joplin/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.ts

72 lines
1.9 KiB
TypeScript

import { useEffect, useCallback, useRef } from 'react';
import shim from '@joplin/lib/shim';
interface HookDependencies {
editor: any;
onScroll: Function;
}
export default function useScroll(dependencies: HookDependencies) {
const { editor, onScroll } = dependencies;
const scrollTimeoutId_ = useRef(null);
const maxScrollTop = useCallback(() => {
if (!editor) return 0;
const doc = editor.getDoc();
const win = editor.getWin();
if (!doc || !win) return 0;
const firstChild = doc.firstElementChild;
if (!firstChild) return 0;
const winHeight = win.innerHeight;
const contentHeight = firstChild.scrollHeight;
return contentHeight < winHeight ? 0 : contentHeight - winHeight;
}, [editor]);
const scrollTop = useCallback(() => {
if (!editor) return 0;
const win = editor.getWin();
if (!win) return 0;
return win.scrollY;
}, [editor]);
const scrollPercent = useCallback(() => {
const m = maxScrollTop();
const t = scrollTop();
return m <= 0 ? 0 : t / m;
}, [maxScrollTop, scrollTop]);
const scrollToPercent = useCallback((percent: number) => {
if (!editor) return;
editor.getWin().scrollTo(0, maxScrollTop() * percent);
}, [editor, maxScrollTop]);
const scheduleOnScroll = useCallback((event: any) => {
if (scrollTimeoutId_.current) {
shim.clearTimeout(scrollTimeoutId_.current);
scrollTimeoutId_.current = null;
}
scrollTimeoutId_.current = shim.setTimeout(() => {
scrollTimeoutId_.current = null;
onScroll(event);
}, 10);
}, [onScroll]);
const onEditorScroll = useCallback(() => {
scheduleOnScroll({ percent: scrollPercent() });
}, [scheduleOnScroll, scrollPercent]);
useEffect(() => {
if (!editor) return () => {};
editor.getDoc().addEventListener('scroll', onEditorScroll);
return () => {
editor.getDoc().removeEventListener('scroll', onEditorScroll);
};
}, [editor, onEditorScroll]);
return { scrollToPercent };
}