import { routeActions } from 'react-router-redux'; import { broadcast, inform, addMessage, addMessages } from './actions/message'; import { select } from './actions/tab'; import { normalizeChannel } from './util'; function withReason(message, reason) { return message + (reason ? ` (${reason})` : ''); } function findChannels(state, server, user) { const channels = []; state.channels.get(server).forEach((channel, channelName) => { if (channel.get('users').find(u => u.nick === user)) { channels.push(channelName); } }); return channels; } export default function handleSocket(socket, { dispatch, getState }) { const handlers = { message(message) { dispatch(addMessage(message)); }, pm(message) { dispatch(addMessage(message)); }, join(data) { const state = getState(); const { server, channel } = state.tab.selected; if (server && channel) { const { nick } = state.servers.get(server); const [joinedChannel] = data.channels; if (server === data.server && nick === data.user && channel !== joinedChannel && normalizeChannel(channel) === normalizeChannel(joinedChannel)) { dispatch(select(server, joinedChannel)); } } dispatch(inform(`${data.user} joined the channel`, data.server, data.channels[0])); }, servers(data) { if (!data) { dispatch(routeActions.replace('/connect')); } }, part({ user, server, channel, reason }) { dispatch(inform(withReason(`${user} left the channel`, reason), server, channel)); }, quit({ user, server, reason }) { const channels = findChannels(getState(), server, user); dispatch(broadcast(withReason(`${user} quit`, reason), server, channels)); }, nick(data) { const channels = findChannels(getState(), data.server, data.old); dispatch(broadcast(`${data.old} changed nick to ${data.new}`, data.server, channels)); }, motd({ content, server }) { dispatch(addMessages(content.map(line => ({ server, to: server, content: line })))); }, whois(data) { const tab = getState().tab.selected; dispatch(inform([ `Nick: ${data.nick}`, `Username: ${data.username}`, `Realname: ${data.realname}`, `Host: ${data.host}`, `Server: ${data.server}`, `Channels: ${data.channels}` ], tab.server, tab.channel)); }, print({ server, message }) { dispatch(inform(message, server)); } }; socket.onMessage((type, data) => { if (type in handlers) { handlers[type](data); } type = `SOCKET_${type.toUpperCase()}`; if (Array.isArray(data)) { dispatch({ type, data }); } else { dispatch({ type, ...data }); } }); }