diff --git a/app/containers/NewMediaCall/NewMediaCall.tsx b/app/containers/NewMediaCall/NewMediaCall.tsx index f19a92d80fb..6d7ba5968ab 100644 --- a/app/containers/NewMediaCall/NewMediaCall.tsx +++ b/app/containers/NewMediaCall/NewMediaCall.tsx @@ -1,5 +1,6 @@ import React, { useEffect } from 'react'; import { StyleSheet, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { PeerList } from './PeerList'; import { SelectedPeer } from './SelectedPeer'; @@ -11,10 +12,11 @@ import { useTheme } from '../../theme'; export const NewMediaCall = (): React.ReactElement => { const { colors } = useTheme(); const reset = usePeerAutocompleteStore(state => state.reset); + const { bottom } = useSafeAreaInsets(); useEffect(() => () => reset(), [reset]); return ( - + diff --git a/app/containers/NewMediaCall/PeerList.test.tsx b/app/containers/NewMediaCall/PeerList.test.tsx index 76ea517fe82..c653c1ecf13 100644 --- a/app/containers/NewMediaCall/PeerList.test.tsx +++ b/app/containers/NewMediaCall/PeerList.test.tsx @@ -67,6 +67,12 @@ describe('PeerList', () => { expect(queryByTestId('new-media-call-option-user-1')).toBeNull(); }); + it('should return null when there are no options', () => { + usePeerAutocompleteStore.setState({ options: [], selectedPeer: null }); + const { toJSON } = render(); + expect(toJSON()).toBeNull(); + }); + it('should set selected peer, clear filter and fetch options when option is pressed', () => { usePeerAutocompleteStore.setState({ options: mockOptions, diff --git a/app/containers/NewMediaCall/PeerList.tsx b/app/containers/NewMediaCall/PeerList.tsx index 9c28dd3ada3..86fe0cbf68a 100644 --- a/app/containers/NewMediaCall/PeerList.tsx +++ b/app/containers/NewMediaCall/PeerList.tsx @@ -10,7 +10,9 @@ export const PeerList = () => { const selectedPeer = usePeerAutocompleteStore(state => state.selectedPeer); const options = usePeerAutocompleteStore(state => state.options); - if (selectedPeer) return null; + if (selectedPeer || options.length === 0) { + return null; + } const handleSelectOption = (option: TPeerItem) => { setSelectedPeer(option); diff --git a/app/lib/hooks/useNewMediaCall/useNewMediaCall.test.tsx b/app/lib/hooks/useNewMediaCall/useNewMediaCall.test.tsx index 6bc46b0ff1a..1fde131abb2 100644 --- a/app/lib/hooks/useNewMediaCall/useNewMediaCall.test.tsx +++ b/app/lib/hooks/useNewMediaCall/useNewMediaCall.test.tsx @@ -44,17 +44,22 @@ jest.mock('../../../containers/NewMediaCall', () => ({ NewMediaCall: jest.fn(() => null) })); +jest.mock('../../methods/helpers/deviceInfo', () => ({ + isAndroid: false +})); + describe('useNewMediaCall', () => { beforeEach(() => { jest.clearAllMocks(); mockUseIsInActiveVoipCall.mockReturnValue(false); }); - const expectNewMediaCallActionSheet = () => { + const expectNewMediaCallActionSheet = (expectedFullContainer = false) => { expect(mockShowActionSheetRef).toHaveBeenCalledTimes(1); const [actionSheetArgs] = mockShowActionSheetRef.mock.calls[0]; expect(React.isValidElement(actionSheetArgs.children)).toBe(true); expect(actionSheetArgs.children.type).toBe(NewMediaCall); + expect(actionSheetArgs.fullContainer).toBe(expectedFullContainer); }; it('should set selected peer and open action sheet when room has a direct message peer', () => { @@ -136,4 +141,29 @@ describe('useNewMediaCall', () => { expect(mockShowActionSheetRef).not.toHaveBeenCalled(); expect(mockSetSelectedPeer).not.toHaveBeenCalled(); }); + + it('should pass fullContainer to the action sheet when isAndroid is true', () => { + jest.resetModules(); + jest.doMock('../../methods/helpers/deviceInfo', () => ({ + isAndroid: true + })); + // Must load hook after doMock so `fullContainer: isAndroid` uses Android. + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { useNewMediaCall: useNewMediaCallAndroid } = require('./useNewMediaCall'); + + mockUseSubscription.mockReturnValue(undefined); + mockUseMediaCallPermission.mockReturnValue(false); + + const { result } = renderHook(() => useNewMediaCallAndroid('room-id')); + + act(() => { + result.current.openNewMediaCall(); + }); + + // Re-required hook uses a fresh NewMediaCall mock ref; only assert fullContainer and element shape. + expect(mockShowActionSheetRef).toHaveBeenCalledTimes(1); + const [actionSheetArgs] = mockShowActionSheetRef.mock.calls[0]; + expect(React.isValidElement(actionSheetArgs.children)).toBe(true); + expect(actionSheetArgs.fullContainer).toBe(true); + }); }); diff --git a/app/lib/hooks/useNewMediaCall/useNewMediaCall.tsx b/app/lib/hooks/useNewMediaCall/useNewMediaCall.tsx index ff1233ddf0d..10f9eaae388 100644 --- a/app/lib/hooks/useNewMediaCall/useNewMediaCall.tsx +++ b/app/lib/hooks/useNewMediaCall/useNewMediaCall.tsx @@ -7,6 +7,7 @@ import { usePeerAutocompleteStore } from '../../services/voip/usePeerAutocomplet import { useIsInActiveVoipCall } from '../../services/voip/isInActiveVoipCall'; import { useSubscription } from '../useSubscription'; import { useMediaCallPermission } from '../useMediaCallPermission'; +import { isAndroid } from '../../methods/helpers/deviceInfo'; export const useNewMediaCall = (rid?: string) => { const room = useSubscription(rid); @@ -23,10 +24,7 @@ export const useNewMediaCall = (rid?: string) => { } showActionSheetRef({ children: , - portraitSnaps: ['60%'], - landscapeSnaps: ['90%'], - enableContentPanningGesture: false, - fullContainer: true + fullContainer: isAndroid }); };