diff --git a/app/components/search_bar/search_bar.android.js b/app/components/search_bar/search_bar.android.js index bcc15db7a..5fb745942 100644 --- a/app/components/search_bar/search_bar.android.js +++ b/app/components/search_bar/search_bar.android.js @@ -44,6 +44,7 @@ export default class SearchBarAndroid extends PureComponent { showArrow: PropTypes.bool, value: PropTypes.string, containerStyle: CustomPropTypes.Style, + leftComponent: PropTypes.element, }; static defaultProps = { @@ -63,6 +64,7 @@ export default class SearchBarAndroid extends PureComponent { onBlur: () => true, onSelectionChange: () => true, value: '', + leftComponent: null, }; constructor(props) { @@ -174,6 +176,7 @@ export default class SearchBarAndroid extends PureComponent { backgroundColor && {backgroundColor}, ]} > + {!isFocused && this.props.leftComponent} true, onSelectionChange: () => true, blurOnSubmit: true, + leftComponent: null, }; cancel = () => { diff --git a/app/components/search_bar/search_box.js b/app/components/search_bar/search_box.js index f9dee6d91..02ea12211 100644 --- a/app/components/search_bar/search_box.js +++ b/app/components/search_bar/search_box.js @@ -75,6 +75,7 @@ export default class Search extends Component { shadowOpacityExpanded: PropTypes.number, shadowRadius: PropTypes.number, shadowVisible: PropTypes.bool, + leftComponent: PropTypes.element, }; static defaultProps = { @@ -97,6 +98,7 @@ export default class Search extends Component { shadowRadius: 4, shadowVisible: false, value: '', + leftComponent: null, }; constructor(props) { @@ -104,6 +106,7 @@ export default class Search extends Component { this.state = { expanded: false, + leftComponentWidth: 0, }; const {width} = Dimensions.get('window'); this.contentWidth = width; @@ -111,6 +114,8 @@ export default class Search extends Component { 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); @@ -161,6 +166,11 @@ export default class Search extends Component { } }; + onLeftComponentLayout = (event) => { + const leftComponentWidth = event.nativeEvent.layout.width; + this.setState({leftComponentWidth}); + }; + onSearch = async () => { if (this.props.keyboardShouldPersist === false) { await Keyboard.dismiss(); @@ -177,6 +187,7 @@ export default class Search extends Component { { toValue: (text.length > 0) ? 1 : 0, duration: 200, + useNativeDriver: true, } ).start(); @@ -202,6 +213,7 @@ export default class Search extends Component { { toValue: 0, duration: 200, + useNativeDriver: true, } ).start(); this.focus(); @@ -233,43 +245,59 @@ export default class Search extends Component { toValue: this.contentWidth - 70, duration: 200, } - ).start(), + ), + Animated.timing( + this.inputFocusAnimated, + { + toValue: this.state.leftComponentWidth, + duration: 200, + } + ), + Animated.timing( + this.leftComponentAnimated, + { + toValue: this.contentWidth, + duration: 200, + } + ), Animated.timing( this.btnCancelAnimated, { - toValue: 10, + toValue: this.state.leftComponentWidth ? 15 - this.state.leftComponentWidth : 10, duration: 200, } - ).start(), + ), Animated.timing( this.inputFocusPlaceholderAnimated, { toValue: this.props.placeholderExpandedMargin, duration: 200, } - ).start(), + ), Animated.timing( this.iconSearchAnimated, { toValue: this.props.searchIconExpandedMargin, duration: 200, } - ).start(), + ), Animated.timing( this.iconDeleteAnimated, { toValue: (this.props.value.length > 0) ? 1 : 0, duration: 200, + useNativeDriver: true, } - ).start(), + ), Animated.timing( this.shadowOpacityAnimated, { toValue: this.props.shadowOpacityExpanded, duration: 200, + useNativeDriver: true, } - ).start(), - ]); + ), + ]).start(); this.shadowHeight = this.props.shadowOffsetHeightExpanded; resolve(); }); @@ -282,17 +310,31 @@ export default class Search extends Component { Animated.timing( this.inputFocusWidthAnimated, { - toValue: this.contentWidth - 10, + toValue: this.contentWidth - this.state.leftComponentWidth - 10, duration: 200, } - ).start(), + ), + 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, } - ).start(), + ), ((this.props.keyboardShouldPersist === false) ? Animated.timing( this.inputFocusPlaceholderAnimated, @@ -300,30 +342,32 @@ export default class Search extends Component { toValue: this.props.placeholderCollapsedMargin, duration: 200, } - ).start() : null), + ) : null), ((this.props.keyboardShouldPersist === false || isForceAnim === true) ? Animated.timing( this.iconSearchAnimated, { - toValue: this.props.searchIconCollapsedMargin, + toValue: this.props.searchIconCollapsedMargin + this.state.leftComponentWidth, duration: 200, } - ).start() : null), + ) : null), Animated.timing( this.iconDeleteAnimated, { toValue: 0, duration: 200, + useNativeDriver: true, } - ).start(), + ), Animated.timing( this.shadowOpacityAnimated, { toValue: this.props.shadowOpacityCollapsed, duration: 200, + useNativeDriver: true, } - ).start(), - ]); + ), + ]).start(); this.shadowHeight = this.props.shadowOffsetHeightCollapsed; resolve(); }); @@ -331,16 +375,27 @@ export default class Search extends Component { render() { const {backgroundColor, ...restOfInputPropStyles} = this.props.inputStyle; + return ( - + {((this.props.leftComponent) ? + + {this.props.leftComponent} + : + null + )} + - + {((this.props.iconSearch) ? + )} /> ); @@ -155,12 +160,6 @@ export default class ChannelsList extends PureComponent { > - - - {title} diff --git a/app/components/sidebars/main/channels_list/switch_teams_button/switch_teams_button.js b/app/components/sidebars/main/channels_list/switch_teams_button/switch_teams_button.js index 772b6f1aa..928136e63 100644 --- a/app/components/sidebars/main/channels_list/switch_teams_button/switch_teams_button.js +++ b/app/components/sidebars/main/channels_list/switch_teams_button/switch_teams_button.js @@ -18,7 +18,6 @@ import TeamIcon from 'app/components/team_icon'; export default class SwitchTeamsButton extends React.PureComponent { static propTypes = { currentTeamId: PropTypes.string, - searching: PropTypes.bool.isRequired, onShowTeams: PropTypes.func.isRequired, mentionCount: PropTypes.number.isRequired, teamsCount: PropTypes.number.isRequired, @@ -33,7 +32,6 @@ export default class SwitchTeamsButton extends React.PureComponent { const { currentTeamId, mentionCount, - searching, teamsCount, theme, } = this.props; @@ -42,7 +40,7 @@ export default class SwitchTeamsButton extends React.PureComponent { return null; } - if (searching || teamsCount < 2) { + if (teamsCount < 2) { return null; } diff --git a/app/components/sidebars/main/main_sidebar.js b/app/components/sidebars/main/main_sidebar.js index b837a04a7..0b9b246b9 100644 --- a/app/components/sidebars/main/main_sidebar.js +++ b/app/components/sidebars/main/main_sidebar.js @@ -63,6 +63,7 @@ export default class ChannelSidebar extends Component { show: false, openDrawerOffset, drawerOpened: false, + searching: false, }; } @@ -92,9 +93,9 @@ export default class ChannelSidebar extends Component { shouldComponentUpdate(nextProps, nextState) { const {currentTeamId, deviceWidth, isLandscape, teamsCount} = this.props; - const {openDrawerOffset} = this.state; + const {openDrawerOffset, show, searching} = this.state; - if (nextState.openDrawerOffset !== openDrawerOffset || nextState.show !== this.state.show) { + if (nextState.openDrawerOffset !== openDrawerOffset || nextState.show !== show || nextState.searching !== searching) { return true; } @@ -258,24 +259,14 @@ export default class ChannelSidebar extends Component { }; onSearchEnds = () => { - //hack to update the drawer when the offset changes - const {isLandscape, isTablet} = this.props; - - let openDrawerOffset = DRAWER_INITIAL_OFFSET; - if (isLandscape || isTablet) { - openDrawerOffset = DRAWER_LANDSCAPE_OFFSET; - } - if (this.refs.drawer) { - this.refs.drawer.canClose = true; - } - this.setState({openDrawerOffset}); + this.setState({searching: false}); }; onSearchStart = () => { if (this.refs.drawer) { this.refs.drawer.canClose = false; } - this.setState({openDrawerOffset: 0}); + this.setState({searching: true}); }; showTeams = () => { @@ -300,6 +291,7 @@ export default class ChannelSidebar extends Component { const { show, openDrawerOffset, + searching, } = this.state; if (!show) { @@ -307,7 +299,7 @@ export default class ChannelSidebar extends Component { } const multipleTeams = teamsCount > 1; - const showTeams = openDrawerOffset !== 0 && multipleTeams; + const showTeams = !searching && multipleTeams; if (this.drawerSwiper) { if (multipleTeams) { this.drawerSwiper.getWrappedInstance().runOnLayout(); 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 c42a68f7f..f8b923121 100644 --- a/app/screens/more_channels/__snapshots__/more_channels.test.js.snap +++ b/app/screens/more_channels/__snapshots__/more_channels.test.js.snap @@ -23,6 +23,7 @@ exports[`MoreChannels should match snapshot 1`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]} 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 ba688bd43..0a4ea823e 100644 --- a/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap +++ b/app/screens/selector_screen/__snapshots__/selector_screen.test.js.snap @@ -30,6 +30,7 @@ exports[`SelectorScreen should match snapshot for channels 1`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]} @@ -117,6 +118,7 @@ exports[`SelectorScreen should match snapshot for channels 2`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]} @@ -204,6 +206,7 @@ exports[`SelectorScreen should match snapshot for explicit options 1`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]} @@ -298,6 +301,7 @@ exports[`SelectorScreen should match snapshot for searching 1`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]} @@ -385,6 +389,7 @@ exports[`SelectorScreen should match snapshot for users 1`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]} @@ -472,6 +477,7 @@ exports[`SelectorScreen should match snapshot for users 2`] = ` "fontSize": 15, } } + leftComponent={null} onBlur={[Function]} onCancelButtonPress={[Function]} onChangeText={[Function]}