some interface work

This commit is contained in:
Evert Prants 2016-09-23 10:38:47 +03:00
parent 9a7c59e6de
commit 966b2a01e5
5 changed files with 543 additions and 53 deletions

View File

@ -90,3 +90,147 @@ body {
background: -webkit-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%); background: linear-gradient(to bottom, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
} }
.ircclient #chat .ircwrapper {
position: absolute;
width: 100%;
height: 100%;
}
.ircclient #chat .ircwrapper .toolbar {
height: 56px;
background-color: #00c7e0;
position: relative;
z-index: 10;
box-shadow: 2px 2px 4px #cecece;
}
.ircclient #chat .ircwrapper .toolbar .logo {
width: 56px;
height: 56px;
display: inline-block;
margin: 0 5px;
}
.ircclient #chat .ircwrapper .toolbar .tabby {
display: inline-block;
height: 56px;
position: absolute;
left: 60px;
right: 0;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab {
display: inline-block;
min-width: 60px;
height: 25px;
margin: 5px;
margin-right: 0;
padding: 10px;
line-height: 25px;
background-color: #29e1ff;
border-radius: 5px;
border: 1px solid #00d0ea;
box-shadow: inset 4px 4px 8px #44ebff;
color: #fff;
cursor: pointer;
font-weight: 600;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #close {
display: inline-block;
width: 12px;
text-align: center;
color: #ff3d3d;
float: right;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab:hover {
background-color: #63e9ff;
box-shadow: inset 4px 4px 8px #86f2ff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active {
background-color: #00b9d8;
border: 1px solid #009aad;
box-shadow: inset 4px 4px 8px #009caf;
color: #fff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active:hover {
background-color: #00c7e8;
}
.ircclient #chat .ircwrapper .chatarea {
position: absolute;
top: 56px;
width: 100%;
bottom: 46px;
}
.ircclient #chat .ircwrapper .chatarea .topicbar {
position: absolute;
top: 0;
height: 20px;
right: 0;
left: 0;
background-color: #fff;
border-bottom: 1px solid #ddd;
padding: 12px;
display: none;
}
.ircclient #chat .ircwrapper .chatarea .letterbox {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.ircclient #chat .ircwrapper .chatarea .nicklist {
width: 280px;
position: absolute;
right: 0;
border-left: 1px solid #ddd;
padding: 10px;
top: 0;
bottom: 0;
display: none;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .nicklist {
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .letterbox {
right: 301px;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .topicbar {
right: 301px;
}
.ircclient #chat .ircwrapper .chatarea.vtopic .topicbar {
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vtopic .letterbox {
top: 45px;
}
.ircclient #chat .ircwrapper .input {
position: absolute;
bottom: 0;
height: 46px;
width: 100%;
background-color: #00c7e0;
}
.ircclient #chat .ircwrapper .input .nickname {
background-color: #00efef;
margin: 5px;
padding: 7px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding-right: 20px;
margin-right: 0;
width: 183px;
text-overflow: clip;
}
.ircclient #chat .ircwrapper .input .inputwrapper {
display: inline-block;
position: absolute;
margin: 5px 0;
left: 210px;
right: 46px;
top: 0;
}
.ircclient #chat .ircwrapper .input .inputwrapper input {
width: 100%;
padding: 6px;
font-size: 120%;
border: 1px solid #929292;
border-left: 0;
box-shadow: inset 4px 4px 8px #d8d8d8;
}

View File

@ -30,9 +30,28 @@
</form> </form>
</div> </div>
</div> </div>
<div class="coverwindow" id="chat" style="display: none;"> <div class="coverwindow" id="chat">
<div class="ircwrapper">
<div class="toolbar">
<span class="logo"></span>
<div class="tabby">
</div> </div>
</div>
<div class="chatarea">
<div class="topicbar"></div>
<div class="letterbox"></div>
<div class="nicklist"></div>
</div>
<div class="input">
<div class="nickname">Test</div>
<div class="inputwrapper">
<input type="text" id="input">
</div>
<span class="send"></span>
</div>
</div>
</div>
</section> </section>
</body> </body>
</html> </html>

View File

