diff --git a/client/src/js/actions/route.js b/client/src/js/actions/route.js
new file mode 100644
index 00000000..858a8f69
--- /dev/null
+++ b/client/src/js/actions/route.js
@@ -0,0 +1,7 @@
+var Reflux = require('reflux');
+
+var routeActions = Reflux.createActions([
+ 'navigate'
+]);
+
+module.exports = routeActions;
\ No newline at end of file
diff --git a/client/src/js/actions/tab.js b/client/src/js/actions/tab.js
index f14eb391..738eb08c 100644
--- a/client/src/js/actions/tab.js
+++ b/client/src/js/actions/tab.js
@@ -1,7 +1,13 @@
var Reflux = require('reflux');
+var routeActions = require('./route');
+
var tabActions = Reflux.createActions([
'select'
]);
+tabActions.select.preEmit = function() {
+ routeActions.navigate('app');
+};
+
module.exports = tabActions;
\ No newline at end of file
diff --git a/client/src/js/app.js b/client/src/js/app.js
index 28d1d1e8..c41ecd0f 100644
--- a/client/src/js/app.js
+++ b/client/src/js/app.js
@@ -7,6 +7,7 @@ require('./irc');
var socket = require('./socket');
var util = require('./util');
var App = require('./components/App.jsx');
+var Connect = require('./components/Connect.jsx');
var Chat = require('./components/Chat.jsx');
var Settings = require('./components/Settings.jsx');
var tabActions = require('./actions/tab');
@@ -19,11 +20,11 @@ var nick = 'test' + Math.floor(Math.random() * 99999);
socket.on('connect', function() {
socket.send('uuid', uuid);
- serverActions.connect('irc.freenode.net', nick, 'username', true, 'Freenode');
+ /*serverActions.connect('irc.freenode.net', nick, 'username', true, 'Freenode');
serverActions.connect('irc.quakenet.org', nick, 'username', false, 'QuakeNet');
channelActions.join(['#stuff'], 'irc.freenode.net');
- channelActions.join(['#herp'], 'irc.quakenet.org');
+ channelActions.join(['#herp'], 'irc.quakenet.org');*/
});
socket.on('error', function(error) {
@@ -32,6 +33,7 @@ socket.on('error', function(error) {
var routes = (
+
diff --git a/client/src/js/components/App.jsx b/client/src/js/components/App.jsx
index de5803c8..0f438d97 100644
--- a/client/src/js/components/App.jsx
+++ b/client/src/js/components/App.jsx
@@ -1,9 +1,22 @@
var React = require('react');
-var RouteHandler = require('react-router').RouteHandler;
+var Reflux = require('reflux');
+var Router = require('react-router');
+var RouteHandler = Router.RouteHandler;
+var Navigation = Router.Navigation;
var TabList = require('./TabList.jsx');
+var routeActions = require('../actions/route');
var App = React.createClass({
+ mixins: [
+ Navigation,
+ Reflux.listenTo(routeActions.navigate, 'navigate')
+ ],
+
+ navigate: function(path) {
+ this.transitionTo(path);
+ },
+
render: function() {
return (
diff --git a/client/src/js/components/Connect.jsx b/client/src/js/components/Connect.jsx
new file mode 100644
index 00000000..d34ea21f
--- /dev/null
+++ b/client/src/js/components/Connect.jsx
@@ -0,0 +1,45 @@
+var React = require('react');
+var _ = require('lodash');
+
+var serverActions = require('../actions/server');
+var channelActions = require('../actions/channel');
+
+var Connect = React.createClass({
+ handleSubmit: function(e) {
+ e.preventDefault();
+
+ var name = e.target.name.value.trim();
+ var address = e.target.address.value.trim();
+ var ssl = e.target.ssl.checked;
+ var nick = e.target.nick.value.trim();
+ var username = e.target.username.value.trim();
+ var channels = _.filter(_.map(e.target.channels.value.split(','), _.trim));
+
+ if (address.indexOf('.') > 0 && nick && username) {
+ serverActions.connect(address, nick, username, ssl, name);
+
+ if (channels.length > 0) {
+ channelActions.join(channels, address);
+ }
+ }
+ },
+
+ render: function() {
+ return (
+
+
+
+ );
+ }
+});
+
+module.exports = Connect;
\ No newline at end of file
diff --git a/client/src/js/components/MessageInput.jsx b/client/src/js/components/MessageInput.jsx
index ea28d007..3e75f2f9 100644
--- a/client/src/js/components/MessageInput.jsx
+++ b/client/src/js/components/MessageInput.jsx
@@ -4,6 +4,7 @@ var Reflux = require('reflux');
var selectedTabStore = require('../stores/selectedTab');
var messageActions = require('../actions/message');
var channelActions = require('../actions/channel');
+var tabActions = require('../actions/tab');
function dispatchCommand(cmd, channel, server) {
var params = cmd.slice(1).split(' ');
@@ -12,6 +13,7 @@ function dispatchCommand(cmd, channel, server) {
case 'join':
if (params[1]) {
channelActions.join([params[1]], server);
+ tabActions.select(server, params[1]);
}
break;
diff --git a/client/src/js/components/TabList.jsx b/client/src/js/components/TabList.jsx
index 38ba0835..a7436f57 100644
--- a/client/src/js/components/TabList.jsx
+++ b/client/src/js/components/TabList.jsx
@@ -7,6 +7,7 @@ var privateChatStore = require('../stores/privateChat');
var serverStore = require('../stores/server');
var selectedTabStore = require('../stores/selectedTab');
var tabActions = require('../actions/tab');
+var routeActions = require('../actions/route');
var TabList = React.createClass({
mixins: [
@@ -25,6 +26,14 @@ var TabList = React.createClass({
};
},
+ handleConnectClick: function() {
+ routeActions.navigate('connect');
+ },
+
+ handleSettingsClick: function() {
+ routeActions.navigate('settings');
+ },
+
render: function() {
var self = this;
var tabClass;
@@ -85,10 +94,10 @@ var TabList = React.createClass({
return (
-
+
{tabs}
-
+
);
diff --git a/client/src/js/stores/channel.js b/client/src/js/stores/channel.js
index c18517d2..1d70e0dc 100644
--- a/client/src/js/stores/channel.js
+++ b/client/src/js/stores/channel.js
@@ -82,6 +82,7 @@ var channelStore = Reflux.createStore({
init: function() {
this.listenToMany(actions);
this.listenTo(serverActions.connect, 'addServer');
+ this.listenTo(serverActions.load, 'loadServers');
},
part: function(partChannels, server) {
@@ -99,8 +100,10 @@ var channelStore = Reflux.createStore({
},
removeUser: function(user, server, channel) {
- _.remove(channels[server][channel].users, { nick: user });
- this.trigger(channels);
+ if (channels[server][channel]) {
+ _.remove(channels[server][channel].users, { nick: user });
+ this.trigger(channels);
+ }
},
removeUserAll: function(user, server) {
@@ -182,6 +185,15 @@ var channelStore = Reflux.createStore({
}
},
+ loadServers: function(storedServers) {
+ _.each(storedServers, function(server) {
+ if (!(server.address in channels)) {
+ channels[server.address] = {};
+ }
+ });
+ this.trigger(channels);
+ },
+
getChannels: function(server) {
return channels[server];
},
diff --git a/client/src/js/stores/server.js b/client/src/js/stores/server.js
index c5c4c732..59b72aa4 100644
--- a/client/src/js/stores/server.js
+++ b/client/src/js/stores/server.js
@@ -2,6 +2,7 @@ var Reflux = require('reflux');
var _ = require('lodash');
var actions = require('../actions/server');
+var tabActions = require('../actions/tab');
var servers = {};
@@ -11,13 +12,20 @@ var serverStore = Reflux.createStore({
},
connect: function(server, nick, username, tls, name) {
+ var i = server.indexOf(':');
+ if (i > 0) {
+ server = server.slice(0, i);
+ }
+
servers[server] = {
address: server,
nick: nick,
username: username,
name: name || server
};
+
this.trigger(servers);
+ tabActions.select(server);
},
load: function(storedServers) {
diff --git a/client/src/style.css b/client/src/style.css
index 2c4e6cbe..5c945cc6 100644
--- a/client/src/style.css
+++ b/client/src/style.css
@@ -89,6 +89,62 @@ p {
width: 100px;
}
+.connect {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: fixed;
+ top: 0;
+ left: 200px;
+ right: 0;
+ bottom: 0;
+}
+
+.connect-form h1 {
+ font: 32px Montserrat, sans-serif;
+ margin-bottom: 15px;
+ text-align: center;
+}
+
+.connect-form input {
+ display: block;
+ margin: 5px 0px;
+ padding: 10px;
+ border: none;
+}
+
+.connect-form input[type="submit"],
+.connect-form input[type="text"] {
+ width: 200px;
+}
+
+.connect-form input[type="submit"] {
+ height: 50px;
+ font-family: Montserrat, sans-serif;
+ background: #6BB758;
+ color: #FFF;
+ cursor: pointer;
+}
+
+.connect-form input[type="submit"]:hover {
+ background: #7BBF6A;
+}
+
+.connect-form input[type="submit"]:active {
+ background: #6BB758;
+}
+
+.connect-form input[type="checkbox"] {
+ display: inline-block;
+ margin: 15px 10px;
+ margin-left: 0;
+ vertical-align: center;
+}
+
+.connect-form label {
+ color: #333;
+}
+
.chat-title-bar {
font-family: Montserrat, sans-serif;
position: fixed;
diff --git a/message_handler.go b/message_handler.go
index fb77edf4..9ac23673 100644
--- a/message_handler.go
+++ b/message_handler.go
@@ -24,19 +24,26 @@ func handleMessages(irc *IRC, session *Session) {
case JOIN:
user := msg.Prefix
+ var channel string
+
+ if len(msg.Params) > 0 {
+ channel = msg.Params[0]
+ } else {
+ channel = msg.Trailing
+ }
session.sendJSON("join", Join{
Server: irc.Host,
User: user,
- Channels: msg.Params,
+ Channels: []string{channel},
})
- channelStore.AddUser(user, irc.Host, msg.Params[0])
+ channelStore.AddUser(user, irc.Host, channel)
if user == irc.nick {
session.user.AddChannel(storage.Channel{
Server: irc.Host,
- Name: msg.Params[0],
+ Name: channel,
})
}