Skip to content

Commit 341918d

Browse files
committed
fix ui scroll
1 parent 3b62101 commit 341918d

3 files changed

Lines changed: 35 additions & 15 deletions

File tree

moon/apps/web/components/ClView/components/Checks/cpns/Task.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,8 @@ const TaskItem = memo(function TaskItem({
288288

289289
const showQueued = Boolean(isQueued) && build.status === 'Building'
290290

291-
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
292-
const scrollParent = e.currentTarget.closest('[data-build-list-scroll]') as HTMLElement | null
293-
const scrollTop = scrollParent?.scrollTop ?? 0
294-
291+
const handleClick = () => {
295292
onSelectBuild(build.id)
296-
297-
requestAnimationFrame(() => {
298-
if (scrollParent) scrollParent.scrollTop = scrollTop
299-
})
300293
}
301294

302295
const handleRetry = (e: React.MouseEvent) => {
Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
1-
import { RefObject, useEffect, useRef } from 'react'
1+
import { RefObject, useCallback, useEffect, useLayoutEffect, useRef } from 'react'
22

33
export function useLeftPanelScroll(cl: string, buildId: string, leftPanelRef: RefObject<HTMLDivElement | null>) {
44
const leftPanelScrollRef = useRef(0)
5+
const pendingRestoreRef = useRef<number | null>(null)
6+
const isRestoringRef = useRef(false)
57
const prevClRef = useRef(cl)
68

79
useEffect(() => {
810
if (prevClRef.current !== cl) {
911
prevClRef.current = cl
1012
leftPanelScrollRef.current = 0
13+
pendingRestoreRef.current = null
1114
}
1215
}, [cl])
1316

17+
const preserveScroll = useCallback(() => {
18+
const panel = leftPanelRef.current
19+
20+
if (panel) {
21+
pendingRestoreRef.current = panel.scrollTop
22+
}
23+
}, [leftPanelRef])
24+
1425
useEffect(() => {
1526
const panel = leftPanelRef.current
1627

1728
if (!panel) return
1829

1930
const onScroll = () => {
31+
if (isRestoringRef.current) return
32+
2033
leftPanelScrollRef.current = panel.scrollTop
2134
}
2235

@@ -25,17 +38,25 @@ export function useLeftPanelScroll(cl: string, buildId: string, leftPanelRef: Re
2538
return () => panel.removeEventListener('scroll', onScroll)
2639
}, [leftPanelRef])
2740

28-
useEffect(() => {
41+
// Restore before paint so a re-render cannot reset scroll to 0 and clobber the
42+
// saved position via the scroll listener.
43+
useLayoutEffect(() => {
2944
const panel = leftPanelRef.current
3045

3146
if (!panel) return
3247

33-
const saved = leftPanelScrollRef.current
48+
const saved = pendingRestoreRef.current ?? leftPanelScrollRef.current
49+
50+
pendingRestoreRef.current = null
51+
52+
isRestoringRef.current = true
53+
panel.scrollTop = saved
54+
leftPanelScrollRef.current = saved
3455

3556
requestAnimationFrame(() => {
36-
panel.scrollTop = saved
57+
isRestoringRef.current = false
3758
})
3859
}, [buildId, leftPanelRef])
3960

40-
return {}
61+
return { preserveScroll }
4162
}

moon/apps/web/components/ClView/components/Checks/index.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ const Checks = ({ cl, path, prName }: { cl: string; path?: string; prName?: stri
4040
defaultLeftWidthPercent
4141
} = useResizablePanels()
4242

43-
useLeftPanelScroll(cl, buildId, leftPanelRef)
43+
const { preserveScroll } = useLeftPanelScroll(cl, buildId, leftPanelRef)
44+
45+
const handleSelectBuild = (nextBuildId: string, taskId?: string) => {
46+
preserveScroll()
47+
selectBuild(nextBuildId, taskId)
48+
}
4449

4550
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
4651

@@ -278,6 +283,7 @@ const Checks = ({ cl, path, prName }: { cl: string; path?: string; prName?: stri
278283
key={task.task_id}
279284
onClick={(e) => {
280285
e.stopPropagation()
286+
preserveScroll()
281287
selectTask(task.task_id)
282288
setIsDropdownOpen(false)
283289
}}
@@ -326,7 +332,7 @@ const Checks = ({ cl, path, prName }: { cl: string; path?: string; prName?: stri
326332
tasks={tasksToDisplay}
327333
logsAvailableIds={logsAvailableIds}
328334
selectedBuildId={buildId}
329-
onSelectBuild={selectBuild}
335+
onSelectBuild={handleSelectBuild}
330336
totalTasksCount={validTasks.length}
331337
cl={cl}
332338
/>

0 commit comments

Comments
 (0)