import React from 'react'; import PropTypes from 'prop-types'; import { FlatList, StyleSheet, Text, View } from 'react-native'; import { connect } from 'react-redux'; import { Q } from '@nozbe/watermelondb'; import * as List from '../containers/List'; import Touch from '../utils/touch'; import database from '../lib/database'; import RocketChat from '../lib/rocketchat'; import UserItem from '../presentation/UserItem'; import I18n from '../i18n'; import log, { events, logEvent } from '../utils/log'; import SearchBox from '../containers/SearchBox'; import { CustomIcon } from '../lib/Icons'; import * as HeaderButton from '../containers/HeaderButton'; import StatusBar from '../containers/StatusBar'; import { themes } from '../constants/colors'; import { withTheme } from '../theme'; import { getUserSelector } from '../selectors/login'; import Navigation from '../lib/Navigation'; import { createChannelRequest } from '../actions/createChannel'; import { goRoom } from '../utils/goRoom'; import SafeAreaView from '../containers/SafeAreaView'; import { compareServerVersion, methods } from '../lib/utils'; import sharedStyles from './Styles'; const QUERY_SIZE = 50; const styles = StyleSheet.create({ button: { height: 46, flexDirection: 'row', alignItems: 'center' }, buttonIcon: { marginLeft: 18, marginRight: 16 }, buttonText: { fontSize: 17, ...sharedStyles.textRegular }, buttonContainer: { paddingVertical: 25 } }); class NewMessageView extends React.Component { static navigationOptions = ({ navigation }) => ({ headerLeft: () => , title: I18n.t('New_Message') }); static propTypes = { navigation: PropTypes.object, baseUrl: PropTypes.string, user: PropTypes.shape({ id: PropTypes.string, token: PropTypes.string }), create: PropTypes.func, maxUsers: PropTypes.number, theme: PropTypes.string, isMasterDetail: PropTypes.bool, serverVersion: PropTypes.string }; constructor(props) { super(props); this.init(); this.state = { search: [], chats: [] }; } // eslint-disable-next-line react/sort-comp init = async () => { try { const db = database.active; const chats = await db.collections .get('subscriptions') .query(Q.where('t', 'd'), Q.experimentalTake(QUERY_SIZE), Q.experimentalSortBy('room_updated_at', Q.desc)) .fetch(); this.setState({ chats }); } catch (e) { log(e); } }; onSearchChangeText(text) { this.search(text); } dismiss = () => { const { navigation } = this.props; return navigation.pop(); }; search = async text => { const result = await RocketChat.search({ text, filterRooms: false }); this.setState({ search: result }); }; createChannel = () => { logEvent(events.NEW_MSG_CREATE_CHANNEL); const { navigation } = this.props; navigation.navigate('SelectedUsersViewCreateChannel', { nextAction: () => navigation.navigate('CreateChannelView') }); }; createTeam = () => { logEvent(events.NEW_MSG_CREATE_TEAM); const { navigation } = this.props; navigation.navigate('SelectedUsersViewCreateChannel', { nextAction: () => navigation.navigate('CreateChannelView', { isTeam: true }) }); }; createGroupChat = () => { logEvent(events.NEW_MSG_CREATE_GROUP_CHAT); const { create, maxUsers, navigation } = this.props; navigation.navigate('SelectedUsersViewCreateChannel', { nextAction: () => create({ group: true }), buttonText: I18n.t('Create'), maxUsers }); }; goRoom = item => { logEvent(events.NEW_MSG_CHAT_WITH_USER); const { isMasterDetail, navigation } = this.props; if (isMasterDetail) { navigation.pop(); } goRoom({ item, isMasterDetail }); }; renderButton = ({ onPress, testID, title, icon, first }) => { const { theme } = this.props; return ( {title} ); }; createDiscussion = () => { logEvent(events.NEW_MSG_CREATE_DISCUSSION); Navigation.navigate('CreateDiscussionView'); }; renderHeader = () => { const { maxUsers, theme, serverVersion } = this.props; return ( this.onSearchChangeText(text)} testID='new-message-view-search' /> {this.renderButton({ onPress: this.createChannel, title: I18n.t('Create_Channel'), icon: 'channel-public', testID: 'new-message-view-create-channel', first: true })} {compareServerVersion(serverVersion, '3.13.0', methods.greaterThanOrEqualTo) ? this.renderButton({ onPress: this.createTeam, title: I18n.t('Create_Team'), icon: 'teams', testID: 'new-message-view-create-team' }) : null} {maxUsers > 2 ? this.renderButton({ onPress: this.createGroupChat, title: I18n.t('Create_Direct_Messages'), icon: 'message', testID: 'new-message-view-create-direct-message' }) : null} {this.renderButton({ onPress: this.createDiscussion, title: I18n.t('Create_Discussion'), icon: 'discussions', testID: 'new-message-view-create-discussion' })} ); }; renderItem = ({ item, index }) => { const { search, chats } = this.state; const { baseUrl, user, theme } = this.props; let style = { borderColor: themes[theme].separatorColor }; if (index === 0) { style = { ...style, ...sharedStyles.separatorTop }; } if (search.length > 0 && index === search.length - 1) { style = { ...style, ...sharedStyles.separatorBottom }; } if (search.length === 0 && index === chats.length - 1) { style = { ...style, ...sharedStyles.separatorBottom }; } return ( this.goRoom(item)} baseUrl={baseUrl} testID={`new-message-view-item-${item.name}`} style={style} user={user} theme={theme} /> ); }; renderList = () => { const { search, chats } = this.state; const { theme } = this.props; return ( 0 ? search : chats} extraData={this.state} keyExtractor={item => item._id} ListHeaderComponent={this.renderHeader} renderItem={this.renderItem} ItemSeparatorComponent={List.Separator} contentContainerStyle={{ backgroundColor: themes[theme].backgroundColor }} keyboardShouldPersistTaps='always' /> ); }; render() { return ( {this.renderList()} ); } } const mapStateToProps = state => ({ serverVersion: state.server.version, isMasterDetail: state.app.isMasterDetail, baseUrl: state.server.server, maxUsers: state.settings.DirectMesssage_maxUsers || 1, user: getUserSelector(state) }); const mapDispatchToProps = dispatch => ({ create: params => dispatch(createChannelRequest(params)) }); export default connect(mapStateToProps, mapDispatchToProps)(withTheme(NewMessageView));