(cherry picked from commit b966e1f356)
Co-authored-by: Daniel Espino García <larkox@gmail.com>
This commit is contained in:
parent
fc06c0e189
commit
272895d37f
5 changed files with 100 additions and 36 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import BottomSheetM, {BottomSheetBackdrop, type BottomSheetBackdropProps, type BottomSheetFooterProps} from '@gorhom/bottom-sheet';
|
||||
import BottomSheetM, {BottomSheetBackdrop, type BottomSheetBackdropProps} from '@gorhom/bottom-sheet';
|
||||
import React, {type ReactNode, useCallback, useEffect, useMemo, useRef} from 'react';
|
||||
import {DeviceEventEmitter, type Handle, InteractionManager, Keyboard, type StyleProp, View, type ViewStyle} from 'react-native';
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ type Props = {
|
|||
componentId: AvailableScreens;
|
||||
contentStyle?: StyleProp<ViewStyle>;
|
||||
initialSnapIndex?: number;
|
||||
footerComponent?: React.FC<BottomSheetFooterProps>;
|
||||
footerComponent?: React.FC<unknown>;
|
||||
renderContent: () => ReactNode;
|
||||
snapPoints?: Array<string | number>;
|
||||
testID?: string;
|
||||
|
|
@ -188,10 +188,12 @@ const BottomSheet = ({
|
|||
);
|
||||
|
||||
if (isTablet) {
|
||||
const FooterComponent = footerComponent;
|
||||
return (
|
||||
<>
|
||||
<View style={styles.separator}/>
|
||||
{renderContainerContent()}
|
||||
{FooterComponent && (<FooterComponent/>)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import React, {useCallback} from 'react';
|
|||
import {DeviceEventEmitter, StyleSheet} from 'react-native';
|
||||
|
||||
import {Events} from '@constants';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import BottomSheet from '@screens/bottom_sheet';
|
||||
|
||||
import Picker from './picker';
|
||||
|
|
@ -25,6 +26,8 @@ const style = StyleSheet.create({
|
|||
});
|
||||
|
||||
const EmojiPickerScreen = ({closeButtonId, componentId, onEmojiPress}: Props) => {
|
||||
const isTablet = useIsTablet();
|
||||
|
||||
const handleEmojiPress = useCallback((emoji: string) => {
|
||||
onEmojiPress(emoji);
|
||||
DeviceEventEmitter.emit(Events.CLOSE_BOTTOM_SHEET);
|
||||
|
|
@ -46,7 +49,7 @@ const EmojiPickerScreen = ({closeButtonId, componentId, onEmojiPress}: Props) =>
|
|||
componentId={componentId}
|
||||
contentStyle={style.contentStyle}
|
||||
initialSnapIndex={1}
|
||||
footerComponent={PickerFooter}
|
||||
footerComponent={isTablet ? undefined : PickerFooter}
|
||||
testID='post_options'
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -61,34 +61,41 @@ const PostPriorityPickerFooter = ({onCancel, onSubmit, ...props}: Props) => {
|
|||
const style = getStyleSheet(theme);
|
||||
const isTablet = useIsTablet();
|
||||
|
||||
const footer = (
|
||||
<View
|
||||
style={[style.container, {
|
||||
paddingBottom: FOOTER_PADDING + Platform.select({ios: (isTablet ? FOOTER_PADDING_BOTTOM_TABLET_ADJUST : 0), default: 0}),
|
||||
}]}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={onCancel}
|
||||
style={style.cancelButton}
|
||||
>
|
||||
<FormattedText
|
||||
id='post_priority.picker.cancel'
|
||||
defaultMessage='Cancel'
|
||||
style={style.cancelButtonText}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={onSubmit}
|
||||
style={style.applyButton}
|
||||
>
|
||||
<FormattedText
|
||||
id='post_priority.picker.apply'
|
||||
defaultMessage='Apply'
|
||||
style={style.applyButtonText}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
if (isTablet) {
|
||||
return footer;
|
||||
}
|
||||
return (
|
||||
<BottomSheetFooter {...props}>
|
||||
<View
|
||||
style={[style.container, {
|
||||
paddingBottom: FOOTER_PADDING + Platform.select({ios: (isTablet ? FOOTER_PADDING_BOTTOM_TABLET_ADJUST : 0), default: 0}),
|
||||
}]}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={onCancel}
|
||||
style={style.cancelButton}
|
||||
>
|
||||
<FormattedText
|
||||
id='post_priority.picker.cancel'
|
||||
defaultMessage='Cancel'
|
||||
style={style.cancelButtonText}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={onSubmit}
|
||||
style={style.applyButton}
|
||||
>
|
||||
<FormattedText
|
||||
id='post_priority.picker.apply'
|
||||
defaultMessage='Apply'
|
||||
style={style.applyButtonText}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{footer}
|
||||
</BottomSheetFooter>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {screen} from '@testing-library/react-native';
|
||||
import React, {type ComponentProps} from 'react';
|
||||
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {renderWithIntl} from '@test/intl-test-helper';
|
||||
|
||||
import PostPriorityPicker from './post_priority_picker';
|
||||
|
||||
jest.mock('@hooks/device');
|
||||
const mockedIsTablet = jest.mocked(useIsTablet);
|
||||
|
||||
function getBaseProps(): ComponentProps<typeof PostPriorityPicker> {
|
||||
return {
|
||||
closeButtonId: '',
|
||||
componentId: 'BottomSheet',
|
||||
isPersistenNotificationsEnabled: true,
|
||||
isPostAcknowledgementEnabled: true,
|
||||
persistentNotificationInterval: 0,
|
||||
postPriority: {priority: ''},
|
||||
updatePostPriority: jest.fn(),
|
||||
};
|
||||
}
|
||||
describe('post_priority_picker', () => {
|
||||
it('correctly shows the apply and cancel buttons on mobile', async () => {
|
||||
mockedIsTablet.mockReturnValue(false);
|
||||
const props = getBaseProps();
|
||||
renderWithIntl(<PostPriorityPicker {...props}/>);
|
||||
expect(await screen.findByText('Apply')).toBeVisible();
|
||||
expect(await screen.findByText('Cancel')).toBeVisible();
|
||||
});
|
||||
|
||||
it('correctly shows the apply and cancel buttons on tablet', async () => {
|
||||
mockedIsTablet.mockReturnValue(true);
|
||||
const props = getBaseProps();
|
||||
renderWithIntl(<PostPriorityPicker {...props}/>);
|
||||
expect(await screen.findByText('Apply')).toBeVisible();
|
||||
expect(await screen.findByText('Cancel')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
@ -5,12 +5,14 @@
|
|||
|
||||
import {setGenerator} from '@nozbe/watermelondb/utils/common/randomId';
|
||||
import * as ReactNative from 'react-native';
|
||||
import 'react-native-gesture-handler/jestSetup';
|
||||
import mockSafeAreaContext from 'react-native-safe-area-context/jest/mock';
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
|
||||
import type {ReadDirItem, StatResult} from 'react-native-fs';
|
||||
|
||||
import 'react-native-gesture-handler/jestSetup';
|
||||
import '@testing-library/react-native/extend-expect';
|
||||
|
||||
// @ts-expect-error Promise does not exists in global
|
||||
global.Promise = jest.requireActual('promise');
|
||||
|
||||
|
|
@ -248,12 +250,12 @@ jest.mock('../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitte
|
|||
|
||||
jest.mock('react-native-device-info', () => {
|
||||
return {
|
||||
getVersion: () => '0.0.0',
|
||||
getBuildNumber: () => '0',
|
||||
getModel: () => 'iPhone X',
|
||||
hasNotch: () => true,
|
||||
isTablet: () => false,
|
||||
getApplicationName: () => 'Mattermost',
|
||||
getVersion: jest.fn(() => '0.0.0'),
|
||||
getBuildNumber: jest.fn(() => '0'),
|
||||
getModel: jest.fn(() => 'iPhone X'),
|
||||
hasNotch: jest.fn(() => true),
|
||||
isTablet: jest.fn(() => false),
|
||||
getApplicationName: jest.fn(() => 'Mattermost'),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -389,6 +391,14 @@ jest.mock('react-native-safe-area-context', () => mockSafeAreaContext);
|
|||
jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));
|
||||
jest.mock('react-native-permissions', () => require('react-native-permissions/mock'));
|
||||
|
||||
jest.mock('react-native-haptic-feedback', () => {
|
||||
const RNHF = jest.requireActual('react-native-haptic-feedback');
|
||||
return {
|
||||
...RNHF,
|
||||
trigger: () => '',
|
||||
};
|
||||
});
|
||||
|
||||
declare const global: {requestAnimationFrame: (callback: any) => void};
|
||||
global.requestAnimationFrame = (callback) => {
|
||||
setTimeout(callback, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue