diff --git a/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap b/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap index e86bee72b..c6549a034 100644 --- a/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap +++ b/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap @@ -20,17 +20,23 @@ exports[`components/emoji_picker/EmojiPicker should match snapshot 1`] = ` Array [ Object { "backgroundColor": "rgba(61,60,64,0.2)", + "height": 50, + "paddingLeft": 8, "paddingVertical": 5, }, null, ] } > - { searchBar: { backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), paddingVertical: 5, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), + height: 50, }, sectionList: { ...Platform.select({ diff --git a/app/components/search_bar/search_bar.android.js b/app/components/search_bar/search_bar.android.js deleted file mode 100644 index 7a6575b80..000000000 --- a/app/components/search_bar/search_bar.android.js +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import { - InteractionManager, - Keyboard, - TextInput, - TouchableWithoutFeedback, - StyleSheet, - View, -} from 'react-native'; -import Icon from 'react-native-vector-icons/MaterialIcons'; - -import CustomPropTypes from 'app/constants/custom_prop_types'; -import {changeOpacity} from 'app/utils/theme'; - -export default class SearchBarAndroid extends PureComponent { - static propTypes = { - autoFocus: PropTypes.bool, - backArrowSize: PropTypes.number, - deleteIconSize: PropTypes.number, - searchIconSize: PropTypes.number, - onCancelButtonPress: PropTypes.func, - onChangeText: PropTypes.func, - onFocus: PropTypes.func, - onBlur: PropTypes.func, - onSearchButtonPress: PropTypes.func, - onSelectionChange: PropTypes.func, - backgroundColor: PropTypes.string, - selectionColor: PropTypes.string, - placeholderTextColor: PropTypes.string, - titleCancelColor: PropTypes.string, - tintColorSearch: PropTypes.string, - tintColorDelete: PropTypes.string, - inputStyle: CustomPropTypes.Style, - placeholder: PropTypes.string, - returnKeyType: PropTypes.string, - keyboardType: PropTypes.string, - autoCapitalize: PropTypes.string, - inputHeight: PropTypes.number, - inputBorderRadius: PropTypes.number, - blurOnSubmit: PropTypes.bool, - showArrow: PropTypes.bool, - value: PropTypes.string, - containerStyle: CustomPropTypes.Style, - leftComponent: PropTypes.element, - keyboardAppearance: PropTypes.string, - }; - - static defaultProps = { - backArrowSize: 24, - deleteIconSize: 20, - searchIconSize: 24, - blurOnSubmit: true, - placeholder: 'Search', - showCancelButton: true, - showArrow: true, - placeholderTextColor: changeOpacity('#000', 0.5), - containerStyle: {}, - onSearchButtonPress: () => true, - onCancelButtonPress: () => true, - onChangeText: () => true, - onFocus: () => true, - onBlur: () => true, - onSelectionChange: () => true, - value: '', - leftComponent: null, - }; - - constructor(props) { - super(props); - this.state = { - isFocused: false, - refocusInput: true, - }; - } - - setInputRef = (ref) => { - this.inputRef = ref; - } - - cancel = () => { - this.onCancelButtonPress(); - }; - - onBlur = () => { - this.props.onBlur(); - }; - - onSearchButtonPress = () => { - const {value} = this.props; - this.setState({refocusInput: false}, () => { - if (value) { - this.props.onSearchButtonPress(value); - } - this.setState({refocusInput: true}); - }); - }; - - onCancelButtonPress = () => { - Keyboard.dismiss(); - InteractionManager.runAfterInteractions(() => { - this.setState({ - isFocused: false, - }, () => { - this.props.onCancelButtonPress(); - }); - }); - }; - - onClearPress = () => { - this.onChangeText(''); - }; - - onChangeText = (value) => { - this.props.onChangeText(value); - }; - - onSelectionChange = (event) => { - this.props.onSelectionChange(event); - }; - - onFocus = () => { - this.setState({isFocused: true}); - this.props.onFocus(); - }; - - blur = () => { - this.inputRef.blur(); - }; - - focus = () => { - this.inputRef.focus(); - }; - - render() { - const { - autoCapitalize, - backArrowSize, - deleteIconSize, - searchIconSize, - backgroundColor, - blurOnSubmit, - inputHeight, - inputStyle, - keyboardType, - placeholder, - placeholderTextColor, - selectionColor, - returnKeyType, - titleCancelColor, - tintColorDelete, - tintColorSearch, - containerStyle, - value, - showArrow, - keyboardAppearance, - } = this.props; - const {isFocused} = this.state; - - const { - backgroundColor: bgColor, //eslint-disable-line no-unused-vars - ...otherStyles - } = inputStyle; - - const inputNoBackground = otherStyles; - - let inputColor = styles.searchBarInput.backgroundColor; - if (inputStyle) { - inputColor = inputStyle.backgroundColor; - } else { - inputNoBackground.backgroundColor = '#fff'; - } - - return ( - - {!isFocused && this.props.leftComponent} - - {isFocused && showArrow ? - - - : - - } - - {isFocused && value ? - - - : null - } - - - ); - } -} - -const styles = StyleSheet.create({ - container: { - backgroundColor: 'grey', - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'center', - }, - searchBar: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - }, - searchBarInput: { - flex: 1, - fontWeight: 'normal', - textAlignVertical: 'center', - fontSize: 15, - includeFontPadding: true, - }, - searchBarBlurredInput: { - padding: 0, - }, -}); diff --git a/app/components/search_bar/search_bar.ios.js b/app/components/search_bar/search_bar.ios.js deleted file mode 100644 index 00a7028ff..000000000 --- a/app/components/search_bar/search_bar.ios.js +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import PropTypes from 'prop-types'; -import React, {PureComponent} from 'react'; -import {InteractionManager, Keyboard} from 'react-native'; - -import CustomPropTypes from 'app/constants/custom_prop_types'; - -import Search from './search_box'; - -export default class SearchBarIos extends PureComponent { - static propTypes = { - onCancelButtonPress: PropTypes.func, - onChangeText: PropTypes.func, - onFocus: PropTypes.func, - onBlur: PropTypes.func, - onSearchButtonPress: PropTypes.func, - onSelectionChange: PropTypes.func, - backgroundColor: PropTypes.string, - placeholderTextColor: PropTypes.string, - titleCancelColor: PropTypes.string, - tintColorSearch: PropTypes.string, - tintColorDelete: PropTypes.string, - cancelButtonStyle: CustomPropTypes.Style, - inputStyle: CustomPropTypes.Style, - placeholder: PropTypes.string, - cancelTitle: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object, - ]), - returnKeyType: PropTypes.string, - keyboardType: PropTypes.string, - autoCapitalize: PropTypes.string, - inputHeight: PropTypes.number, - inputBorderRadius: PropTypes.number, - blurOnSubmit: PropTypes.bool, - value: PropTypes.string, - leftComponent: PropTypes.element, - searchIconCollapsedMargin: PropTypes.number, - searchIconExpandedMargin: PropTypes.number, - keyboardAppearance: PropTypes.string, - onAnimationComplete: PropTypes.func, - }; - - static defaultProps = { - onSearchButtonPress: () => true, - onCancelButtonPress: () => true, - onChangeText: () => true, - onFocus: () => true, - onBlur: () => true, - onSelectionChange: () => true, - blurOnSubmit: true, - leftComponent: null, - searchIconCollapsedMargin: 10, - searchIconExpandedMargin: 10, - }; - - setSearchRef = (ref) => { - this.searchRef = ref; - } - - cancel = () => { - this.searchRef.onCancel(); - }; - - onBlur = () => { - this.props.onBlur(); - }; - - onCancel = () => { - Keyboard.dismiss(); - InteractionManager.runAfterInteractions(() => { - this.props.onCancelButtonPress(); - }); - }; - - onChangeText = (text) => { - this.props.onChangeText(text); - }; - - onDelete = () => { - this.props.onChangeText('', true); - }; - - onFocus = () => { - this.props.onFocus(); - }; - - onSearch = (text) => { - if (text) { - this.props.onSearchButtonPress(text); - } - }; - - onSelectionChange = (event) => { - this.props.onSelectionChange(event); - }; - - blur = () => { - this.searchRef.blur(); - }; - - focus = () => { - this.searchRef.focus(); - }; - - render() { - return ( - - ); - } -} diff --git a/app/components/search_bar/search_bar.js b/app/components/search_bar/search_bar.js new file mode 100644 index 000000000..3059ead79 --- /dev/null +++ b/app/components/search_bar/search_bar.js @@ -0,0 +1,453 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {PureComponent} from 'react'; +import PropTypes from 'prop-types'; +import { + Animated, + InteractionManager, + Keyboard, + TouchableWithoutFeedback, + StyleSheet, + View, + Platform, +} from 'react-native'; +import {intlShape} from 'react-intl'; + +import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; +import EvilIcon from 'react-native-vector-icons/EvilIcons'; + +import {SearchBar} from 'react-native-elements'; + +import {memoizeResult} from 'mattermost-redux/utils/helpers'; + +import CustomPropTypes from 'app/constants/custom_prop_types'; + +export default class Search extends PureComponent { + static propTypes = { + onBlur: PropTypes.func, + onFocus: PropTypes.func, + onSearchButtonPress: PropTypes.func, + onChangeText: PropTypes.func, + onCancelButtonPress: PropTypes.func, + onSelectionChange: PropTypes.func, + backgroundColor: PropTypes.string, + placeholderTextColor: PropTypes.string, + titleCancelColor: PropTypes.string, + tintColorSearch: PropTypes.string, + tintColorDelete: PropTypes.string, + selectionColor: PropTypes.string, + inputStyle: CustomPropTypes.Style, + cancelButtonStyle: CustomPropTypes.Style, + autoFocus: PropTypes.bool, + placeholder: PropTypes.string, + cancelTitle: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.object, + ]), + returnKeyType: PropTypes.string, + keyboardType: PropTypes.string, + autoCapitalize: PropTypes.string, + inputHeight: PropTypes.number, + editable: PropTypes.bool, + blurOnSubmit: PropTypes.bool, + keyboardShouldPersist: PropTypes.bool, + value: PropTypes.string, + keyboardAppearance: PropTypes.string, + showArrow: PropTypes.bool, + searchBarRightMargin: PropTypes.number, + leftComponent: PropTypes.element, + searchIconSize: PropTypes.number, + backArrowSize: PropTypes.number, + deleteIconSize: PropTypes.number, + showCancel: PropTypes.bool, + containerHeight: PropTypes.number, + }; + + static contextTypes = { + intl: intlShape, + }; + + static defaultProps = { + onSelectionChange: () => true, + onBlur: () => true, + editable: true, + blurOnSubmit: false, + keyboardShouldPersist: false, + placeholderTextColor: 'grey', + value: '', + showArrow: false, + showCancel: true, + searchIconSize: 24, + backArrowSize: 24, + deleteIconSize: 20, + searchBarRightMargin: 0, + returnKeyType: 'search', + keyboardType: 'default', + containerHeight: 40, + }; + + constructor(props) { + super(props); + this.state = { + leftComponentWidth: 0, + }; + + this.leftComponentAnimated = new Animated.Value(0); + this.searchContainerAnimated = new Animated.Value(0); + } + + setSearchContainerRef = (ref) => { + this.searchContainerRef = ref; + } + + setInputKeywordRef = (ref) => { + this.inputKeywordRef = ref; + } + + blur = () => { + this.inputKeywordRef.blur(); + }; + + focus = () => { + this.inputKeywordRef.focus(); + }; + + onBlur = async () => { + if (this.props.leftComponent) { + await this.collapseAnimation(); + } + this.props.onBlur(); + }; + + onLeftComponentLayout = (event) => { + const leftComponentWidth = event.nativeEvent.layout.width; + this.setState({leftComponentWidth}); + }; + + onSearch = async () => { + if (this.props.keyboardShouldPersist === false) { + await Keyboard.dismiss(); + } + + this.props.onSearchButtonPress(this.props.value); + }; + + onChangeText = (text) => { + if (this.props.onChangeText) { + this.props.onChangeText(text); + } + }; + + onFocus = () => { + InteractionManager.runAfterInteractions(async () => { + if (this.props.leftComponent) { + await this.expandAnimation(); + } + + if (this.props.onFocus) { + this.props.onFocus(); + } + }); + }; + + onClear = () => { + this.focus(); + this.props.onChangeText('', true); + }; + + onCancel = () => { + Keyboard.dismiss(); + InteractionManager.runAfterInteractions(() => { + if (this.props.onCancelButtonPress) { + this.props.onCancelButtonPress(); + } + }); + }; + + onSelectionChange = (event) => { + this.props.onSelectionChange(event); + }; + + expandAnimation = () => { + return new Promise((resolve) => { + Animated.parallel([ + Animated.timing( + this.leftComponentAnimated, + { + toValue: 100, + duration: 200, + }, + ), + Animated.timing( + this.searchContainerAnimated, + { + toValue: this.state.leftComponentWidth * -1, + duration: 200, + }, + ), + ]).start(resolve); + }); + } + + collapseAnimation = () => { + return new Promise((resolve) => { + Animated.parallel([ + Animated.timing( + this.leftComponentAnimated, + { + toValue: 0, + duration: 200, + }, + ), + Animated.timing( + this.searchContainerAnimated, + { + toValue: 0, + duration: 200, + }, + ), + ]).start(resolve); + }); + } + + render() { + const {backgroundColor, inputHeight, inputStyle, placeholderTextColor, tintColorSearch, cancelButtonStyle, tintColorDelete, titleCancelColor, searchBarRightMargin, containerHeight} = this.props; + const searchBarStyle = getSearchBarStyle( + backgroundColor, + cancelButtonStyle, + inputHeight, + inputStyle, + placeholderTextColor, + tintColorDelete, + tintColorSearch, + titleCancelColor, + searchBarRightMargin, + containerHeight, + ); + const {intl} = this.context; + + let clearIcon = null; + let searchIcon = null; + let cancelIcon = null; + + if (Platform.OS === 'ios') { + clearIcon = { + type: 'ionicon', + name: 'ios-close-circle', + size: 17, + color: searchBarStyle.clearIconColorIos, + }; + + searchIcon = ( + + ); + } else { + searchIcon = this.props.showArrow ? + ( + + + + ) : + { + type: 'material', + size: this.props.searchIconSize, + color: searchBarStyle.searchIconColor, + name: 'search', + }; + + // Making sure the icon won't change depending on whether the input is in focus on Android devices + cancelIcon = { + type: 'material', + size: 25, + color: searchBarStyle.clearIconColorAndroid, + name: 'arrow-back', + }; + + clearIcon = { + type: 'material', + size: this.props.deleteIconSize, + color: searchBarStyle.clearIconColorAndroid, + name: 'close', + }; + } + + return ( + + {((this.props.leftComponent) ? + + {this.props.leftComponent} + : + null + )} + + + + + ); + } +} + +const getSearchBarStyle = memoizeResult(( + backgroundColor, + cancelButtonStyle, + inputHeight, + inputStyle, + placeholderTextColor, + tintColorDelete, + tintColorSearch, + titleCancelColor, + searchBarRightMargin, + containerHeight, +) => ({ + cancelButtonText: { + ...cancelButtonStyle, + color: titleCancelColor, + }, + container: { + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + height: containerHeight, + flex: 1, + }, + clearIconColorIos: tintColorDelete || styles.defaultColor.color, + clearIconColorAndroid: titleCancelColor || placeholderTextColor, + inputStyle: { + ...inputStyle, + backgroundColor: 'transparent', + height: inputHeight, + }, + inputContainer: { + backgroundColor: inputStyle.backgroundColor, + height: inputHeight, + }, + searchBarWrapper: { + marginRight: searchBarRightMargin, + height: Platform.select({ + ios: inputHeight || containerHeight - 10, + android: inputHeight, + }), + }, + searchBarContainer: { + backgroundColor, + }, + searchIcon: { + color: tintColorSearch || placeholderTextColor, + top: 10, + }, + searchIconColor: tintColorSearch || placeholderTextColor, +})); + +const styles = StyleSheet.create({ + defaultColor: { + color: 'grey', + }, + fullWidth: { + flex: 1, + }, + inputContainer: { + marginLeft: 0, + borderRadius: Platform.select({ + ios: 2, + android: 0, + }), + }, + inputMargin: { + marginLeft: 4, + paddingTop: 0, + marginTop: Platform.select({ + ios: 0, + android: 8, + }), + }, + leftIcon: { + marginLeft: 4, + }, + searchContainer: { + paddingTop: 0, + paddingBottom: 0, + marginLeft: 0, + }, + text: { + fontSize: Platform.select({ + ios: 14, + android: 15, + }), + color: '#fff', + }, +}); diff --git a/app/components/search_bar/search_box.js b/app/components/search_bar/search_box.js deleted file mode 100644 index 710545a66..000000000 --- a/app/components/search_bar/search_box.js +++ /dev/null @@ -1,578 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React, {Component} from 'react'; -import PropTypes from 'prop-types'; -import { - Animated, - Dimensions, - InteractionManager, - Keyboard, - Text, - TextInput, - TouchableWithoutFeedback, - StyleSheet, - View, -} from 'react-native'; -import EvilIcon from 'react-native-vector-icons/EvilIcons'; -import IonIcon from 'react-native-vector-icons/Ionicons'; - -import CustomPropTypes from 'app/constants/custom_prop_types'; -import {emptyFunction} from 'app/utils/general'; - -const AnimatedTextInput = Animated.createAnimatedComponent(TextInput); -const AnimatedIonIcon = Animated.createAnimatedComponent(IonIcon); -const AnimatedEvilcon = Animated.createAnimatedComponent(EvilIcon); -const containerHeight = 40; -const middleHeight = 20; - -export default class Search extends Component { - static propTypes = { - onBlur: PropTypes.func, - onFocus: PropTypes.func, - onSearch: PropTypes.func, - onChangeText: PropTypes.func, - onCancel: PropTypes.func, - onDelete: PropTypes.func, - onSelectionChange: PropTypes.func, - backgroundColor: PropTypes.string, - placeholderTextColor: PropTypes.string, - titleCancelColor: PropTypes.string, - tintColorSearch: PropTypes.string, - tintColorDelete: PropTypes.string, - selectionColor: PropTypes.string, - inputStyle: CustomPropTypes.Style, - onLayout: PropTypes.func, - cancelButtonStyle: CustomPropTypes.Style, - autoFocus: PropTypes.bool, - placeholder: PropTypes.string, - cancelTitle: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object, - ]), - iconDelete: PropTypes.object, - iconSearch: PropTypes.object, - returnKeyType: PropTypes.string, - keyboardType: PropTypes.string, - autoCapitalize: PropTypes.string, - inputHeight: PropTypes.number, - inputBorderRadius: PropTypes.number, - contentWidth: PropTypes.number, - middleWidth: PropTypes.number, - editable: PropTypes.bool, - blurOnSubmit: PropTypes.bool, - keyboardShouldPersist: PropTypes.bool, - value: PropTypes.string, - positionRightDelete: PropTypes.number, - searchIconCollapsedMargin: PropTypes.number, - searchIconExpandedMargin: PropTypes.number, - placeholderCollapsedMargin: PropTypes.number, - placeholderExpandedMargin: PropTypes.number, - shadowOffsetHeightCollapsed: PropTypes.number, - shadowOffsetHeightExpanded: PropTypes.number, - shadowOffsetWidth: PropTypes.number, - shadowColor: PropTypes.string, - shadowOpacityCollapsed: PropTypes.number, - shadowOpacityExpanded: PropTypes.number, - shadowRadius: PropTypes.number, - shadowVisible: PropTypes.bool, - leftComponent: PropTypes.element, - inputCollapsedMargin: PropTypes.number, - keyboardAppearance: PropTypes.string, - onAnimationComplete: PropTypes.func, - }; - - static defaultProps = { - onSelectionChange: () => true, - onBlur: () => true, - editable: true, - blurOnSubmit: false, - keyboardShouldPersist: false, - placeholderTextColor: 'grey', - searchIconCollapsedMargin: 25, - searchIconExpandedMargin: 10, - placeholderCollapsedMargin: 15, - placeholderExpandedMargin: 20, - shadowOffsetWidth: 0, - shadowOffsetHeightCollapsed: 2, - shadowOffsetHeightExpanded: 4, - shadowColor: '#000', - shadowOpacityCollapsed: 0.12, - shadowOpacityExpanded: 0.24, - shadowRadius: 4, - shadowVisible: false, - value: '', - leftComponent: null, - inputCollapsedMargin: 10, - onAnimationComplete: emptyFunction, - }; - - constructor(props) { - super(props); - - this.state = { - expanded: false, - leftComponentWidth: 0, - }; - const {width} = Dimensions.get('window'); - this.contentWidth = width; - this.middleWidth = width / 2; - - this.iconSearchAnimated = new Animated.Value(this.props.searchIconCollapsedMargin); - this.iconDeleteAnimated = new Animated.Value(0); - this.leftComponentAnimated = new Animated.Value(0); - this.inputFocusAnimated = new Animated.Value(0); - this.inputFocusWidthAnimated = new Animated.Value(this.contentWidth - 10); - this.inputFocusPlaceholderAnimated = new Animated.Value(this.props.placeholderCollapsedMargin); - this.btnCancelAnimated = new Animated.Value(this.contentWidth); - this.shadowOpacityAnimated = new Animated.Value(this.props.shadowOpacityCollapsed); - - this.placeholder = this.props.placeholder || 'Search'; - this.cancelTitle = this.props.cancelTitle || 'Cancel'; - this.shadowHeight = this.props.shadowOffsetHeightCollapsed; - } - - componentDidUpdate(prevProps) { - if (this.props.value !== prevProps.value) { - if (this.props.value) { - this.iconDeleteAnimated = new Animated.Value(1); - } else { - this.iconDeleteAnimated = new Animated.Value(0); - } - } - } - - setSearchContainerRef = (ref) => { - this.searchContainerRef = ref; - } - - setInputKeywordRef = (ref) => { - this.inputKeywordRef = ref; - } - - blur = () => { - this.inputKeywordRef.getNode().blur(); - this.setState({expanded: false}); - this.collapseAnimation(); - }; - - focus = () => { - InteractionManager.runAfterInteractions(() => { - const input = this.inputKeywordRef.getNode(); - if (!input.isFocused()) { - input.focus(); - } - }); - }; - - onBlur = () => { - this.props.onBlur(); - }; - - onLayout = (event) => { - const contentWidth = event.nativeEvent.layout.width; - this.contentWidth = contentWidth; - this.middleWidth = contentWidth / 2; - if (this.state.expanded) { - this.expandAnimation(); - } else { - this.collapseAnimation(); - } - }; - - onLeftComponentLayout = (event) => { - const leftComponentWidth = event.nativeEvent.layout.width; - this.setState({leftComponentWidth}); - }; - - onSearch = async () => { - if (this.props.keyboardShouldPersist === false) { - await Keyboard.dismiss(); - } - - if (this.props.onSearch) { - this.props.onSearch(this.props.value); - } - }; - - onChangeText = (text) => { - Animated.timing( - this.iconDeleteAnimated, - { - toValue: (text.length > 0) ? 1 : 0, - duration: 200, - useNativeDriver: true, - }, - ).start(); - - if (this.props.onChangeText) { - this.props.onChangeText(text); - } - }; - - onFocus = () => { - InteractionManager.runAfterInteractions(async () => { - this.setState({expanded: true}); - await this.expandAnimation(); - - if (this.props.onFocus) { - this.props.onFocus(this.props.value); - } - }); - }; - - onDelete = () => { - Animated.timing( - this.iconDeleteAnimated, - { - toValue: 0, - duration: 200, - useNativeDriver: true, - }, - ).start(); - this.focus(); - - if (this.props.onDelete) { - this.props.onDelete(); - } - }; - - onCancel = async () => { - this.setState({expanded: false}); - await this.collapseAnimation(true); - - if (this.props.onCancel) { - this.props.onCancel(); - } - }; - - onSelectionChange = (event) => { - this.props.onSelectionChange(event); - }; - - expandAnimation = () => { - return new Promise((resolve) => { - Animated.parallel([ - Animated.timing( - this.inputFocusWidthAnimated, - { - toValue: this.contentWidth - 90, - duration: 200, - }, - ), - Animated.timing( - this.inputFocusAnimated, - { - toValue: this.state.leftComponentWidth, - duration: 200, - }, - ), - Animated.timing( - this.leftComponentAnimated, - { - toValue: this.contentWidth, - duration: 200, - }, - ), - Animated.timing( - this.btnCancelAnimated, - { - toValue: this.state.leftComponentWidth ? 15 - this.state.leftComponentWidth : 5, - duration: 200, - }, - ), - Animated.timing( - this.inputFocusPlaceholderAnimated, - { - toValue: this.props.placeholderExpandedMargin, - duration: 200, - }, - ), - Animated.timing( - this.iconSearchAnimated, - { - toValue: this.props.searchIconExpandedMargin, - duration: 200, - }, - ), - Animated.timing( - this.iconDeleteAnimated, - { - toValue: (this.props.value.length > 0) ? 1 : 0, - duration: 200, - useNativeDriver: true, - }, - ), - Animated.timing( - this.shadowOpacityAnimated, - { - toValue: this.props.shadowOpacityExpanded, - duration: 200, - useNativeDriver: true, - }, - ), - ]).start(); - this.shadowHeight = this.props.shadowOffsetHeightExpanded; - resolve(); - }); - }; - - collapseAnimation = (isForceAnim = false) => { - return new Promise((resolve) => { - Animated.parallel([ - ((this.props.keyboardShouldPersist === false) ? Keyboard.dismiss() : null), - Animated.timing( - this.inputFocusWidthAnimated, - { - toValue: this.contentWidth - this.state.leftComponentWidth - this.props.inputCollapsedMargin, - duration: 200, - }, - ), - Animated.timing( - this.inputFocusAnimated, - { - toValue: 0, - duration: 200, - }, - ), - Animated.timing( - this.leftComponentAnimated, - { - toValue: 0, - duration: 200, - }, - ), - Animated.timing( - this.btnCancelAnimated, - { - toValue: this.contentWidth, - duration: 200, - }, - ), - ((this.props.keyboardShouldPersist === false) ? - Animated.timing( - this.inputFocusPlaceholderAnimated, - { - toValue: this.props.placeholderCollapsedMargin, - duration: 200, - }, - ) : null), - ((this.props.keyboardShouldPersist === false || isForceAnim === true) ? - Animated.timing( - this.iconSearchAnimated, - { - toValue: (this.props.searchIconCollapsedMargin + this.state.leftComponentWidth), - duration: 200, - }, - ) : null), - Animated.timing( - this.iconDeleteAnimated, - { - toValue: 0, - duration: 200, - useNativeDriver: true, - }, - ), - Animated.timing( - this.shadowOpacityAnimated, - { - toValue: this.props.shadowOpacityCollapsed, - duration: 200, - useNativeDriver: true, - }, - ), - ]).start(({finished}) => this.props.onAnimationComplete(finished)); - this.shadowHeight = this.props.shadowOffsetHeightCollapsed; - resolve(); - }); - }; - - render() { - const {backgroundColor, ...restOfInputPropStyles} = this.props.inputStyle; - - return ( - - {((this.props.leftComponent) ? - - {this.props.leftComponent} - : - null - )} - - - - - {((this.props.iconSearch) ? - - {this.props.iconSearch} - : - - )} - - - {((this.props.iconDelete) ? - - {this.props.iconDelete} - : - - - - )} - - - - - {this.cancelTitle} - - - - - ); - } -} - -const styles = StyleSheet.create({ - container: { - backgroundColor: 'grey', - height: containerHeight, - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'center', - padding: 5, - }, - input: { - height: containerHeight - 10, - paddingTop: 7, - paddingBottom: 5, - paddingRight: 32, - borderColor: '#444', - borderRadius: 5, - fontSize: 15, - }, - iconSearch: { - flex: 1, - position: 'absolute', - }, - iconSearchDefault: { - color: 'grey', - }, - iconDelete: { - alignItems: 'flex-start', - justifyContent: 'center', - position: 'absolute', - paddingLeft: 1, - paddingTop: 3, - right: 80, - width: 25, - }, - iconDeleteDefault: { - color: 'grey', - }, - cancelButton: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: 'transparent', - minWidth: 75, - height: 50, - }, - cancelButtonText: { - fontSize: 14, - color: '#fff', - }, -}); diff --git a/app/components/sidebars/main/channels_list/channels_list.js b/app/components/sidebars/main/channels_list/channels_list.js index 01f03acf1..adbe7f49f 100644 --- a/app/components/sidebars/main/channels_list/channels_list.js +++ b/app/components/sidebars/main/channels_list/channels_list.js @@ -59,7 +59,7 @@ export default class ChannelsList extends PureComponent { cancelSearch = () => { if (this.searchBarRef) { - this.searchBarRef.cancel(); + this.searchBarRef.onCancel(); } }; @@ -124,11 +124,6 @@ export default class ChannelsList extends PureComponent { backgroundColor: changeOpacity(theme.sidebarHeaderTextColor, 0.2), color: theme.sidebarHeaderTextColor, fontSize: 15, - ...Platform.select({ - android: { - marginBottom: -5, - }, - }), }; const title = ( @@ -137,7 +132,6 @@ export default class ChannelsList extends PureComponent { ref={this.setSearchBarRef} placeholder={intl.formatMessage({id: 'mobile.channel_drawer.search', defaultMessage: 'Jump to...'})} cancelTitle={intl.formatMessage({id: 'mobile.post.cancel', defaultMessage: 'Cancel'})} - inputCollapsedMargin={0} backgroundColor='transparent' inputHeight={33} inputStyle={searchBarInput} @@ -150,16 +144,15 @@ export default class ChannelsList extends PureComponent { onCancelButtonPress={this.onSearchCancel} onChangeText={this.onSearch} onFocus={this.onSearchFocused} - searchIconCollapsedMargin={5} - searchIconExpandedMargin={5} keyboardAppearance={getKeyboardAppearanceFromTheme(theme)} value={term} + showCancel={Platform.OS === 'android'} + leftComponentWidth={67} leftComponent={( )} - positionRightDelete={5} /> ); @@ -228,10 +221,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { }, searchContainer: { flex: 1, - paddingRight: 10, + flexDirection: 'row', ...Platform.select({ android: { marginBottom: 1, + paddingRight: 17, }, ios: { marginBottom: 3, diff --git a/app/screens/channel_add_members/channel_add_members.js b/app/screens/channel_add_members/channel_add_members.js index d2adaff58..5e1ba50a7 100644 --- a/app/screens/channel_add_members/channel_add_members.js +++ b/app/screens/channel_add_members/channel_add_members.js @@ -306,11 +306,6 @@ export default class ChannelAddMembers extends PureComponent { backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), color: theme.centerChannelColor, fontSize: 15, - ...Platform.select({ - android: { - marginBottom: -5, - }, - }), }; let data; @@ -385,6 +380,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, searchBar: { marginVertical: 5, + height: 38, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/channel_members/__snapshots__/channel_members.test.js.snap b/app/screens/channel_members/__snapshots__/channel_members.test.js.snap index aea51b1dd..5b7bc6271 100644 --- a/app/screens/channel_members/__snapshots__/channel_members.test.js.snap +++ b/app/screens/channel_members/__snapshots__/channel_members.test.js.snap @@ -7,17 +7,23 @@ exports[`ChannelMembers should match snapshot 1`] = ` style={ Array [ Object { + "height": 38, "marginVertical": 5, + "paddingLeft": 8, }, null, ] } > - { }, searchBar: { marginVertical: 5, + height: 38, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/index.js b/app/screens/index.js index 5b309cc62..6668aa103 100644 --- a/app/screens/index.js +++ b/app/screens/index.js @@ -3,6 +3,8 @@ import React from 'react'; import {Platform} from 'react-native'; +import {ThemeProvider} from 'react-native-elements'; + import {Navigation} from 'react-native-navigation'; import {gestureHandlerRootHOC} from 'react-native-gesture-handler'; @@ -16,9 +18,11 @@ export function registerScreens(store, Provider) { const wrapper = (Comp) => (props) => ( // eslint-disable-line react/display-name - - - + + + + + ); diff --git a/app/screens/more_channels/__snapshots__/more_channels.test.js.snap b/app/screens/more_channels/__snapshots__/more_channels.test.js.snap index 1f8a93b0a..f8b2ce81b 100644 --- a/app/screens/more_channels/__snapshots__/more_channels.test.js.snap +++ b/app/screens/more_channels/__snapshots__/more_channels.test.js.snap @@ -8,16 +8,22 @@ exports[`MoreChannels should match snapshot 1`] = ` style={ Array [ Object { + "height": 38, "marginVertical": 5, + "paddingLeft": 8, }, null, ] } > - { return { searchBar: { marginVertical: 5, + height: 38, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/more_dms/more_dms.js b/app/screens/more_dms/more_dms.js index 1989addfb..0291349f5 100644 --- a/app/screens/more_dms/more_dms.js +++ b/app/screens/more_dms/more_dms.js @@ -424,11 +424,6 @@ export default class MoreDirectMessages extends PureComponent { backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), color: theme.centerChannelColor, fontSize: 15, - ...Platform.select({ - android: { - marginBottom: -5, - }, - }), }; let data; @@ -508,6 +503,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => { }, searchBar: { marginVertical: 5, + height: 38, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/search/search.js b/app/screens/search/search.js index 76009b402..854610f0c 100644 --- a/app/screens/search/search.js +++ b/app/screens/search/search.js @@ -729,10 +729,12 @@ export default class Search extends PureComponent { onCancelButtonPress={this.cancelSearch} onSelectionChange={this.handleSelectionChange} autoCapitalize='none' + showArrow={true} value={value} containerStyle={style.searchBarContainer} backArrowSize={28} keyboardAppearance={getKeyboardAppearanceFromTheme(theme)} + containerHeight={33} /> { }, ios: { height: 44, + paddingLeft: 8, + paddingBottom: 10, }, }), }, diff --git a/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap b/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap index aa3753838..7b60f53cf 100644 --- a/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap +++ b/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap @@ -13,17 +13,23 @@ exports[`SelectorScreen should match snapshot for channels 1`] = ` style={ Array [ Object { + "height": 38, "marginVertical": 5, + "paddingLeft": 8, }, null, ] } > - - - - - - { }, searchBar: { marginVertical: 5, + height: 38, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), }, loadingContainer: { alignItems: 'center', diff --git a/app/screens/settings/timezone/select_timezone/select_timezone.js b/app/screens/settings/timezone/select_timezone/select_timezone.js index 829588c3b..6b7368d72 100644 --- a/app/screens/settings/timezone/select_timezone/select_timezone.js +++ b/app/screens/settings/timezone/select_timezone/select_timezone.js @@ -157,6 +157,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { }, header: { backgroundColor: theme.sidebarHeaderBg, + height: 38, width: '100%', ...Platform.select({ android: { @@ -165,6 +166,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { }, ios: { height: 44, + paddingLeft: 8, }, }), }, diff --git a/package-lock.json b/package-lock.json index 5e2974804..681a12c1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5302,6 +5302,23 @@ "csstype": "^2.2.0" } }, + "@types/react-native": { + "version": "0.61.23", + "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.61.23.tgz", + "integrity": "sha512-upHmySsrVBDBokWWhYIKkKnpvadsHdioSjbBTu4xl7fjN0yb94KR5ngUOBXsyqAYqQzF+hP6qpvobG9M7Jr6hw==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-native-vector-icons": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.5.tgz", + "integrity": "sha512-JBpcjWQE4n0GlE0p6HpDDclT+uXpFC453T5k4h+B38q0utlGJhvgNr8899BoJGc1xOktA2cgqFKmFMJd0h7YaA==", + "requires": { + "@types/react": "*", + "@types/react-native": "*" + } + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", @@ -6804,6 +6821,15 @@ "object-visit": "^1.0.0" } }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6817,6 +6843,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -9742,7 +9777,8 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "optional": true } } @@ -18295,6 +18331,11 @@ "is-wsl": "^1.1.0" } }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -19215,6 +19256,36 @@ "resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-3.3.0.tgz", "integrity": "sha512-h/O8USFx1TWQT7Sx5Qj1OVpADabHawckVPDrEiGUf6qCJF2h5kKZs3ZuxZe7wHSZX4LgQE0agZqagQUK+HLIVQ==" }, + "react-native-elements": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/react-native-elements/-/react-native-elements-1.2.7.tgz", + "integrity": "sha512-0S+0R1cbItl15i64qrkWnyMztwpw60d0SUsZGVDKRAMf0Jvq9Clgyh/MzxJx2sr42mbedQP1sg5Et4fZM7Fp1w==", + "requires": { + "@types/react-native-vector-icons": "^6.4.4", + "color": "^3.1.0", + "deepmerge": "^3.1.0", + "hoist-non-react-statics": "^3.1.0", + "opencollective-postinstall": "^2.0.0", + "prop-types": "^15.7.2", + "react-native-ratings": "^6.3.0", + "react-native-status-bar-height": "^2.2.0" + }, + "dependencies": { + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==" + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + } + } + }, "react-native-exception-handler": { "version": "2.10.8", "resolved": "https://registry.npmjs.org/react-native-exception-handler/-/react-native-exception-handler-2.10.8.tgz", @@ -19352,6 +19423,15 @@ "resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-2.0.10.tgz", "integrity": "sha512-oQmWgm4tqUYyWmMNtYzNO7U/+6+WHyKiRd5cwNeE1FCJTGh8cJ5HapjHw3d6ZVfhSLzNwWqgJy1P4NpTANYa/g==" }, + "react-native-ratings": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-6.5.0.tgz", + "integrity": "sha512-YMcfQ7UQCmXGEc/WPlukHSHs5yvckTwjq5fTRk1FG8gaO7fZCNygEUGPuw4Dbvvp3IlsCUn0bOQd63RYsb7NDQ==", + "requires": { + "lodash": "^4.17.4", + "prop-types": "^15.5.10" + } + }, "react-native-safe-area": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/react-native-safe-area/-/react-native-safe-area-0.5.1.tgz", @@ -19389,6 +19469,11 @@ "prop-types": "^15.5.6" } }, + "react-native-status-bar-height": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-native-status-bar-height/-/react-native-status-bar-height-2.4.0.tgz", + "integrity": "sha512-pWvZFlyIHiuxLugLioq97vXiaGSovFXEyxt76wQtbq0gxv4dGXMPqYow46UmpwOgeJpBhqL1E0EKxnfJRrFz5w==" + }, "react-native-status-bar-size": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/react-native-status-bar-size/-/react-native-status-bar-size-0.3.3.tgz", @@ -20566,6 +20651,21 @@ "plist": "^3.0.1" } }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sisteransi": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", diff --git a/package.json b/package.json index dcb4a274b..9d02e1bb9 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "react-native-device-info": "github:mattermost/react-native-device-info#f7175f10822d8f66b9806206e3313eaf2f4aabc6", "react-native-doc-viewer": "github:mattermost/react-native-doc-viewer#c913e54ec8e4a60753bc7dd39256fa4be8229d19", "react-native-document-picker": "3.3.0", + "react-native-elements": "1.2.7", "react-native-exception-handler": "2.10.8", "react-native-fast-image": "8.1.5", "react-native-gesture-handler": "1.6.0", diff --git a/patches/react-native-elements+1.2.7.patch b/patches/react-native-elements+1.2.7.patch new file mode 100644 index 000000000..9b1ec8527 --- /dev/null +++ b/patches/react-native-elements+1.2.7.patch @@ -0,0 +1,51 @@ +diff --git a/node_modules/react-native-elements/src/searchbar/SearchBar-android.js b/node_modules/react-native-elements/src/searchbar/SearchBar-android.js +index eeaeb81..93f58de 100644 +--- a/node_modules/react-native-elements/src/searchbar/SearchBar-android.js ++++ b/node_modules/react-native-elements/src/searchbar/SearchBar-android.js +@@ -78,6 +78,12 @@ class SearchBar extends Component { + }; + } + ++ componentDidUpdate(prevProps) { ++ if (this.props.value !== prevProps.value) { ++ this.setState({isEmpty: this.props.value === ''}); ++ } ++ } ++ + render() { + const { + clearIcon, +diff --git a/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js b/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js +index 41ef6be..dbf727b 100644 +--- a/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js ++++ b/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js +@@ -41,6 +41,12 @@ class SearchBar extends Component { + }; + } + ++ componentDidUpdate(prevProps) { ++ if (this.props.value !== prevProps.value) { ++ this.setState({isEmpty: this.props.value === ''}); ++ } ++ } ++ + focus = () => { + this.input.focus(); + }; +@@ -259,7 +265,6 @@ const styles = StyleSheet.create({ + paddingBottom: 13, + paddingTop: 13, + flexDirection: 'row', +- overflow: 'hidden', + alignItems: 'center', + }, + input: { +@@ -270,7 +275,7 @@ const styles = StyleSheet.create({ + borderBottomWidth: 0, + backgroundColor: '#dcdce1', + borderRadius: 9, +- minHeight: 36, ++ minHeight: 30, + marginLeft: 8, + marginRight: 8, + }, diff --git a/share_extension/android/extension_channels/extension_channels.js b/share_extension/android/extension_channels/extension_channels.js index f69481853..c26e9a1e9 100644 --- a/share_extension/android/extension_channels/extension_channels.js +++ b/share_extension/android/extension_channels/extension_channels.js @@ -10,6 +10,7 @@ import { SectionList, Text, View, + Platform, } from 'react-native'; import {Preferences} from 'mattermost-redux/constants'; @@ -251,6 +252,12 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { }, searchContainer: { paddingBottom: 2, + height: 38, + ...Platform.select({ + ios: { + paddingLeft: 8, + }, + }), }, searchBarInput: { backgroundColor: '#fff',