2017-06-21 07:23:07 +02:00

215 lines
4.2 KiB
JavaScript

import { Map, Record } from 'immutable';
import { createSelector } from 'reselect';
import createReducer from '../util/createReducer';
import { getSelectedTab, updateSelection } from './tab';
import * as actions from './actions';
const Server = Record({
nick: '',
editedNick: null,
name: '',
connected: false
});
export const getServers = state => state.servers;
export const getCurrentNick = createSelector(
getServers,
getSelectedTab,
(servers, tab) => {
const editedNick = servers.getIn([tab.server, 'editedNick']);
if (editedNick === null) {
return servers.getIn([tab.server, 'nick']);
}
return editedNick;
}
);
export const getCurrentServerName = createSelector(
getServers,
getSelectedTab,
(servers, tab) => servers.getIn([tab.server, 'name'])
);
export default createReducer(Map(), {
[actions.CONNECT](state, { host, nick, options }) {
if (!state.has(host)) {
return state.set(host, new Server({
nick,
name: options.name || host
}));
}
return state;
},
[actions.DISCONNECT](state, { server }) {
return state.delete(server);
},
[actions.SET_SERVER_NAME](state, { server, name }) {
return state.setIn([server, 'name'], name);
},
[actions.SET_NICK](state, { server, nick, editing }) {
if (editing) {
return state.setIn([server, 'editedNick'], nick);
} else if (nick === '') {
return state.setIn([server, 'editedNick'], null);
}
return state;
},
[actions.socket.NICK](state, { server, oldNick, newNick }) {
if (!oldNick || oldNick === state.get(server).nick) {
return state.update(server, s => s
.set('nick', newNick)
.set('editedNick', null)
);
}
return state;
},
[actions.socket.NICK_FAIL](state, { server }) {
return state.setIn([server, 'editedNick'], null);
},
[actions.socket.SERVERS](state, { data }) {
if (!data) {
return state;
}
return state.withMutations(s => {
data.forEach(server => {
s.set(server.host, new Server(server));
});
});
},
[actions.socket.CONNECTION_UPDATE](state, action) {
return state.withMutations(s =>
Object.keys(action).forEach(server => {
if (s.has(server)) {
s.setIn([server, 'connected'], action[server]);
}
})
);
}
});
export function connect(server, nick, options) {
let host = server;
const i = server.indexOf(':');
if (i > 0) {
host = server.slice(0, i);
}
return {
type: actions.CONNECT,
host,
nick,
options,
socket: {
type: 'connect',
data: {
server,
nick,
username: options.username || nick,
password: options.password,
realname: options.realname || nick,
tls: options.tls || false,
name: options.name || server
}
}
};
}
export function disconnect(server) {
return dispatch => {
dispatch({
type: actions.DISCONNECT,
server,
socket: {
type: 'quit',
data: { server }
}
});
dispatch(updateSelection());
};
}
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: 1000,
key: server
}
};
}
return action;
}