Skip to content

Commit d72affc

Browse files
committed
Fix Contact list modal broken in landscape mode
1 parent 908172c commit d72affc

4 files changed

Lines changed: 39 additions & 19 deletions

File tree

src/components/EmojiPicker/EmojiPickerMenu/useEmojiPickerMenu.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import useKeyboardState from '@hooks/useKeyboardState';
44
import useLocalize from '@hooks/useLocalize';
55
import useOnyx from '@hooks/useOnyx';
66
import usePreferredEmojiSkinTone from '@hooks/usePreferredEmojiSkinTone';
7+
import useSafeAreaInsets from '@hooks/useSafeAreaInsets';
78
import useStyleUtils from '@hooks/useStyleUtils';
89
import useWindowDimensions from '@hooks/useWindowDimensions';
910

1011
import type {EmojiPickerList, EmojiPickerListItem} from '@libs/EmojiUtils';
1112
import {getHeaderEmojis, getSpacersIndexes, mergeEmojisWithFrequentlyUsedEmojis, processFrequentlyUsedEmojis, suggestEmojis} from '@libs/EmojiUtils';
1213
import isInLandscapeModeUtil from '@libs/isInLandscapeMode';
1314

14-
import CONST from '@src/CONST';
1515
import ONYXKEYS from '@src/ONYXKEYS';
16+
import calculateModalHeightInLandscapeMode from '@src/utils/calculateModalHeightInLandscapeMode';
1617

1718
import type {FlashListRef} from '@shopify/flash-list';
1819

