11import React from 'react' ;
22
33import { attachmentsText } from '../../localization/attachments' ;
4+ import { listen } from '../../utils/events' ;
45import type { RA } from '../../utils/types' ;
56import { replaceItem } from '../../utils/utils' ;
67import { Container } from '../Atoms' ;
@@ -11,11 +12,13 @@ import type { Attachment } from '../DataModel/types';
1112import { raise } from '../Errors/Crash' ;
1213import { ErrorBoundary } from '../Errors/ErrorBoundary' ;
1314import { ResourceView } from '../Forms/ResourceView' ;
15+ import { getPref } from '../InitialContext/remotePrefs' ;
1416import { AttachmentGallerySkeleton } from '../SkeletonLoaders/AttachmentGallery' ;
1517import { AttachmentCell } from './Cell' ;
1618import { AttachmentDialog } from './Dialog' ;
1719
18- const preFetchDistance = 200 ;
20+ const defaultPreFetchDistance = 200 ;
21+ const attachmentSkeletonRows = 2 ;
1922
2023export function AttachmentGallery ( {
2124 attachments,
@@ -37,6 +40,32 @@ export function AttachmentGallery({
3740} ) : JSX . Element {
3841 const containerRef = React . useRef < HTMLElement | null > ( null ) ;
3942
43+ const [ preFetchDistance , setPreFetchDistance ] = React . useState < number > (
44+ defaultPreFetchDistance
45+ ) ;
46+ const [ columns , setColumns ] = React . useState < number > ( 3 ) ;
47+ const attachmentHeight = getPref ( 'attachment.preview_size' ) ;
48+ React . useEffect ( ( ) => {
49+ const calculateColumns = ( ref : React . RefObject < HTMLElement | null > ) => {
50+ if ( ref . current ) {
51+ const rootFontSize = Number . parseFloat (
52+ window . getComputedStyle ( document . documentElement ) . fontSize
53+ ) ; // Equivalent to 1rem
54+ const gap = rootFontSize ;
55+ const columnWidth = scale * rootFontSize + gap ;
56+ setPreFetchDistance (
57+ Math . max (
58+ defaultPreFetchDistance ,
59+ ( attachmentHeight + gap ) * attachmentSkeletonRows + gap
60+ )
61+ ) ;
62+ setColumns ( Math . floor ( ( ref . current . clientWidth - gap ) / columnWidth ) ) ;
63+ }
64+ } ;
65+ calculateColumns ( containerRef ) ;
66+ return listen ( window , 'resize' , ( ) => calculateColumns ( containerRef ) ) ;
67+ } , [ scale ] ) ;
68+
4069 const rawFillPage = React . useCallback (
4170 async ( ) =>
4271 // Fetch more attachments when within 200px of the bottom
@@ -50,15 +79,16 @@ export function AttachmentGallery({
5079
5180 const fillPage = handleFetchMore === undefined ? undefined : rawFillPage ;
5281
53- React . useEffect (
54- ( ) =>
55- // Fetch attachments while scroll bar is not visible
56- void ( containerRef . current ?. scrollHeight ===
57- containerRef . current ?. clientHeight
58- ? fillPage ?.( ) . catch ( raise )
59- : undefined ) ,
60- [ fillPage , attachments ]
61- ) ;
82+ React . useEffect ( ( ) => {
83+ // Fetch attachments while scroll bar is not visible
84+ const noScrollFetch = ( ) => {
85+ setTimeout ( ( ) => {
86+ fillPage ?.( ) . catch ( raise ) ;
87+ } , 10 ) ; // Wait for container to re-render before checking if scrolling is disabled
88+ } ;
89+ noScrollFetch ( ) ;
90+ return listen ( window , 'resize' , noScrollFetch ) ;
91+ } , [ fillPage , attachments , scale ] ) ;
6292
6393 const [ viewRecord , setViewRecord ] = React . useState <
6494 SpecifyResource < AnySchema > | undefined
@@ -75,11 +105,11 @@ export function AttachmentGallery({
75105 return (
76106 < >
77107 < Container . Base
78- className = "grid flex-1 grid-cols-[repeat(auto-fit,minmax(var(--scale),1fr))]
79- items-center gap-4 shadow-none"
108+ className = "grid flex-1 items-center gap-4 shadow-none"
80109 forwardRef = { containerRef }
81110 style = {
82111 {
112+ gridTemplateColumns : `repeat(${ columns } , minmax(0px, 1fr))` ,
83113 '--scale' : `${ scale } rem` ,
84114 } as React . CSSProperties
85115 }
@@ -106,7 +136,11 @@ export function AttachmentGallery({
106136 { isComplete ? (
107137 attachments . length === 0 && < p > { attachmentsText . noAttachments ( ) } </ p >
108138 ) : (
109- < AttachmentGallerySkeleton />
139+ < AttachmentGallerySkeleton
140+ fetchNumber = {
141+ columns * attachmentSkeletonRows - ( attachments . length % columns )
142+ }
143+ />
110144 ) }
111145 </ Container . Base >
112146 { typeof viewRecord === 'object' && (
0 commit comments