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