@@ -4,6 +4,7 @@ import { PullToRefresh, PullToRefreshHandle, ScrollToEndOptions } from '../PullT
4
4
import { Message , MessageProps } from '../Message' ;
5
5
import { BackBottom } from '../BackBottom' ;
6
6
import canUse from '../../utils/canUse' ;
7
+ import throttle from '../../utils/throttle' ;
7
8
import getToBottom from '../../utils/getToBottom' ;
8
9
9
10
const listenerOpts = canUse ( 'passiveListener' ) ? { passive : true } : false ;
@@ -22,8 +23,8 @@ export interface MessageContainerHandle {
22
23
scrollToEnd : ( options ?: ScrollToEndOptions ) => void ;
23
24
}
24
25
25
- function getMaxOffsetHeight ( wrapper : HTMLElement ) {
26
- return wrapper . offsetHeight * 1.5 ;
26
+ function isNearBottom ( el : HTMLElement ) {
27
+ return getToBottom ( el ) < el . offsetHeight * 1.5 ;
27
28
}
28
29
29
30
export const MessageContainer = React . forwardRef < MessageContainerHandle , MessageContainerProps > (
@@ -42,7 +43,6 @@ export const MessageContainer = React.forwardRef<MessageContainerHandle, Message
42
43
const messagesRef = useRef < HTMLDivElement > ( null ) ;
43
44
const scrollerRef = useRef < PullToRefreshHandle > ( null ) ;
44
45
const bottomRef = useRef < HTMLDivElement > ( null ) ;
45
- const isTouching = useRef ( false ) ;
46
46
const lastMessage = messages [ messages . length - 1 ] ;
47
47
48
48
const scrollToEnd = useCallback ( ( opts ?: ScrollToEndOptions ) => {
@@ -57,17 +57,36 @@ export const MessageContainer = React.forwardRef<MessageContainerHandle, Message
57
57
setNewCount ( 0 ) ;
58
58
} ;
59
59
60
+ const checkShowBottomRef = useRef (
61
+ throttle ( ( el : HTMLElement ) => {
62
+ if ( isNearBottom ( el ) ) {
63
+ setShowBackBottom ( false ) ;
64
+ setNewCount ( 0 ) ;
65
+ } else {
66
+ setShowBackBottom ( true ) ;
67
+ }
68
+ } ) ,
69
+ ) ;
70
+
71
+ const handleScroll = ( e : React . UIEvent < HTMLDivElement , UIEvent > ) => {
72
+ checkShowBottomRef . current ( e . target ) ;
73
+
74
+ if ( onScroll ) {
75
+ onScroll ( e ) ;
76
+ }
77
+ } ;
78
+
60
79
useEffect ( ( ) => {
61
80
const scroller = scrollerRef . current ;
62
81
const wrapper = scroller && scroller . wrapperRef . current ;
63
82
64
- if ( ! wrapper ) {
83
+ if ( ! wrapper || ! lastMessage ) {
65
84
return ;
66
85
}
67
86
68
87
if ( lastMessage . position === 'right' ) {
69
88
scrollToEnd ( ) ;
70
- } else if ( getToBottom ( wrapper ) < getMaxOffsetHeight ( wrapper ) ) {
89
+ } else if ( isNearBottom ( wrapper ) ) {
71
90
const animated = ! ! wrapper . scrollTop ;
72
91
scrollToEnd ( { animated } ) ;
73
92
} else {
@@ -76,38 +95,6 @@ export const MessageContainer = React.forwardRef<MessageContainerHandle, Message
76
95
}
77
96
} , [ lastMessage , scrollToEnd ] ) ;
78
97
79
- useEffect ( ( ) => {
80
- const scroller = scrollerRef . current ;
81
- const wrapper = scroller && scroller . wrapperRef . current ;
82
-
83
- if ( ! wrapper ) {
84
- return ;
85
- }
86
-
87
- const options = {
88
- root : wrapper ,
89
- rootMargin : `0px 0px ${ getMaxOffsetHeight ( wrapper ) } px 0px` ,
90
- threshold : 1.0 ,
91
- } ;
92
-
93
- const observer = new IntersectionObserver ( ( [ entry ] ) => {
94
- if ( ! isTouching . current ) {
95
- if ( entry . isIntersecting ) {
96
- setShowBackBottom ( false ) ;
97
- setNewCount ( 0 ) ;
98
- } else {
99
- setShowBackBottom ( true ) ;
100
- }
101
- }
102
- } , options ) ;
103
-
104
- observer . observe ( bottomRef . current ! ) ;
105
-
106
- return ( ) => {
107
- observer . disconnect ( ) ;
108
- } ;
109
- } , [ ] ) ;
110
-
111
98
useEffect ( ( ) => {
112
99
const wrapper = messagesRef . current ! ;
113
100
@@ -117,7 +104,6 @@ export const MessageContainer = React.forwardRef<MessageContainerHandle, Message
117
104
function reset ( ) {
118
105
needBlur = false ;
119
106
startY = 0 ;
120
- isTouching . current = false ;
121
107
}
122
108
123
109
function touchStart ( e : TouchEvent ) {
@@ -126,7 +112,6 @@ export const MessageContainer = React.forwardRef<MessageContainerHandle, Message
126
112
needBlur = true ;
127
113
startY = e . touches [ 0 ] . clientY ;
128
114
}
129
- isTouching . current = true ;
130
115
}
131
116
132
117
function touchMove ( e : TouchEvent ) {
@@ -156,7 +141,7 @@ export const MessageContainer = React.forwardRef<MessageContainerHandle, Message
156
141
{ renderBeforeMessageList && renderBeforeMessageList ( ) }
157
142
< PullToRefresh
158
143
onRefresh = { onRefresh }
159
- onScroll = { onScroll }
144
+ onScroll = { handleScroll }
160
145
loadMoreText = { loadMoreText }
161
146
ref = { scrollerRef }
162
147
>
0 commit comments