Merge pull request #759 from thelounge/yamanickill/condense-joins
Initial part/join condensing
This commit is contained in:
commit
28e32dc558
@ -194,6 +194,7 @@ kbd {
|
|||||||
#chat .title:before,
|
#chat .title:before,
|
||||||
#footer .icon,
|
#footer .icon,
|
||||||
#chat .count:before,
|
#chat .count:before,
|
||||||
|
#settings .extra-help,
|
||||||
#settings #play:before,
|
#settings #play:before,
|
||||||
#form #submit:before,
|
#form #submit:before,
|
||||||
#chat .invite .from:before,
|
#chat .invite .from:before,
|
||||||
@ -317,6 +318,10 @@ kbd {
|
|||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#settings .extra-help:before {
|
||||||
|
content: "\f059"; /* http://fontawesome.io/icon/question-circle/ */
|
||||||
|
}
|
||||||
|
|
||||||
#settings #play:before {
|
#settings #play:before {
|
||||||
content: "\f028"; /* http://fontawesome.io/icon/volume-up/ */
|
content: "\f028"; /* http://fontawesome.io/icon/volume-up/ */
|
||||||
margin-right: 9px;
|
margin-right: 9px;
|
||||||
@ -801,6 +806,31 @@ kbd {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .condensed {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .condensed .content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .condensed-text {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity .2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .condensed-text:hover {
|
||||||
|
opacity: .6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .condensed-text .toggle-button:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .condensed.closed .msg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#windows .header .topic,
|
#windows .header .topic,
|
||||||
.messages .msg,
|
.messages .msg,
|
||||||
.sidebar {
|
.sidebar {
|
||||||
@ -1092,15 +1122,17 @@ kbd {
|
|||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat.hide-join .join,
|
#chat.hide-status-messages .join,
|
||||||
#chat.hide-mode .mode,
|
#chat.hide-status-messages .mode,
|
||||||
#chat.hide-motd .motd,
|
#chat.hide-status-messages .nick,
|
||||||
#chat.hide-nick .nick,
|
#chat.hide-status-messages .part,
|
||||||
#chat.hide-part .part,
|
#chat.hide-status-messages .quit,
|
||||||
#chat.hide-quit .quit {
|
#chat.hide-status-messages .condensed,
|
||||||
|
#chat.hide-motd .motd {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .condensed .content,
|
||||||
#chat .join .content,
|
#chat .join .content,
|
||||||
#chat .kick .content,
|
#chat .kick .content,
|
||||||
#chat .mode .content,
|
#chat .mode .content,
|
||||||
@ -1138,19 +1170,14 @@ kbd {
|
|||||||
|
|
||||||
#chat .toggle-button {
|
#chat .toggle-button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #666;
|
transition: opacity .2s, transform .2s;
|
||||||
transition: color .2s, transform .2s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .toggle-button.opened {
|
#chat .toggle-button.opened, /* Thumbnail toggle */
|
||||||
|
#chat .msg.condensed:not(.closed) .toggle-button { /* Expanded status message toggle */
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .toggle-button:hover {
|
|
||||||
/* transform and opacity together glitch, so need to use RGBA transition */
|
|
||||||
color: rgba(102, 102, 102, .8); /* #666 x .8 opacity */
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat .toggle-content {
|
#chat .toggle-content {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
@ -1361,18 +1388,26 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
|
|||||||
|
|
||||||
#settings .opt {
|
#settings .opt {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 5px 0 10px 1px;
|
padding: 5px 0 5px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings .opt input {
|
#settings .opt input {
|
||||||
float: left;
|
margin-right: 6px;
|
||||||
margin: 4px 10px 0 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#settings .extra-help,
|
||||||
#settings #play {
|
#settings #play {
|
||||||
color: #7f8c8d;
|
color: #7f8c8d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#settings .extra-help {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings h2 .extra-help {
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
#settings #play {
|
#settings #play {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
transition: opacity .2s;
|
transition: opacity .2s;
|
||||||
@ -1694,6 +1729,16 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
|
|||||||
animation-delay: .4s;
|
animation-delay: .4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltipped-no-delay:hover:before,
|
||||||
|
.tooltipped-no-delay:hover:after,
|
||||||
|
.tooltipped-no-delay:active:before,
|
||||||
|
.tooltipped-no-delay:active:after,
|
||||||
|
.tooltipped-no-delay:focus:before,
|
||||||
|
.tooltipped-no-delay:focus:after {
|
||||||
|
-webkit-animation-delay: 0s;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
.tooltipped-s:after,
|
.tooltipped-s:after,
|
||||||
.tooltipped-se:after,
|
.tooltipped-se:after,
|
||||||
.tooltipped-sw:after {
|
.tooltipped-sw:after {
|
||||||
@ -2130,3 +2175,7 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
|
|||||||
#chat table.channel-list .topic {
|
#chat table.channel-list .topic {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide-text {
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
@ -216,48 +216,40 @@
|
|||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<h2>Messages</h2>
|
<h2>Messages</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
|
||||||
<label class="opt">
|
|
||||||
<input type="checkbox" name="join">
|
|
||||||
Show joins
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<label class="opt">
|
<label class="opt">
|
||||||
<input type="checkbox" name="motd">
|
<input type="checkbox" name="motd">
|
||||||
Show <abbr title="Message Of The Day">MOTD</abbr>
|
Show <abbr title="Message Of The Day">MOTD</abbr>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
|
||||||
<label class="opt">
|
|
||||||
<input type="checkbox" name="part">
|
|
||||||
Show parts
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<label class="opt">
|
|
||||||
<input type="checkbox" name="nick">
|
|
||||||
Show nick changes
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<label class="opt">
|
|
||||||
<input type="checkbox" name="mode">
|
|
||||||
Show mode
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<label class="opt">
|
|
||||||
<input type="checkbox" name="quit">
|
|
||||||
Show quits
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<label class="opt">
|
<label class="opt">
|
||||||
<input type="checkbox" name="showSeconds">
|
<input type="checkbox" name="showSeconds">
|
||||||
Show seconds in timestamp
|
Show seconds in timestamp
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<h2>
|
||||||
|
Status messages
|
||||||
|
<span class="tooltipped tooltipped-n tooltipped-no-delay" aria-label="Joins, parts, kicks, nick changes, and mode changes">
|
||||||
|
<button class="extra-help" aria-label="Joins, parts, kicks, nick changes, and mode changes"></button>
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<label class="opt">
|
||||||
|
<input type="radio" name="statusMessages" value="shown">
|
||||||
|
Show all status messages individually
|
||||||
|
</label>
|
||||||
|
<label class="opt">
|
||||||
|
<input type="radio" name="statusMessages" value="condensed">
|
||||||
|
Condense status messages together
|
||||||
|
</label>
|
||||||
|
<label class="opt">
|
||||||
|
<input type="radio" name="statusMessages" value="hidden">
|
||||||
|
Hide all status messages
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<h2>Visual Aids</h2>
|
<h2>Visual Aids</h2>
|
||||||
</div>
|
</div>
|
||||||
|
55
client/js/condensed.js
Normal file
55
client/js/condensed.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const constants = require("./constants");
|
||||||
|
const templates = require("../views");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
updateText
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateText(condensed, addedTypes) {
|
||||||
|
const obj = {};
|
||||||
|
|
||||||
|
constants.condensedTypes.forEach((type) => {
|
||||||
|
obj[type] = condensed.data(type) || 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
addedTypes.forEach((type) => {
|
||||||
|
obj[type]++;
|
||||||
|
condensed.data(type, obj[type]);
|
||||||
|
});
|
||||||
|
|
||||||
|
const strings = [];
|
||||||
|
constants.condensedTypes.forEach((type) => {
|
||||||
|
if (obj[type]) {
|
||||||
|
switch (type) {
|
||||||
|
case "join":
|
||||||
|
strings.push(obj[type] + (obj[type] > 1 ? " users have joined the channel" : " user has joined the channel"));
|
||||||
|
break;
|
||||||
|
case "part":
|
||||||
|
strings.push(obj[type] + (obj[type] > 1 ? " users have left the channel" : " user has left the channel"));
|
||||||
|
break;
|
||||||
|
case "quit":
|
||||||
|
strings.push(obj[type] + (obj[type] > 1 ? " users have quit" : " user has quit"));
|
||||||
|
break;
|
||||||
|
case "nick":
|
||||||
|
strings.push(obj[type] + (obj[type] > 1 ? " users have changed nick" : " user has changed nick"));
|
||||||
|
break;
|
||||||
|
case "kick":
|
||||||
|
strings.push(obj[type] + (obj[type] > 1 ? " users were kicked" : " user was kicked"));
|
||||||
|
break;
|
||||||
|
case "mode":
|
||||||
|
strings.push(obj[type] + (obj[type] > 1 ? " modes were set" : " mode was set"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let text = strings.pop();
|
||||||
|
if (strings.length) {
|
||||||
|
text = strings.join(", ") + ", and " + text;
|
||||||
|
}
|
||||||
|
|
||||||
|
condensed.find(".condensed-text")
|
||||||
|
.html(text + templates.msg_condensed_toggle());
|
||||||
|
}
|
@ -56,6 +56,32 @@ const commands = [
|
|||||||
"/whois"
|
"/whois"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const actionTypes = [
|
||||||
|
"ban_list",
|
||||||
|
"invite",
|
||||||
|
"join",
|
||||||
|
"mode",
|
||||||
|
"kick",
|
||||||
|
"nick",
|
||||||
|
"part",
|
||||||
|
"quit",
|
||||||
|
"topic",
|
||||||
|
"topic_set_by",
|
||||||
|
"action",
|
||||||
|
"whois",
|
||||||
|
"ctcp",
|
||||||
|
"channel_list",
|
||||||
|
];
|
||||||
|
|
||||||
|
const condensedTypes = [
|
||||||
|
"join",
|
||||||
|
"part",
|
||||||
|
"quit",
|
||||||
|
"nick",
|
||||||
|
"kick",
|
||||||
|
"mode",
|
||||||
|
];
|
||||||
|
|
||||||
const timeFormats = {
|
const timeFormats = {
|
||||||
msgDefault: "HH:mm",
|
msgDefault: "HH:mm",
|
||||||
msgWithSeconds: "HH:mm:ss"
|
msgWithSeconds: "HH:mm:ss"
|
||||||
@ -63,6 +89,8 @@ const timeFormats = {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
colorCodeMap: colorCodeMap,
|
colorCodeMap: colorCodeMap,
|
||||||
timeFormats: timeFormats,
|
commands: commands,
|
||||||
commands: commands
|
condensedTypes: condensedTypes,
|
||||||
|
actionTypes: actionTypes,
|
||||||
|
timeFormats: timeFormats
|
||||||
};
|
};
|
||||||
|
@ -439,6 +439,10 @@ $(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
chat.on("click", ".condensed-text", function() {
|
||||||
|
$(this).closest(".msg.condensed").toggleClass("closed");
|
||||||
|
});
|
||||||
|
|
||||||
chat.on("click", ".user", function() {
|
chat.on("click", ".user", function() {
|
||||||
var name = $(this).data("name");
|
var name = $(this).data("name");
|
||||||
var chan = findCurrentNetworkChan(name);
|
var chan = findCurrentNetworkChan(name);
|
||||||
@ -707,6 +711,9 @@ $(function() {
|
|||||||
chat.on("click", ".show-more-button", function() {
|
chat.on("click", ".show-more-button", function() {
|
||||||
var self = $(this);
|
var self = $(this);
|
||||||
var lastMessage = self.parent().next(".messages").children(".msg").first();
|
var lastMessage = self.parent().next(".messages").children(".msg").first();
|
||||||
|
if (lastMessage.is(".condensed")) {
|
||||||
|
lastMessage = lastMessage.children(".msg").first();
|
||||||
|
}
|
||||||
var lastMessageId = parseInt(lastMessage[0].id.replace("msg-", ""), 10);
|
var lastMessageId = parseInt(lastMessage[0].id.replace("msg-", ""), 10);
|
||||||
|
|
||||||
self
|
self
|
||||||
|
@ -9,25 +9,29 @@ const tz = require("./libs/handlebars/tz");
|
|||||||
const windows = $("#windows");
|
const windows = $("#windows");
|
||||||
const chat = $("#chat");
|
const chat = $("#chat");
|
||||||
|
|
||||||
const options = $.extend({
|
// Default options
|
||||||
|
const options = {
|
||||||
|
autocomplete: true,
|
||||||
coloredNicks: true,
|
coloredNicks: true,
|
||||||
desktopNotifications: false,
|
desktopNotifications: false,
|
||||||
join: true,
|
highlights: [],
|
||||||
links: true,
|
links: true,
|
||||||
mode: true,
|
|
||||||
motd: true,
|
motd: true,
|
||||||
nick: true,
|
|
||||||
notification: true,
|
notification: true,
|
||||||
notifyAllMessages: false,
|
notifyAllMessages: false,
|
||||||
part: true,
|
|
||||||
quit: true,
|
|
||||||
showSeconds: false,
|
showSeconds: false,
|
||||||
|
statusMessages: "condensed",
|
||||||
theme: $("#theme").attr("href").replace(/^themes\/(.*).css$/, "$1"), // Extracts default theme name, set on the server configuration
|
theme: $("#theme").attr("href").replace(/^themes\/(.*).css$/, "$1"), // Extracts default theme name, set on the server configuration
|
||||||
thumbnails: true,
|
thumbnails: true,
|
||||||
userStyles: userStyles.text(),
|
userStyles: userStyles.text(),
|
||||||
highlights: [],
|
};
|
||||||
autocomplete: true
|
const userOptions = JSON.parse(storage.get("settings")) || {};
|
||||||
}, JSON.parse(storage.get("settings")));
|
|
||||||
|
for (const key in options) {
|
||||||
|
if (userOptions[key]) {
|
||||||
|
options[key] = userOptions[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = options;
|
module.exports = options;
|
||||||
|
|
||||||
@ -43,6 +47,9 @@ for (var i in options) {
|
|||||||
settings.find("#user-specified-css-input").val(options[i]);
|
settings.find("#user-specified-css-input").val(options[i]);
|
||||||
} else if (i === "highlights") {
|
} else if (i === "highlights") {
|
||||||
settings.find("input[name=" + i + "]").val(options[i]);
|
settings.find("input[name=" + i + "]").val(options[i]);
|
||||||
|
} else if (i === "statusMessages") {
|
||||||
|
settings.find(`input[name=${i}][value=${options[i]}]`)
|
||||||
|
.prop("checked", true);
|
||||||
} else if (i === "theme") {
|
} else if (i === "theme") {
|
||||||
$("#theme").attr("href", "themes/" + options[i] + ".css");
|
$("#theme").attr("href", "themes/" + options[i] + ".css");
|
||||||
settings.find("select[name=" + i + "]").val(options[i]);
|
settings.find("select[name=" + i + "]").val(options[i]);
|
||||||
@ -58,6 +65,10 @@ settings.on("change", "input, select, textarea", function() {
|
|||||||
|
|
||||||
if (type === "password") {
|
if (type === "password") {
|
||||||
return;
|
return;
|
||||||
|
} else if (type === "radio") {
|
||||||
|
if (self.prop("checked")) {
|
||||||
|
options[name] = self.val();
|
||||||
|
}
|
||||||
} else if (type === "checkbox") {
|
} else if (type === "checkbox") {
|
||||||
options[name] = self.prop("checked");
|
options[name] = self.prop("checked");
|
||||||
} else {
|
} else {
|
||||||
@ -66,16 +77,10 @@ settings.on("change", "input, select, textarea", function() {
|
|||||||
|
|
||||||
storage.set("settings", JSON.stringify(options));
|
storage.set("settings", JSON.stringify(options));
|
||||||
|
|
||||||
if ([
|
if (name === "motd") {
|
||||||
"join",
|
|
||||||
"mode",
|
|
||||||
"motd",
|
|
||||||
"nick",
|
|
||||||
"part",
|
|
||||||
"quit",
|
|
||||||
"notifyAllMessages",
|
|
||||||
].indexOf(name) !== -1) {
|
|
||||||
chat.toggleClass("hide-" + name, !self.prop("checked"));
|
chat.toggleClass("hide-" + name, !self.prop("checked"));
|
||||||
|
} else if (name === "statusMessages") {
|
||||||
|
chat.toggleClass("hide-status-messages", options[name] === "hidden");
|
||||||
} else if (name === "coloredNicks") {
|
} else if (name === "coloredNicks") {
|
||||||
chat.toggleClass("colored-nicks", self.prop("checked"));
|
chat.toggleClass("colored-nicks", self.prop("checked"));
|
||||||
} else if (name === "theme") {
|
} else if (name === "theme") {
|
||||||
|
@ -6,11 +6,14 @@ const options = require("./options");
|
|||||||
const renderPreview = require("./renderPreview");
|
const renderPreview = require("./renderPreview");
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
const sorting = require("./sorting");
|
const sorting = require("./sorting");
|
||||||
|
const constants = require("./constants");
|
||||||
|
const condense = require("./condensed");
|
||||||
|
|
||||||
const chat = $("#chat");
|
const chat = $("#chat");
|
||||||
const sidebar = $("#sidebar");
|
const sidebar = $("#sidebar");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
appendMessage,
|
||||||
buildChannelMessages,
|
buildChannelMessages,
|
||||||
buildChatMessage,
|
buildChatMessage,
|
||||||
renderChannel,
|
renderChannel,
|
||||||
@ -19,16 +22,39 @@ module.exports = {
|
|||||||
renderNetworks,
|
renderNetworks,
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildChannelMessages(channel, messages) {
|
function buildChannelMessages(data) {
|
||||||
return messages.reduce(function(docFragment, message) {
|
return data.messages.reduce(function(docFragment, message) {
|
||||||
docFragment.append(buildChatMessage({
|
appendMessage(docFragment, data.id, data.type, message.type, buildChatMessage({
|
||||||
chan: channel,
|
chan: data.id,
|
||||||
msg: message
|
msg: message
|
||||||
}));
|
}));
|
||||||
return docFragment;
|
return docFragment;
|
||||||
}, $(document.createDocumentFragment()));
|
}, $(document.createDocumentFragment()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function appendMessage(container, chan, chanType, messageType, msg) {
|
||||||
|
if (constants.condensedTypes.indexOf(messageType) !== -1 && chanType !== "lobby") {
|
||||||
|
var condensedTypesClasses = "." + constants.condensedTypes.join(", .");
|
||||||
|
var lastChild = container.children("div.msg").last();
|
||||||
|
var lastDate = (new Date(lastChild.attr("data-time"))).toDateString();
|
||||||
|
var msgDate = (new Date(msg.attr("data-time"))).toDateString();
|
||||||
|
if (lastChild && $(lastChild).hasClass("condensed") && !$(msg).hasClass("message") && lastDate === msgDate) {
|
||||||
|
lastChild.append(msg);
|
||||||
|
condense.updateText(lastChild, [messageType]);
|
||||||
|
} else if (lastChild && $(lastChild).is(condensedTypesClasses) && options.statusMessages === "condensed") {
|
||||||
|
var condensed = buildChatMessage({msg: {type: "condensed", time: msg.attr("data-time"), previews: []}, chan: chan});
|
||||||
|
condensed.append(lastChild);
|
||||||
|
condensed.append(msg);
|
||||||
|
container.append(condensed);
|
||||||
|
condense.updateText(condensed, [messageType, lastChild.attr("data-type")]);
|
||||||
|
} else {
|
||||||
|
container.append(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container.append(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function buildChatMessage(data) {
|
function buildChatMessage(data) {
|
||||||
const type = data.msg.type;
|
const type = data.msg.type;
|
||||||
let target = "#chan-" + data.chan;
|
let target = "#chan-" + data.chan;
|
||||||
@ -45,25 +71,13 @@ function buildChatMessage(data) {
|
|||||||
data.msg.highlight = true;
|
data.msg.highlight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([
|
if (constants.actionTypes.indexOf(type) !== -1) {
|
||||||
"invite",
|
data.msg.template = "actions/" + type;
|
||||||
"join",
|
|
||||||
"mode",
|
|
||||||
"kick",
|
|
||||||
"nick",
|
|
||||||
"part",
|
|
||||||
"quit",
|
|
||||||
"topic",
|
|
||||||
"topic_set_by",
|
|
||||||
"action",
|
|
||||||
"whois",
|
|
||||||
"ctcp",
|
|
||||||
"channel_list",
|
|
||||||
"ban_list",
|
|
||||||
].indexOf(type) !== -1) {
|
|
||||||
template = "msg_action";
|
template = "msg_action";
|
||||||
} else if (type === "unhandled") {
|
} else if (type === "unhandled") {
|
||||||
template = "msg_unhandled";
|
template = "msg_unhandled";
|
||||||
|
} else if (type === "condensed") {
|
||||||
|
template = "msg_condensed";
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = $(templates[template](data.msg));
|
const msg = $(templates[template](data.msg));
|
||||||
@ -100,7 +114,7 @@ function renderChannel(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderChannelMessages(data) {
|
function renderChannelMessages(data) {
|
||||||
const documentFragment = buildChannelMessages(data.id, data.messages);
|
const documentFragment = buildChannelMessages(data);
|
||||||
const channel = chat.find("#chan-" + data.id + " .messages").append(documentFragment);
|
const channel = chat.find("#chan-" + data.id + " .messages").append(documentFragment);
|
||||||
|
|
||||||
if (data.firstUnread > 0) {
|
if (data.firstUnread > 0) {
|
||||||
@ -109,6 +123,8 @@ function renderChannelMessages(data) {
|
|||||||
// TODO: If the message is far off in the history, we still need to append the marker into DOM
|
// TODO: If the message is far off in the history, we still need to append the marker into DOM
|
||||||
if (!first.length) {
|
if (!first.length) {
|
||||||
channel.prepend(templates.unread_marker());
|
channel.prepend(templates.unread_marker());
|
||||||
|
} else if (first.parent().hasClass("condensed")) {
|
||||||
|
first.parent().before(templates.unread_marker());
|
||||||
} else {
|
} else {
|
||||||
first.before(templates.unread_marker());
|
first.before(templates.unread_marker());
|
||||||
}
|
}
|
||||||
@ -129,6 +145,10 @@ function renderChannelMessages(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastDate.toDateString() !== msgDate.toDateString()) {
|
if (lastDate.toDateString() !== msgDate.toDateString()) {
|
||||||
|
var parent = msg.parent();
|
||||||
|
if (parent.hasClass("condensed")) {
|
||||||
|
msg.insertAfter(parent);
|
||||||
|
}
|
||||||
msg.before(templates.date_marker({msgDate: msgDate}));
|
msg.before(templates.date_marker({msgDate: msgDate}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ function renderPreview(preview, msg) {
|
|||||||
container.trigger("keepToBottom");
|
container.trigger("keepToBottom");
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#chat").on("click", ".toggle-button", function() {
|
$("#chat").on("click", ".text .toggle-button", function() {
|
||||||
const self = $(this);
|
const self = $(this);
|
||||||
const container = self.closest(".chat");
|
const container = self.closest(".chat");
|
||||||
const content = self.closest(".content")
|
const content = self.closest(".content")
|
||||||
|
@ -7,7 +7,7 @@ const chat = $("#chat");
|
|||||||
const templates = require("../../views");
|
const templates = require("../../views");
|
||||||
|
|
||||||
socket.on("more", function(data) {
|
socket.on("more", function(data) {
|
||||||
const documentFragment = render.buildChannelMessages(data.chan, data.messages);
|
const documentFragment = render.buildChannelMessages(data);
|
||||||
const chan = chat
|
const chan = chat
|
||||||
.find("#chan-" + data.chan)
|
.find("#chan-" + data.chan)
|
||||||
.find(".messages");
|
.find(".messages");
|
||||||
@ -24,6 +24,8 @@ socket.on("more", function(data) {
|
|||||||
} else if (children.eq(1).hasClass("date-marker-container")) {
|
} else if (children.eq(1).hasClass("date-marker-container")) {
|
||||||
// The unread-marker could be at index 0, which will cause the date-marker to become "stuck"
|
// The unread-marker could be at index 0, which will cause the date-marker to become "stuck"
|
||||||
children.eq(1).remove();
|
children.eq(1).remove();
|
||||||
|
} else if (children.eq(0).hasClass("condensed") && children.eq(0).children(".date-marker-container").eq(0).hasClass("date-marker-container")) {
|
||||||
|
children.eq(0).children(".date-marker-container").eq(0).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the older messages
|
// Add the older messages
|
||||||
@ -52,6 +54,10 @@ socket.on("more", function(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastDate.toDateString() !== msgDate.toDateString()) {
|
if (lastDate.toDateString() !== msgDate.toDateString()) {
|
||||||
|
var parent = msg.parent();
|
||||||
|
if (parent.hasClass("condensed")) {
|
||||||
|
msg.insertAfter(parent);
|
||||||
|
}
|
||||||
msg.before(templates.date_marker({msgDate: msgDate}));
|
msg.before(templates.date_marker({msgDate: msgDate}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,9 @@ const templates = require("../../views");
|
|||||||
|
|
||||||
socket.on("msg", function(data) {
|
socket.on("msg", function(data) {
|
||||||
const msg = render.buildChatMessage(data);
|
const msg = render.buildChatMessage(data);
|
||||||
const target = data.chan;
|
const targetId = data.chan;
|
||||||
const channel = chat.find("#chan-" + target);
|
const target = "#chan-" + targetId;
|
||||||
|
const channel = chat.find(target);
|
||||||
const container = channel.find(".messages");
|
const container = channel.find(".messages");
|
||||||
|
|
||||||
const activeChannelId = chat.find(".chan.active").data("id");
|
const activeChannelId = chat.find(".chan.active").data("id");
|
||||||
@ -19,7 +20,7 @@ socket.on("msg", function(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if date changed
|
// Check if date changed
|
||||||
const prevMsg = $(container.find(".msg")).last();
|
let prevMsg = $(container.find(".msg")).last();
|
||||||
const prevMsgTime = new Date(prevMsg.attr("data-time"));
|
const prevMsgTime = new Date(prevMsg.attr("data-time"));
|
||||||
const msgTime = new Date(msg.attr("data-time"));
|
const msgTime = new Date(msg.attr("data-time"));
|
||||||
|
|
||||||
@ -29,17 +30,26 @@ socket.on("msg", function(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prevMsgTime.toDateString() !== msgTime.toDateString()) {
|
if (prevMsgTime.toDateString() !== msgTime.toDateString()) {
|
||||||
|
var parent = prevMsg.parent();
|
||||||
|
if (parent.hasClass("condensed")) {
|
||||||
|
prevMsg = parent;
|
||||||
|
}
|
||||||
prevMsg.after(templates.date_marker({msgDate: msgTime}));
|
prevMsg.after(templates.date_marker({msgDate: msgTime}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add message to the container
|
// Add message to the container
|
||||||
container
|
render.appendMessage(
|
||||||
.append(msg)
|
container,
|
||||||
.trigger("msg", [
|
data.chan,
|
||||||
"#chan-" + target,
|
$(target).attr("data-type"),
|
||||||
data
|
data.msg.type,
|
||||||
])
|
msg
|
||||||
.trigger("keepToBottom");
|
);
|
||||||
|
|
||||||
|
container.trigger("msg", [
|
||||||
|
target,
|
||||||
|
data
|
||||||
|
]).trigger("keepToBottom");
|
||||||
|
|
||||||
var lastVisible = container.find("div:visible").last();
|
var lastVisible = container.find("div:visible").last();
|
||||||
if (data.msg.self
|
if (data.msg.self
|
||||||
@ -52,7 +62,7 @@ socket.on("msg", function(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Message arrived in a non active channel, trim it to 100 messages
|
// Message arrived in a non active channel, trim it to 100 messages
|
||||||
if (activeChannelId !== target && container.find(".msg").slice(0, -100).remove().length) {
|
if (activeChannelId !== targetId && container.find(".msg").slice(0, -100).remove().length) {
|
||||||
channel.find(".show-more").addClass("show");
|
channel.find(".show-more").addClass("show");
|
||||||
|
|
||||||
// Remove date-seperators that would otherwise
|
// Remove date-seperators that would otherwise
|
||||||
|
@ -101,10 +101,6 @@ body {
|
|||||||
color: #428bca;
|
color: #428bca;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat button:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increase contrast of some IRC colors */
|
/* Increase contrast of some IRC colors */
|
||||||
.irc-fg2 { color: #0074d9; }
|
.irc-fg2 { color: #0074d9; }
|
||||||
.irc-fg5 { color: #e969a7; }
|
.irc-fg5 { color: #e969a7; }
|
||||||
@ -208,17 +204,9 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Embeds */
|
/* Embeds */
|
||||||
#chat .toggle-content,
|
|
||||||
#chat .toggle-button {
|
|
||||||
color: #f3f3f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat .toggle-button:hover {
|
|
||||||
color: rgba(243, 243, 243, .8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat .toggle-content {
|
#chat .toggle-content {
|
||||||
background: #242a33;
|
background: #242a33;
|
||||||
|
color: #f3f3f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .toggle-content .body {
|
#chat .toggle-content .body {
|
||||||
|
@ -127,10 +127,6 @@ body {
|
|||||||
color: #8c8cbc;
|
color: #8c8cbc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat button:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increase contrast of some IRC colors */
|
/* Increase contrast of some IRC colors */
|
||||||
.irc-fg2 { color: #1b94ff; }
|
.irc-fg2 { color: #1b94ff; }
|
||||||
.irc-fg5 { color: #e969a7; }
|
.irc-fg5 { color: #e969a7; }
|
||||||
@ -235,17 +231,9 @@ body {
|
|||||||
|
|
||||||
/* Previews */
|
/* Previews */
|
||||||
|
|
||||||
#chat .toggle-content,
|
|
||||||
#chat .toggle-button {
|
|
||||||
color: #dcdccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat .toggle-button:hover {
|
|
||||||
color: rgba(220, 220, 204, .8);
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat .toggle-content {
|
#chat .toggle-content {
|
||||||
background: #333;
|
background: #333;
|
||||||
|
color: #dcdccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .toggle-content .body {
|
#chat .toggle-content .body {
|
||||||
|
@ -25,6 +25,8 @@ module.exports = {
|
|||||||
date_marker: require("./date-marker.tpl"),
|
date_marker: require("./date-marker.tpl"),
|
||||||
msg: require("./msg.tpl"),
|
msg: require("./msg.tpl"),
|
||||||
msg_action: require("./msg_action.tpl"),
|
msg_action: require("./msg_action.tpl"),
|
||||||
|
msg_condensed_toggle: require("./msg_condensed_toggle.tpl"),
|
||||||
|
msg_condensed: require("./msg_condensed.tpl"),
|
||||||
msg_preview: require("./msg_preview.tpl"),
|
msg_preview: require("./msg_preview.tpl"),
|
||||||
msg_preview_toggle: require("./msg_preview_toggle.tpl"),
|
msg_preview_toggle: require("./msg_preview_toggle.tpl"),
|
||||||
msg_unhandled: require("./msg_unhandled.tpl"),
|
msg_unhandled: require("./msg_unhandled.tpl"),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<div class="msg {{type}}{{#if self}} self{{/if}}{{#if highlight}} highlight{{/if}}" id="msg-{{id}}" data-time="{{time}}">
|
<div class="msg {{type}}{{#if self}} self{{/if}}{{#if highlight}} highlight{{/if}}"
|
||||||
|
data-type="{{type}}" id="msg-{{id}}" data-time="{{time}}">
|
||||||
<span class="time tooltipped tooltipped-e" aria-label="{{localetime time}}">
|
<span class="time tooltipped tooltipped-e" aria-label="{{localetime time}}">
|
||||||
{{tz time}}
|
{{tz time}}
|
||||||
</span>
|
</span>
|
||||||
|
7
client/views/msg_condensed.tpl
Normal file
7
client/views/msg_condensed.tpl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<div class="msg {{type}} closed" data-time="{{time}}">
|
||||||
|
<span class="time hide-text">{{tz time}}</span>
|
||||||
|
<span class="from"></span>
|
||||||
|
<span class="content">
|
||||||
|
<span class="condensed-text"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
1
client/views/msg_condensed_toggle.tpl
Normal file
1
client/views/msg_condensed_toggle.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
<button class="toggle-button" aria-label="Toggle status messages"></button>
|
Loading…
Reference in New Issue
Block a user