From f1a31b95907b31e4c3ca88d08ba86a5fe63d8de2 Mon Sep 17 00:00:00 2001 From: chrox Date: Mon, 2 Dec 2024 21:36:28 +0100 Subject: [PATCH] Fix scrollbar auto hide on macOS --- .../app/reader/components/FoliateViewer.tsx | 52 ++++++++++++++----- packages/foliate-js | 2 +- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx index d1773e01..c0a88e15 100644 --- a/apps/readest-app/src/app/reader/components/FoliateViewer.tsx +++ b/apps/readest-app/src/app/reader/components/FoliateViewer.tsx @@ -46,7 +46,7 @@ export interface FoliateView extends HTMLElement { removeAttribute: (name: string) => void; next: () => Promise; prev: () => Promise; - scrollTo?: (offset: number, reason: string, smooth: boolean) => void; + goTo?: (params: { index: number; anchor: number }) => void; setStyles?: (css: string) => void; addEventListener: (type: string, listener: EventListener) => void; removeEventListener: (type: string, listener: EventListener) => void; @@ -74,7 +74,6 @@ const FoliateViewer: React.FC<{ const containerRef = useRef(null); const viewRef = useRef(null); const isViewCreated = useRef(false); - const isScrolling = useRef(false); const { getView, setView: setFoliateView, setProgress, getViewSettings } = useReaderStore(); const { getParallels } = useParallelViewStore(); const { themeCode } = useTheme(); @@ -85,9 +84,41 @@ const FoliateViewer: React.FC<{ setProgress(bookKey, detail.cfi, detail.tocItem, detail.section, detail.location, detail.range); }; + const handleScrollbarAutoHide = (doc: Document) => { + if (doc && doc.defaultView && doc.defaultView.frameElement) { + const iframe = doc.defaultView.frameElement as HTMLIFrameElement; + const container = iframe.parentElement?.parentElement; + if (!container) return; + + let hideScrollbarTimeout: ReturnType; + const showScrollbar = () => { + container.style.overflow = 'auto'; + container.style.scrollbarWidth = 'thin'; + }; + + const hideScrollbar = () => { + container.style.overflow = 'hidden'; + container.style.scrollbarWidth = 'none'; + requestAnimationFrame(() => { + container.style.overflow = 'auto'; + }); + }; + container.addEventListener('scroll', () => { + showScrollbar(); + clearTimeout(hideScrollbarTimeout); + hideScrollbarTimeout = setTimeout(hideScrollbar, 1000); + }); + hideScrollbar(); + } + }; + const docLoadHandler = (event: Event) => { const detail = (event as CustomEvent).detail; if (detail.doc) { + const viewSettings = getViewSettings(bookKey)!; + if (viewSettings.scrolled) { + handleScrollbarAutoHide(detail.doc); + } if (!detail.doc.isEventListenersAdded) { detail.doc.isEventListenersAdded = true; detail.doc.addEventListener('keydown', handleKeydown.bind(null, bookKey)); @@ -99,23 +130,16 @@ const FoliateViewer: React.FC<{ } }; - const docScrollHandler = (event: Event) => { - setTimeout(() => { - isScrolling.current = false; - }, 300); - if (isScrolling.current) return; - isScrolling.current = true; - + const docRelocateHandler = (event: Event) => { const detail = (event as CustomEvent).detail; - if (detail.reason !== 'scroll') return; - if (!viewRef.current!.renderer.scrolled) return; + if (detail.reason !== 'scroll' && detail.reason !== 'page') return; const parallelViews = getParallels(bookKey); if (parallelViews && parallelViews.size > 0) { parallelViews.forEach((key) => { if (key !== bookKey) { const target = getView(key)?.renderer; - if (target && target.scrolled && target.viewSize) { - target.scrollTo?.(detail.fraction * target.viewSize, 'follow-scroll', true); + if (target) { + target.goTo?.({ index: detail.index, anchor: detail.fraction }); } } }); @@ -166,7 +190,7 @@ const FoliateViewer: React.FC<{ useFoliateEvents(viewRef.current, { onLoad: docLoadHandler, onRelocate: progressRelocateHandler, - onRendererRelocate: docScrollHandler, + onRendererRelocate: docRelocateHandler, }); useEffect(() => { diff --git a/packages/foliate-js b/packages/foliate-js index 1a3b141e..2973329d 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit 1a3b141e288434864e3555c48de3573b58638ddc +Subproject commit 2973329dcde12c1a126e899c9b51f636d130ac30