|
1 |
| -import React, { memo, useCallback, useMemo, useRef, useState } from 'react'; |
| 1 | +import React, { memo, useCallback, useMemo, useRef } from 'react'; |
2 | 2 | import PropTypes from 'prop-types';
|
3 | 3 | import { useSelector } from 'react-redux';
|
4 | 4 | import { Container } from '@metamask/snaps-sdk/jsx';
|
@@ -81,66 +81,30 @@ const SnapUIRendererComponent = ({
|
81 | 81 |
|
82 | 82 | const isProgrammaticScrollRef = useRef(false);
|
83 | 83 |
|
84 |
| - const [scrollState, setScrollState] = useState({ |
85 |
| - buttonsEnabled: !requireScroll, |
86 |
| - showArrow: false, |
87 |
| - }); |
88 |
| - |
89 |
| - const handleScrollStateUpdate = useCallback( |
90 |
| - (buttonsAreEnabled, showArrow) => { |
91 |
| - if ( |
92 |
| - buttonsAreEnabled !== scrollState.buttonsEnabled || |
93 |
| - showArrow !== scrollState.showArrow |
94 |
| - ) { |
95 |
| - setScrollState({ |
96 |
| - buttonsEnabled: buttonsAreEnabled, |
97 |
| - showArrow, |
98 |
| - }); |
99 |
| - } |
100 |
| - }, |
101 |
| - [scrollState], |
102 |
| - ); |
103 |
| - |
104 |
| - const { scrollToBottom, ref } = useScrollRequired([], { |
| 84 | + const { |
| 85 | + scrollToBottom, |
| 86 | + ref, |
| 87 | + isScrolledToBottom, |
| 88 | + hasScrolledToBottom, |
| 89 | + isScrollable, |
| 90 | + onScroll, |
| 91 | + } = useScrollRequired([], { |
105 | 92 | // Only enable the hook if we need to handle scroll events
|
106 | 93 | enabled: requireScroll,
|
107 |
| - // This lets us batch state updates and avoid an unnecessary render |
108 |
| - onMeasure: ({ isScrollable: canScroll, hasMeasured }) => { |
109 |
| - if (!requireScroll || !hasMeasured) { |
110 |
| - return; |
111 |
| - } |
112 |
| - |
113 |
| - handleScrollStateUpdate(!canScroll, canScroll); |
114 |
| - }, |
115 | 94 | });
|
116 | 95 |
|
117 |
| - const buttonsEnabled = useMemo( |
118 |
| - () => (requireScroll ? scrollState.buttonsEnabled : true), |
119 |
| - [requireScroll, scrollState.buttonsEnabled], |
120 |
| - ); |
| 96 | + const shouldShowArrow = useMemo(() => { |
| 97 | + if (!requireScroll || isScrolledToBottom || hasScrolledToBottom) { |
| 98 | + return false; |
| 99 | + } else if (!isScrolledToBottom && !hasScrolledToBottom && isScrollable) { |
| 100 | + return true; |
| 101 | + } |
| 102 | + return false; |
| 103 | + }, [requireScroll, isScrolledToBottom, hasScrolledToBottom, isScrollable]); |
121 | 104 |
|
122 |
| - const handleScroll = useCallback( |
123 |
| - (e) => { |
124 |
| - if (!requireScroll) { |
125 |
| - return; |
126 |
| - } |
127 |
| - |
128 |
| - const isAtBottom = |
129 |
| - Math.abs( |
130 |
| - e.target.scrollTop + e.target.clientHeight - e.target.scrollHeight, |
131 |
| - ) < 2; |
132 |
| - |
133 |
| - handleScrollStateUpdate( |
134 |
| - scrollState.buttonsEnabled || isAtBottom, |
135 |
| - !isAtBottom && scrollState.showArrow, |
136 |
| - ); |
137 |
| - }, |
138 |
| - [ |
139 |
| - requireScroll, |
140 |
| - scrollState.buttonsEnabled, |
141 |
| - handleScrollStateUpdate, |
142 |
| - scrollState.showArrow, |
143 |
| - ], |
| 105 | + const buttonsEnabled = useMemo( |
| 106 | + () => (requireScroll ? !shouldShowArrow : true), |
| 107 | + [requireScroll, shouldShowArrow], |
144 | 108 | );
|
145 | 109 |
|
146 | 110 | const handleScrollToBottom = useCallback(() => {
|
@@ -200,15 +164,15 @@ const SnapUIRendererComponent = ({
|
200 | 164 | initialState={initialState}
|
201 | 165 | context={context}
|
202 | 166 | requireScroll={requireScroll}
|
203 |
| - showArrow={scrollState.showArrow} |
| 167 | + showArrow={shouldShowArrow} |
204 | 168 | buttonsEnabled={buttonsEnabled}
|
205 | 169 | scrollToBottom={handleScrollToBottom}
|
206 | 170 | >
|
207 | 171 | <Box
|
208 | 172 | className="snap-ui-renderer__content"
|
209 | 173 | data-testid="snap-ui-renderer__content"
|
210 | 174 | ref={ref}
|
211 |
| - onScroll={handleScroll} |
| 175 | + onScroll={onScroll} |
212 | 176 | height={BlockSize.Full}
|
213 | 177 | backgroundColor={backgroundColor}
|
214 | 178 | style={{
|
|
0 commit comments