Skip to content

Commit f47b911

Browse files
committed
fix: recursive event emits to onGoToPartInstance when scrollToPartInstance was called
fix, use timeout and measure scroll to position
1 parent a4fd32d commit f47b911

File tree

1 file changed

+49
-10
lines changed

1 file changed

+49
-10
lines changed

packages/webui/src/client/lib/viewPort.ts

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ export async function scrollToPartInstance(
6868
quitFocusOnPart()
6969
const partInstance = UIPartInstances.findOne(partInstanceId)
7070
if (partInstance) {
71-
RundownViewEventBus.emit(RundownViewEvents.GO_TO_PART_INSTANCE, {
72-
segmentId: partInstance.segmentId,
73-
partInstanceId: partInstanceId,
74-
})
71+
console.log('scrollToPartInstance - Emitting GO_TO_PART_INSTANCE', partInstance.segmentId, partInstanceId)
72+
// RundownViewEventBus.emit(RundownViewEvents.GO_TO_PART_INSTANCE, {
73+
// segmentId: partInstance.segmentId,
74+
// partInstanceId: partInstanceId,
75+
// })
7576
return scrollToSegment(partInstance.segmentId, forceScroll, noAnimation, partInstanceId)
7677
}
7778
throw new Error('Could not find PartInstance')
@@ -255,9 +256,13 @@ let scrollToPositionRequest: number | undefined
255256
let scrollToPositionRequestReject: ((reason?: any) => void) | undefined
256257

257258
export async function scrollToPosition(scrollPosition: number, noAnimation?: boolean): Promise<void> {
259+
// Calculate the exact position
260+
const headerOffset = getHeaderHeight() + HEADER_MARGIN
261+
const targetTop = Math.max(0, scrollPosition - headerOffset)
262+
258263
if (noAnimation) {
259264
window.scroll({
260-
top: Math.max(0, scrollPosition - getHeaderHeight() - HEADER_MARGIN),
265+
top: targetTop,
261266
left: 0,
262267
})
263268
return Promise.resolve()
@@ -268,21 +273,55 @@ export async function scrollToPosition(scrollPosition: number, noAnimation?: boo
268273
scrollToPositionRequestReject('Prevented by another scroll')
269274

270275
scrollToPositionRequestReject = reject
271-
const currentTop = window.scrollY
272-
const targetTop = Math.max(0, scrollPosition - getHeaderHeight() - HEADER_MARGIN)
276+
273277
scrollToPositionRequest = window.requestIdleCallback(
274278
() => {
275279
window.scroll({
276280
top: targetTop,
277281
left: 0,
278282
behavior: 'smooth',
279283
})
280-
setTimeout(() => {
284+
285+
const checkScrollPosition = () => {
286+
const currentPosition = window.scrollY
287+
// Check if target position is reached
288+
if (
289+
Math.abs(currentPosition - targetTop) < 2 ||
290+
Math.abs(currentPosition - lastCheckedPosition) < 1
291+
) {
292+
// Fine adjust the position
293+
if (Math.abs(currentPosition - targetTop) > 2) {
294+
window.scroll({
295+
top: targetTop,
296+
left: 0,
297+
})
298+
}
299+
300+
// Clean up and resolve
301+
clearInterval(checkInterval)
302+
clearTimeout(timeoutTimer)
303+
resolve()
304+
scrollToPositionRequestReject = undefined
305+
return
306+
}
307+
308+
lastCheckedPosition = currentPosition
309+
}
310+
311+
// Keep track of the last position to detect when scrolling stops
312+
let lastCheckedPosition = window.scrollY
313+
314+
// Check every 100ms
315+
const checkInterval = setInterval(checkScrollPosition, 100)
316+
317+
// Fallback timeout - resolve after a reasonable time even if not at target
318+
const timeoutTimer = setTimeout(() => {
319+
clearInterval(checkInterval)
281320
resolve()
282321
scrollToPositionRequestReject = undefined
283-
// this formula was experimentally created from Chrome 86 behavior
284-
}, 3000 * Math.log(Math.abs(currentTop - targetTop) / 2000 + 1))
322+
}, 1500)
285323
},
324+
// Make sure we wait to ensure the scroll is started
286325
{ timeout: 250 }
287326
)
288327
})

0 commit comments

Comments
 (0)