import React, { Component } from 'react'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { createSelector, createStructuredSelector } from 'reselect'; import { List, Map } from 'immutable'; import pure from 'pure-render-decorator'; import ChatTitle from '../components/ChatTitle'; import Search from '../components/Search'; import MessageBox from '../components/MessageBox'; import MessageInput from '../components/MessageInput'; import UserList from '../components/UserList'; import { part } from '../actions/channel'; import { openPrivateChat, closePrivateChat } from '../actions/privateChat'; import { searchMessages, toggleSearch } from '../actions/search'; import { select, setSelectedChannel, setSelectedUser } from '../actions/tab'; import { runCommand, sendMessage, updateMessageHeight } from '../actions/message'; import { disconnect } from '../actions/server'; import { setWrapWidth, setCharWidth } from '../actions/environment'; import { stringWidth } from '../util'; import { toggleUserList } from '../actions/ui'; import * as inputHistoryActions from '../actions/inputHistory'; function updateSelected({ params, dispatch }) { if (params.channel) { dispatch(setSelectedChannel(params.server, params.channel)); } else if (params.user) { dispatch(setSelectedUser(params.server, params.user)); } else if (params.server) { dispatch(setSelectedChannel(params.server)); } } function updateCharWidth() { const charWidth = stringWidth(' ', '16px Roboto Mono'); window.messageIndent = 6 * charWidth; return setCharWidth(charWidth); } @pure class Chat extends Component { componentWillMount() { const { dispatch } = this.props; dispatch(updateCharWidth()); setTimeout(() => dispatch(updateCharWidth()), 1000); } componentDidMount() { updateSelected(this.props); } componentWillReceiveProps(nextProps) { if (nextProps.params.server !== this.props.params.server || nextProps.params.channel !== this.props.params.channel || nextProps.params.user !== this.props.params.user) { updateSelected(nextProps); } } handleSearch = phrase => { const { dispatch, tab } = this.props; if (tab.channel) { dispatch(searchMessages(tab.server, tab.channel, phrase)); } }; render() { const { title, tab, channel, search, history, messages, users, showUserList, inputActions } = this.props; let chatClass; if (tab.channel) { chatClass = 'chat-channel'; } else if (tab.user) { chatClass = 'chat-private'; } else { chatClass = 'chat-server'; } return (
); } } const tabSelector = state => state.tab.selected; const messageSelector = state => state.messages; const serverSelector = state => state.servers; const channelSelector = state => state.channels; const searchSelector = state => state.search; const showUserListSelector = state => state.ui.showUserList; const historySelector = state => state.input.index === -1 ? null : state.input.history.get(state.input.index); const selectedMessagesSelector = createSelector( tabSelector, messageSelector, (tab, messages) => messages.getIn([tab.server, tab.channel || tab.user || tab.server], List()) ); const selectedChannelSelector = createSelector( tabSelector, channelSelector, (tab, channels) => channels.getIn([tab.server, tab.channel], Map()) ); const usersSelector = createSelector( selectedChannelSelector, channel => channel.get('users', List()) ); const titleSelector = createSelector( tabSelector, serverSelector, (tab, servers) => tab.channel || tab.user || servers.getIn([tab.server, 'name']) ); const mapStateToProps = createStructuredSelector({ title: titleSelector, tab: tabSelector, channel: selectedChannelSelector, messages: selectedMessagesSelector, users: usersSelector, showUserList: showUserListSelector, search: searchSelector, history: historySelector }); function mapDispatchToProps(dispatch) { return { dispatch, ...bindActionCreators({ select, toggleSearch, toggleUserList, searchMessages, runCommand, sendMessage, part, disconnect, openPrivateChat, closePrivateChat, setWrapWidth, updateMessageHeight }, dispatch), inputActions: bindActionCreators(inputHistoryActions, dispatch) }; } export default connect(mapStateToProps, mapDispatchToProps)(Chat);