From ebadb321e39f9da4f1a30e5ca2dd26a5e1938dc4 Mon Sep 17 00:00:00 2001 From: Jaret Burkett Date: Mon, 29 Sep 2025 03:56:17 -0600 Subject: [PATCH] On samples page, auto scroll to bottom on load. Added a floating button to scroll to bottom. --- ui/src/components/SampleImages.tsx | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/ui/src/components/SampleImages.tsx b/ui/src/components/SampleImages.tsx index 85d50c03..50d0dead 100644 --- a/ui/src/components/SampleImages.tsx +++ b/ui/src/components/SampleImages.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState, useRef } from 'react'; +import { useMemo, useState, useRef, useEffect } from 'react'; import useSampleImages from '@/hooks/useSampleImages'; import SampleImageCard from './SampleImageCard'; import { Job } from '@prisma/client'; @@ -8,6 +8,7 @@ import { Button } from '@headlessui/react'; import { FaDownload } from 'react-icons/fa'; import { apiClient } from '@/utils/api'; import classNames from 'classnames'; +import { FaCaretDown } from 'react-icons/fa'; import SampleImageViewer from './SampleImageViewer'; interface SampleImagesMenuProps { @@ -69,6 +70,7 @@ export default function SampleImages({ job }: SampleImagesProps) { const { sampleImages, status, refreshSampleImages } = useSampleImages(job.id, 5000); const [selectedSamplePath, setSelectedSamplePath] = useState(null); const containerRef = useRef(null); + const didFirstScroll = useRef(false); const numSamples = useMemo(() => { if (job?.job_config) { const jobConfig = JSON.parse(job.job_config) as JobConfig; @@ -80,6 +82,12 @@ export default function SampleImages({ job }: SampleImagesProps) { return 10; }, [job]); + const scrollToBottom = () => { + if (containerRef.current) { + containerRef.current.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'instant' }); + } + }; + const PageInfoContent = useMemo(() => { let icon = null; let text = ''; @@ -232,6 +240,16 @@ export default function SampleImages({ job }: SampleImagesProps) { return null; }, [job]); + // scroll to bottom on first load of samples + useEffect(() => { + if (status === 'success' && sampleImages.length > 0 && !didFirstScroll.current) { + didFirstScroll.current = true; + setTimeout(() => { + scrollToBottom(); + }, 100); + } + }, [status, sampleImages.length]); + return (
@@ -259,6 +277,13 @@ export default function SampleImages({ job }: SampleImagesProps) { onChange={setPath => setSelectedSamplePath(setPath)} sampleConfig={sampleConfig} /> +
+ +
); }