diff --git a/app/containers/routes/AuthRoutes.js b/app/containers/routes/AuthRoutes.js index c50ce6c6a..a5ab0837d 100644 --- a/app/containers/routes/AuthRoutes.js +++ b/app/containers/routes/AuthRoutes.js @@ -13,12 +13,7 @@ const AuthRoutes = StackNavigator( screen: RoomsListView }, Room: { - screen: RoomView, - navigationOptions({ navigation }) { - return { - title: navigation.state.params.name || navigation.state.params.room.name || 'Room' - }; - } + screen: RoomView }, CreateChannel: { screen: CreateChannelView, diff --git a/app/views/RoomView/Header/index.js b/app/views/RoomView/Header/index.js new file mode 100644 index 000000000..7b29da837 --- /dev/null +++ b/app/views/RoomView/Header/index.js @@ -0,0 +1,219 @@ +import React from 'react'; +import { Text, View, Platform, TouchableOpacity, TextInput } from 'react-native'; +import Icon from 'react-native-vector-icons/Ionicons'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import Modal from 'react-native-modal'; +import { CachedImage } from 'react-native-img-cache'; + +import Avatar from '../../../containers/Avatar'; +import RocketChat from '../../../lib/rocketchat'; +import { STATUS_COLORS } from '../../../constants/colors'; +import { setSearch } from '../../../actions/rooms'; +import styles from './styles'; + +@connect(state => ({ + user: state.login.user, + baseUrl: state.settings.Site_Url +}), dispatch => ({ + setSearch: searchText => dispatch(setSearch(searchText)) +})) +export default class extends React.Component { + static propTypes = { + navigation: PropTypes.object.isRequired, + user: PropTypes.object.isRequired, + baseUrl: PropTypes.string, + setSearch: PropTypes.func + } + + constructor(props) { + super(props); + this.state = { + isModalVisible: false, + searching: false + }; + } + + onPressModalButton(status) { + RocketChat.setUserPresenceDefaultStatus(status); + this.hideModal(); + } + + onSearchChangeText(text) { + this.props.setSearch(text.trim()); + } + + onPressCancelSearchButton() { + this.setState({ searching: false }); + this.props.setSearch(''); + } + + onPressSearchButton() { + this.setState({ searching: true }); + requestAnimationFrame(() => { + this.inputSearch.focus(); + }); + } + + showModal() { + this.setState({ isModalVisible: true }); + } + + hideModal() { + this.setState({ isModalVisible: false }); + } + + createChannel() { + this.props.navigation.navigate('SelectUsers'); + } + + renderLeft() { + return ( + + this.props.navigation.navigate('DrawerOpen')} + > + + + + ); + } + + renderTitle() { + if (!this.props.user.username) { + return null; + } + return ( + this.showModal()}> + + + {this.props.user.username} + + ); + } + + renderRight() { + return ( + + {Platform.OS === 'android' ? + this.onPressSearchButton()} + > + + : null} + {Platform.OS === 'ios' ? + this.createChannel()} + > + + : null} + + ); + } + + renderModalButton = (status, text) => { + const statusStyle = [styles.status, { backgroundColor: STATUS_COLORS[status] }]; + const textStyle = { flex: 1, fontWeight: this.props.user.status === status ? 'bold' : 'normal' }; + return ( + this.onPressModalButton(status)} + > + + + {text || status.charAt(0).toUpperCase() + status.slice(1)} + + + ); + }; + + renderHeader() { + if (this.state.searching) { + return null; + } + return ( + + {this.renderLeft()} + {this.renderTitle()} + {this.renderRight()} + + ); + } + + renderSearch() { + if (!this.state.searching) { + return null; + } + return ( + + + this.onPressCancelSearchButton()} + > + + + + this.inputSearch = inputSearch} + underlineColorAndroid='transparent' + style={styles.inputSearch} + onChangeText={text => this.onSearchChangeText(text)} + returnKeyType='search' + placeholder='Search' + clearButtonMode='while-editing' + blurOnSubmit + /> + + ); + } + + render() { + return ( + + {this.renderHeader()} + {this.renderSearch()} + this.hideModal()} + onBackdropPress={() => this.hideModal()} + > + + {this.renderModalButton('online')} + {this.renderModalButton('busy')} + {this.renderModalButton('away')} + {this.renderModalButton('offline', 'Invisible')} + + + + ); + } +} diff --git a/app/views/RoomView/Header/styles.js b/app/views/RoomView/Header/styles.js new file mode 100644 index 000000000..33d252ce8 --- /dev/null +++ b/app/views/RoomView/Header/styles.js @@ -0,0 +1,75 @@ +import { StyleSheet, Platform, Dimensions } from 'react-native'; + +const TITLE_OFFSET = Platform.OS === 'ios' ? 70 : 56; +const { width } = Dimensions.get('window'); +export default StyleSheet.create({ + header: { + flexDirection: 'row', + alignItems: 'center', + flex: 1 + }, + titleContainer: { + left: TITLE_OFFSET, + right: TITLE_OFFSET, + position: 'absolute', + alignItems: 'center', + justifyContent: Platform.OS === 'ios' ? 'center' : 'flex-start', + flexDirection: 'row', + height: 44 + }, + status: { + borderRadius: 4, + width: 8, + height: 8, + marginRight: 10 + }, + avatar: { + marginRight: 10 + }, + title: { + fontWeight: '500', + color: '#292E35' + }, + left: { + left: 0, + position: 'absolute' + }, + right: { + right: 0, + position: 'absolute', + flexDirection: 'row' + }, + modal: { + width: width - 60, + height: width - 60, + backgroundColor: '#F7F7F7', + borderRadius: 4, + flexDirection: 'column' + }, + modalButton: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'transparent', + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: 'rgba(0, 0, 0, .3)', + paddingHorizontal: 20 + }, + headerButton: { + backgroundColor: 'transparent', + height: 44, + width: 44, + alignItems: 'center', + justifyContent: 'center' + }, + serverImage: { + width: 24, + height: 24, + borderRadius: 4 + }, + inputSearch: { + flex: 1, + marginLeft: 44 + } +}); diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index 0d66595a7..3daaaddb3 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -15,6 +15,8 @@ import MessageActions from '../../containers/MessageActions'; import MessageBox from '../../containers/MessageBox'; import Typing from '../../containers/Typing'; import KeyboardView from '../../presentation/KeyboardView'; +import Header from '../../containers/Header'; +import RoomsHeader from './Header'; const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1._id !== r2._id }); const styles = StyleSheet.create({ @@ -78,6 +80,10 @@ export default class RoomView extends React.Component { loading: PropTypes.bool }; + static navigationOptions = ({ navigation }) => ({ + header:
} /> + }); + constructor(props) { super(props); this.rid =