useTraceScrollToPath.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import {useRef} from 'react';
  2. import * as qs from 'query-string';
  3. import type {TraceTree} from './traceModels/traceTree';
  4. function decodeScrollQueue(maybePath: unknown): TraceTree.NodePath[] | null {
  5. if (Array.isArray(maybePath)) {
  6. return maybePath;
  7. }
  8. if (typeof maybePath === 'string') {
  9. return [maybePath as TraceTree.NodePath];
  10. }
  11. return null;
  12. }
  13. type UseTraceScrollToPath =
  14. | {eventId?: string; path?: TraceTree.NodePath[]}
  15. | null
  16. | undefined;
  17. export function useTraceScrollToPath(
  18. path: UseTraceScrollToPath
  19. ): React.MutableRefObject<UseTraceScrollToPath> {
  20. const scrollQueueRef = useRef<
  21. {eventId?: string; path?: TraceTree.NodePath[]} | null | undefined
  22. >(undefined);
  23. // If we havent decoded anything yet, then decode the path
  24. if (scrollQueueRef.current === undefined) {
  25. let scrollToNode: UseTraceScrollToPath = path;
  26. if (!path) {
  27. const queryParams = qs.parse(location.search);
  28. scrollToNode = {
  29. eventId: (queryParams.eventId ?? queryParams.targetId) as string | undefined,
  30. path: decodeScrollQueue(queryParams.node) as TraceTree.NodePath[] | undefined,
  31. };
  32. }
  33. if (scrollToNode && (scrollToNode.path || scrollToNode.eventId)) {
  34. scrollQueueRef.current = {
  35. eventId: scrollToNode.eventId as string,
  36. path: scrollToNode.path,
  37. };
  38. } else {
  39. scrollQueueRef.current = null;
  40. }
  41. }
  42. return scrollQueueRef;
  43. }