input handler, better message constructor
This commit is contained in:
parent
5e1ac8134c
commit
3a648e9584
@ -114,6 +114,8 @@ body {
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
right: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.ircclient #chat .ircwrapper .toolbar .tabby .tab {
|
||||
display: inline-block;
|
||||
@ -182,6 +184,7 @@ body {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 12px;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ircclient #chat .ircwrapper .chatarea .letterbox {
|
||||
position: absolute;
|
||||
@ -244,7 +247,7 @@ body {
|
||||
position: absolute;
|
||||
margin: 5px 0;
|
||||
left: 210px;
|
||||
right: 46px;
|
||||
right: 55px;
|
||||
top: 0;
|
||||
}
|
||||
.ircclient #chat .ircwrapper .input .inputwrapper input {
|
||||
@ -255,6 +258,18 @@ body {
|
||||
border-left: 0;
|
||||
box-shadow: inset 4px 4px 8px #d8d8d8;
|
||||
}
|
||||
.ircclient #chat .ircwrapper .input .sendbutton {
|
||||
background-image: url("/image/send.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
width: 32px;
|
||||
position: absolute;
|
||||
height: 32px;
|
||||
float: right;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.message.type_simple .timestamp {
|
||||
color: #696969;
|
||||
}
|
||||
@ -275,14 +290,53 @@ body {
|
||||
.message.type_simple .sender:after {
|
||||
content: ">";
|
||||
}
|
||||
.m_topic .content {
|
||||
.message.type_simple .arrowin,
|
||||
.message.type_simple .arrowout {
|
||||
font-weight: bolder;
|
||||
}
|
||||
.message .reason:before,
|
||||
.message .hostmask:before {
|
||||
content: "(";
|
||||
}
|
||||
.message .reason:after,
|
||||
.message .hostmask:after {
|
||||
content: ")";
|
||||
}
|
||||
.message .reason:before,
|
||||
.message .hostmask:before,
|
||||
.message .reason:after,
|
||||
.message .hostmask:after {
|
||||
color: #009606;
|
||||
font-weight: bold;
|
||||
}
|
||||
.message .reason {
|
||||
color: #bf0000;
|
||||
}
|
||||
.message .hostmask {
|
||||
color: #004c88;
|
||||
}
|
||||
.message .arrowin {
|
||||
color: #00ab00;
|
||||
}
|
||||
.message .arrowout {
|
||||
color: #dc0f00;
|
||||
}
|
||||
.message.m_quit,
|
||||
.message.m_part,
|
||||
.message.m_kick {
|
||||
color: #f00;
|
||||
}
|
||||
.message.m_join {
|
||||
color: #008000;
|
||||
}
|
||||
.message.m_topic .content {
|
||||
color: #03a9f4;
|
||||
font-weight: bold;
|
||||
}
|
||||
.m_nick .content {
|
||||
.message.m_nick .content {
|
||||
color: #ff9800;
|
||||
font-weight: bold;
|
||||
}
|
||||
.m_action .actionee {
|
||||
.message.m_action .actionee {
|
||||
color: #3f51b5;
|
||||
}
|
||||
|
8
public/image/send.svg
Normal file
8
public/image/send.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 495.003 495.003" style="enable-background:new 0 0 495.003 495.003;" xml:space="preserve" width="512px" height="512px">
|
||||
<g id="XMLID_51_">
|
||||
<path id="XMLID_53_" d="M164.711,456.687c0,2.966,1.647,5.686,4.266,7.072c2.617,1.385,5.799,1.207,8.245-0.468l55.09-37.616 l-67.6-32.22V456.687z" fill="#FFFFFF"/>
|
||||
<path id="XMLID_52_" d="M492.431,32.443c-1.513-1.395-3.466-2.125-5.44-2.125c-1.19,0-2.377,0.264-3.5,0.816L7.905,264.422 c-4.861,2.389-7.937,7.353-7.904,12.783c0.033,5.423,3.161,10.353,8.057,12.689l125.342,59.724l250.62-205.99L164.455,364.414 l156.145,74.4c1.918,0.919,4.012,1.376,6.084,1.376c1.768,0,3.519-0.322,5.186-0.977c3.637-1.438,6.527-4.318,7.97-7.956 L494.436,41.257C495.66,38.188,494.862,34.679,492.431,32.443z" fill="#FFFFFF"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -46,9 +46,9 @@
|
||||
<div class="input">
|
||||
<div class="my_nickname">Test</div>
|
||||
<div class="inputwrapper">
|
||||
<input type="text" id="input">
|
||||
<input type="text" class="userinput">
|
||||
</div>
|
||||
<span class="send"></span>
|
||||
<span class="sendbutton"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,7 +3,8 @@ window.irc = {
|
||||
primaryFrame: null,
|
||||
timestamps: true,
|
||||
timestampFormat: "HH:mm:ss",
|
||||
serverData: {}
|
||||
serverData: {},
|
||||
chatType: "simple"
|
||||
};
|
||||
|
||||
window.clientdom = {connector: {}};
|
||||
@ -124,7 +125,6 @@ Date.prototype.format = function (format, utc){
|
||||
return format;
|
||||
};
|
||||
|
||||
|
||||
function removeClass(element, cl) {
|
||||
let classList = element.className.split(" ");
|
||||
remove_str(classList, cl);
|
||||
@ -137,6 +137,44 @@ function addClass(element, cl) {
|
||||
element.className = classList.join(" ");
|
||||
}
|
||||
|
||||
let composer = {
|
||||
message: {
|
||||
simple: function(time, sender, message, type) {
|
||||
let element = document.createElement('div');
|
||||
element.className = "message type_simple m_"+type;
|
||||
|
||||
if(irc.timestamps)
|
||||
element.innerHTML += "<span class='timestamp'>"+time.format(irc.timestampFormat)+"</span> ";
|
||||
|
||||
switch(type) {
|
||||
case "action":
|
||||
element.innerHTML += "<span class='asterisk'>*</span> <span class='actionee'>"+sender+"</span> ";
|
||||
element.innerHTML += "<span class='content'>"+message+"</span>";
|
||||
break;
|
||||
case "part":
|
||||
case "quit":
|
||||
case "kick":
|
||||
element.innerHTML += "<span class='arrowout'><--</span> <span class='content'><span class='actionee'>"+sender+"</span>";
|
||||
element.innerHTML += " "+message+"</span>";
|
||||
break;
|
||||
case "join":
|
||||
element.innerHTML += "<span class='arrowin'>--></span> <span class='content'><span class='actionee'>"+sender+"</span>";
|
||||
element.innerHTML += " "+message+"</span>";
|
||||
break;
|
||||
default:
|
||||
if(sender) {
|
||||
element.innerHTML += "<span class='sender'>"+sender+"</span> <span class='content'>"+message+"</span>";
|
||||
} else {
|
||||
element.innerHTML += "<span class='content'>"+message+"</span>";
|
||||
addClass(element, "no_sender");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************\
|
||||
|** **|
|
||||
|** CLASSES **|
|
||||
@ -187,6 +225,7 @@ class Nicklist {
|
||||
}
|
||||
|
||||
render() {
|
||||
if(!this.buffer.active) return;
|
||||
clientdom.nicklist.innerHTML = "";
|
||||
this.sort();
|
||||
for(let n in this.nicks) {
|
||||
@ -197,6 +236,7 @@ class Nicklist {
|
||||
|
||||
nickAdd(nickname) {
|
||||
let newbie = { nickname: nickname, prefix: "", modes: [] }
|
||||
if(this.getNickIndex(nickname) != null) return;
|
||||
this.nicks.push(newbie);
|
||||
this.render();
|
||||
}
|
||||
@ -213,7 +253,9 @@ class Nicklist {
|
||||
else
|
||||
return;
|
||||
|
||||
this.render();
|
||||
if(!this.buffer.active) return;
|
||||
let tt = clientdom.nicklist.querySelector('#nick-'+nickname);
|
||||
if(tt) tt.remove();
|
||||
}
|
||||
|
||||
nickChange(oldNickname, newNickname) {
|
||||
@ -395,26 +437,7 @@ class Buffer {
|
||||
}
|
||||
|
||||
appendMessage(meta) {
|
||||
let mesgConstr = document.createElement('div');
|
||||
mesgConstr.className = "message type_simple m_"+meta.type;
|
||||
|
||||
let construct = "";
|
||||
if(irc.timestamps)
|
||||
construct += "<span class='timestamp'>"+meta.time.format(irc.timestampFormat)+"</span> ";
|
||||
|
||||
if(meta.sender != null && meta.type != "action") {
|
||||
construct += "<span class='sender'>"+meta.sender+"</span> ";
|
||||
} else {
|
||||
construct += "<span class='asterisk'>*</span> ";
|
||||
addClass(mesgConstr, "no_sender");
|
||||
}
|
||||
|
||||
if(meta.type == "action")
|
||||
construct += "<span class='actionee'>"+meta.sender+"</span> <span class='content'>"+meta.message+"</span>";
|
||||
else
|
||||
construct += "<span class='content'>"+meta.message+"</span>";
|
||||
|
||||
mesgConstr.innerHTML = construct;
|
||||
let mesgConstr = composer.message[irc.chatType](meta.time, meta.sender, meta.message, meta.type);
|
||||
clientdom.letterbox.appendChild(mesgConstr);
|
||||
|
||||
let lFactor = clientdom.letterbox.offsetHeight + clientdom.letterbox.scrollTop
|
||||
@ -545,12 +568,42 @@ class IRCConnector {
|
||||
}
|
||||
}
|
||||
|
||||
class InputHandler {
|
||||
constructor() {
|
||||
this.history = [];
|
||||
|
||||
clientdom.input.onkeyup = (evt) => {
|
||||
let key = evt.keyCode || evt.which || evt.charCode || 0;
|
||||
if (key == 13) {
|
||||
this.handleInput();
|
||||
}
|
||||
}
|
||||
|
||||
clientdom.send.onclick = (e) => {
|
||||
this.handleInput();
|
||||
}
|
||||
}
|
||||
|
||||
handleInput() {
|
||||
let inp = clientdom.input.value;
|
||||
let buf = irc.chat.getActiveBuffer();
|
||||
|
||||
if(!buf) return;
|
||||
if(inp.trim() == "") return;
|
||||
|
||||
irc.socket.emit("userinput", {target: buf.name, server: buf.server, message: inp, splitup: inp.split(" ")});
|
||||
this.history.push(inp);
|
||||
clientdom.input.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
class IRCChatWindow {
|
||||
constructor() {
|
||||
this.buffers = [];
|
||||
clientdom.frame.style.display = "none";
|
||||
this.firstServer = true;
|
||||
this.currentBuffer = null;
|
||||
this.input_handler = new InputHandler();
|
||||
}
|
||||
|
||||
getBufferByName(buffername) {
|
||||
@ -730,6 +783,46 @@ class IRCChatWindow {
|
||||
buf.addMessage("Topic of "+channel+ " is \""+topic+"\"", null, "topic");
|
||||
}
|
||||
|
||||
handleQuit(server, user, reason) {
|
||||
let buffers = this.getBuffersByServer(server);
|
||||
|
||||
for(let i in buffers) {
|
||||
let buffer = buffers[i];
|
||||
|
||||
if(buffer.type != "channel") continue;
|
||||
if(buffer.nicklist.getNickIndex(user.nickname) == null) continue;
|
||||
|
||||
buffer.nicklist.nickRemove(user.nickname);
|
||||
buffer.addMessage("<span class='hostmask'>"+user.username+"@"+user.hostname+
|
||||
"</span> has quit <span class='reason'>"+reason+"</span>", user.nickname, "quit");
|
||||
}
|
||||
}
|
||||
|
||||
handleJoin(server, user, channel) {
|
||||
let buffer = this.getBufferByServerName(server, channel);
|
||||
|
||||
if(!buffer) return;
|
||||
|
||||
buffer.addMessage("<span class='hostmask'>"+user.username+"@"+user.hostname+"</span> has joined "+channel, user.nickname, "join");
|
||||
buffer.nicklist.nickAdd(user.nickname);
|
||||
}
|
||||
|
||||
handleLeave(server, user, channel, reason, kicker) {
|
||||
let buffer = this.getBufferByServerName(server, channel);
|
||||
|
||||
if(!buffer) return;
|
||||
|
||||
if(kicker)
|
||||
buffer.addMessage("has kicked "+user+" <span class='reason'>"+reason+"</span>", kicker.nickname, "part");
|
||||
else
|
||||
buffer.addMessage("<span class='hostmask'>"+user.username+"@"+user.hostname+"</span> has left "+
|
||||
channel+(reason != null ? "<span class='reason'>"+reason+"</span>" : ""), user.nickname, "part");
|
||||
if(kicker)
|
||||
buffer.nicklist.nickRemove(user);
|
||||
else
|
||||
buffer.nicklist.nickRemove(user.nickname);
|
||||
}
|
||||
|
||||
render(buffer) {
|
||||
let activeNow = this.getActiveBuffer();
|
||||
|
||||
@ -758,10 +851,12 @@ window.onload = function() {
|
||||
clientdom.connector['port'] = clientdom.connector.form.querySelector('#port');
|
||||
clientdom['tabby'] = irc.primaryFrame.querySelector('.tabby')
|
||||
clientdom['frame'] = irc.primaryFrame.querySelector('#chat');
|
||||
clientdom['chat'] = clientdom.frame.querySelector('.chatarea');
|
||||
clientdom['letterbox'] = clientdom.frame.querySelector('.letterbox');
|
||||
clientdom['nicklist'] = clientdom.frame.querySelector('.nicklist');
|
||||
clientdom['currentNickname'] = clientdom.frame.querySelector('.my_nickname');
|
||||
clientdom['input'] = clientdom.frame.querySelector('.userinput');
|
||||
clientdom['send'] = clientdom.frame.querySelector('.sendbutton');
|
||||
clientdom['chat'] = clientdom.frame.querySelector('.chatarea');
|
||||
clientdom['topicbar'] = clientdom.chat.querySelector('.topicbar');
|
||||
|
||||
irc.socket = io.connect('http://localhost:8080');
|
||||
@ -786,10 +881,21 @@ window.onload = function() {
|
||||
irc.chat.newServerBuffer(data);
|
||||
break;
|
||||
case "event_join_channel":
|
||||
irc.chat.createBuffer(data.server, data.name, "channel", true);
|
||||
if(data.user.nickname == irc.serverData[data.server].my_nick)
|
||||
irc.chat.createBuffer(data.server, data.channel, "channel", true);
|
||||
irc.chat.handleJoin(data.server, data.user, data.channel);
|
||||
break;
|
||||
case "event_kick_channel":
|
||||
irc.chat.handleLeave(data.server, data.kickee, data.channel, data.reason, data.user);
|
||||
break;
|
||||
case "event_part_channel":
|
||||
irc.chat.handleLeave(data.server, data.user, data.channel, data.reason);
|
||||
break;
|
||||
case "event_quit":
|
||||
irc.chat.handleQuit(data.server, data.user, data.reason);
|
||||
break;
|
||||
case "message":
|
||||
irc.chat.messageBuffer(data.to, data.server, {message: data.message, type: data.messageType, from: data.from});
|
||||
irc.chat.messageBuffer(data.to, data.server, {message: data.message, type: data.messageType, from: data.user.nickname});
|
||||
break;
|
||||
case "channel_nicks":
|
||||
irc.chat.buildNicklist(data.channel, data.server, data.nicks);
|
||||
|
@ -105,6 +105,8 @@ body
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
right: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
.tab
|
||||
display: inline-block;
|
||||
min-width: 60px;
|
||||
@ -164,6 +166,7 @@ body
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 12px;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
.letterbox
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -213,22 +216,34 @@ body
|
||||
width: 183px;
|
||||
text-overflow: clip;
|
||||
.inputwrapper
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
margin: 5px 0;
|
||||
left: 210px;
|
||||
right: 46px;
|
||||
top: 0;
|
||||
display: inline-block
|
||||
position: absolute
|
||||
margin: 5px 0
|
||||
left: 210px
|
||||
right: 55px
|
||||
top: 0
|
||||
input
|
||||
width: 100%;
|
||||
padding: 6px;
|
||||
font-size: 120%;
|
||||
border: 1px solid #929292;
|
||||
border-left: 0;
|
||||
box-shadow: inset 4px 4px 8px #d8d8d8;
|
||||
width: 100%
|
||||
padding: 6px
|
||||
font-size: 120%
|
||||
border: 1px solid #929292
|
||||
border-left: 0
|
||||
box-shadow: inset 4px 4px 8px #d8d8d8
|
||||
.sendbutton
|
||||
background-image: url(/image/send.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
width: 32px;
|
||||
position: absolute;
|
||||
height: 32px;
|
||||
float: right;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
.message.type_simple
|
||||
.message
|
||||
&.type_simple
|
||||
.timestamp
|
||||
color: #696969;
|
||||
&:before
|
||||
@ -243,14 +258,34 @@ body
|
||||
content: "<";
|
||||
&:after
|
||||
content: ">";
|
||||
.arrowin, .arrowout
|
||||
font-weight: bolder;
|
||||
|
||||
.m_topic .content
|
||||
.reason, .hostmask
|
||||
&:before
|
||||
content: "(";
|
||||
&:after
|
||||
content: ")";
|
||||
&:before, &:after
|
||||
color: #009606;
|
||||
font-weight: bold;
|
||||
.reason
|
||||
color: #bf0000;
|
||||
.hostmask
|
||||
color: #004c88;
|
||||
.arrowin
|
||||
color: #00ab00;
|
||||
.arrowout
|
||||
color: #dc0f00;
|
||||
&.m_quit, &.m_part, &.m_kick
|
||||
color: red;
|
||||
&.m_join
|
||||
color: green;
|
||||
&.m_topic .content
|
||||
color: #03A9F4;
|
||||
font-weight: bold;
|
||||
|
||||
.m_nick .content
|
||||
&.m_nick .content
|
||||
color: #FF9800;
|
||||
font-weight: bold;
|
||||
|
||||
.m_action .actionee
|
||||
&.m_action .actionee
|
||||
color: #3f51b5;
|
||||
|
18
teemant.js
18
teemant.js
@ -23,6 +23,10 @@ io.sockets.on('connection', function (socket) {
|
||||
console.log('clientID: '+socket.id+' connection: ', socket.request.connection._peername);
|
||||
connections[socket.id] = {}
|
||||
|
||||
socket.on('userinput', function(data) {
|
||||
console.log(data);
|
||||
})
|
||||
|
||||
socket.on('disconnect', function() {
|
||||
for (let d in connections[socket.id]) d.disconnect("Client exited");
|
||||
|
||||
@ -44,26 +48,32 @@ io.sockets.on('connection', function (socket) {
|
||||
|
||||
setTimeout(function() {
|
||||
console.log("fake channel");
|
||||
socket.emit('act_client', {type: 'event_join_channel', server: connectiondata.server, name: "#channel"});
|
||||
socket.emit('act_client', {type: 'event_join_channel', server: connectiondata.server, channel: "#channel", user: {nickname: connectiondata.nickname, username: "teemant", hostname: socket.request.connection._peername.address}});
|
||||
socket.emit('act_client', {type: 'channel_nicks', channel: "#channel", server: connectiondata.server, nicks: ["+horse", "@scoper", "@aspire", "+random", "lol"]});
|
||||
socket.emit('act_client', {type: 'channel_topic', channel: "#channel", server: connectiondata.server, topic: "This channel is the best."});
|
||||
socket.emit('act_client', {type: 'channel_topic', channel: "#channel", server: connectiondata.server, set_by: "horse", time: Date.now()});
|
||||
socket.emit('act_client', {type: 'message', messageType: "privmsg", server: connectiondata.server, to: "#channel", from: "horse", message: "I like ponies"});
|
||||
socket.emit('act_client', {type: 'message', messageType: "privmsg", server: connectiondata.server, to: "#channel", user: {nickname: "horse"}, message: "I like ponies"});
|
||||
|
||||
setTimeout(function() {
|
||||
socket.emit('act_client', {type: 'nick_change', server: connectiondata.server, nick: "horse", newNick: "pony"});
|
||||
}, 2000)
|
||||
|
||||
setTimeout(function() {
|
||||
socket.emit('act_client', {type: 'message', messageType: "action", server: connectiondata.server, to: "#channel", from: "pony", message: "Is the greatest pony fan"});
|
||||
socket.emit('act_client', {type: 'message', messageType: "action", server: connectiondata.server, to: "#channel", user: {nickname: "pony"}, message: "Is the greatest pony fan"});
|
||||
}, 3000)
|
||||
|
||||
setTimeout(function() {
|
||||
socket.emit('act_client', {type: 'event_join_channel', server: connectiondata.server, name: "#poni"});
|
||||
socket.emit('act_client', {type: 'event_join_channel', server: connectiondata.server, channel: "#poni", user: {nickname: connectiondata.nickname, username: "teemant", hostname: socket.request.connection._peername.address}});
|
||||
socket.emit('act_client', {type: 'channel_nicks', channel: "#poni", server: connectiondata.server, nicks: ["+horse", "@Diamond", "@aspire", "+random", "lol"]});
|
||||
socket.emit('act_client', {type: 'channel_topic', channel: "#poni", server: connectiondata.server, topic: "This channel is the second best."});
|
||||
socket.emit('act_client', {type: 'channel_topic', channel: "#poni", server: connectiondata.server, set_by: "Diamond", time: Date.now()});
|
||||
}, 5000)
|
||||
|
||||
setTimeout(function() {
|
||||
socket.emit('act_client', {type: 'event_kick_channel', server: connectiondata.server, channel: "#channel", user: {nickname: "scoper", username: "teemant", hostname: socket.request.connection._peername.address}, kickee: "random", reason: "Get out."});
|
||||
socket.emit('act_client', {type: 'event_quit', server: connectiondata.server, user: {nickname: "lol", username: "teemant", hostname: socket.request.connection._peername.address}, reason: "Sleep."});
|
||||
socket.emit('act_client', {type: 'event_part_channel', server: connectiondata.server, channel: "#poni", user: {nickname: "aspire", username: "teemant", hostname: socket.request.connection._peername.address}, reason: "Bye, lol."});
|
||||
}, 6000);
|
||||
}, 4000);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user