@@ -3,10 +3,6 @@ import { IPreviewUrlResponse } from '$types/matrix-sdk';
33import { Box , Icon , IconButton , Icons , Scroll , Spinner , Text , as , color , config } from 'folds' ;
44import { AsyncStatus , useAsyncCallback } from '$hooks/useAsyncCallback' ;
55import { useMatrixClient } from '$hooks/useMatrixClient' ;
6- import {
7- getIntersectionObserverEntry ,
8- useIntersectionObserver ,
9- } from '$hooks/useIntersectionObserver' ;
106import { mxcUrlToHttp , downloadMedia } from '$utils/matrix' ;
117import { useMediaAuthentication } from '$hooks/useMediaAuthentication' ;
128import * as css from './UrlPreviewCard.css' ;
@@ -242,43 +238,34 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number; mediaType?: s
242238
243239export const UrlPreviewHolder = as < 'div' > ( ( { children, ...props } , ref ) => {
244240 const scrollRef = useRef < HTMLDivElement > ( null ) ;
245- const backAnchorRef = useRef < HTMLDivElement > ( null ) ;
246- const frontAnchorRef = useRef < HTMLDivElement > ( null ) ;
247- const [ backVisible , setBackVisible ] = useState ( true ) ;
248- const [ frontVisible , setFrontVisible ] = useState ( true ) ;
241+ const innerBoxRef = useRef < HTMLDivElement > ( null ) ;
242+ const [ canScrollLeft , setCanScrollLeft ] = useState ( false ) ;
243+ const [ canScrollRight , setCanScrollRight ] = useState ( false ) ;
249244
250- const intersectionObserver = useIntersectionObserver (
251- useCallback ( ( entries ) => {
252- const backAnchor = backAnchorRef . current ;
253- const frontAnchor = frontAnchorRef . current ;
254- const backEntry = backAnchor && getIntersectionObserverEntry ( backAnchor , entries ) ;
255- const frontEntry = frontAnchor && getIntersectionObserverEntry ( frontAnchor , entries ) ;
256- if ( backEntry ) {
257- setBackVisible ( backEntry . isIntersecting ) ;
258- }
259- if ( frontEntry ) {
260- setFrontVisible ( frontEntry . isIntersecting ) ;
261- }
262- } , [ ] ) ,
263- useCallback (
264- ( ) => ( {
265- root : scrollRef . current ,
266- rootMargin : '10px' ,
267- } ) ,
268- [ ]
269- )
270- ) ;
245+ const updateArrows = useCallback ( ( ) => {
246+ const scroll = scrollRef . current ;
247+ if ( ! scroll ) return ;
248+ const { scrollLeft, scrollWidth, clientWidth } = scroll ;
249+ setCanScrollLeft ( scrollLeft > 1 ) ;
250+ setCanScrollRight ( scrollLeft + clientWidth < scrollWidth - 1 ) ;
251+ } , [ ] ) ;
271252
272253 useEffect ( ( ) => {
273- const backAnchor = backAnchorRef . current ;
274- const frontAnchor = frontAnchorRef . current ;
275- if ( backAnchor ) intersectionObserver ?. observe ( backAnchor ) ;
276- if ( frontAnchor ) intersectionObserver ?. observe ( frontAnchor ) ;
254+ const scroll = scrollRef . current ;
255+ if ( ! scroll ) return undefined ;
256+
257+ updateArrows ( ) ;
258+ scroll . addEventListener ( 'scroll' , updateArrows , { passive : true } ) ;
259+
260+ const resizeObserver = new ResizeObserver ( updateArrows ) ;
261+ resizeObserver . observe ( scroll ) ;
262+ if ( innerBoxRef . current ) resizeObserver . observe ( innerBoxRef . current ) ;
263+
277264 return ( ) => {
278- if ( backAnchor ) intersectionObserver ?. unobserve ( backAnchor ) ;
279- if ( frontAnchor ) intersectionObserver ?. unobserve ( frontAnchor ) ;
265+ scroll . removeEventListener ( 'scroll' , updateArrows ) ;
266+ resizeObserver . disconnect ( ) ;
280267 } ;
281- } , [ intersectionObserver ] ) ;
268+ } , [ updateArrows ] ) ;
282269
283270 const handleScrollBack = ( ) => {
284271 const scroll = scrollRef . current ;
@@ -308,8 +295,7 @@ export const UrlPreviewHolder = as<'div'>(({ children, ...props }, ref) => {
308295 >
309296 < Scroll ref = { scrollRef } direction = "Horizontal" size = "0" visibility = "Hover" hideTrack >
310297 < Box shrink = "No" alignItems = "Center" >
311- < div ref = { backAnchorRef } />
312- { ! backVisible && (
298+ { canScrollLeft && (
313299 < >
314300 < div className = { css . UrlPreviewHolderGradient ( { position : 'Left' } ) } />
315301 < IconButton
@@ -324,10 +310,9 @@ export const UrlPreviewHolder = as<'div'>(({ children, ...props }, ref) => {
324310 </ IconButton >
325311 </ >
326312 ) }
327- < Box alignItems = "Inherit" gap = "200" >
313+ < Box ref = { innerBoxRef } alignItems = "Inherit" gap = "200" >
328314 { children }
329-
330- { ! frontVisible && (
315+ { canScrollRight && (
331316 < >
332317 < div className = { css . UrlPreviewHolderGradient ( { position : 'Right' } ) } />
333318 < IconButton
@@ -342,7 +327,6 @@ export const UrlPreviewHolder = as<'div'>(({ children, ...props }, ref) => {
342327 </ IconButton >
343328 </ >
344329 ) }
345- < div ref = { frontAnchorRef } />
346330 </ Box >
347331 </ Box >
348332 </ Scroll >
0 commit comments