@@ -120,7 +120,7 @@ export function SceneWrapper(props: SceneWrapperProps): JSX.Element {
120
120
const activeUsername = useSelector ( state => state . core . account . username )
121
121
const isLightAccount = accountId != null && activeUsername == null
122
122
123
- const { footerHeight = 0 } = useSceneFooterState ( )
123
+ const footerHeight = useSceneFooterState ( ( { footerHeight = 0 } ) => footerHeight )
124
124
125
125
const navigation = useNavigation < NavigationBase > ( )
126
126
const theme = useTheme ( )
@@ -138,88 +138,117 @@ export function SceneWrapper(props: SceneWrapperProps): JSX.Element {
138
138
[ frame . height , frame . width ]
139
139
)
140
140
141
- const notificationHeight = theme . rem ( 4 )
142
- const headerBarHeight = getDefaultHeaderHeight ( frame , false , 0 )
143
-
144
141
// If the scene has scroll, this will be required for tabs and/or header animation
145
142
const handleScroll = useSceneScrollHandler ( scroll && ( hasTabs || hasHeader ) )
146
143
147
- const { renderFooter } = useSceneFooterRenderState ( )
148
-
149
- const renderScene = ( keyboardAnimation : Animated . Value | undefined , trackerValue : number ) : JSX . Element => {
150
- // If function children, the caller handles the insets and overscroll
151
- const isFuncChildren = typeof children === 'function'
152
-
153
- // Derive the keyboard height by getting the difference between screen height
154
- // and trackerValue. This value should be from zero to keyboard height
155
- // depending on the open state of the keyboard
156
- const keyboardHeight = frame . height - trackerValue
157
- const isKeyboardOpen = avoidKeyboard && keyboardHeight !== 0
158
-
159
- // Calculate app insets considering the app's header, tab-bar,
160
- // notification area, etc:
161
- const maybeHeaderHeight = hasHeader ? headerBarHeight : 0
162
- const maybeNotificationHeight = isLightAccount ? notificationHeight : 0
163
- const maybeTabBarHeight = hasTabs ? MAX_TAB_BAR_HEIGHT : 0
164
- const maybeInsetBottom = ! hasTabs && ! isKeyboardOpen ? safeAreaInsets . bottom : 0
165
- const insets : EdgeInsets = {
166
- top : safeAreaInsets . top + maybeHeaderHeight ,
167
- right : safeAreaInsets . right ,
168
- bottom : maybeInsetBottom + maybeNotificationHeight + maybeTabBarHeight + footerHeight ,
169
- left : safeAreaInsets . left
170
- }
171
-
172
- // This is a convenient styles object which may be applied as
173
- // contentContainerStyles for child scroll components. It will also be
174
- // used for the ScrollView component internal to the SceneWrapper.
175
- const insetStyle : InsetStyle = {
176
- paddingTop : insets . top ,
177
- paddingRight : insets . right ,
178
- paddingBottom : insets . bottom ,
179
- paddingLeft : insets . left
180
- }
181
-
182
- // This is a convenient styles object which may be applied to scene container
183
- // components to offset the inset styles applied to the SceneWrapper.
184
- const undoInsetStyle : UndoInsetStyle = {
185
- flex : 1 ,
186
- marginTop : - insets . top ,
187
- marginRight : - insets . right ,
188
- marginBottom : - insets . bottom ,
189
- marginLeft : - insets . left
190
- }
191
-
192
- const info : SceneWrapperInfo = { insets, insetStyle, undoInsetStyle, hasTabs, isKeyboardOpen }
193
-
194
- return (
195
- < >
196
- < MaybeAnimatedView when = { avoidKeyboard } style = { [ styles . sceneContainer , layoutStyle , insetStyle , { maxHeight : keyboardAnimation , padding } ] } >
197
- < DotsBackground
198
- accentColors = { accentColors }
199
- overrideDots = { overrideDots }
200
- backgroundGradientColors = { backgroundGradientColors }
201
- backgroundGradientStart = { backgroundGradientStart }
202
- backgroundGradientEnd = { backgroundGradientEnd }
203
- />
204
- < MaybeAnimatedScrollView
205
- when = { scroll && ! avoidKeyboard }
206
- style = { [ layoutStyle , { padding } ] }
207
- keyboardShouldPersistTaps = { keyboardShouldPersistTaps }
208
- contentContainerStyle = { insetStyle }
209
- onScroll = { hasTabs || hasHeader ? handleScroll : ( ) => { } }
210
- // Fixes middle-floating scrollbar issue
211
- scrollIndicatorInsets = { { right : 1 } }
212
- >
213
- < MaybeView when = { ! scroll && ! avoidKeyboard } style = { [ styles . sceneContainer , layoutStyle , insetStyle , { padding } ] } >
214
- { isFuncChildren ? children ( info ) : children }
215
- </ MaybeView >
216
- </ MaybeAnimatedScrollView >
217
- { renderFooter != null && ! hasTabs ? < SceneFooter > { renderFooter ( info ) } </ SceneFooter > : null }
218
- </ MaybeAnimatedView >
219
- { hasNotifications ? < NotificationView hasTabs = { hasTabs } navigation = { navigation } /> : null }
220
- </ >
221
- )
222
- }
144
+ const renderFooter = useSceneFooterRenderState ( ( { renderFooter } ) => renderFooter )
145
+
146
+ const renderScene = React . useCallback (
147
+ ( keyboardAnimation : Animated . Value | undefined , trackerValue : number ) : JSX . Element => {
148
+ const notificationHeight = theme . rem ( 4 )
149
+ const headerBarHeight = getDefaultHeaderHeight ( frame , false , 0 )
150
+
151
+ // If function children, the caller handles the insets and overscroll
152
+ const isFuncChildren = typeof children === 'function'
153
+
154
+ // Derive the keyboard height by getting the difference between screen height
155
+ // and trackerValue. This value should be from zero to keyboard height
156
+ // depending on the open state of the keyboard
157
+ const keyboardHeight = frame . height - trackerValue
158
+ const isKeyboardOpen = avoidKeyboard && keyboardHeight !== 0
159
+
160
+ // Calculate app insets considering the app's header, tab-bar,
161
+ // notification area, etc:
162
+ const maybeHeaderHeight = hasHeader ? headerBarHeight : 0
163
+ const maybeNotificationHeight = isLightAccount ? notificationHeight : 0
164
+ const maybeTabBarHeight = hasTabs ? MAX_TAB_BAR_HEIGHT : 0
165
+ const maybeInsetBottom = ! hasTabs && ! isKeyboardOpen ? safeAreaInsets . bottom : 0
166
+ const insets : EdgeInsets = {
167
+ top : safeAreaInsets . top + maybeHeaderHeight ,
168
+ right : safeAreaInsets . right ,
169
+ bottom : maybeInsetBottom + maybeNotificationHeight + maybeTabBarHeight + footerHeight ,
170
+ left : safeAreaInsets . left
171
+ }
172
+
173
+ // This is a convenient styles object which may be applied as
174
+ // contentContainerStyles for child scroll components. It will also be
175
+ // used for the ScrollView component internal to the SceneWrapper.
176
+ const insetStyle : InsetStyle = {
177
+ paddingTop : insets . top ,
178
+ paddingRight : insets . right ,
179
+ paddingBottom : insets . bottom ,
180
+ paddingLeft : insets . left
181
+ }
182
+
183
+ // This is a convenient styles object which may be applied to scene container
184
+ // components to offset the inset styles applied to the SceneWrapper.
185
+ const undoInsetStyle : UndoInsetStyle = {
186
+ flex : 1 ,
187
+ marginTop : - insets . top ,
188
+ marginRight : - insets . right ,
189
+ marginBottom : - insets . bottom ,
190
+ marginLeft : - insets . left
191
+ }
192
+
193
+ const info : SceneWrapperInfo = { insets, insetStyle, undoInsetStyle, hasTabs, isKeyboardOpen }
194
+
195
+ return (
196
+ < >
197
+ < MaybeAnimatedView when = { avoidKeyboard } style = { [ styles . sceneContainer , layoutStyle , insetStyle , { maxHeight : keyboardAnimation , padding } ] } >
198
+ < DotsBackground
199
+ accentColors = { accentColors }
200
+ overrideDots = { overrideDots }
201
+ backgroundGradientColors = { backgroundGradientColors }
202
+ backgroundGradientStart = { backgroundGradientStart }
203
+ backgroundGradientEnd = { backgroundGradientEnd }
204
+ />
205
+ < MaybeAnimatedScrollView
206
+ when = { scroll && ! avoidKeyboard }
207
+ style = { [ layoutStyle , { padding } ] }
208
+ keyboardShouldPersistTaps = { keyboardShouldPersistTaps }
209
+ contentContainerStyle = { insetStyle }
210
+ onScroll = { hasTabs || hasHeader ? handleScroll : ( ) => { } }
211
+ // Fixes middle-floating scrollbar issue
212
+ scrollIndicatorInsets = { { right : 1 } }
213
+ >
214
+ < MaybeView when = { ! scroll && ! avoidKeyboard } style = { [ styles . sceneContainer , layoutStyle , insetStyle , { padding } ] } >
215
+ { isFuncChildren ? children ( info ) : children }
216
+ </ MaybeView >
217
+ </ MaybeAnimatedScrollView >
218
+ { renderFooter != null && ! hasTabs ? < SceneFooter > { renderFooter ( info ) } </ SceneFooter > : null }
219
+ </ MaybeAnimatedView >
220
+ { hasNotifications ? < NotificationView hasTabs = { hasTabs } navigation = { navigation } /> : null }
221
+ </ >
222
+ )
223
+ } ,
224
+ [
225
+ accentColors ,
226
+ avoidKeyboard ,
227
+ backgroundGradientColors ,
228
+ backgroundGradientEnd ,
229
+ backgroundGradientStart ,
230
+ children ,
231
+ footerHeight ,
232
+ frame ,
233
+ handleScroll ,
234
+ hasHeader ,
235
+ hasNotifications ,
236
+ hasTabs ,
237
+ isLightAccount ,
238
+ keyboardShouldPersistTaps ,
239
+ layoutStyle ,
240
+ navigation ,
241
+ overrideDots ,
242
+ padding ,
243
+ renderFooter ,
244
+ safeAreaInsets . bottom ,
245
+ safeAreaInsets . left ,
246
+ safeAreaInsets . right ,
247
+ safeAreaInsets . top ,
248
+ scroll ,
249
+ theme
250
+ ]
251
+ )
223
252
224
253
// These represent the distance from the top of the screen to the top of
225
254
// the keyboard depending if the keyboard is down or up.
0 commit comments