diff --git a/app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap b/app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap new file mode 100644 index 000000000..de2a8784e --- /dev/null +++ b/app/components/safe_area_view/__snapshots__/safe_area_view.ios.test.js.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SafeAreaIos should match snapshot 1`] = ` + + + + +`; diff --git a/app/components/safe_area_view/safe_area_view.ios.js b/app/components/safe_area_view/safe_area_view.ios.js index 97c5117ff..91a38d238 100644 --- a/app/components/safe_area_view/safe_area_view.ios.js +++ b/app/components/safe_area_view/safe_area_view.ios.js @@ -3,7 +3,7 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import {Dimensions, Keyboard, NativeModules, View} from 'react-native'; +import {Keyboard, NativeModules, View} from 'react-native'; import SafeArea from 'react-native-safe-area'; import EventEmitter from 'mattermost-redux/utils/event_emitter'; @@ -54,23 +54,19 @@ export default class SafeAreaIos extends PureComponent { }; } - componentWillMount() { - this.mounted = true; - this.getSafeAreaInsets(); - this.mounted = true; - } - componentDidMount() { - Dimensions.addEventListener('change', this.getSafeAreaInsets); + this.mounted = true; + + SafeArea.addEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsForRootViewChange); EventEmitter.on('update_safe_area_view', this.getSafeAreaInsets); this.keyboardDidShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); this.keyboardDidHideListener = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide); - this.getStatusBarHeight(); + + this.getSafeAreaInsets(); } componentWillUnmount() { - this.mounted = false; - Dimensions.removeEventListener('change', this.getSafeAreaInsets); + SafeArea.removeEventListener('safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsForRootViewChange); EventEmitter.off('update_safe_area_view', this.getSafeAreaInsets); this.keyboardDidShowListener.remove(); this.keyboardDidHideListener.remove(); @@ -105,6 +101,15 @@ export default class SafeAreaIos extends PureComponent { } }; + onSafeAreaInsetsForRootViewChange = (result) => { + const {safeAreaInsets} = result; + + if (this.mounted && (DeviceTypes.IS_IPHONE_WITH_INSETS || mattermostManaged.hasSafeAreaInsets)) { + this.getStatusBarHeight(); + this.setState({safeAreaInsets}); + } + } + keyboardWillHide = () => { this.setState({keyboard: false}); }; diff --git a/app/components/safe_area_view/safe_area_view.ios.test.js b/app/components/safe_area_view/safe_area_view.ios.test.js new file mode 100644 index 000000000..85c64b572 --- /dev/null +++ b/app/components/safe_area_view/safe_area_view.ios.test.js @@ -0,0 +1,151 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React from 'react'; +import SafeArea from 'react-native-safe-area'; +import {shallow} from 'enzyme'; + +import Preferences from 'mattermost-redux/constants/preferences'; + +import {DeviceTypes} from 'app/constants'; +import mattermostManaged from 'app/mattermost_managed'; + +import SafeAreaIos from './safe_area_view.ios'; + +describe('SafeAreaIos', () => { + const baseProps = { + children: [], + keyboardOffset: 100, + useLandscapeMargin: false, + theme: Preferences.THEMES.default, + }; + + const TEST_INSETS_1 = { + safeAreaInsets: { + top: 123, + left: 123, + bottom: 123, + right: 123, + }, + }; + + const TEST_INSETS_2 = { + safeAreaInsets: { + top: 456, + left: 456, + bottom: 456, + right: 456, + }, + }; + + SafeArea.getSafeAreaInsetsForRootView = jest.fn().mockImplementation(() => { + return Promise.resolve(TEST_INSETS_1); + }); + + test('should match snapshot', () => { + const wrapper = shallow( + + ); + + expect(wrapper.getElement()).toMatchSnapshot(); + }); + + test('should get safe area insets on mount if DeviceTypes.IS_IPHONE_WITH_INSETS is true', async () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = true; + mattermostManaged.hasSafeAreaInsets = false; + + const wrapper = shallow( + + ); + + expect(SafeArea.getSafeAreaInsetsForRootView).toHaveBeenCalled(); + await SafeArea.getSafeAreaInsetsForRootView(); + expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_1.safeAreaInsets); + }); + + test('should get safe area insets on mount if mattermostManaged.hasSafeAreaInsets is true', async () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = false; + mattermostManaged.hasSafeAreaInsets = true; + + const wrapper = shallow( + + ); + + expect(SafeArea.getSafeAreaInsetsForRootView).toHaveBeenCalled(); + await SafeArea.getSafeAreaInsetsForRootView(); + expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_1.safeAreaInsets); + }); + + test('should not get safe area insets on mount if neither DeviceTypes.IS_IPHONE_WITH_INSET nor mattermostManaged.hasSafeAreaInsets is true', async () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = false; + mattermostManaged.hasSafeAreaInsets = false; + + const wrapper = shallow( + + ); + + expect(SafeArea.getSafeAreaInsetsForRootView).not.toHaveBeenCalled(); + await SafeArea.getSafeAreaInsetsForRootView(); + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_1.safeAreaInsets); + }); + + test('should set safe area insets on change if mounted and DeviceTypes.IS_IPHONE_WITH_INSETS is true', () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = true; + mattermostManaged.hasSafeAreaInsets = false; + + const wrapper = shallow( + + ); + + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); + + const instance = wrapper.instance(); + instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); + expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_2.safeAreaInsets); + }); + + test('should set safe area insets on change if mounted and mattermostManaged.hasSafeAreaInsets is true', () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = false; + mattermostManaged.hasSafeAreaInsets = true; + + const wrapper = shallow( + + ); + + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); + + const instance = wrapper.instance(); + instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); + expect(wrapper.state().safeAreaInsets).toEqual(TEST_INSETS_2.safeAreaInsets); + }); + + test('should not set safe area insets on change if mounted and neither DeviceTypes.IS_IPHONE_WITH_INSETS nor mattermostManaged.hasSafeAreaInsets is true', () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = false; + mattermostManaged.hasSafeAreaInsets = false; + + const wrapper = shallow( + + ); + + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); + + const instance = wrapper.instance(); + instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); + }); + + test('should set safe area insets on change not mounted', () => { + DeviceTypes.IS_IPHONE_WITH_INSETS = true; + mattermostManaged.hasSafeAreaInsets = true; + + const wrapper = shallow( + + ); + + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); + + const instance = wrapper.instance(); + instance.mounted = false; + instance.onSafeAreaInsetsForRootViewChange(TEST_INSETS_2); + expect(wrapper.state().safeAreaInsets).not.toEqual(TEST_INSETS_2.safeAreaInsets); + }); +}); diff --git a/app/screens/permalink/index.js b/app/screens/permalink/index.js index d97525ec9..275d4df3e 100644 --- a/app/screens/permalink/index.js +++ b/app/screens/permalink/index.js @@ -20,8 +20,6 @@ import {isLandscape} from 'app/selectors/device'; import { handleSelectChannel, loadThreadIfNecessary, - setChannelDisplayName, - setChannelLoading, } from 'app/actions/views/channel'; import {handleTeamChange} from 'app/actions/views/select_team'; @@ -73,8 +71,6 @@ function mapDispatchToProps(dispatch) { joinChannel, loadThreadIfNecessary, selectPost, - setChannelDisplayName, - setChannelLoading, }, dispatch), }; } diff --git a/app/screens/permalink/permalink.js b/app/screens/permalink/permalink.js index 7d6bb3aeb..8577461f1 100644 --- a/app/screens/permalink/permalink.js +++ b/app/screens/permalink/permalink.js @@ -65,8 +65,6 @@ export default class Permalink extends PureComponent { joinChannel: PropTypes.func.isRequired, loadThreadIfNecessary: PropTypes.func.isRequired, selectPost: PropTypes.func.isRequired, - setChannelDisplayName: PropTypes.func.isRequired, - setChannelLoading: PropTypes.func.isRequired, }).isRequired, channelId: PropTypes.string, channelIsArchived: PropTypes.bool, @@ -221,24 +219,22 @@ export default class Permalink extends PureComponent { }; handlePress = () => { - const {channelIdState, channelNameState} = this.state; + const {channelIdState} = this.state; if (this.refs.view) { this.refs.view.growOut().then(() => { - this.jumpToChannel(channelIdState, channelNameState); + this.jumpToChannel(channelIdState); }); } }; - jumpToChannel = async (channelId, channelDisplayName) => { + jumpToChannel = async (channelId) => { if (channelId) { const {actions, channelTeamId, currentTeamId, onClose} = this.props; const currentChannelId = this.props.channelId; const { handleSelectChannel, handleTeamChange, - setChannelLoading, - setChannelDisplayName, } = actions; actions.selectPost(''); @@ -263,8 +259,6 @@ export default class Permalink extends PureComponent { handleTeamChange(channelTeamId); } - setChannelLoading(channelId !== currentChannelId); - setChannelDisplayName(channelDisplayName); handleSelectChannel(channelId); } }; diff --git a/app/screens/permalink/permalink.test.js b/app/screens/permalink/permalink.test.js index 0d8edbe6b..d104633b9 100644 --- a/app/screens/permalink/permalink.test.js +++ b/app/screens/permalink/permalink.test.js @@ -20,8 +20,6 @@ describe('Permalink', () => { joinChannel: jest.fn(), loadThreadIfNecessary: jest.fn(), selectPost: jest.fn(), - setChannelDisplayName: jest.fn(), - setChannelLoading: jest.fn(), }; const baseProps = {