useScrubberMouseTracking.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import type {RefObject} from 'react';
  2. import {useCallback} from 'react';
  3. import {useReplayContext} from 'sentry/components/replays/replayContext';
  4. import {divide} from 'sentry/components/replays/utils';
  5. import useMouseTracking from 'sentry/utils/replays/hooks/useMouseTracking';
  6. type Opts<T extends Element> = {
  7. elem: RefObject<T>;
  8. };
  9. export function useScrubberMouseTracking<T extends Element>({elem}: Opts<T>) {
  10. const {replay, setCurrentHoverTime} = useReplayContext();
  11. const durationMs = replay?.getDurationMs();
  12. const handlePositionChange = useCallback(
  13. params => {
  14. if (!params || durationMs === undefined) {
  15. setCurrentHoverTime(undefined);
  16. return;
  17. }
  18. const {left, width} = params;
  19. if (left >= 0) {
  20. const percent = left / width;
  21. const time = percent * durationMs;
  22. setCurrentHoverTime(time);
  23. } else {
  24. setCurrentHoverTime(undefined);
  25. }
  26. },
  27. [durationMs, setCurrentHoverTime]
  28. );
  29. const mouseTrackingProps = useMouseTracking({
  30. elem,
  31. onPositionChange: handlePositionChange,
  32. });
  33. return mouseTrackingProps;
  34. }
  35. export function useTimelineScrubberMouseTracking<T extends Element>(
  36. {elem}: Opts<T>,
  37. scale: number
  38. ) {
  39. const {replay, currentTime, setCurrentHoverTime} = useReplayContext();
  40. const durationMs = replay?.getDurationMs();
  41. const handlePositionChange = useCallback(
  42. params => {
  43. if (!params || durationMs === undefined) {
  44. setCurrentHoverTime(undefined);
  45. return;
  46. }
  47. const {left, width} = params;
  48. const initialTranslate = 0.5 / scale;
  49. const percentComplete = divide(currentTime, durationMs);
  50. const starting = percentComplete < initialTranslate;
  51. const ending = percentComplete + initialTranslate > 1;
  52. if (left >= 0) {
  53. const time = () => {
  54. let percent = left / width;
  55. if (starting) {
  56. return (percent * durationMs) / scale;
  57. }
  58. if (ending) {
  59. return (percent * durationMs) / scale + (1 - 1 / scale) * durationMs;
  60. }
  61. percent = (left - width / 2) / width;
  62. return currentTime + (percent * durationMs) / scale;
  63. };
  64. setCurrentHoverTime(time());
  65. } else {
  66. setCurrentHoverTime(undefined);
  67. }
  68. },
  69. [durationMs, setCurrentHoverTime, currentTime, scale]
  70. );
  71. const mouseTrackingProps = useMouseTracking({
  72. elem,
  73. onPositionChange: handlePositionChange,
  74. });
  75. return mouseTrackingProps;
  76. }
  77. export default useScrubberMouseTracking;