diff --git a/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap b/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap new file mode 100644 index 000000000..a432dbf15 --- /dev/null +++ b/app/components/channel_loader/__snapshots__/channel_loader.test.js.snap @@ -0,0 +1,383 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ChannelLoader should match snapshot 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; diff --git a/app/components/channel_loader/channel_loader.js b/app/components/channel_loader/channel_loader.js index 7b9d51580..dea4f5c4f 100644 --- a/app/components/channel_loader/channel_loader.js +++ b/app/components/channel_loader/channel_loader.js @@ -4,17 +4,20 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import { - Platform, View, + Dimensions, } from 'react-native'; import {ImageContent} from 'rn-placeholder'; import EventEmitter from 'mattermost-redux/utils/event_emitter'; -import {DeviceTypes} from 'app/constants'; import CustomPropTypes from 'app/constants/custom_prop_types'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; +function calculateMaxRows(height) { + return Math.round(height / 100); +} + export default class ChannelLoader extends PureComponent { static propTypes = { actions: PropTypes.shape({ @@ -23,28 +26,35 @@ export default class ChannelLoader extends PureComponent { }).isRequired, backgroundColor: PropTypes.string, channelIsLoading: PropTypes.bool.isRequired, - maxRows: PropTypes.number, style: CustomPropTypes.Style, theme: PropTypes.object.isRequired, + height: PropTypes.number, }; - static defaultProps = { - maxRows: 6, - }; + constructor(props) { + super(props); - state = { - switch: false, - }; + const height = props.height || Dimensions.get('window').height; + const maxRows = calculateMaxRows(height); + + this.state = { + switch: false, + maxRows, + }; + } static getDerivedStateFromProps(nextProps, prevState) { + const state = {}; + + if (nextProps.height) { + state.maxRows = calculateMaxRows(nextProps.height); + } if (!nextProps.channelIsLoading && prevState.switch) { - return { - switch: false, - channel: null, - }; + state.switch = false; + state.channel = null; } - return null; + return Object.keys(state) ? state : null; } componentDidMount() { @@ -99,10 +109,15 @@ export default class ChannelLoader extends PureComponent { } }; + handleLayout = (e) => { + const {height} = e.nativeEvent.layout; + const maxRows = calculateMaxRows(height); + this.setState({maxRows}); + } + render() { const { channelIsLoading, - maxRows, style: styleProp, theme, } = this.props; @@ -113,15 +128,13 @@ export default class ChannelLoader extends PureComponent { const style = getStyleSheet(theme); const bg = this.props.backgroundColor || theme.centerChannelBg; - const containerStyle = [style.container]; - - if (DeviceTypes.IS_TABLET) { - containerStyle.push(style.tablet); - } return ( - - {Array(maxRows).fill().map((item, index) => this.buildSections({ + + {Array(this.state.maxRows).fill().map((item, index) => this.buildSections({ key: index, style, bg, @@ -137,16 +150,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { container: { flex: 1, }, - tablet: { - ...Platform.select({ - android: { - paddingTop: 25, - }, - ios: { - paddingTop: 30, - }, - }), - }, section: { backgroundColor: theme.centerChannelBg, flexDirection: 'row', diff --git a/app/components/channel_loader/channel_loader.test.js b/app/components/channel_loader/channel_loader.test.js new file mode 100644 index 000000000..f742cc385 --- /dev/null +++ b/app/components/channel_loader/channel_loader.test.js @@ -0,0 +1,29 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; +import {shallow} from 'enzyme'; + +import Preferences from 'mattermost-redux/constants/preferences'; + +import ChannelLoader from './channel_loader'; + +jest.mock('rn-placeholder', () => ({ + ImageContent: () => {}, +})); + +describe('ChannelLoader', () => { + const baseProps = { + channelIsLoading: true, + theme: Preferences.THEMES.default, + actions: { + handleSelectChannel: jest.fn(), + setChannelLoading: jest.fn(), + }, + }; + + test('should match snapshot', () => { + const wrapper = shallow(); + expect(wrapper.getElement()).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/app/screens/channel/channel.js b/app/screens/channel/channel.js index 54d3cf8ae..27a8aa83b 100644 --- a/app/screens/channel/channel.js +++ b/app/screens/channel/channel.js @@ -28,7 +28,7 @@ import SettingsSidebar from 'app/components/sidebars/settings'; import NetworkIndicator from 'app/components/network_indicator'; import SafeAreaView from 'app/components/safe_area_view'; import StatusBar from 'app/components/status_bar'; -import {DeviceTypes, ViewTypes} from 'app/constants'; +import {DeviceTypes} from 'app/constants'; import {preventDoubleTap} from 'app/utils/tap'; import PostTextbox from 'app/components/post_textbox'; import PushNotifications from 'app/push_notifications'; @@ -40,14 +40,6 @@ import telemetry from 'app/telemetry'; import ChannelNavBar from './channel_nav_bar'; import ChannelPostList from './channel_post_list'; -const { - ANDROID_TOP_LANDSCAPE, - ANDROID_TOP_PORTRAIT, - IOS_TOP_LANDSCAPE, - IOS_TOP_PORTRAIT, - IOSX_TOP_PORTRAIT, -} = ViewTypes; - const CHANNEL_POST_TEXTBOX_CURSOR_CHANGE = 'onChannelTextBoxCursorChange'; const CHANNEL_POST_TEXTBOX_VALUE_CHANGE = 'onChannelTextBoxValueChange'; @@ -169,32 +161,6 @@ export default class Channel extends PureComponent { } }; - channelLoaderDimensions = () => { - const {isLandscape} = this.props; - let top = 0; - let {height} = Dimensions.get('window'); - switch (Platform.OS) { - case 'android': - if (isLandscape) { - top = ANDROID_TOP_LANDSCAPE; - } else { - top = ANDROID_TOP_PORTRAIT; - height -= 84; - } - break; - case 'ios': - if (isLandscape) { - top = IOS_TOP_LANDSCAPE; - } else { - height = DeviceTypes.IS_IPHONE_X ? (height - IOSX_TOP_PORTRAIT) : (height - IOS_TOP_PORTRAIT); - top = DeviceTypes.IS_IPHONE_X ? IOSX_TOP_PORTRAIT : IOS_TOP_PORTRAIT; - } - break; - } - - return {height, top}; - }; - channelSidebarRef = (ref) => { if (ref) { this.channelSidebar = ref; @@ -316,6 +282,8 @@ export default class Channel extends PureComponent { theme, } = this.props; + const {height} = Dimensions.get('window'); + if (!currentChannelId) { if (channelsRequestFailed) { const PostListRetry = require('app/components/post_list_retry').default; @@ -333,7 +301,7 @@ export default class Channel extends PureComponent { @@ -341,7 +309,10 @@ export default class Channel extends PureComponent { ); } - const loaderDimensions = this.channelLoaderDimensions(); + const channelLoaderStyle = [style.channelLoader, {height}]; + if (Platform.OS === 'ios' && (DeviceTypes.IS_IPHONE_X || DeviceTypes.IS_TABLET)) { + channelLoaderStyle.push(style.iOSHomeIndicator); + } return ( {LocalConfig.EnableMobileClientUpgrade && } @@ -410,4 +381,7 @@ const style = StyleSheet.create({ width: '100%', flex: 1, }, + iOSHomeIndicator: { + paddingBottom: 5, + }, }); diff --git a/package-lock.json b/package-lock.json index 964912ca1..21f49f877 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16790,8 +16790,8 @@ "dev": true }, "rn-placeholder": { - "version": "github:mattermost/rn-placeholder#0389b32e0c7e2f88ea21b4bd978b5834fb09ab1d", - "from": "github:mattermost/rn-placeholder#0389b32e0c7e2f88ea21b4bd978b5834fb09ab1d", + "version": "github:mattermost/rn-placeholder#02c629c65d0123a2eee623ada0fd17186415d3c3", + "from": "github:mattermost/rn-placeholder#02c629c65d0123a2eee623ada0fd17186415d3c3", "requires": { "prop-types": "15.6.2" }, diff --git a/package.json b/package.json index 07d14c6c8..feeb8572c 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "redux-thunk": "2.3.0", "reselect": "4.0.0", "rn-fetch-blob": "github:mattermost/react-native-fetch-blob#d5a1efb3166f3d42e4f316b4be99da82fdc159b4", - "rn-placeholder": "github:mattermost/rn-placeholder#0389b32e0c7e2f88ea21b4bd978b5834fb09ab1d", + "rn-placeholder": "github:mattermost/rn-placeholder#02c629c65d0123a2eee623ada0fd17186415d3c3", "semver": "6.0.0", "shallow-equals": "1.0.0", "tinycolor2": "1.4.1",