123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import {Component, createContext} from 'react';
- import {clamp, rectOfContent} from 'sentry/components/performance/waterfall/utils';
- import {DragManagerChildrenProps} from './dragManager';
- import {ParsedTraceType} from './types';
- export type CursorGuideManagerChildrenProps = {
- displayCursorGuide: (mousePageX: number) => void;
- hideCursorGuide: () => void;
- mouseLeft: number | undefined;
- showCursorGuide: boolean;
- traceViewMouseLeft: number | undefined;
- };
- const CursorGuideManagerContext = createContext<CursorGuideManagerChildrenProps>({
- showCursorGuide: false,
- mouseLeft: void 0,
- traceViewMouseLeft: void 0,
- displayCursorGuide: () => {},
- hideCursorGuide: () => {},
- });
- type PropType = {
- children: React.ReactNode;
- dragProps: DragManagerChildrenProps;
- // this is the DOM element where the drag events occur. it's also the reference point
- // for calculating the relative mouse x coordinate.
- interactiveLayerRef: React.RefObject<HTMLDivElement>;
- trace: ParsedTraceType;
- };
- type StateType = {
- mouseLeft: number | undefined;
- showCursorGuide: boolean;
- traceViewMouseLeft: number | undefined;
- };
- export class Provider extends Component<PropType, StateType> {
- state: StateType = {
- showCursorGuide: false,
- mouseLeft: void 0,
- traceViewMouseLeft: void 0,
- };
- hasInteractiveLayer = (): boolean => !!this.props.interactiveLayerRef.current;
- displayCursorGuide = (mousePageX: number) => {
- if (!this.hasInteractiveLayer()) {
- return;
- }
- const {trace, dragProps} = this.props;
- const interactiveLayer = this.props.interactiveLayerRef.current!;
- const rect = rectOfContent(interactiveLayer);
- // duration of the entire trace in seconds
- const traceDuration = trace.traceEndTimestamp - trace.traceStartTimestamp;
- const viewStart = dragProps.viewWindowStart;
- const viewEnd = dragProps.viewWindowEnd;
- const viewStartTimestamp = trace.traceStartTimestamp + viewStart * traceDuration;
- const viewEndTimestamp = trace.traceEndTimestamp - (1 - viewEnd) * traceDuration;
- const viewDuration = viewEndTimestamp - viewStartTimestamp;
- // clamp mouseLeft to be within [0, 1]
- const mouseLeft = clamp((mousePageX - rect.x) / rect.width, 0, 1);
- const duration =
- mouseLeft * Math.abs(trace.traceEndTimestamp - trace.traceStartTimestamp);
- const startTimestamp = trace.traceStartTimestamp + duration;
- const start = (startTimestamp - viewStartTimestamp) / viewDuration;
- this.setState({
- showCursorGuide: true,
- mouseLeft,
- traceViewMouseLeft: start,
- });
- };
- hideCursorGuide = () => {
- if (!this.hasInteractiveLayer()) {
- return;
- }
- this.setState({
- showCursorGuide: false,
- mouseLeft: void 0,
- traceViewMouseLeft: void 0,
- });
- };
- render() {
- const childrenProps = {
- showCursorGuide: this.state.showCursorGuide,
- mouseLeft: this.state.mouseLeft,
- traceViewMouseLeft: this.state.traceViewMouseLeft,
- displayCursorGuide: this.displayCursorGuide,
- hideCursorGuide: this.hideCursorGuide,
- };
- return (
- <CursorGuideManagerContext.Provider value={childrenProps}>
- {this.props.children}
- </CursorGuideManagerContext.Provider>
- );
- }
- }
- export const Consumer = CursorGuideManagerContext.Consumer;
|