diff --git a/public/css/main.css b/public/css/main.css index 4e8f330..84f5561 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -3,3 +3,90 @@ body { padding: 0; font-family: Open Sans, Everson Mono, Helvetica; } +.grade1 { + font-size: 200%; + margin-bottom: 0; + margin-top: 0; + display: block; + color: #00bcd4; + text-align: center; +} +.grade2 { + font-size: 150%; + margin-bottom: 0; + margin-top: 20px; + display: block; + color: #00bcd4; + text-align: center; +} +.grade3 { + font-size: 120%; + margin-bottom: 0; + margin-top: 20px; + display: block; + color: #00bcd4; + text-align: center; +} +.ircclient { + position: absolute; + width: 100%; + height: 100%; + background: #fff; + background: -moz-linear-gradient(top, #fff 0%, #e5e5e5 100%); + background: -webkit-linear-gradient(top, #fff 0%, #e5e5e5 100%); + background: linear-gradient(to bottom, #fff 0%, #e5e5e5 100%); +} +.ircclient .coverwindow { + position: absolute; + width: 100%; + height: 100%; +} +.ircclient .coverwindow .wrapper { + width: 320px; + margin: auto; + margin-top: 5%; + padding: 15px; + background-color: #f7f7f7; + border: 1px solid #dadada; + box-shadow: 4px 4px 18px #d6d6d6; +} +.ircclient .coverwindow .wrapper .msg.error { + color: #f00; +} +.ircclient .coverwindow .wrapper label { + display: block; + font-size: 80%; + margin-top: 5px; + color: #2196f3; +} +.ircclient .coverwindow .wrapper input[type=text], +.ircclient .coverwindow .wrapper input[type=number] { + padding: 8px; + width: 300px; + border-radius: 5px; + border: 1px solid #d2d2d2; + box-shadow: inset 2px 2px 4px #dcdcdc; +} +.ircclient .coverwindow .wrapper input[type="submit"] { + width: 318px; + padding: 12px; + margin-top: 20px; + display: block; + background: #87e0fd; + background: -moz-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%); + background: -webkit-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%); + background: linear-gradient(to bottom, #87e0fd 0%, #53cbf1 40%, #05abe0 100%); + border: 1px solid #2196f3; + border-radius: 4px; + color: #fff; + font-size: 120%; + font-weight: bold; + text-transform: uppercase; + cursor: pointer; +} +.ircclient .coverwindow .wrapper input[type="submit"]:hover { + background: #c4effc; + background: -moz-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%); + background: -webkit-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%); + background: linear-gradient(to bottom, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%); +} diff --git a/public/index.html b/public/index.html index bcd5b17..08a63db 100644 --- a/public/index.html +++ b/public/index.html @@ -12,6 +12,27 @@ +
+
+
+

Teemant

+ Think of a nickname +
+ + + + + + + + + +
+
+
+ +
diff --git a/public/js/main.js b/public/js/main.js index 5bddd8c..f681ec5 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,9 +1,255 @@ +window.irc = { + socketUp: false, + primaryFrame: null +}; + +window.validators = {}; + +Array.prototype.remove_str = function(str) { + let arr = this; + let index = arr.indexOf(str); + + if(indexOf > -1) { + arr.splice(index, 1); + return arr; + } + return arr; +}; + +window.validators.iporhost = function(str) { + let valid = false; + + if(str.match(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/i)) { + valid = true; + } else if (str.match(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/i)) { + valid = true; + } + + return valid; +} + +window.validators.nickname = function(str) { + if(str.match(/[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*/i)) { + return true; + } + return false; +} + +class Tab { + constructor(buffer) { + this.buffer = buffer; + } +} + +class Buffer { + constructor(servername, buffername, tabname, type) { + this.messages = []; + this.nicklist = []; + this.topic = null; + this.input = ""; + this.lastscroll = 0; + + this.server = servername; + this.name = buffername; + this.title = tabname; + this.type = type; + + this.nicklistDisplayed = false; + + this.tab = new Tab(this); + + if(type == "channel") + nicklistDisplayed = true; + } +} + +class IRCConnector { + constructor(frame) { + this.frame = frame; + this.messenger = frame.querySelector('#connmsg'); + this.f_form = frame.querySelector('#IRCConnector'); + + this.f_nickname = this.f_form.querySelector('#nickname'); + this.f_channel = this.f_form.querySelector('#channel'); + this.f_server = this.f_form.querySelector('#server'); + this.f_port = this.f_form.querySelector('#port'); + this.formLocked = false; + + let instance = this; + + this.f_form.onsubmit = function(e) { + if(instance.formLocked) { + e.preventDefault(); + return false; + } + + instance.formLocked = true; + + let success = instance.validateForm(e); + + if(!success) + instance.formLocked = false; + } + } + + validateForm(event) { + event.preventDefault(); + + let nickname = this.f_nickname.value; + let channel = this.f_channel.value; + let server = this.f_server.value; + let port = this.f_port.value; + + if (!window.validators.nickname(nickname)) { + this.authMessage("Erronous nickname!", true); + return false; + } + + if (channel.indexOf(",") !== -1) { + channel = channel.trim().split(","); + + for (let t in channel) { + if(typeof(t) != "number") continue; + let chan = channel[t]; + + channel[t] = chan.trim(); + + if (chan.indexOf("#") != 0) { + channel[t] = "#"+chan; + } + } + } else if(channel != "") { + channel = channel.trim(); + if (channel.indexOf("#") != 0) { + channel = "#"+channel; + } + channel = [channel]; + } else { + channel = []; + } + + if(!window.validators.iporhost(server)) { + this.authMessage("Erronous server address!", true); + return false; + } + + try { + port = parseInt(port); + } catch(e) { + this.authMessage("Erronous port!", true); + return false; + } + + if(port < 10 || port > 65535) { + this.authMessage("Erronous port!", true); + return false; + } + + irc.socket.emit('irc_create', {nickname: nickname, + autojoin: channel, + server: server, + port: port, + password: null, + secure: false }); + return true; + } + + authMessage(message, error) { + this.messenger.innerHTML = ""+message+""; + } + + authComplete() { + this.frame.style.display = "none"; + this.formLocked = false; + } +} + +class IRCChatWindow { + constructor(frame) { + this.frame = frame; + this.buffers = []; + this.frame.style.display = "none"; + this.firstServer = true; + + this.currentBuffer = null; + } + + newServerBuffer(serverinfo) { + console.log("wat"); + if(this.firstServer) { + this.frame.style.display = "block"; + } + + let newServer = new Buffer(serverinfo.address, serverinfo.address, serverinfo.network, "server"); + this.buffers.push(newServer); + this.render(newServer); + this.firstServer = false; + } + + getBufferByName(buffername) { + let result = null; + for (let t in this.buffers) { + if(typeof(t) != "number") continue; + let buf = this.buffers[t]; + if(buf.name == buffername) + result = buf + } + return result; + } + + getBuffersByServer(server) { + let result = []; + for (let t in this.buffers) { + if(typeof(t) != "number") continue; + let buf = this.buffers[t]; + if(buf.server == server) + result.push(buf); + } + return result; + } + + getBuffersByType(type) { + let result = []; + for (let t in this.buffers) { + if(typeof(t) != "number") continue; + let buf = this.buffers[t]; + if(buf.type == type) + result.push(buf); + } + return result; + } + + render(buffer) { + console.log(buffer); + } +} + window.onload = function() { + irc.socket = io.connect('http://localhost:8080'); - var messages = []; - var socket = io.connect('http://localhost:8080'); + irc.primaryFrame = document.querySelector('.ircclient'); + irc.auther = new IRCConnector(irc.primaryFrame.querySelector("#authdialog")); + irc.chat = new IRCChatWindow(irc.primaryFrame.querySelector("#chat")); - socket.on('connect', function (data) { - alert("socketio works!") + irc.socket.on('connect', function (data) { + irc.socketUp = true; + }); + + irc.socket.on('disconnect', function (data) { + irc.socketUp = false; + alert("Server died. Please try again later."); + }); + + // Does everything + irc.socket.on('act_client', function (data) { + switch(data.type) { + case "event_connect": + irc.auther.authComplete(); + irc.chat.newServerBuffer(data); + break; + case "connect_message": + irc.auther.authMessage(data.data, data.error); + break; + } }); } diff --git a/public/main.styl b/public/main.styl index c1d70c7..a9d978d 100644 --- a/public/main.styl +++ b/public/main.styl @@ -4,3 +4,82 @@ body margin: 0 padding: 0 font-family: Open Sans, Everson Mono, Helvetica + +.grade1 + font-size: 200% + margin-bottom: 0 + margin-top: 0 + display: block + color: #00BCD4 + text-align: center + +.grade2 + font-size: 150% + margin-bottom: 0 + margin-top: 20px + display: block + color: #00BCD4 + text-align: center + +.grade3 + font-size: 120% + margin-bottom: 0 + margin-top: 20px + display: block + color: #00BCD4 + text-align: center + +.ircclient + position: absolute + width: 100% + height: 100% + background: rgb(255,255,255) + background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%) + background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%) + background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%) + .coverwindow + position: absolute + width: 100% + height: 100% + .wrapper + width: 320px + margin: auto + margin-top: 5% + padding: 15px + background-color: #f7f7f7; + border: 1px solid #dadada; + box-shadow: 4px 4px 18px #d6d6d6; + .msg.error + color: red; + label + display: block + font-size: 80% + margin-top: 5px + color: #2196F3 + input[type=text], input[type=number] + padding: 8px; + width: 300px; + border-radius: 5px; + border: 1px solid #d2d2d2; + box-shadow: inset 2px 2px 4px #dcdcdc; + input[type="submit"] + width: 318px; + padding: 12px; + margin-top: 20px; + display: block; + background: rgb(135,224,253); + background: -moz-linear-gradient(top, rgba(135,224,253,1) 0%, rgba(83,203,241,1) 40%, rgba(5,171,224,1) 100%); + background: -webkit-linear-gradient(top, rgba(135,224,253,1) 0%,rgba(83,203,241,1) 40%,rgba(5,171,224,1) 100%); + background: linear-gradient(to bottom, rgba(135,224,253,1) 0%,rgba(83,203,241,1) 40%,rgba(5,171,224,1) 100%); + border: 1px solid #2196F3; + border-radius: 4px; + color: #fff; + font-size: 120%; + font-weight: bold; + text-transform: uppercase; + cursor: pointer + &:hover + background: rgb(196,239,252); + background: -moz-linear-gradient(top, rgba(196,239,252,1) 0%, rgba(127,213,239,1) 40%, rgba(57,183,221,1) 100%); + background: -webkit-linear-gradient(top, rgba(196,239,252,1) 0%,rgba(127,213,239,1) 40%,rgba(57,183,221,1) 100%); + background: linear-gradient(to bottom, rgba(196,239,252,1) 0%,rgba(127,213,239,1) 40%,rgba(57,183,221,1) 100%); diff --git a/teemant.js b/teemant.js index 51cf81f..0f60d42 100755 --- a/teemant.js +++ b/teemant.js @@ -7,15 +7,38 @@ let app = express(); let pubdir = path.join(__dirname+"/public"); let port = 8080; +let connections = {} + app.get("/", function(req, res){ res.sendFile(pubdir+"/index.html"); }); app.use(express.static(__dirname + '/public')); -let io = sockio.listen(app.listen(port)); -console.log("Listening on port " + port); +let io = sockio.listen(app.listen(port, function() { + console.log("*** Listening on port " + port); +})); io.sockets.on('connection', function (socket) { - console.log(socket) + console.log('clientID: '+socket.id+' connection: ', socket.request.connection._peername); + connections[socket.id] = {} + + socket.on('disconnect', function() { + for (let d in connections[socket.id]) d.disconnect("Client exited"); + + delete connections[socket.id]; + + console.log('clientID: '+socket.id+' disconnect'); + }); + + socket.on('irc_create', function(connectiondata) { + console.log(socket.id+" created irc connection: ", connectiondata); + + socket.emit('act_client', {type: 'connect_message', data: "Attempting connection..", error: false}); + + setTimeout(function() { + console.log("fake connect"); + socket.emit('act_client', {type: 'event_connect', address: connectiondata.server, network: "IcyNet", raw: connectiondata}); + }, 2000) + }); });