var Reflux = require('reflux'); var _ = require('lodash'); var actions = require('../actions/channel'); var serverActions = require('../actions/server'); var channels = {}; function initChannel(server, channel) { if (!(server in channels)) { channels[server] = {}; channels[server][channel] = { users: [] }; } else if (!(channel in channels[server])) { channels[server][channel] = { users: [] }; } } function createUser(nick, mode) { return updateRenderName({ nick: nick, renderName: nick, mode: mode || '' }); } function loadUser(users, nick) { var mode; if (nick[0] === '@') { mode = 'o'; } else if (nick[0] === '+') { mode = 'v'; } if (mode) { nick = nick.slice(1); } users.push(createUser(nick, mode)); } function updateRenderName(user) { if (user.mode.indexOf('o') !== -1) { user.renderName = '@' + user.nick; } else if (user.mode.indexOf('v') !== -1) { user.renderName = '+' + user.nick; } else { user.renderName = user.nick; } return user; } function sortUsers(server, channel) { channels[server][channel].users.sort(function(a, b) { a = a.renderName.toLowerCase(); b = b.renderName.toLowerCase(); if (a[0] === '@' && b[0] !== '@') { return -1; } if (b[0] === '@' && a[0] !== '@') { return 1; } if (a[0] === '+' && b[0] !== '+') { return -1; } if (b[0] === '+' && a[0] !== '+') { return 1; } if (a < b) { return -1; } if (a > b) { return 1; } return 0; }); } var channelStore = Reflux.createStore({ init() { this.listenToMany(actions); this.listenTo(serverActions.connect, 'addServer'); this.listenTo(serverActions.disconnect, 'removeServer'); this.listenTo(serverActions.load, 'loadServers'); }, part(partChannels, server) { _.each(partChannels, function(channel) { delete channels[server][channel]; }); this.trigger(channels); }, addUser(user, server, channel) { initChannel(server, channel); channels[server][channel].users.push(createUser(user)); sortUsers(server, channel); this.trigger(channels); }, removeUser(user, server, channel) { if (channels[server][channel]) { _.remove(channels[server][channel].users, { nick: user }); this.trigger(channels); } }, removeUserAll(user, server) { _.each(channels[server], function(channel) { _.remove(channel.users, { nick: user }); }); this.trigger(channels); }, renameUser(oldNick, newNick, server) { _.each(channels[server], function(channel, channelName) { var user = _.find(channel.users, { nick: oldNick }); if (user) { user.nick = newNick; updateRenderName(user); sortUsers(server, channelName); } }); this.trigger(channels); }, setUsers(users, server, channel) { initChannel(server, channel); var chan = channels[server][channel]; chan.users = []; _.each(users, function(user) { loadUser(chan.users, user); }); sortUsers(server, channel); this.trigger(channels); }, setTopic(topic, server, channel) { channels[server][channel].topic = topic; this.trigger(channels); }, setMode(mode) { var user = _.find(channels[mode.server][mode.channel].users, { nick: mode.user }); if (user) { _.each(mode.remove, function(mode) { user.mode = user.mode.replace(mode, ''); }); _.each(mode.add, function(mode) { user.mode += mode; }); updateRenderName(user); sortUsers(mode.server, mode.channel); this.trigger(channels); } }, load(storedChannels) { _.each(storedChannels, function(channel) { initChannel(channel.server, channel.name); var chan = channels[channel.server][channel.name]; chan.users = []; chan.topic = channel.topic; _.each(channel.users, function(user) { loadUser(chan.users, user); }); sortUsers(channel.server, channel.name); }); this.trigger(channels); }, addServer(server) { if (!(server in channels)) { channels[server] = {}; this.trigger(channels); } }, removeServer(server) { delete channels[server]; this.trigger(channels); }, loadServers(storedServers) { _.each(storedServers, function(server) { if (!(server.address in channels)) { channels[server.address] = {}; } }); this.trigger(channels); }, getChannels(server) { return channels[server]; }, getUsers(server, channel) { if (channels[server] && channels[server][channel]) { return channels[server][channel].users; } return []; }, getTopic(server, channel) { if (channels[server] && channels[server][channel]) { return channels[server][channel].topic || null; } return null; }, getState() { return channels; } }); module.exports = channelStore;