Skip to content

Commit 4428d48

Browse files
authored
Merge pull request #58909 from margelo/@chrispader/fix-offline-indicator-keyboard-offset
fix: Add keyboard offset if offline indicator is visible
2 parents c236250 + 49858c4 commit 4428d48

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

src/components/ScreenWrapper.tsx

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,29 +335,65 @@ function ScreenWrapper(
335335
[enableEdgeToEdgeBottomSafeAreaPadding, edgeToEdgeBottomContentStyle, legacyBottomContentStyle],
336336
);
337337

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+
*/
338345
const mobileOfflineIndicatorBackgroundStyle = useMemo(() => {
339346
const showOfflineIndicatorBackground = !bottomContent && (isSoftKeyNavigation || isOffline);
340347
if (!showOfflineIndicatorBackground) {
341348
return undefined;
342349
}
343350
return isOfflineIndicatorTranslucent ? styles.navigationBarBG : styles.appBG;
344351
}, [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+
*/
345361
const mobileOfflineIndicatorBottomSafeAreaStyle = useBottomSafeSafeAreaPaddingStyle({
346362
addBottomSafeAreaPadding: enableEdgeToEdgeBottomSafeAreaPadding ? true : !includeSafeAreaPaddingBottom,
347363
styleProperty: isSoftKeyNavigation ? 'bottom' : 'paddingBottom',
348364
});
349365

366+
/** If there is no bottom content, the mobile offline indicator will stick to the bottom of the screen by default. */
350367
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+
*/
351374
const mobileOfflineIndicatorContainerStyle = useMemo(
352375
() => [mobileOfflineIndicatorBottomSafeAreaStyle, displayStickyMobileOfflineIndicator && styles.stickToBottom, !isSoftKeyNavigation && mobileOfflineIndicatorBackgroundStyle],
353376
[mobileOfflineIndicatorBottomSafeAreaStyle, displayStickyMobileOfflineIndicator, styles.stickToBottom, isSoftKeyNavigation, mobileOfflineIndicatorBackgroundStyle],
354377
);
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+
*/
355384
const mobileOfflineIndicatorStyle = useMemo(
356385
() => [styles.pl5, isSoftKeyNavigation && mobileOfflineIndicatorBackgroundStyle, offlineIndicatorStyle],
357386
[isSoftKeyNavigation, mobileOfflineIndicatorBackgroundStyle, offlineIndicatorStyle, styles.pl5],
358387
);
359388

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;
361397

362398
const isAvoidingViewportScroll = useTackInputFocus(isFocused && shouldEnableMaxHeight && shouldAvoidScrollOnVirtualViewport && isMobileWebKit());
363399
const contextValue = useMemo(
@@ -384,7 +420,7 @@ function ScreenWrapper(
384420
style={[styles.w100, styles.h100, !isBlurred ? {maxHeight} : undefined, isAvoidingViewportScroll ? [styles.overflowAuto, styles.overscrollBehaviorContain] : {}]}
385421
behavior={keyboardAvoidingViewBehavior}
386422
enabled={shouldEnableKeyboardAvoidingView}
387-
shouldOffsetBottomSafeAreaPadding={shouldKeyboardOffsetBottomSafeAreaPadding}
423+
shouldOffsetBottomSafeAreaPadding={shouldOffsetBottomSafeAreaPadding}
388424
>
389425
<PickerAvoidingView
390426
style={isAvoidingViewportScroll ? [styles.h100, {marginTop: 1}] : styles.flex1}
@@ -403,7 +439,7 @@ function ScreenWrapper(
403439
})
404440
: children
405441
}
406-
{isSmallScreenWidth && shouldShowOfflineIndicator && (
442+
{displayMobileOfflineIndicator && (
407443
<>
408444
{isOffline && (
409445
<View style={[mobileOfflineIndicatorContainerStyle]}>
@@ -414,11 +450,11 @@ function ScreenWrapper(
414450
<ImportedStateIndicator />
415451
</>
416452
)}
417-
{!shouldUseNarrowLayout && shouldShowOfflineIndicatorInWideScreen && (
453+
{displayWidescreenOfflineIndicator && (
418454
<>
419455
<OfflineIndicator
420456
style={[styles.pl5, offlineIndicatorStyle]}
421-
addBottomSafeAreaPadding={addWidescreenOfflineIndicatorBottomSafeAreaPadding}
457+
addBottomSafeAreaPadding={enableEdgeToEdgeBottomSafeAreaPadding ? !bottomContent : true}
422458
/>
423459
{/* Since import state is tightly coupled to the offline state, it is safe to display it when showing offline indicator */}
424460
<ImportedStateIndicator />

0 commit comments

Comments
 (0)