Socialify

Folder ..

Viewing useScroll.ts
62 lines (50 loc) • 1.8 KB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

export function ScrollToTop() {
  const location = useLocation();
  const prevPathnameRef = useRef<string | null>(null);

  useEffect(() => {
    const restoreScrollPosition = () => {
      const savedPosition = sessionStorage.getItem(location.pathname);
      if (savedPosition) {
        window.scrollTo(0, parseInt(savedPosition, 10));
      }
    };

    const saveScrollPosition = () =>
      sessionStorage.setItem(location.pathname, window.scrollY.toString());

    window.addEventListener('beforeunload', saveScrollPosition);
    window.addEventListener('popstate', restoreScrollPosition);

    const ignoreRoutePattern = /^\/watch\/[^/]+\/[^/]+\/[^/]+$/;
    if (
      prevPathnameRef.current !== location.pathname &&
      !ignoreRoutePattern.test(location.pathname)
    ) {
      if (location.state?.preserveScroll) {
        restoreScrollPosition();
      } else {
        window.scrollTo(0, 0);
      }
    }

    prevPathnameRef.current = location.pathname;

    return () => {
      window.removeEventListener('beforeunload', saveScrollPosition);
      window.removeEventListener('popstate', restoreScrollPosition);
    };
  }, [location]);

  return null;
}

export const usePreserveScrollOnReload = () => {
  useEffect(() => {
    const savedScrollPosition = sessionStorage.getItem('scrollPosition');
    if (savedScrollPosition) {
      window.scrollTo(0, parseInt(savedScrollPosition, 10));
    }

    const handleBeforeUnload = () => {
      sessionStorage.setItem('scrollPosition', window.scrollY.toString());
    };

    window.addEventListener('beforeunload', handleBeforeUnload);

    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
    };
  }, []);
};