diff --git a/src/web/traceViewer/ui/filmStrip.tsx b/src/web/traceViewer/ui/filmStrip.tsx index 7d721ad044..5acc065b42 100644 --- a/src/web/traceViewer/ui/filmStrip.tsx +++ b/src/web/traceViewer/ui/filmStrip.tsx @@ -21,18 +21,26 @@ import { useMeasure } from './helpers'; import { upperBound } from '../../uiUtils'; import { ContextEntry, PageEntry } from '../../../server/trace/viewer/traceModel'; +const tileSize = { width: 200, height: 45 }; + export const FilmStrip: React.FunctionComponent<{ context: ContextEntry, boundaries: Boundaries, - previewX?: number, -}> = ({ context, boundaries, previewX }) => { + previewPoint?: { x: number, clientY: number }, +}> = ({ context, boundaries, previewPoint }) => { const [measure, ref] = useMeasure(); - const screencastFrames = context.pages[0]?.screencastFrames; + let pageIndex = 0; + if (ref.current && previewPoint) { + const bounds = ref.current.getBoundingClientRect(); + pageIndex = ((previewPoint.clientY - bounds.top) / tileSize.height) | 0; + } + + const screencastFrames = context.pages[pageIndex]?.screencastFrames; // TODO: pick file from the Y position. let previewImage = undefined; - if (previewX !== undefined && context.pages.length) { - const previewTime = boundaries.minimum + (boundaries.maximum - boundaries.minimum) * previewX / measure.width; + if (previewPoint !== undefined && screencastFrames) { + const previewTime = boundaries.minimum + (boundaries.maximum - boundaries.minimum) * previewPoint.x / measure.width; previewImage = screencastFrames[upperBound(screencastFrames, previewTime, timeComparator) - 1]; } const previewSize = inscribe(context.created.viewportSize!, { width: 600, height: 600 }); @@ -45,12 +53,12 @@ export const FilmStrip: React.FunctionComponent<{ key={index} />) } - {previewImage && previewX !== undefined && + {previewImage && previewPoint?.x !== undefined &&
@@ -69,7 +77,7 @@ const FilmStripLane: React.FunctionComponent<{ viewportSize.width = Math.max(viewportSize.width, frame.width); viewportSize.height = Math.max(viewportSize.height, frame.height); } - const frameSize = inscribe(viewportSize!, { width: 200, height: 45 }); + const frameSize = inscribe(viewportSize!, tileSize); const frameMargin = 2.5; const startTime = screencastFrames[0].timestamp; const endTime = screencastFrames[screencastFrames.length - 1].timestamp; diff --git a/src/web/traceViewer/ui/timeline.tsx b/src/web/traceViewer/ui/timeline.tsx index 2b8ebc3ff0..c353ede53b 100644 --- a/src/web/traceViewer/ui/timeline.tsx +++ b/src/web/traceViewer/ui/timeline.tsx @@ -44,7 +44,7 @@ export const Timeline: React.FunctionComponent<{ onHighlighted: (action: ActionEntry | undefined) => void, }> = ({ context, boundaries, selectedAction, highlightedAction, onSelected, onHighlighted }) => { const [measure, ref] = useMeasure(); - const [previewX, setPreviewX] = React.useState(); + const [previewPoint, setPreviewPoint] = React.useState<{ x: number, clientY: number } | undefined>(); const [hoveredBarIndex, setHoveredBarIndex] = React.useState(); const offsets = React.useMemo(() => { @@ -144,22 +144,23 @@ export const Timeline: React.FunctionComponent<{ const onMouseMove = (event: React.MouseEvent) => { if (!ref.current) return; - const x = event.clientX - ref.current.getBoundingClientRect().left; + const bounds = ref.current.getBoundingClientRect(); + const x = event.clientX - bounds.left; const index = findHoveredBarIndex(x); - setPreviewX(x); + setPreviewPoint({ x, clientY: event.clientY }); setHoveredBarIndex(index); if (typeof index === 'number') onHighlighted(bars[index].entry); }; const onMouseLeave = () => { - setPreviewX(undefined); + setPreviewPoint(undefined); setHoveredBarIndex(undefined); onHighlighted(undefined); }; const onClick = (event: React.MouseEvent) => { - setPreviewX(undefined); + setPreviewPoint(undefined); if (!ref.current) return; const x = event.clientX - ref.current.getBoundingClientRect().left; @@ -203,10 +204,10 @@ export const Timeline: React.FunctionComponent<{ >; }) } - +
; };