From b153dd96a1e6ccce49bdddcfcdeaccc11ebf10a0 Mon Sep 17 00:00:00 2001 From: Saturnino Abril Date: Wed, 30 Jan 2019 01:07:58 +0800 Subject: [PATCH] [MM-13412 & MM-13711] Allow showing of all post options if possible to fit 75% of the screen height (#2501) * allow showing all options if possible to fit 60% of the screen height * change max initial position from 60% to 70% * fix broken UI of the bottom part of post options * change to 75% --- app/screens/post_options/post_options.js | 8 ++-- .../post_options/post_options_utils.js | 27 ++++++++++++ .../post_options/post_options_utils.test.js | 41 +++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 app/screens/post_options/post_options_utils.js create mode 100644 app/screens/post_options/post_options_utils.test.js diff --git a/app/screens/post_options/post_options.js b/app/screens/post_options/post_options.js index e47f1d4da..9e5c81fdd 100644 --- a/app/screens/post_options/post_options.js +++ b/app/screens/post_options/post_options.js @@ -9,12 +9,10 @@ import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; import SlideUpPanel from 'app/components/slide_up_panel'; import {BOTTOM_MARGIN} from 'app/components/slide_up_panel/slide_up_panel'; -import DeviceTypes from 'app/constants/device'; +import {OPTION_HEIGHT, getInitialPosition} from './post_options_utils'; import PostOption from './post_option'; -const OPTION_HEIGHT = 50; - export default class PostOptions extends PureComponent { static propTypes = { actions: PropTypes.shape({ @@ -401,14 +399,14 @@ export default class PostOptions extends PureComponent { const {deviceHeight} = this.props; const options = this.getPostOptions(); const marginFromTop = deviceHeight - BOTTOM_MARGIN - ((options.length + 1) * OPTION_HEIGHT); - const initialPosition = DeviceTypes.IS_IPHONE_X ? 280 : 305; + const initialPosition = getInitialPosition(deviceHeight, marginFromTop); return ( 0 ? marginFromTop : 0} onRequestClose={this.close} initialPosition={initialPosition} > diff --git a/app/screens/post_options/post_options_utils.js b/app/screens/post_options/post_options_utils.js new file mode 100644 index 000000000..530a13f87 --- /dev/null +++ b/app/screens/post_options/post_options_utils.js @@ -0,0 +1,27 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +export const OPTION_HEIGHT = 50; +const BOTTOM_HEIGHT = 18; +export const MAX_INITIAL_POSITION_MULTIPLIER = 0.75; + +export function getInitialPosition(deviceHeight, marginFromTop) { + const computedSlidePanelHeight = deviceHeight - marginFromTop; + const maxInitialPosition = deviceHeight * MAX_INITIAL_POSITION_MULTIPLIER; + + if (computedSlidePanelHeight <= maxInitialPosition) { + // Show all options to the user + return computedSlidePanelHeight; + } + + const optionHeightWithBorder = OPTION_HEIGHT + 1; + + // Partially show options to user with the first hidden option in mid appearance + // to indicate that are still option/s available on slide up + let adjustedInitialPosition = computedSlidePanelHeight - BOTTOM_HEIGHT - (optionHeightWithBorder / 2); + while (adjustedInitialPosition > maxInitialPosition) { + adjustedInitialPosition -= optionHeightWithBorder; + } + + return adjustedInitialPosition; +} diff --git a/app/screens/post_options/post_options_utils.test.js b/app/screens/post_options/post_options_utils.test.js new file mode 100644 index 000000000..b261c877a --- /dev/null +++ b/app/screens/post_options/post_options_utils.test.js @@ -0,0 +1,41 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {getInitialPosition, MAX_INITIAL_POSITION_MULTIPLIER} from './post_options_utils'; + +describe('should match return value of getInitialPosition', () => { + const testCases = [ + { + input: {deviceHeight: 600, marginFromTop: 400}, + output: 200, + }, { + input: {deviceHeight: 600, marginFromTop: 300}, + output: 300, + }, { + input: {deviceHeight: 600, marginFromTop: 50}, + output: 404.5, + }, { + input: {deviceHeight: 1000, marginFromTop: 250}, + output: 750, + }, { + input: {deviceHeight: 1000, marginFromTop: 150}, + output: 704.5, + }, { + input: {deviceHeight: 1000, marginFromTop: 400}, + output: 600, + }, + ]; + + for (const testCase of testCases) { + const {input, output} = testCase; + const maxInitialPosition = input.deviceHeight * MAX_INITIAL_POSITION_MULTIPLIER; + + test('should match initial position', () => { + const initialPosition = getInitialPosition(input.deviceHeight, input.marginFromTop); + expect(initialPosition).toEqual(output); + + // should not exceed maximum initial position at 75% of screen height + expect(initialPosition).toBeLessThanOrEqual(maxInitialPosition); + }); + } +});