@@ -33,8 +34,9 @@ const useEmojiPickerMenu = () => {
3334
const [preferredSkinTone] = usePreferredEmojiSkinTone();
3435
const {windowHeight, windowWidth} = useWindowDimensions();
3536
const StyleUtils = useStyleUtils();
36-
const {keyboardHeight} = useKeyboardState();
37+
const {keyboardActiveHeight} = useKeyboardState();
3738
const isInLandscapeMode = isInLandscapeModeUtil(windowWidth, windowHeight);
39+
const {top: topSafeAreaInset} = useSafeAreaInsets();
3840

3941
/**
4042
* The EmojiPicker sets the `innerContainerStyle` with `maxHeight: '95%'` in `styles.popoverInnerContainer`
@@ -44,7 +46,7 @@ const useEmojiPickerMenu = () => {
4446
*/
4547
const listStyle = StyleUtils.getEmojiPickerListHeight(
4648
isListFiltered,
47-
windowHeight * (isInLandscapeMode ? CONST.MODAL_MAX_HEIGHT_TO_WINDOW_HEIGHT_RATIO_LANDSCAPE_MODE : 0.95) - keyboardHeight,
49+
isInLandscapeMode ? calculateModalHeightInLandscapeMode(windowHeight, topSafeAreaInset, keyboardActiveHeight) : (windowHeight - topSafeAreaInset) * 0.95 - keyboardActiveHeight,
4850
);
4951

5052
useEffect(() => {

src/hooks/useReportSubmitToPopover.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import CONST from '@src/CONST';
99
import ONYXKEYS from '@src/ONYXKEYS';
1010
import {personalDetailsLoginSelector} from '@src/selectors/PersonalDetails';
1111
import type AnchorAlignment from '@src/types/utils/AnchorAlignment';
12+
import calculateModalHeightInLandscapeMode from '@src/utils/calculateModalHeightInLandscapeMode';
1213

1314
import type {RefObject} from 'react';
1415

@@ -17,10 +18,12 @@ import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
1718
import {View} from 'react-native';
1819

1920
import useIsInLandscapeMode from './useIsInLandscapeMode';
21+
import useKeyboardState from './useKeyboardState';
2022
import useOnyx from './useOnyx';
2123
import usePopoverPosition from './usePopoverPosition';
2224
import usePrevious from './usePrevious';
2325
import useResponsiveLayout from './useResponsiveLayout';
26+
import useSafeAreaInsets from './useSafeAreaInsets';
2427
import useStyleUtils from './useStyleUtils';
2528
import useThemeStyles from './useThemeStyles';
2629
import useViewportOffsetTop from './useViewportOffsetTop';
@@ -60,15 +63,18 @@ function useReportSubmitToPopover({reportID, onSubmitSuccess, anchorAlignment =
6063
// Bottom-docked Modal path only; aligns with Popover path that omits modal shell padding chrome
6164
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
6265
const {isSmallScreenWidth} = useResponsiveLayout();
63-
const isBottomDockedInLandscape = isSmallScreenWidth && isInLandscapeMode;
66+
const {keyboardActiveHeight} = useKeyboardState();
67+
const {top: topSafeAreaInset} = useSafeAreaInsets();
6468

6569
const submitToPopoverContentHeight = useMemo(() => {
66-
if (!isBottomDockedInLandscape) {
70+
if (!isInLandscapeMode) {
6771
return popoverDimensions.height;
6872
}
6973

70-
return Math.min(popoverDimensions.height, windowHeight * CONST.MODAL_MAX_HEIGHT_TO_WINDOW_HEIGHT_RATIO_LANDSCAPE_MODE);
71-
}, [isBottomDockedInLandscape, windowHeight]);
74+
const contentHeightLandscapeMode = calculateModalHeightInLandscapeMode(windowHeight, topSafeAreaInset, keyboardActiveHeight);
75+
76+
return Math.min(popoverDimensions.height, contentHeightLandscapeMode);
77+
}, [isInLandscapeMode, windowHeight, keyboardActiveHeight, topSafeAreaInset]);
7278
const anchorRef = useRef<View>(null);
7379
const oneShotOnSubmitSuccessRef = useRef<(() => void) | undefined>(undefined);
7480
const onSubmitWithManagerEmailRef = useRef<ReportSubmitToPopoverOpenOptions['onSubmitWithManagerEmail']>(undefined);
@@ -227,9 +233,9 @@ function useReportSubmitToPopover({reportID, onSubmitSuccess, anchorAlignment =
227233
const innerContainerStyle = useMemo(
228234
() => ({
229235
...popoverContainerStyle,
230-
...(isBottomDockedInLandscape ? styles.getPopoverMaxHeight(windowHeight, true) : {minHeight: popoverDimensions.minHeight}),
236+
...(isInLandscapeMode ? styles.getPopoverMaxHeight(windowHeight, true) : {minHeight: popoverDimensions.minHeight}),
231237
}),
232-
[popoverContainerStyle, isBottomDockedInLandscape, windowHeight, styles],
238+
[popoverContainerStyle, isInLandscapeMode, windowHeight, styles],
233239
);
234240

235241
const reportSubmitToPopover = useMemo(() => {
@@ -259,7 +265,7 @@ function useReportSubmitToPopover({reportID, onSubmitSuccess, anchorAlignment =
259265
>
260266
<View
261267
collapsable={false}
262-
style={[StyleUtils.getHeight(submitToPopoverContentHeight), styles.flexColumn, styles.flex1, styles.w100, styles.pt4]}
268+
style={[StyleUtils.getHeight(submitToPopoverContentHeight), styles.flexColumn, styles.w100, styles.pt4]}
263269
>
264270
<ReportSubmitToContent
265271
key={submitToContentKey}
@@ -278,7 +284,6 @@ function useReportSubmitToPopover({reportID, onSubmitSuccess, anchorAlignment =
278284
}, [
279285
StyleUtils,
280286
styles.flexColumn,
281-
styles.flex1,
282287
styles.pt4,
283288
styles.w100,
284289
innerContainerStyle,

src/pages/ReportSubmitToContent.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import Text from '@components/Text';
99
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
1010
import useDebouncedState from '@hooks/useDebouncedState';
1111
import useIsInLandscapeMode from '@hooks/useIsInLandscapeMode';
12+
import useKeyboardState from '@hooks/useKeyboardState';
1213
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
1314
import useLocalize from '@hooks/useLocalize';
1415
import useNetwork from '@hooks/useNetwork';
1516
import useOnyx from '@hooks/useOnyx';
1617
import usePermissions from '@hooks/usePermissions';
17-
import useResponsiveLayout from '@hooks/useResponsiveLayout';
1818
import useSearchShouldCalculateTotals from '@hooks/useSearchShouldCalculateTotals';
1919
import useStyleUtils from '@hooks/useStyleUtils';
2020
import useThemeStyles from '@hooks/useThemeStyles';
@@ -79,10 +79,9 @@ function ReportSubmitToContent({
7979
const styles = useThemeStyles();
8080
const StyleUtils = useStyleUtils();
8181
const {translate, localeCompare} = useLocalize();
82-
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
83-
const {isSmallScreenWidth} = useResponsiveLayout();
8482
const isInLandscapeMode = useIsInLandscapeMode();
85-
const isBottomDockedInLandscape = isSmallScreenWidth && isInLandscapeMode;
83+
const {keyboardActiveHeight} = useKeyboardState();
84+
8685
const currentUserDetails = useCurrentUserPersonalDetails();
8786
const {isBetaEnabled} = usePermissions();
8887
const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS);
@@ -404,22 +403,22 @@ function ReportSubmitToContent({
404403

405404
const confirmButtonOptions = useMemo(
406405
() => ({
407-
showButton: true,
406+
showButton: !keyboardActiveHeight || !isInLandscapeMode,
408407
text: translate('common.confirm'),
409408
onConfirm: handleSubmit,
410409
confirmButtonSize: 'medium' as const,
411410
}),
412-
[handleSubmit, translate],
411+
[handleSubmit, translate, keyboardActiveHeight, isInLandscapeMode],
413412
);
414413

415414
const containerStyle = useMemo(() => {
416415
const baseStyle = [styles.w100, styles.flex1, styles.pt3, styles.pb3];
417-
if (isBottomDockedInLandscape) {
416+
if (isInLandscapeMode) {
418417
return baseStyle;
419418
}
420419

421420
return [...baseStyle, StyleUtils.getMinimumHeight(CONST.POPOVER_REPORT_SUBMIT_TO_CONTENT_HEIGHT)];
422-
}, [StyleUtils, isBottomDockedInLandscape, styles.flex1, styles.pb3, styles.pt3, styles.w100]);
421+
}, [StyleUtils, isInLandscapeMode, styles.flex1, styles.pb3, styles.pt3, styles.w100]);
423422

424423
if (shouldShowNotFoundView) {
425424
return (
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import CONST from '@src/CONST';
2+
3+
// Calculates the height of a modal in landscape mode based on the window height and keyboard state.
4+
function calculateModalHeightInLandscapeMode(windowHeight: number, topSafeAreaInset: number, keyboardActiveHeight: number) {
5+
const availableWindowHeight = windowHeight - topSafeAreaInset;
6+
7+
if (keyboardActiveHeight > 0) {
8+
return availableWindowHeight - keyboardActiveHeight;
9+
}
10+
11+
return windowHeight * CONST.MODAL_MAX_HEIGHT_TO_WINDOW_HEIGHT_RATIO_LANDSCAPE_MODE;
12+
}
13+
14+
export default calculateModalHeightInLandscapeMode;

0 commit comments

Comments
 (0)