File size: 2,412 Bytes
8e3dbd3
 
cfb938a
8e3dbd3
 
 
 
4ec47c5
8e3dbd3
 
 
92f037b
 
8e3dbd3
 
 
 
 
 
4ec47c5
 
 
 
 
 
 
 
 
8e3dbd3
4ec47c5
 
 
 
 
8e3dbd3
4ec47c5
 
 
 
 
 
 
 
 
 
 
8e3dbd3
4ec47c5
 
8e3dbd3
4ec47c5
 
 
 
8e3dbd3
4ec47c5
 
 
 
 
8e3dbd3
 
 
 
 
 
 
 
 
 
 
 
 
 
cfb938a
8e3dbd3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92f037b
8e3dbd3
 
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { useCallback, useEffect, useRef, useState } from 'react';

export const useScrollAnchor = (scrollBottom: number) => {
  const messagesRef = useRef<HTMLDivElement>(null);
  const scrollRef = useRef<HTMLDivElement>(null);
  const visibilityRef = useRef<HTMLDivElement>(null);

  // const [isAtBottom, setIsAtBottom] = useState(true);
  const [isVisible, setIsVisible] = useState(false);

  const scrollToBottom = useCallback(() => {
    if (visibilityRef.current) {
      visibilityRef.current.scrollIntoView({
        block: 'end',
        behavior: 'smooth',
      });
    }
  }, []);

  // useEffect(() => {
  //   if (messagesRef.current) {
  //     if (isAtBottom && !isVisible) {
  //       messagesRef.current.scrollIntoView({
  //         block: 'end',
  //       });
  //     }
  //   }
  // }, [isAtBottom, isVisible]);

  /**
   * Seem to be broken, no time to fix
   */
  // useEffect(() => {
  //   const { current } = scrollRef;

  //   if (current) {
  //     const handleScroll = (event: Event) => {
  //       const target = event.target as HTMLDivElement;
  //       const offset = 100;
  //       console.log(
  //         '[Ming] ~ handleScroll ~ target.scrollTop + target.clientHeight:',
  //         target.scrollTop + target.clientHeight - target.scrollHeight,
  //       );
  //       const isAtBottom =
  //         target.scrollTop + target.clientHeight >=
  //         target.scrollHeight - offset;

  //       setIsAtBottom(isAtBottom);
  //     };

  //     current.addEventListener('scroll', handleScroll, {
  //       passive: true,
  //     });
  //     console.log('[Ming] ~ useEffect ~ current:', current);

  //     return () => {
  //       current.removeEventListener('scroll', handleScroll);
  //     };
  //   }
  // }, []);

  useEffect(() => {
    if (visibilityRef.current) {
      let observer = new IntersectionObserver(
        entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              setIsVisible(true);
            } else {
              setIsVisible(false);
            }
          });
        },
        {
          rootMargin: `0px 0px -${scrollBottom}px 0px`,
        },
      );

      observer.observe(visibilityRef.current);

      return () => {
        observer.disconnect();
      };
    }
  });

  return {
    messagesRef,
    scrollRef,
    visibilityRef,
    scrollToBottom,
    isVisible,
  };
};