Test
diff --git a/public/js/main.js b/public/js/main.js
index e95aba3..7cf13c9 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -1,14 +1,20 @@
window.irc = {
socketUp: false,
primaryFrame: null,
- timestamps: true,
- timestampFormat: "HH:mm:ss",
+ config: {
+ colors: true,
+ sharedInput: false,
+ timestamps: true,
+ timestampFormat: "HH:mm:ss",
+ colorNicknames: true,
+ colorNicklist: false
+ },
serverData: {},
serverChatQueue: {},
chatType: "simple",
};
-window.clientdom = {connector: {}};
+window.clientdom = {connector: {}, settings: {}};
window.colorizer = {
theme: {
@@ -22,6 +28,9 @@ window.colorizer = {
let s = rand(colorizer.theme.S[0], colorizer.theme.S[1]); // saturation 30-100%
let l = rand(colorizer.theme.L[0], colorizer.theme.L[1]); // lightness 30-70%
return 'hsl(' + h + ',' + s + '%,' + l + '%)';
+ },
+ strip: function(message) {
+ return message.replace(/(\x03\d{0,2}(,\d{0,2})?)/g, '').replace(/[\x0F\x02\x16\x1F]/g, '');
}
}
@@ -249,10 +258,14 @@ let composer = {
let element = document.createElement('div');
element.className = "message type_simple m_"+type;
- if(irc.timestamps)
- element.innerHTML += "
"+time.format(irc.timestampFormat)+" ";
+ if(irc.config.timestamps)
+ element.innerHTML += "
"+time.format(irc.config.timestampFormat)+" ";
+
+ if(irc.config.colors)
+ message = colorizer.stylize(message);
+ else
+ message = colorizer.strip(message);
- message = colorizer.stylize(message);
message = linkify(message);
switch(type) {
@@ -284,18 +297,19 @@ let composer = {
break;
}
- if(sender) {
- let sndr1 = element.querySelector('.sender');
- if(sndr1)
- sndr1.style.color = colorizer.get_random_color(sndr1.innerHTML);
- }
+ if(irc.config.colorNicknames == true) {
+ if(sender) {
+ let sndr1 = element.querySelector('.sender');
+ if(sndr1)
+ sndr1.style.color = colorizer.get_random_color(sndr1.innerHTML);
+ }
- let sndr2 = element.querySelectorAll('.nick');
- if(sndr2.length > 0)
- for(let a in sndr2)
- if(sndr2[a] && sndr2[a]['style'])
- sndr2[a].style.color = colorizer.get_random_color(sndr2[a].innerHTML);
-
+ let sndr2 = element.querySelectorAll('.nick');
+ if(sndr2.length > 0)
+ for(let a in sndr2)
+ if(sndr2[a] && sndr2[a]['style'])
+ sndr2[a].style.color = colorizer.get_random_color(sndr2[a].innerHTML);
+ }
return element;
}
}
@@ -345,7 +359,11 @@ class Nicklist {
else
construct += "
";
- construct += "
"+nick.nickname+"";
+ if(irc.config.colorNicklist)
+ construct += "
"+nick.nickname+"";
+ else
+ construct += "
"+nick.nickname+"";
+
str.innerHTML = construct;
clientdom.nicklist.appendChild(str);
}
@@ -556,8 +574,10 @@ class Buffer {
this.active = false;
this.alive = true;
- this.tab = new Tab(this);
- this.tab.renderTab(clientdom.tabby);
+ if(type != "settings") {
+ this.tab = new Tab(this);
+ this.tab.renderTab();
+ }
if(type == "channel")
this.nicklist = new Nicklist(this, clientdom.nicklist);
@@ -573,6 +593,9 @@ class Buffer {
clientdom.nicklist.innerHTML = "";
clientdom.topicbar.innerHTML = "";
+ if(!irc.config.sharedInput)
+ clientdom.input.value = this.input;
+
if(this.nicklist) {
addClass(clientdom.chat, 'vnicks');
this.nicklist.render();
@@ -580,7 +603,10 @@ class Buffer {
if(this.topic != null && this.topic != "") {
addClass(clientdom.chat, 'vtopic');
- clientdom.topicbar.innerHTML = linkify(colorizer.stylize(this.topic));
+ if(irc.config.colors)
+ clientdom.topicbar.innerHTML = linkify(colorizer.stylize(this.topic));
+ else
+ clientdom.topicbar.innerHTML = linkify(colorizer.strip(this.topic));
}
this.renderMessages();
@@ -621,7 +647,10 @@ class Buffer {
topicChange(topic) {
if(this.active) {
- clientdom.topicbar.innerHTML = linkify(colorizer.stylize(topic));
+ if(irc.config.colors)
+ clientdom.topicbar.innerHTML = linkify(colorizer.stylize(topic));
+ else
+ clientdom.topicbar.innerHTML = linkify(colorizer.strip(topic));
if(this.topic == null)
addClass(clientdom.chat, "vtopic");
@@ -654,6 +683,9 @@ class Buffer {
else
this.wasAtBottom = false;
+ if(!irc.config.sharedInput)
+ this.input = clientdom.input.value;
+
this.tab.setActive(false);
this.lastscroll = clientdom.letterbox.scrollTop;
this.active = false;
@@ -672,6 +704,114 @@ class Buffer {
}
}
+class Settings extends Buffer {
+ constructor() {
+ super("", "settings", "Settings", "settings");
+ this.tab = null;
+ this.isOpen = false;
+ this.timeout = null;
+
+ clientdom.settings.save.onclick = (e) => {
+ this.saveSpecified();
+ }
+
+ clientdom.settings.open.onclick = (e) => {
+ this.open();
+ }
+ }
+
+ open() {
+ if(this.isOpen) {
+ irc.chat.render(this);
+ return;
+ }
+
+ this.tab = new Tab(this);
+ this.tab.renderTab();
+ irc.chat.buffers.push(this);
+ irc.chat.render(this);
+ this.isOpen = true;
+ }
+
+ closeBuffer() {
+ irc.chat.closeBuffer(this);
+ this.tab = null;
+ this.isOpen = false;
+ }
+
+ saveSpecified() {
+ if(this.timeout)
+ clearTimeout(this.timeout);
+
+ for(let key in irc.config) {
+ let value = irc.config[key];
+ let type = typeof(value);
+
+ if(type == "boolean")
+ irc.config[key] = clientdom.settings[key].checked;
+ else
+ irc.config[key] = clientdom.settings[key].value;
+ }
+ clientdom.settings.saveStatus.innerHTML = "
Settings saved!";
+
+ if("localStorage" in window) {
+ window.localStorage['teemant_settings'] = JSON.stringify(irc.config);
+ }
+
+ this.timeout = setTimeout(function() {
+ clientdom.settings.saveStatus.innerHTML = "";
+ }, 3000);
+ }
+
+ setInitialValues() {
+ if("localStorage" in window) {
+ if(window.localStorage['teemant_settings']) {
+ try {
+ let settings = JSON.parse(window.localStorage.teemant_settings);
+ for(let key in irc.config) {
+ let value = irc.config[key];
+ let type = typeof(value);
+ if(settings[key]) {
+ if(type == "boolean")
+ clientdom.settings[key].checked = settings[key];
+ else
+ clientdom.settings[key].value = settings[key];
+ }
+ }
+ this.saveSpecified();
+ return;
+ } catch(e) {}
+ }
+ }
+
+ for(let key in irc.config) {
+ let value = irc.config[key];
+ let type = typeof(value);
+
+ if(type == "boolean")
+ clientdom.settings[key].checked = value;
+ else
+ clientdom.settings[key].value = value;
+ }
+ }
+
+ switchOff() {
+ this.active = false;
+ this.tab.setActive(false);
+ clientdom.settings.frame.style.display = "none";
+ }
+
+ render() {
+ this.active = true;
+ this.tab.setActive(true);
+ clientdom.chat.className = "chatarea";
+ clientdom.nicklist.innerHTML = "";
+ clientdom.topicbar.innerHTML = "";
+ clientdom.letterbox.innerHTML = "";
+ clientdom.settings.frame.style.display = "block";
+ }
+}
+
class IRCConnector {
constructor() {
this.formLocked = false;
@@ -1311,6 +1451,14 @@ window.onpopstate = parseURL;
window.onload = function() {
irc.primaryFrame = document.querySelector('.ircclient');
+ clientdom.settings['frame'] = irc.primaryFrame.querySelector('.settings');
+
+ for(let key in irc.config) {
+ clientdom.settings[key] = clientdom.settings.frame.querySelector('#s_'+key);
+ }
+
+ clientdom.settings['save'] = clientdom.settings.frame.querySelector('#save_settings');
+ clientdom.settings['saveStatus'] = clientdom.settings.frame.querySelector('#settings_status');
clientdom.connector['frame'] = irc.primaryFrame.querySelector('#authdialog');
clientdom.connector['messenger'] = clientdom.connector.frame.querySelector('#connmsg');
clientdom.connector['form'] = clientdom.connector.frame.querySelector('#IRCConnector');
@@ -1329,13 +1477,16 @@ window.onload = function() {
clientdom['chat'] = clientdom.frame.querySelector('.chatarea');
clientdom['topicbar'] = clientdom.chat.querySelector('.topicbar');
clientdom['smsctrig'] = clientdom.chat.querySelector('.smsc-nicklistbtn');
+ clientdom.settings['open'] = irc.primaryFrame.querySelector('.open_settings');
irc.socket = io.connect();
+ irc.settings = new Settings();
irc.auther = new IRCConnector();
irc.chat = new IRCChatWindow();
parseURL();
+ irc.settings.setInitialValues();
irc.socket.on('connect', function (data) {
irc.socketUp = true;
diff --git a/public/main.styl b/public/main.styl
index 2f44216..cf05655 100644
--- a/public/main.styl
+++ b/public/main.styl
@@ -1,4 +1,21 @@
// Run `stylus -w main.styl -o css` to compile
+props(prop, args)
+ -webkit-{prop} args
+ -moz-{prop} args
+ -ms-{prop} args
+ -o-{prop} args
+ {prop} args
+
+props2(prop, args)
+ -webkit-{prop} args
+ -moz-{prop} args
+ {prop} args
+
+transition()
+ props('transition', arguments)
+
+box-shadow()
+ props2('box-shadow', arguments)
body
margin: 0
@@ -50,7 +67,7 @@ body
padding: 15px
background-color: #f7f7f7;
border: 1px solid #dadada;
- box-shadow: 4px 4px 18px #d6d6d6;
+ box-shadow 4px 4px 18px #d6d6d6;
.msg.error
color: red;
label
@@ -63,7 +80,7 @@ body
width: 300px;
border-radius: 5px;
border: 1px solid #d2d2d2;
- box-shadow: inset 2px 2px 4px #dcdcdc;
+ box-shadow inset 2px 2px 4px #dcdcdc;
input[type="submit"]
width: 318px;
padding: 12px;
@@ -86,6 +103,7 @@ body
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%);
#chat
+ overflow: hidden;
.ircwrapper
position: absolute
width: 100%
@@ -95,18 +113,27 @@ body
background-color: #00c7e0
position: relative
z-index: 15
- box-shadow: 2px 2px 4px #cecece
- .logo
- width: 56px;
- height: 56px;
+ box-shadow 2px 2px 4px #cecece
+ .open_settings
+ width: 36px;
+ height: 36px;
display: inline-block;
- margin: 0 5px;
+ position: absolute;
+ right: 10px;
+ top: 10px;
+ cursor: pointer;
+ background-image: url(../image/settings.svg);
+ background-repeat: no-repeat;
+ background-size: contain;
+ transition transform 0.2s linear
+ &:hover
+ transform: rotateZ(-90deg);
.tabby
display: inline-block;
height: 56px;
position: absolute;
- left: 60px;
- right: 0;
+ right: 45px;
+ left: 0;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
@@ -119,9 +146,10 @@ body
padding: 10px;
line-height: 25px;
background-color: #29e1ff;
+ transition background-color 0.2s linear
border-radius: 5px;
border: 1px solid #00d0ea;
- box-shadow: inset 4px 4px 8px #44ebff;
+ box-shadow inset 4px 4px 8px #44ebff;
color: #fff;
cursor: pointer;
font-weight: 600;
@@ -131,7 +159,7 @@ body
height: 18px;
background-color: #bf0000;
border: 1px solid #b00;
- box-shadow: inset 2px 2px 3px #f00;
+ box-shadow inset 2px 2px 3px #f00;
text-align: center;
font-size: 12px;
margin: 0 5px;
@@ -144,14 +172,14 @@ body
width: 12px;
text-align: center;
color: #ff3d3d;
- float: right;
+ margin-left: 5px
&:hover
background-color: #63e9ff;
- box-shadow: inset 4px 4px 8px #86f2ff;
+ box-shadow inset 4px 4px 8px #86f2ff;
&.active
background-color: #00b9d8;
border: 1px solid #009aad;
- box-shadow: inset 4px 4px 8px #009caf;
+ box-shadow inset 4px 4px 8px #009caf;
color: #ffffff;
&:hover
background-color: #00c7e8;
@@ -201,6 +229,7 @@ body
overflow-y: auto;
white-space: pre-wrap;
word-wrap: break-word;
+ padding: 5px;
.nicklist
width: 280px;
position: absolute;
@@ -234,6 +263,19 @@ body
.no-prefix
width: 25px;
display: inline-block;
+ .settings
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 20px;
+ width: 60%;
+ min-width: 360px;
+ margin: auto;
+ overflow: auto;
+ .grade1, .grade2, .grade3
+ text-align: left;
&.vnicks
.nicklist
display: block;
@@ -275,7 +317,7 @@ body
font-size: 120%
border: 1px solid #929292
border-left: 0
- box-shadow: inset 4px 4px 8px #d8d8d8
+ box-shadow inset 4px 4px 8px #d8d8d8
.sendbutton
background-image: url(../image/send.svg);
background-repeat: no-repeat;
diff --git a/server/irc.js b/server/irc.js
index 2ec3158..2fb76f4 100644
--- a/server/irc.js
+++ b/server/irc.js
@@ -186,7 +186,7 @@ class IRCConnectionHandler {
this.conn.emit('pass_to_client', {type: "nick_change", nick: line.user.nickname, newNick: line.arguments[0], server: serverName});
break;
case "KICK":
- this.conn.emit('pass_to_client', {type: "event_kick_channel", user: line.user, channel: line.arguments[0], kickee: line.arguments[1], server: serverName});
+ this.conn.emit('pass_to_client', {type: "event_kick_channel", user: line.user, channel: line.arguments[0], reason: line.trailing, kickee: line.arguments[1], server: serverName});
break;
case "TOPIC":
this.conn.emit('pass_to_client', {type: "channel_topic", channel: line.arguments[0], set_by: line.user.nickname, topic: line.trailing, server: serverName});