From 3392f57462fbd330ccac4e172a1d0560ee358dc9 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Wed, 25 Jan 2023 20:37:48 +0800 Subject: [PATCH] Rewrite scrolling logic in carousel Just normal scroll event is enough, don't need intersection observer --- src/app.css | 1 + src/components/status.jsx | 60 ++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/app.css b/src/app.css index a067b0b7..27fc40c1 100644 --- a/src/app.css +++ b/src/app.css @@ -664,6 +664,7 @@ button.carousel-dot { color: var(--text-insignificant-color) !important; font-weight: bold; backdrop-filter: none !important; + transition: all 0.2s; } button.carousel-dot[disabled] { pointer-events: none; diff --git a/src/components/status.jsx b/src/components/status.jsx index b8f4a068..339a9b2d 100644 --- a/src/components/status.jsx +++ b/src/components/status.jsx @@ -12,7 +12,6 @@ import { useState, } from 'preact/hooks'; import { useHotkeys } from 'react-hotkeys-hook'; -import { InView } from 'react-intersection-observer'; import 'swiped-events'; import useResizeObserver from 'use-resize-observer'; import { useSnapshot } from 'valtio'; @@ -26,7 +25,6 @@ import htmlContentLength from '../utils/html-content-length'; import shortenNumber from '../utils/shorten-number'; import states, { saveStatus } from '../utils/states'; import store from '../utils/store'; -import useDebouncedCallback from '../utils/useDebouncedCallback'; import visibilityIconsMap from '../utils/visibility-icons-map'; import Avatar from './avatar'; @@ -1260,19 +1258,8 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) { const [currentIndex, setCurrentIndex] = useState(index); const carouselFocusItem = useRef(null); useLayoutEffect(() => { - carouselFocusItem.current?.node?.scrollIntoView(); + carouselFocusItem.current?.scrollIntoView(); }, []); - useLayoutEffect(() => { - carouselFocusItem.current?.node?.scrollIntoView({ - behavior: 'smooth', - }); - }, [currentIndex]); - - const onSnap = useDebouncedCallback((inView, i) => { - if (inView) { - setCurrentIndex(i); - } - }, 100); const [showControls, setShowControls] = useState(true); @@ -1294,6 +1281,24 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) { const [showMediaAlt, setShowMediaAlt] = useState(false); + useEffect(() => { + let handleScroll = () => { + const { clientWidth, scrollLeft } = carouselRef.current; + const index = Math.round(scrollLeft / clientWidth); + setCurrentIndex(index); + }; + if (carouselRef.current) { + carouselRef.current.addEventListener('scroll', handleScroll, { + passive: true, + }); + } + return () => { + if (carouselRef.current) { + carouselRef.current.removeEventListener('scroll', handleScroll); + } + }; + }, []); + return ( <>
{} }) { ? getBlurHashAverageColor(blurhash) : null; return ( - {} }) { }} tabindex="0" key={media.id} - ref={i === currentIndex ? carouselFocusItem : null} // InView options - root={carouselRef.current} - threshold={1} - onChange={(inView) => onSnap(inView, i)} + ref={i === currentIndex ? carouselFocusItem : null} onClick={(e) => { if (e.target !== e.currentTarget) { setShowControls(!showControls); @@ -1350,7 +1352,7 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) { )} - +
); })} @@ -1377,7 +1379,10 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) { onClick={(e) => { e.preventDefault(); e.stopPropagation(); - setCurrentIndex(i); + carouselRef.current.scrollTo({ + left: carouselRef.current.clientWidth * i, + behavior: 'smooth', + }); }} > • @@ -1410,10 +1415,10 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) { onClick={(e) => { e.preventDefault(); e.stopPropagation(); - setCurrentIndex( - (currentIndex - 1 + mediaAttachments.length) % - mediaAttachments.length, - ); + carouselRef.current.scrollTo({ + left: carouselRef.current.clientWidth * (currentIndex - 1), + behavior: 'smooth', + }); }} > @@ -1425,7 +1430,10 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) { onClick={(e) => { e.preventDefault(); e.stopPropagation(); - setCurrentIndex((currentIndex + 1) % mediaAttachments.length); + carouselRef.current.scrollTo({ + left: carouselRef.current.clientWidth * (currentIndex + 1), + behavior: 'smooth', + }); }} >