import ActionButton from 'react-native-action-button'; import React from 'react'; import PropTypes from 'prop-types'; import Icon from 'react-native-vector-icons/Ionicons'; import { Platform, View, TextInput, FlatList, LayoutAnimation } from 'react-native'; import { connect } from 'react-redux'; import database from '../../lib/realm'; import RocketChat from '../../lib/rocketchat'; import RoomItem from '../../presentation/RoomItem'; import { goRoom } from '../../containers/routes/NavigationService'; import Header from '../../containers/Header'; import RoomsListHeader from './Header'; import styles from './styles'; import throttle from '../../utils/throttle'; @connect(state => ({ user: state.login.user, server: state.server.server, Site_Url: state.settings.Site_Url, searchText: state.rooms.searchText })) export default class RoomsListView extends React.Component { static propTypes = { navigation: PropTypes.object.isRequired, user: PropTypes.object, Site_Url: PropTypes.string, server: PropTypes.string, searchText: PropTypes.string } static navigationOptions = ({ navigation }) => ({ header:
} /> }); constructor(props) { super(props); this.state = { search: [] }; this._keyExtractor = this._keyExtractor.bind(this); this.data = database.objects('subscriptions').filtered('archived != true && open == true').sorted('roomUpdatedAt', true); } componentDidMount() { this.data.addListener(this.updateState); this.props.navigation.setParams({ createChannel: () => this._createChannel() }); this.updateState(); } componentWillReceiveProps(props) { if (this.props.server !== props.server) { this.data.removeListener(this.updateState); this.data = database.objects('subscriptions').filtered('archived != true && open == true').sorted('roomUpdatedAt', true); this.data.addListener(this.updateState); } else if (this.props.searchText !== props.searchText) { this.search(props.searchText); } } componentWillUnmount() { this.updateState.stop(); this.data.removeAllListeners(); } onSearchChangeText(text) { this.search(text); } updateState = throttle(() => { LayoutAnimation.easeInEaseOut(); this.forceUpdate(); }, 1500); async search(text) { const searchText = text.trim(); if (searchText === '') { delete this.oldPromise; return this.setState({ search: [] }); } let data = database.objects('subscriptions').filtered('name CONTAINS[c] $0', searchText).slice(0, 7); const usernames = data.map(sub => sub.map); try { if (data.length < 7) { if (this.oldPromise) { this.oldPromise('cancel'); } const { users, rooms } = await Promise.race([ RocketChat.spotlight(searchText, usernames, { users: true, rooms: true }), new Promise((resolve, reject) => this.oldPromise = reject) ]); data = data.concat(users.map(user => ({ ...user, rid: user.username, name: user.username, t: 'd', search: true })), rooms.map(room => ({ rid: room._id, ...room, search: true }))); delete this.oldPromise; } this.setState({ search: data }); } catch (e) { // alert(JSON.stringify(e)); } } _onPressItem = async(item = {}) => { // if user is using the search we need first to join/create room if (!item.search) { return this.props.navigation.navigate({ key: `Room-${ item._id }`, routeName: 'Room', params: { room: item, ...item } }); } if (item.t === 'd') { const sub = await RocketChat.createDirectMessageAndWait(item.username); return goRoom({ room: sub, name: sub.name }); } return goRoom(item); } _createChannel() { this.props.navigation.navigate({ key: 'SelectedUsers', routeName: 'SelectedUsers', params: { nextAction: () => this.props.navigation.navigate('CreateChannel') } }); } _keyExtractor(item) { return item.rid.replace(this.props.user.id, '').trim(); } renderSearchBar = () => ( this.onSearchChangeText(text)} returnKeyType='search' placeholder='Search' clearButtonMode='while-editing' blurOnSubmit /> ); renderItem = ({ item }) => { const id = item.rid.replace(this.props.user.id, '').trim(); return ( this._onPressItem(item)} />); } renderList = () => ( 0 ? this.state.search : this.data} keyExtractor={this._keyExtractor} style={styles.list} renderItem={this.renderItem} ListHeaderComponent={Platform.OS === 'ios' ? this.renderSearchBar : null} contentOffset={Platform.OS === 'ios' ? { x: 0, y: 38 } : {}} enableEmptySections removeClippedSubviews keyboardShouldPersistTaps='always' /> ) renderCreateButtons = () => ( { this._createChannel(); }} > ); render = () => ( {this.renderList()} {Platform.OS === 'android' && this.renderCreateButtons()} ) }