Immutable channelStore
This commit is contained in:
parent
11ea241b60
commit
17482ee253
|
@ -52,7 +52,7 @@ var Chat = React.createClass({
|
|||
<div className={chatClass}>
|
||||
<ChatTitle />
|
||||
<Search />
|
||||
<MessageBox indent={window.messageIndent} />
|
||||
<MessageBox />
|
||||
<MessageInput />
|
||||
<UserList />
|
||||
</div>
|
||||
|
|
|
@ -18,7 +18,7 @@ var ChatTitle = React.createClass({
|
|||
var tab = selectedTabStore.getState();
|
||||
|
||||
return {
|
||||
usercount: channelStore.getUsers(tab.server, tab.channel).length,
|
||||
usercount: channelStore.getUsers(tab.server, tab.channel).size,
|
||||
selectedTab: tab
|
||||
};
|
||||
},
|
||||
|
@ -26,13 +26,13 @@ var ChatTitle = React.createClass({
|
|||
channelsChanged() {
|
||||
var tab = this.state.selectedTab;
|
||||
|
||||
this.setState({ usercount: channelStore.getUsers(tab.server, tab.channel).length });
|
||||
this.setState({ usercount: channelStore.getUsers(tab.server, tab.channel).size });
|
||||
},
|
||||
|
||||
selectedTabChanged(tab) {
|
||||
this.setState({
|
||||
selectedTab: tab,
|
||||
usercount: channelStore.getUsers(tab.server, tab.channel).length
|
||||
usercount: channelStore.getUsers(tab.server, tab.channel).size
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -66,9 +66,6 @@ var MessageBox = React.createClass({
|
|||
var tab = this.state.selectedTab;
|
||||
var dest = tab.channel || tab.server;
|
||||
var lines = [];
|
||||
var innerStyle = {
|
||||
paddingLeft: this.props.indent + 'px'
|
||||
};
|
||||
|
||||
this.state.messages.forEach((message, j) => {
|
||||
var key = message.server + dest + j;
|
||||
|
|
|
@ -32,8 +32,8 @@ var TabList = React.createClass({
|
|||
},
|
||||
|
||||
render() {
|
||||
var tabs = _.map(this.state.channels, (server, address) => {
|
||||
var serverTabs = _.map(server, (channel, name) => {
|
||||
var tabs = this.state.channels.map((server, address) => {
|
||||
var serverTabs = server.map((channel, name) => {
|
||||
return (
|
||||
<TabListItem
|
||||
server={address}
|
||||
|
@ -41,7 +41,7 @@ var TabList = React.createClass({
|
|||
name={name}>
|
||||
</TabListItem>
|
||||
);
|
||||
});
|
||||
}).toArray();
|
||||
|
||||
_.each(this.state.privateChats[address], (chat, nick) => {
|
||||
serverTabs.push(
|
||||
|
|
|
@ -56,9 +56,9 @@ var UserList = React.createClass({
|
|||
if (!tab.channel || tab.channel[0] !== '#') {
|
||||
style.display = 'none';
|
||||
} else {
|
||||
users = _.map(this.state.users, (user) => {
|
||||
users = this.state.users.map(user => {
|
||||
return <UserListItem key={user.nick} user={user} />;
|
||||
});
|
||||
}).toArray(); // React Infinite uses .length
|
||||
}
|
||||
|
||||
if (users.length !== 1) {
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
var Reflux = require('reflux');
|
||||
var Immutable = require('immutable');
|
||||
var _ = require('lodash');
|
||||
|
||||
var actions = require('../actions/channel');
|
||||
var serverActions = require('../actions/server');
|
||||
|
||||
var channels = {};
|
||||
var channels = Immutable.Map();
|
||||
var empty = Immutable.List();
|
||||
|
||||
function initChannel(server, channel) {
|
||||
if (!(server in channels)) {
|
||||
channels[server] = {};
|
||||
channels[server][channel] = { users: [] };
|
||||
} else if (!(channel in channels[server])) {
|
||||
channels[server][channel] = { users: [] };
|
||||
}
|
||||
}
|
||||
var User = Immutable.Record({
|
||||
nick: null,
|
||||
renderName: null,
|
||||
mode: ''
|
||||
});
|
||||
|
||||
function createUser(nick, mode) {
|
||||
return updateRenderName({
|
||||
return updateRenderName(new User({
|
||||
nick: nick,
|
||||
renderName: nick,
|
||||
mode: mode || ''
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function loadUser(users, nick) {
|
||||
function loadUser(nick) {
|
||||
var mode;
|
||||
|
||||
if (nick[0] === '@') {
|
||||
|
@ -36,46 +35,42 @@ function loadUser(users, nick) {
|
|||
nick = nick.slice(1);
|
||||
}
|
||||
|
||||
users.push(createUser(nick, mode));
|
||||
return createUser(nick, mode);
|
||||
}
|
||||
|
||||
function updateRenderName(user) {
|
||||
if (user.mode.indexOf('o') !== -1) {
|
||||
user.renderName = '@' + user.nick;
|
||||
return user.set('renderName', '@' + user.nick);
|
||||
} else if (user.mode.indexOf('v') !== -1) {
|
||||
user.renderName = '+' + user.nick;
|
||||
return user.set('renderName', '+' + user.nick);
|
||||
} else {
|
||||
user.renderName = user.nick;
|
||||
return user.set('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();
|
||||
function sortUsers(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;
|
||||
});
|
||||
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({
|
||||
|
@ -88,134 +83,112 @@ var channelStore = Reflux.createStore({
|
|||
|
||||
part(partChannels, server) {
|
||||
_.each(partChannels, function(channel) {
|
||||
delete channels[server][channel];
|
||||
channels = channels.deleteIn([server, channel]);
|
||||
});
|
||||
this.trigger(channels);
|
||||
},
|
||||
|
||||
addUser(user, server, channel) {
|
||||
initChannel(server, channel);
|
||||
channels[server][channel].users.push(createUser(user));
|
||||
sortUsers(server, channel);
|
||||
channels = channels.updateIn([server, channel, 'users'], empty, users => {
|
||||
return users.push(createUser(user)).sort(sortUsers);
|
||||
});
|
||||
this.trigger(channels);
|
||||
},
|
||||
|
||||
removeUser(user, server, channel) {
|
||||
if (channels[server][channel]) {
|
||||
_.remove(channels[server][channel].users, { nick: user });
|
||||
if (channels.hasIn([server, channel])) {
|
||||
channels = channels.updateIn([server, channel, 'users'], users => users.filter(u => u.nick !== user));
|
||||
this.trigger(channels);
|
||||
}
|
||||
},
|
||||
|
||||
removeUserAll(user, server) {
|
||||
_.each(channels[server], function(channel) {
|
||||
_.remove(channel.users, { nick: user });
|
||||
channels.get(server).forEach((v, k) => {
|
||||
channels = channels.updateIn([server, k, 'users'], users => users.filter(u => u.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);
|
||||
}
|
||||
channels.get(server).forEach((v, k) => {
|
||||
channels = channels.updateIn([server, k, 'users'], users => {
|
||||
var i = users.findIndex(user => user.nick === oldNick);
|
||||
return users.update(i, user => {
|
||||
return updateRenderName(user.set('nick', newNick));
|
||||
}).sort(sortUsers);
|
||||
});
|
||||
});
|
||||
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);
|
||||
users = _.map(users, user => loadUser(user)).sort(sortUsers);
|
||||
channels = channels.setIn([server, channel, 'users'], Immutable.List(users));
|
||||
this.trigger(channels);
|
||||
},
|
||||
|
||||
setTopic(topic, server, channel) {
|
||||
channels[server][channel].topic = topic;
|
||||
channels = channels.setIn([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;
|
||||
});
|
||||
var i = channels.getIn([mode.server, mode.channel, 'users']).findIndex(u => u.nick === mode.user);
|
||||
|
||||
updateRenderName(user);
|
||||
sortUsers(mode.server, mode.channel);
|
||||
this.trigger(channels);
|
||||
}
|
||||
channels = channels.updateIn([mode.server, mode.channel, 'users', i], user => {
|
||||
_.each(mode.remove, function(mode) {
|
||||
user = user.set('mode', user.mode.replace(mode, ''));
|
||||
});
|
||||
|
||||
user = user.set('mode', user.mode + mode.add);
|
||||
|
||||
return updateRenderName(user);
|
||||
});
|
||||
channels = channels.updateIn([mode.server, mode.channel, 'users'], users => users.sort(sortUsers));
|
||||
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);
|
||||
channels = channels.setIn([channel.server, channel.name], Immutable.Map({
|
||||
users: Immutable.List(),
|
||||
topic: channel.topic
|
||||
}));
|
||||
});
|
||||
|
||||
this.trigger(channels);
|
||||
},
|
||||
|
||||
addServer(server) {
|
||||
if (!(server in channels)) {
|
||||
channels[server] = {};
|
||||
if (!channels.has(server)) {
|
||||
channels = channels.set(server, Immutable.Map());
|
||||
this.trigger(channels);
|
||||
}
|
||||
},
|
||||
|
||||
removeServer(server) {
|
||||
delete channels[server];
|
||||
channels = channels.delete(server);
|
||||
this.trigger(channels);
|
||||
},
|
||||
|
||||
loadServers(storedServers) {
|
||||
_.each(storedServers, function(server) {
|
||||
if (!(server.address in channels)) {
|
||||
channels[server.address] = {};
|
||||
if (!channels.has(server.address)) {
|
||||
channels = channels.set(server.address, Immutable.Map());
|
||||
}
|
||||
});
|
||||
this.trigger(channels);
|
||||
},
|
||||
|
||||
getChannels(server) {
|
||||
return channels[server];
|
||||
return channels.get(server);
|
||||
},
|
||||
|
||||
getUsers(server, channel) {
|
||||
if (channels[server] && channels[server][channel]) {
|
||||
return channels[server][channel].users;
|
||||
}
|
||||
return [];
|
||||
return channels.getIn([server, channel, 'users']) || empty;
|
||||
},
|
||||
|
||||
getTopic(server, channel) {
|
||||
if (channels[server] && channels[server][channel]) {
|
||||
return channels[server][channel].topic || null;
|
||||
}
|
||||
return null;
|
||||
return channels.getIn([server, channel, 'topic']) || null;
|
||||
},
|
||||
|
||||
getState() {
|
||||
|
|
|
@ -63,8 +63,8 @@ var messageStore = Reflux.createStore({
|
|||
},
|
||||
|
||||
broadcast(message, server, user) {
|
||||
_.each(channelStore.getChannels(server), function(channel, channelName) {
|
||||
if (!user || (user && _.find(channel.users, { nick: user }))) {
|
||||
channelStore.getChannels(server).forEach((channel, channelName) => {
|
||||
if (!user || (user && channel.get('users').find(u => u.nick === user))) {
|
||||
addMessage({
|
||||
server: server,
|
||||
to: channelName,
|
||||
|
|
|
@ -6,17 +6,16 @@ var messageStore = require('./message');
|
|||
var selectedTabStore = require('./selectedTab');
|
||||
var messageActions = require('../actions/message');
|
||||
|
||||
var width = window.innerWidth;
|
||||
window.charWidth = util.stringWidth(' ', '16px Droid Sans Mono');
|
||||
window.messageIndent = 6 * charWidth;
|
||||
|
||||
// Temporary hack incase this runs before the font has loaded
|
||||
setTimeout(() => window.charWidth = util.stringWidth(' ', '16px Droid Sans Mono'), 1000);
|
||||
|
||||
var tab = selectedTabStore.getState();
|
||||
var width = window.innerWidth;
|
||||
var messages;
|
||||
var prev;
|
||||
|
||||
function updateCharWidth() {
|
||||
window.charWidth = util.stringWidth(' ', '16px Droid Sans Mono');
|
||||
window.messageIndent = 6 * charWidth;
|
||||
}
|
||||
|
||||
function wrap() {
|
||||
var next = messageStore.getMessages(tab.server, tab.channel || tab.server);
|
||||
if (next !== prev) {
|
||||
|
@ -27,10 +26,14 @@ function wrap() {
|
|||
return false;
|
||||
}
|
||||
|
||||
wrap();
|
||||
|
||||
var messageLineStore = Reflux.createStore({
|
||||
init() {
|
||||
updateCharWidth();
|
||||
wrap();
|
||||
|
||||
// Temporary hack incase this runs before the font has loaded
|
||||
setTimeout(updateCharWidth, 1000);
|
||||
|
||||
this.listenTo(messageActions.setWrapWidth, 'setWrapWidth');
|
||||
this.listenTo(messageStore, 'messagesChanged');
|
||||
this.listenTo(selectedTabStore, 'selectedTabChanged');
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue