import { createSelector } from 'reselect'; import get from 'lodash/get'; import createReducer from 'utils/createReducer'; import { getSelectedTab, updateSelection } from './tab'; import * as actions from './actions'; export const getServers = state => state.servers; export const getCurrentNick = createSelector( getServers, getSelectedTab, (servers, tab) => { if (!servers[tab.server]) { return; } const { editedNick } = servers[tab.server]; if (editedNick === null) { return servers[tab.server].nick; } return editedNick; } ); export const getCurrentServerName = createSelector( getServers, getSelectedTab, (servers, tab) => get(servers, [tab.server, 'name']) ); export const getCurrentServerStatus = createSelector( getServers, getSelectedTab, (servers, tab) => get(servers, [tab.server, 'status'], {}) ); export default createReducer( {}, { [actions.CONNECT](state, { host, nick, name }) { if (!state[host]) { state[host] = { nick, editedNick: null, name: name || host, status: { connected: false, error: null }, features: {} }; } }, [actions.DISCONNECT](state, { server }) { delete state[server]; }, [actions.SET_SERVER_NAME](state, { server, name }) { state[server].name = name; }, [actions.SET_NICK](state, { server, nick, editing }) { if (editing) { state[server].editedNick = nick; } else if (nick === '') { state[server].editedNick = null; } }, [actions.socket.NICK](state, { server, oldNick, newNick }) { if (!oldNick || oldNick === state[server].nick) { state[server].nick = newNick; state[server].editedNick = null; } }, [actions.socket.NICK_FAIL](state, { server }) { state[server].editedNick = null; }, [actions.socket.SERVERS](state, { data }) { if (data) { data.forEach(({ host, name = host, nick, status, features = {} }) => { state[host] = { name, nick, status, features, editedNick: null }; }); } }, [actions.socket.CONNECTION_UPDATE](state, { server, connected, error }) { if (state[server]) { state[server].status.connected = connected; state[server].status.error = error; } }, [actions.socket.FEATURES](state, { server, features }) { const srv = state[server]; if (srv) { srv.features = features; if (features.NETWORK && srv.name === server) { srv.name = features.NETWORK; } } } } ); export function connect(config) { return { type: actions.CONNECT, ...config, socket: { type: 'connect', data: config } }; } export function disconnect(server) { return dispatch => { dispatch({ type: actions.DISCONNECT, server, socket: { type: 'quit', data: { server } } }); dispatch(updateSelection()); }; } export function reconnect(server, settings) { return { type: actions.RECONNECT, server, settings, socket: { type: 'reconnect', data: { ...settings, server } } }; } export function whois(user, server) { return { type: actions.WHOIS, user, server, socket: { type: 'whois', data: { user, server } } }; } export function away(message, server) { return { type: actions.AWAY, message, server, socket: { type: 'away', data: { message, server } } }; } export function setNick(nick, server, editing) { nick = nick.trim().replace(' ', ''); const action = { type: actions.SET_NICK, nick, server, editing }; if (!editing && nick !== '') { action.socket = { type: 'nick', data: { newNick: nick, server } }; } return action; } export function isValidServerName(name) { return name.trim() !== ''; } export function setServerName(name, server) { const action = { type: actions.SET_SERVER_NAME, name, server }; if (isValidServerName(name)) { action.socket = { type: 'set_server_name', data: { name, server }, debounce: { delay: 500, key: `server_name:${server}` } }; } return action; }