@@ -335,29 +335,65 @@ function ScreenWrapper(
335
335
[ enableEdgeToEdgeBottomSafeAreaPadding , edgeToEdgeBottomContentStyle , legacyBottomContentStyle ] ,
336
336
) ;
337
337
338
+ /**
339
+ * This style applies the background color of the mobile offline indicator.
340
+ * When there is not bottom content, and the device either has soft keys or is offline,
341
+ * the background style is applied.
342
+ * By default, the background color of the mobile offline indicator is translucent.
343
+ * If `isOfflineIndicatorTranslucent` is set to true, an opaque background color is applied.
344
+ */
338
345
const mobileOfflineIndicatorBackgroundStyle = useMemo ( ( ) => {
339
346
const showOfflineIndicatorBackground = ! bottomContent && ( isSoftKeyNavigation || isOffline ) ;
340
347
if ( ! showOfflineIndicatorBackground ) {
341
348
return undefined ;
342
349
}
343
350
return isOfflineIndicatorTranslucent ? styles . navigationBarBG : styles . appBG ;
344
351
} , [ bottomContent , isOffline , isOfflineIndicatorTranslucent , isSoftKeyNavigation , styles . appBG , styles . navigationBarBG ] ) ;
352
+
353
+ /**
354
+ * This style includes the bottom safe area padding for the mobile offline indicator.
355
+ * If the device has soft keys, the mobile offline indicator will stick to the navigation bar (bottom of the screen)
356
+ * The mobile offline indicator container will have a translucent background. Therefore, we want to offset it
357
+ * by the bottom safe area padding rather than adding padding to the container, so that there are not
358
+ * two overlapping layers of translucent background.
359
+ * If the device does not have soft keys, the bottom safe area padding is applied as `paddingBottom`.
360
+ */
345
361
const mobileOfflineIndicatorBottomSafeAreaStyle = useBottomSafeSafeAreaPaddingStyle ( {
346
362
addBottomSafeAreaPadding : enableEdgeToEdgeBottomSafeAreaPadding ? true : ! includeSafeAreaPaddingBottom ,
347
363
styleProperty : isSoftKeyNavigation ? 'bottom' : 'paddingBottom' ,
348
364
} ) ;
349
365
366
+ /** If there is no bottom content, the mobile offline indicator will stick to the bottom of the screen by default. */
350
367
const displayStickyMobileOfflineIndicator = shouldMobileOfflineIndicatorStickToBottom && ! bottomContent ;
368
+
369
+ /**
370
+ * This style includes all styles applied to the container of the mobile offline indicator.
371
+ * It always applies the bottom safe area padding as well as the background style, if the device has soft keys.
372
+ * In this case, we want the whole container (including the bottom safe area padding) to have translucent/opaque background.
373
+ */
351
374
const mobileOfflineIndicatorContainerStyle = useMemo (
352
375
( ) => [ mobileOfflineIndicatorBottomSafeAreaStyle , displayStickyMobileOfflineIndicator && styles . stickToBottom , ! isSoftKeyNavigation && mobileOfflineIndicatorBackgroundStyle ] ,
353
376
[ mobileOfflineIndicatorBottomSafeAreaStyle , displayStickyMobileOfflineIndicator , styles . stickToBottom , isSoftKeyNavigation , mobileOfflineIndicatorBackgroundStyle ] ,
354
377
) ;
378
+
379
+ /**
380
+ * This style includes the styles applied to the mobile offline indicator component.
381
+ * If the device has soft keys, we only want to apply the background style to the mobile offline indicator component,
382
+ * rather than the whole container, because otherwise the navigation bar would be extra opaque, since it already has a translucent background.
383
+ */
355
384
const mobileOfflineIndicatorStyle = useMemo (
356
385
( ) => [ styles . pl5 , isSoftKeyNavigation && mobileOfflineIndicatorBackgroundStyle , offlineIndicatorStyle ] ,
357
386
[ isSoftKeyNavigation , mobileOfflineIndicatorBackgroundStyle , offlineIndicatorStyle , styles . pl5 ] ,
358
387
) ;
359
388
360
- const addWidescreenOfflineIndicatorBottomSafeAreaPadding = enableEdgeToEdgeBottomSafeAreaPadding ? ! bottomContent : true ;
389
+ const displayMobileOfflineIndicator = isSmallScreenWidth && shouldShowOfflineIndicator ;
390
+ const displayWidescreenOfflineIndicator = ! shouldUseNarrowLayout && shouldShowOfflineIndicatorInWideScreen ;
391
+
392
+ /** If we currently show the offline indicator and it sticks to the bottom, we need to offset the bottom safe area padding in the KeyboardAvoidingView. */
393
+ const shouldOffsetMobileOfflineIndicator = displayMobileOfflineIndicator && displayStickyMobileOfflineIndicator && isOffline ;
394
+
395
+ /** Whether the mobile offline indicator or the content in general should be offset by the bottom safe area padding. */
396
+ const shouldOffsetBottomSafeAreaPadding = shouldKeyboardOffsetBottomSafeAreaPadding || shouldOffsetMobileOfflineIndicator ;
361
397
362
398
const isAvoidingViewportScroll = useTackInputFocus ( isFocused && shouldEnableMaxHeight && shouldAvoidScrollOnVirtualViewport && isMobileWebKit ( ) ) ;
363
399
const contextValue = useMemo (
@@ -384,7 +420,7 @@ function ScreenWrapper(
384
420
style = { [ styles . w100 , styles . h100 , ! isBlurred ? { maxHeight} : undefined , isAvoidingViewportScroll ? [ styles . overflowAuto , styles . overscrollBehaviorContain ] : { } ] }
385
421
behavior = { keyboardAvoidingViewBehavior }
386
422
enabled = { shouldEnableKeyboardAvoidingView }
387
- shouldOffsetBottomSafeAreaPadding = { shouldKeyboardOffsetBottomSafeAreaPadding }
423
+ shouldOffsetBottomSafeAreaPadding = { shouldOffsetBottomSafeAreaPadding }
388
424
>
389
425
< PickerAvoidingView
390
426
style = { isAvoidingViewportScroll ? [ styles . h100 , { marginTop : 1 } ] : styles . flex1 }
@@ -403,7 +439,7 @@ function ScreenWrapper(
403
439
} )
404
440
: children
405
441
}
406
- { isSmallScreenWidth && shouldShowOfflineIndicator && (
442
+ { displayMobileOfflineIndicator && (
407
443
< >
408
444
{ isOffline && (
409
445
< View style = { [ mobileOfflineIndicatorContainerStyle ] } >
@@ -414,11 +450,11 @@ function ScreenWrapper(
414
450
< ImportedStateIndicator />
415
451
</ >
416
452
) }
417
- { ! shouldUseNarrowLayout && shouldShowOfflineIndicatorInWideScreen && (
453
+ { displayWidescreenOfflineIndicator && (
418
454
< >
419
455
< OfflineIndicator
420
456
style = { [ styles . pl5 , offlineIndicatorStyle ] }
421
- addBottomSafeAreaPadding = { addWidescreenOfflineIndicatorBottomSafeAreaPadding }
457
+ addBottomSafeAreaPadding = { enableEdgeToEdgeBottomSafeAreaPadding ? ! bottomContent : true }
422
458
/>
423
459
{ /* Since import state is tightly coupled to the offline state, it is safe to display it when showing offline indicator */ }
424
460
< ImportedStateIndicator />
0 commit comments