Added more options to the connect form, added support for more IRC commands on the server, added Font Awesome
This commit is contained in:
parent
e942924c15
commit
c15feaa310
@ -1,8 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title>IRC</title>
|
<title>IRC</title>
|
||||||
|
|
||||||
<link href="//fonts.googleapis.com/css?family=Montserrat|Roboto" rel="stylesheet">
|
<link href="//fonts.googleapis.com/css?family=Montserrat|Roboto" rel="stylesheet">
|
||||||
|
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
<link href="style.css" rel="stylesheet">
|
<link href="style.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -9,13 +9,15 @@ var serverActions = Reflux.createActions([
|
|||||||
'load'
|
'load'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
serverActions.connect.preEmit = function(server, nick, username, tls, name) {
|
serverActions.connect.preEmit = function(server, nick, opts) {
|
||||||
socket.send('connect', {
|
socket.send('connect', {
|
||||||
server: server,
|
server: server,
|
||||||
nick: nick,
|
nick: nick,
|
||||||
username: username,
|
username: opts.username || nick,
|
||||||
tls: tls || false,
|
password: opts.password,
|
||||||
name: name || server
|
realname: opts.realname || nick,
|
||||||
|
tls: opts.tls || false,
|
||||||
|
name: opts.name || server
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,18 +5,31 @@ var serverActions = require('../actions/server');
|
|||||||
var channelActions = require('../actions/channel');
|
var channelActions = require('../actions/channel');
|
||||||
|
|
||||||
var Connect = React.createClass({
|
var Connect = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
showOptionals: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
handleSubmit: function(e) {
|
handleSubmit: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var name = e.target.name.value.trim();
|
|
||||||
var address = e.target.address.value.trim();
|
var address = e.target.address.value.trim();
|
||||||
var ssl = e.target.ssl.checked;
|
|
||||||
var nick = e.target.nick.value.trim();
|
var nick = e.target.nick.value.trim();
|
||||||
var username = e.target.username.value.trim();
|
|
||||||
var channels = _.filter(_.map(e.target.channels.value.split(','), _.trim));
|
var channels = _.filter(_.map(e.target.channels.value.split(','), _.trim));
|
||||||
|
var opts = {
|
||||||
|
name: e.target.name.value.trim(),
|
||||||
|
ssl: e.target.ssl.checked
|
||||||
|
};
|
||||||
|
|
||||||
if (address.indexOf('.') > 0 && nick && username) {
|
if (this.state.showOptionals) {
|
||||||
serverActions.connect(address, nick, username, ssl, name);
|
opts.realname = e.target.realname.value.trim();
|
||||||
|
opts.username = e.target.username.value.trim();
|
||||||
|
opts.password = e.target.password.value.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address.indexOf('.') > 0 && nick) {
|
||||||
|
serverActions.connect(address, nick, opts);
|
||||||
|
|
||||||
if (channels.length > 0) {
|
if (channels.length > 0) {
|
||||||
channelActions.join(channels, address);
|
channelActions.join(channels, address);
|
||||||
@ -24,17 +37,36 @@ var Connect = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleShowClick: function() {
|
||||||
|
this.setState({ showOptionals: !this.state.showOptionals});
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
var optionals = null;
|
||||||
|
|
||||||
|
if (this.state.showOptionals) {
|
||||||
|
optionals = (
|
||||||
|
<div>
|
||||||
|
<input name="username" type="text" placeholder="Username" />
|
||||||
|
<input name="password" type="text" placeholder="Password" />
|
||||||
|
<input name="realname" type="text" placeholder="Realname" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="connect">
|
<div className="connect">
|
||||||
<form ref="form" className="connect-form" onSubmit={this.handleSubmit}>
|
<form ref="form" className="connect-form" onSubmit={this.handleSubmit}>
|
||||||
<h1>Connect</h1>
|
<h1>Connect</h1>
|
||||||
<input name="name" type="text" placeholder="Name" defaultValue="Freenode" />
|
<input name="name" type="text" placeholder="Name" defaultValue="Freenode" />
|
||||||
<input name="address" type="text" placeholder="Address" defaultValue="irc.freenode.net" />
|
<input name="address" type="text" placeholder="Address" defaultValue="irc.freenode.net" />
|
||||||
<label><input name="ssl" type="checkbox" />SSL</label>
|
<input name="nick" type="text" placeholder="Nick" />
|
||||||
<input name="nick" type="text" placeholder="Nick" onChange={this.handleNickChange} />
|
|
||||||
<input name="username" type="text" placeholder="Username" />
|
|
||||||
<input name="channels" type="text" placeholder="Channels" />
|
<input name="channels" type="text" placeholder="Channels" />
|
||||||
|
{optionals}
|
||||||
|
<p>
|
||||||
|
<label><input name="ssl" type="checkbox" />SSL</label>
|
||||||
|
<i className="fa fa-ellipsis-h" onClick={this.handleShowClick}></i>
|
||||||
|
</p>
|
||||||
<input type="submit" value="Connect" />
|
<input type="submit" value="Connect" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,6 +34,7 @@ var MessageBox = React.createClass({
|
|||||||
render: function() {
|
render: function() {
|
||||||
var tab = this.state.selectedTab;
|
var tab = this.state.selectedTab;
|
||||||
var dest = tab.channel || tab.server;
|
var dest = tab.channel || tab.server;
|
||||||
|
var style = {}
|
||||||
|
|
||||||
var messages = _.map(messageStore.getMessages(tab.server, dest), function(message) {
|
var messages = _.map(messageStore.getMessages(tab.server, dest), function(message) {
|
||||||
var messageClass = 'message';
|
var messageClass = 'message';
|
||||||
@ -51,8 +52,12 @@ var MessageBox = React.createClass({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!tab.channel || tab.channel[0] !== '#') {
|
||||||
|
style.right = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="messagebox">{messages}</div>
|
<div className="messagebox" style={style}>{messages}</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -71,7 +71,7 @@ var TabList = React.createClass({
|
|||||||
<button className="button-connect" onClick={this.handleConnectClick}>Connect</button>
|
<button className="button-connect" onClick={this.handleConnectClick}>Connect</button>
|
||||||
{tabs}
|
{tabs}
|
||||||
<div className="side-buttons">
|
<div className="side-buttons">
|
||||||
<button onClick={this.handleSettingsClick}>Settings</button>
|
<i className="fa fa-cog" onClick={this.handleSettingsClick}></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -12,7 +12,6 @@ body {
|
|||||||
input {
|
input {
|
||||||
font: 16px Roboto, sans-serif;
|
font: 16px Roboto, sans-serif;
|
||||||
border: none;
|
border: none;
|
||||||
border-top: 1px solid #DDD;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,12 +80,17 @@ p {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-buttons button {
|
.side-buttons i {
|
||||||
background: #333;
|
color: #999;
|
||||||
color: #FFF;
|
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
height: 40px;
|
line-height: 40px;
|
||||||
width: 100px;
|
width: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-buttons i:hover {
|
||||||
|
color: #FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.connect {
|
.connect {
|
||||||
@ -136,12 +140,25 @@ p {
|
|||||||
|
|
||||||
.connect-form input[type="checkbox"] {
|
.connect-form input[type="checkbox"] {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 15px 10px;
|
margin-right: 10px;
|
||||||
margin-left: 0;
|
vertical-align: middle;
|
||||||
vertical-align: center;
|
}
|
||||||
|
|
||||||
|
.connect-form i {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #999;
|
||||||
|
padding: 10px 5px;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connect-form i:hover {
|
||||||
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.connect-form label {
|
.connect-form label {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 0;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +252,7 @@ p {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
border-top: 1px solid #DDD;
|
||||||
}
|
}
|
||||||
|
|
||||||
.userlist {
|
.userlist {
|
||||||
|
44
irc.go
44
irc.go
@ -67,6 +67,7 @@ type IRC struct {
|
|||||||
Host string
|
Host string
|
||||||
TLS bool
|
TLS bool
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
Password string
|
||||||
Username string
|
Username string
|
||||||
Realname string
|
Realname string
|
||||||
}
|
}
|
||||||
@ -117,6 +118,9 @@ func (i *IRC) Connect(address string) error {
|
|||||||
|
|
||||||
i.reader = bufio.NewReader(i.conn)
|
i.reader = bufio.NewReader(i.conn)
|
||||||
|
|
||||||
|
if i.Password != "" {
|
||||||
|
i.Pass(i.Password)
|
||||||
|
}
|
||||||
i.Nick(i.nick)
|
i.Nick(i.nick)
|
||||||
i.User(i.Username, i.Realname)
|
i.User(i.Username, i.Realname)
|
||||||
|
|
||||||
@ -143,6 +147,22 @@ func (i *IRC) User(username, realname string) {
|
|||||||
i.writef("USER %s 0 * :%s", username, realname)
|
i.writef("USER %s 0 * :%s", username, realname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *IRC) Oper(name, password string) {
|
||||||
|
i.Write("OPER " + name + " " + password)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IRC) Mode(target, modes, params string) {
|
||||||
|
i.Write(strings.TrimRight("MODE "+target+" "+modes+" "+params, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IRC) Quit() {
|
||||||
|
go func() {
|
||||||
|
i.ready.Wait()
|
||||||
|
i.write("QUIT")
|
||||||
|
i.conn.Close()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
func (i *IRC) Join(channels ...string) {
|
func (i *IRC) Join(channels ...string) {
|
||||||
i.Write("JOIN " + strings.Join(channels, ","))
|
i.Write("JOIN " + strings.Join(channels, ","))
|
||||||
}
|
}
|
||||||
@ -151,6 +171,18 @@ func (i *IRC) Part(channels ...string) {
|
|||||||
i.Write("PART " + strings.Join(channels, ","))
|
i.Write("PART " + strings.Join(channels, ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *IRC) Topic(channel string) {
|
||||||
|
i.Write("TOPIC " + channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IRC) Invite(nick, channel string) {
|
||||||
|
i.Write("INVITE " + nick + " " + channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IRC) Kick(channel string, users ...string) {
|
||||||
|
i.Write("KICK " + channel + " " + strings.Join(users, ","))
|
||||||
|
}
|
||||||
|
|
||||||
func (i *IRC) Privmsg(target, msg string) {
|
func (i *IRC) Privmsg(target, msg string) {
|
||||||
i.Writef("PRIVMSG %s :%s", target, msg)
|
i.Writef("PRIVMSG %s :%s", target, msg)
|
||||||
}
|
}
|
||||||
@ -159,22 +191,10 @@ func (i *IRC) Notice(target, msg string) {
|
|||||||
i.Writef("NOTICE %s :%s", target, msg)
|
i.Writef("NOTICE %s :%s", target, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IRC) Topic(channel string) {
|
|
||||||
i.Write("TOPIC " + channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *IRC) Whois(nick string) {
|
func (i *IRC) Whois(nick string) {
|
||||||
i.Write("WHOIS " + nick)
|
i.Write("WHOIS " + nick)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IRC) Quit() {
|
|
||||||
go func() {
|
|
||||||
i.ready.Wait()
|
|
||||||
i.write("QUIT")
|
|
||||||
i.conn.Close()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *IRC) GetNick() string {
|
func (i *IRC) GetNick() string {
|
||||||
i.nickLock.Lock()
|
i.nickLock.Lock()
|
||||||
defer i.nickLock.Unlock()
|
defer i.nickLock.Unlock()
|
||||||
|
@ -15,11 +15,13 @@ type WSResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Connect struct {
|
type Connect struct {
|
||||||
|
Name string `json:"name"`
|
||||||
Server string `json:"server"`
|
Server string `json:"server"`
|
||||||
TLS bool `json:"tls"`
|
TLS bool `json:"tls"`
|
||||||
Name string `json:"name,omitempty"`
|
Password string `json:"password"`
|
||||||
Nick string `json:"nick"`
|
Nick string `json:"nick"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
Realname string `json:"realname"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Nick struct {
|
type Nick struct {
|
||||||
|
@ -8,9 +8,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
Name string `json:"name"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
TLS bool `json:"tls"`
|
TLS bool `json:"tls"`
|
||||||
Name string `json:"name"`
|
Password string `json:"password,omitempty"`
|
||||||
Nick string `json:"nick"`
|
Nick string `json:"nick"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Realname string `json:"realname"`
|
Realname string `json:"realname"`
|
||||||
|
@ -75,6 +75,8 @@ func handleWS(ws *websocket.Conn) {
|
|||||||
|
|
||||||
irc := NewIRC(data.Nick, data.Username)
|
irc := NewIRC(data.Nick, data.Username)
|
||||||
irc.TLS = data.TLS
|
irc.TLS = data.TLS
|
||||||
|
irc.Password = data.Password
|
||||||
|
irc.Realname = data.Realname
|
||||||
|
|
||||||
if err := irc.Connect(data.Server); err != nil {
|
if err := irc.Connect(data.Server); err != nil {
|
||||||
session.sendError(err, irc.Host)
|
session.sendError(err, irc.Host)
|
||||||
@ -85,11 +87,13 @@ func handleWS(ws *websocket.Conn) {
|
|||||||
go handleMessages(irc, session)
|
go handleMessages(irc, session)
|
||||||
|
|
||||||
session.user.AddServer(storage.Server{
|
session.user.AddServer(storage.Server{
|
||||||
|
Name: data.Name,
|
||||||
Address: irc.Host,
|
Address: irc.Host,
|
||||||
TLS: data.TLS,
|
TLS: data.TLS,
|
||||||
Name: data.Name,
|
Password: data.Password,
|
||||||
Nick: data.Nick,
|
Nick: data.Nick,
|
||||||
Username: data.Username,
|
Username: data.Username,
|
||||||
|
Realname: data.Realname,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user