@ -1,21 +1,11 @@
window.irc = { window.irc = {
socketUp: false, socketUp: false,
primaryFrame: null primaryFrame: null,
timestamps: true
}; };
window.validators = {}; 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) { window.validators.iporhost = function(str) {
let valid = false; let valid = false;
@ -35,9 +25,85 @@ window.validators.nickname = function(str) {
return false; return false;
} }
function remove_str(arr, str) {
let index = arr.indexOf(str);
if(index > -1) {
arr.splice(index, 1);
return arr;
}
return arr;
};
function removeClass(element, cl) {
let classList = element.className.split(" ");
remove_str(classList, cl);
element.className = classList.join(" ");
}
function addClass(element, cl) {
let classList = element.className.split(" ");
classList.push(cl);
element.className = classList.join(" ");
}
class Nicklist {
constructor(buffer) {
this.buffer = buffer;
this.nicks = [];
}
render(frame) {
}
}
class Tab { class Tab {
constructor(buffer) { constructor(buffer) {
this.buffer = buffer; this.buffer = buffer;
this.element = null;
}
// Create a tab element
renderTab(frame) {
let internals = "<span id='title'>"+ this.buffer.title +"</span><span id='unread'></span><span id='close'>x</span>";
let ttt = document.createElement('div');
ttt.innerHTML = internals;
ttt.className = "tab";
ttt.setAttribute('id', 'tab-'+this.name);
frame.appendChild(ttt);
this.element = ttt;
let instance = this;
ttt.addEventListener('click', function() {
if(instance.buffer.active)
return;
irc.chat.render(instance.buffer);
}, false);
}
setActive(active) {
if(this.element) {
this.element.className = "tab";
if(active) {
addClass(this.element, "active");
}
}
}
setUnreadCount(count) {
if(this.element) {
let counter = this.element.querySelector('#unread');
if(count == 0)
counter.innerHTML = "";
else
counter.innerHTML = count;
}
}
close() {
console.log('close requested for '+this.buffer.title);
} }
} }
@ -55,16 +121,90 @@ class Buffer {
this.type = type; this.type = type;
this.nicklistDisplayed = false; this.nicklistDisplayed = false;
this.active = false;
this.tab = new Tab(this); this.tab = new Tab(this);
this.tab.renderTab(irc.primaryFrame.querySelector('.tabby'));
if(type == "channel") if(type == "channel")
nicklistDisplayed = true; this.nicklistDisplayed = true;
this.frame = irc.primaryFrame.querySelector('#chat');
this.letterbox = this.frame.querySelector('.letterbox');
}
render() {
this.active = true;
this.tab.setActive(true);
let chat = this.frame.querySelector('.chatarea');
let topicbar = chat.querySelector('.topicbar');
let nicklist = chat.querySelector('.nicklist');
chat.className = "chatarea";
nicklist.innerHTML = "";
topicbar.innerHTML = "";
if(this.nicklistDisplayed) {
addClass(chat, 'vnicks');
}
if(this.topic != null && this.topic != "") {
addClass(chat, 'vtopic');
topicbar.innerHTML = this.topic;
}
this.renderMessages();
}
renderMessages() {
if(!this.active) return;
this.letterbox.innerHTML = "";
let instance = this;
for(let t in this.messages) {
let mesg = instance.messages[t];
instance.appendMessage({message: mesg.message, sender: mesg.sender, type: mesg.type, time: mesg.time});
}
}
appendMessage(meta) {
let mesgConstr = document.createElement('div');
mesgConstr.className = "message m_"+meta.type;
let construct = "";
if(irc.timestamps)
construct += "<span class='timestamp'>"+meta.time+"</span>";
if(meta.sender != null)
construct += "<span class='sender'>"+meta.sender+"</span>";
else
addClass(mesgConstr, "no_sender");
construct += "<span class='content'>"+meta.message+"</span>";
mesgConstr.innerHTML = construct;
this.letterbox.appendChild(mesgConstr);
}
addMessage(message, sender, type) {
let mesg = {message: message, sender: sender, type: type, time: Date.now()}
this.messages.push(mesg);
if(this.active)
this.appendMessage(mesg);
}
close() {
} }
} }
class IRCConnector { class IRCConnector {
constructor(frame) { constructor(frame) {
let instance = this;
this.frame = frame; this.frame = frame;
this.messenger = frame.querySelector('#connmsg'); this.messenger = frame.querySelector('#connmsg');
this.f_form = frame.querySelector('#IRCConnector'); this.f_form = frame.querySelector('#IRCConnector');
@ -75,8 +215,6 @@ class IRCConnector {
this.f_port = this.f_form.querySelector('#port'); this.f_port = this.f_form.querySelector('#port');
this.formLocked = false; this.formLocked = false;
let instance = this;
this.f_form.onsubmit = function(e) { this.f_form.onsubmit = function(e) {
if(instance.formLocked) { if(instance.formLocked) {
e.preventDefault(); e.preventDefault();
@ -101,7 +239,7 @@ class IRCConnector {
let port = this.f_port.value; let port = this.f_port.value;
if (!window.validators.nickname(nickname)) { if (!window.validators.nickname(nickname)) {
this.authMessage("Erronous nickname!", true); this.authMessage("Erroneous nickname!", true);
return false; return false;
} }
@ -109,7 +247,6 @@ class IRCConnector {
channel = channel.trim().split(","); channel = channel.trim().split(",");
for (let t in channel) { for (let t in channel) {
if(typeof(t) != "number") continue;
let chan = channel[t]; let chan = channel[t];
channel[t] = chan.trim(); channel[t] = chan.trim();
@ -129,19 +266,19 @@ class IRCConnector {
} }
if(!window.validators.iporhost(server)) { if(!window.validators.iporhost(server)) {
this.authMessage("Erronous server address!", true); this.authMessage("Erroneous server address!", true);
return false; return false;
} }
try { try {
port = parseInt(port); port = parseInt(port);
} catch(e) { } catch(e) {
this.authMessage("Erronous port!", true); this.authMessage("Erroneous port!", true);
return false; return false;
} }
if(port < 10 || port > 65535) { if(port < 10 || port > 65535) {
this.authMessage("Erronous port!", true); this.authMessage("Erroneous port!", true);
return false; return false;
} }
@ -172,10 +309,61 @@ class IRCChatWindow {
this.firstServer = true; this.firstServer = true;
this.currentBuffer = null; this.currentBuffer = null;
irc.switchBuffer = this.render;
}
getBufferByName(buffername) {
let result = null;
for (let t in this.buffers) {
let buf = this.buffers[t];
if(buf.name == buffername)
result = buf
}
return result;
}
getActiveBuffer() {
let result = null;
for (let t in this.buffers) {
let buf = this.buffers[t];
if(buf.active == true)
result = buf
}
return result;
}
getBuffersByServer(server) {
let result = [];
for (let t in this.buffers) {
let buf = this.buffers[t];
if(buf.server == server)
result.push(buf);
}
return result;
}
getBufferByNameServer(server, channel) {
let result = null;
for (let t in this.buffers) {
let buf = this.buffers[t];
if(buf.server == server && buf.name == channel)
result = buf;
}
return result;
}
getBuffersByType(type) {
let result = [];
for (let t in this.buffers) {
let buf = this.buffers[t];
if(buf.type == type)
result.push(buf);
}
return result;
} }
newServerBuffer(serverinfo) { newServerBuffer(serverinfo) {
console.log("wat");
if(this.firstServer) { if(this.firstServer) {
this.frame.style.display = "block"; this.frame.style.display = "block";
} }
@ -186,41 +374,38 @@ class IRCChatWindow {
this.firstServer = false; this.firstServer = false;
} }
getBufferByName(buffername) { createBuffer(server, name, type, autoswitch) {
let result = null; let buf = this.getBufferByNameServer(server, name);
for (let t in this.buffers) { if(buf) {
if(typeof(t) != "number") continue; if(autoswitch)
let buf = this.buffers[t]; this.render(buf);
if(buf.name == buffername) return;
result = buf
}
return result;
} }
getBuffersByServer(server) { buf = new Buffer(server, name, name, type);
let result = []; this.buffers.push(buf);
for (let t in this.buffers) {
if(typeof(t) != "number") continue; if(autoswitch)
let buf = this.buffers[t]; this.render(buf);
if(buf.server == server)
result.push(buf);
}
return result;
} }
getBuffersByType(type) { messageBuffer(name, server, message) {
let result = []; let buf = this.getBufferByNameServer(server, name);
for (let t in this.buffers) { if(buf == null)
if(typeof(t) != "number") continue; return;
let buf = this.buffers[t]; buf.addMessage(message.message, message.from, message.type);
if(buf.type == type)
result.push(buf);
}
return result;
} }
render(buffer) { render(buffer) {
console.log(buffer); let instance = this;
let activeNow = this.getActiveBuffer();
if(activeNow) {
activeNow.tab.setActive(false);
activeNow.active = false;
}
buffer.render();
} }
} }
@ -247,6 +432,12 @@ window.onload = function() {
irc.auther.authComplete(); irc.auther.authComplete();
irc.chat.newServerBuffer(data); irc.chat.newServerBuffer(data);
break; break;
case "event_join_channel":
irc.chat.createBuffer(data.server, data.name, "channel", true);
break;
case "server_message":
irc.chat.messageBuffer(data.to, data.server, {message: data.message, type: data.messageType, from: data.from});
break;
case "connect_message": case "connect_message":
irc.auther.authMessage(data.data, data.error); irc.auther.authMessage(data.data, data.error);
break; break;

View File

@ -83,3 +83,129 @@ body
background: -moz-linear-gradient(top, rgba(196,239,252,1) 0%, rgba(127,213,239,1) 40%, rgba(57,183,221,1) 100%); 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: -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%); background: linear-gradient(to bottom, rgba(196,239,252,1) 0%,rgba(127,213,239,1) 40%,rgba(57,183,221,1) 100%);
#chat
.ircwrapper
position: absolute
width: 100%
height: 100%
.toolbar
height: 56px
background-color: #00c7e0
position: relative
z-index: 10
box-shadow: 2px 2px 4px #cecece
.logo
width: 56px;
height: 56px;
display: inline-block;
margin: 0 5px;
.tabby
display: inline-block;
height: 56px;
position: absolute;
left: 60px;
right: 0;
.tab
display: inline-block;
min-width: 60px;
height: 25px;
margin: 5px;
margin-right: 0;
padding: 10px;
line-height: 25px;
background-color: #29e1ff;
border-radius: 5px;
border: 1px solid #00d0ea;
box-shadow: inset 4px 4px 8px #44ebff;
color: #fff;
cursor: pointer;
font-weight: 600;
#close
display: inline-block;
width: 12px;
text-align: center;
color: #ff3d3d;
float: right;
&:hover
background-color: #63e9ff;
box-shadow: inset 4px 4px 8px #86f2ff;
&.active
background-color: #00b9d8;
border: 1px solid #009aad;
box-shadow: inset 4px 4px 8px #009caf;
color: #ffffff;
&:hover
background-color: #00c7e8;
.chatarea
position: absolute;
top: 56px;
width: 100%;
bottom: 46px;
.topicbar
position: absolute;
top: 0;
height: 20px;
right: 0;
left: 0;
background-color: #fff;
border-bottom: 1px solid #ddd;
padding: 12px;
display: none;
.letterbox
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
.nicklist
width: 280px;
position: absolute;
right: 0;
border-left: 1px solid #ddd;
padding: 10px;
top: 0;
bottom: 0;
display: none;
&.vnicks
.nicklist
display: block;
.letterbox
right: 301px;
.topicbar
right: 301px;
&.vtopic
.topicbar
display: block;
.letterbox
top: 45px;
.input
position: absolute;
bottom: 0;
height: 46px;
width: 100%;
background-color: #00c7e0;
.nickname
background-color: #00efef;
margin: 5px;
padding: 7px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding-right: 20px;
margin-right: 0;
width: 183px;
text-overflow: clip;
.inputwrapper
display: inline-block;
position: absolute;
margin: 5px 0;
left: 210px;
right: 46px;
top: 0;
input
width: 100%;
padding: 6px;
font-size: 120%;
border: 1px solid #929292;
border-left: 0;
box-shadow: inset 4px 4px 8px #d8d8d8;

View File

@ -39,6 +39,16 @@ io.sockets.on('connection', function (socket) {
setTimeout(function() { setTimeout(function() {
console.log("fake connect"); console.log("fake connect");
socket.emit('act_client', {type: 'event_connect', address: connectiondata.server, network: "IcyNet", raw: connectiondata}); socket.emit('act_client', {type: 'event_connect', address: connectiondata.server, network: "IcyNet", raw: connectiondata});
}, 2000) socket.emit('act_client', {type: 'server_message', messageType: "notice", server: connectiondata.server, to: connectiondata.server, from: null, message: "Connection established"});
}, 2000);
setTimeout(function() {
console.log("fake channel");
socket.emit('act_client', {type: 'event_join_channel', server: connectiondata.server, name: "#channel"});
// Spam the client with messages (for testing)
setInterval(function() {
socket.emit('act_client', {type: 'server_message', messageType: "privmsg", server: connectiondata.server, to: "#channel", from: "horse", message: "I like ponies"});
}, 4000);
}, 4000);
}); });
}); });