Merge pull request #332 from thelounge/xpaw/unread-marker
A proper unread marker
This commit is contained in:
commit
18c615236d
@ -679,6 +679,7 @@ button {
|
|||||||
#chat .show-more {
|
#chat .show-more {
|
||||||
display: none;
|
display: none;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
padding-bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,15 +701,40 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#chat .messages {
|
#chat .messages {
|
||||||
display: table;
|
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
word-wrap: break-word;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .msg {
|
#chat .unread-marker {
|
||||||
display: table-row;
|
position: relative;
|
||||||
word-wrap: break-word;
|
text-align: center;
|
||||||
|
opacity: .5;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker:before {
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
content: "";
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
border-top: 1px solid #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker-text:before {
|
||||||
|
content: "New messages";
|
||||||
|
background-color: white;
|
||||||
|
color: #e74c3c;
|
||||||
|
padding: 0 10px;
|
||||||
|
font: bold 12px Lato;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker:last-child {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-channel {
|
.inline-channel {
|
||||||
@ -739,7 +765,7 @@ button {
|
|||||||
color: #b1c3ce;
|
color: #b1c3ce;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
width: 134px;
|
max-width: 134px;
|
||||||
min-width: 134px;
|
min-width: 134px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1629,10 +1655,6 @@ button {
|
|||||||
padding: 2px 0;
|
padding: 2px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .msg:last-child {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chat .time,
|
#chat .time,
|
||||||
#chat .from,
|
#chat .from,
|
||||||
#chat .text {
|
#chat .text {
|
||||||
@ -1640,6 +1662,10 @@ button {
|
|||||||
display: inline;
|
display: inline;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
|
@ -287,7 +287,20 @@ $(function() {
|
|||||||
|
|
||||||
function renderChannelMessages(data) {
|
function renderChannelMessages(data) {
|
||||||
var documentFragment = buildChannelMessages(data.id, data.messages);
|
var documentFragment = buildChannelMessages(data.id, data.messages);
|
||||||
chat.find("#chan-" + data.id + " .messages").append(documentFragment);
|
var channel = chat.find("#chan-" + data.id + " .messages").append(documentFragment);
|
||||||
|
|
||||||
|
if (data.firstUnread > 0) {
|
||||||
|
var first = channel.find("#msg-" + data.firstUnread);
|
||||||
|
|
||||||
|
// TODO: If the message is far off in the history, we still need to append the marker into DOM
|
||||||
|
if (!first.length) {
|
||||||
|
channel.prepend(render("unread_marker"));
|
||||||
|
} else {
|
||||||
|
first.before(render("unread_marker"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.append(render("unread_marker"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderChannelUsers(data) {
|
function renderChannelUsers(data) {
|
||||||
@ -315,12 +328,20 @@ $(function() {
|
|||||||
socket.on("msg", function(data) {
|
socket.on("msg", function(data) {
|
||||||
var msg = buildChatMessage(data);
|
var msg = buildChatMessage(data);
|
||||||
var target = "#chan-" + data.chan;
|
var target = "#chan-" + data.chan;
|
||||||
chat.find(target + " .messages")
|
var container = chat.find(target + " .messages");
|
||||||
|
|
||||||
|
container
|
||||||
.append(msg)
|
.append(msg)
|
||||||
.trigger("msg", [
|
.trigger("msg", [
|
||||||
target,
|
target,
|
||||||
data.msg
|
data.msg
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if (data.msg.self) {
|
||||||
|
container
|
||||||
|
.find(".unread-marker")
|
||||||
|
.appendTo(container);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("more", function(data) {
|
socket.on("more", function(data) {
|
||||||
@ -753,11 +774,17 @@ $(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewport.removeClass("lt");
|
viewport.removeClass("lt");
|
||||||
$("#windows .active")
|
var lastActive = $("#windows .active");
|
||||||
|
|
||||||
|
lastActive
|
||||||
.removeClass("active")
|
.removeClass("active")
|
||||||
.find(".chat")
|
.find(".chat")
|
||||||
.unsticky();
|
.unsticky();
|
||||||
|
|
||||||
|
lastActive
|
||||||
|
.find(".unread-marker")
|
||||||
|
.appendTo(lastActive.find(".messages"));
|
||||||
|
|
||||||
var chan = $(target)
|
var chan = $(target)
|
||||||
.addClass("active")
|
.addClass("active")
|
||||||
.trigger("show")
|
.trigger("show")
|
||||||
@ -1031,14 +1058,14 @@ $(function() {
|
|||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
chat.find(".chan:not(.active)").each(function() {
|
chat.find(".chan:not(.active)").each(function() {
|
||||||
var chan = $(this);
|
var chan = $(this);
|
||||||
if (chan.find(".messages").children().slice(0, -100).remove().length) {
|
if (chan.find(".messages .msg:not(.unread-marker)").slice(0, -100).remove().length) {
|
||||||
chan.find(".show-more").addClass("show");
|
chan.find(".show-more").addClass("show");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 1000 * 10);
|
}, 1000 * 10);
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
chat.find(".active .messages").empty();
|
chat.find(".active .messages .msg:not(.unread-marker)").remove();
|
||||||
chat.find(".active .show-more").addClass("show");
|
chat.find(".active .show-more").addClass("show");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +117,10 @@ a:hover,
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker-text:before {
|
||||||
|
font: bold 12px Inconsolata-g, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
#form .input {
|
#form .input {
|
||||||
font: 12px Inconsolata-g, monospace;
|
font: 12px Inconsolata-g, monospace;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,14 @@ body {
|
|||||||
color: #99a2b4;
|
color: #99a2b4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker-text:before {
|
||||||
|
background-color: #333c4a;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup text colors */
|
/* Setup text colors */
|
||||||
#chat .msg {
|
#chat .msg {
|
||||||
color: #f3f3f3;
|
color: #f3f3f3;
|
||||||
|
@ -202,6 +202,14 @@ body {
|
|||||||
color: #d2d39b;
|
color: #d2d39b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .unread-marker-text:before {
|
||||||
|
background-color: #3f3f3f;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup text colors */
|
/* Setup text colors */
|
||||||
#chat .msg {
|
#chat .msg {
|
||||||
color: #ffcfaf;
|
color: #ffcfaf;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div class="msg {{type}}{{#if self}} self{{/if}}{{#if highlight}} highlight{{/if}}">
|
<div class="msg {{type}}{{#if self}} self{{/if}}{{#if highlight}} highlight{{/if}}" id="msg-{{id}}">
|
||||||
<span class="time">
|
<span class="time">
|
||||||
{{tz time}}
|
{{tz time}}
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div class="msg {{type}}{{#if self}} self{{/if}}{{#if highlight}} highlight{{/if}}">
|
<div class="msg {{type}}{{#if self}} self{{/if}}{{#if highlight}} highlight{{/if}}" id="msg-{{id}}">
|
||||||
<span class="time">
|
<span class="time">
|
||||||
{{tz time}}
|
{{tz time}}
|
||||||
</span>
|
</span>
|
||||||
|
3
client/views/unread_marker.tpl
Normal file
3
client/views/unread_marker.tpl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div class="unread-marker">
|
||||||
|
<span class="unread-marker-text"></span>
|
||||||
|
</div>
|
@ -362,6 +362,7 @@ Client.prototype.more = function(data) {
|
|||||||
Client.prototype.open = function(data) {
|
Client.prototype.open = function(data) {
|
||||||
var target = this.find(data);
|
var target = this.find(data);
|
||||||
if (target) {
|
if (target) {
|
||||||
|
target.chan.firstUnread = 0;
|
||||||
target.chan.unread = 0;
|
target.chan.unread = 0;
|
||||||
target.chan.highlight = false;
|
target.chan.highlight = false;
|
||||||
this.activeChannel = target.chan.id;
|
this.activeChannel = target.chan.id;
|
||||||
|
@ -18,6 +18,7 @@ function Chan(attr) {
|
|||||||
name: "",
|
name: "",
|
||||||
topic: "",
|
topic: "",
|
||||||
type: Chan.Type.CHANNEL,
|
type: Chan.Type.CHANNEL,
|
||||||
|
firstUnread: 0,
|
||||||
unread: 0,
|
unread: 0,
|
||||||
highlight: false,
|
highlight: false,
|
||||||
users: []
|
users: []
|
||||||
@ -41,6 +42,16 @@ Chan.prototype.pushMessage = function(client, msg) {
|
|||||||
if (Helper.config.maxHistory >= 0 && this.messages.length > Helper.config.maxHistory) {
|
if (Helper.config.maxHistory >= 0 && this.messages.length > Helper.config.maxHistory) {
|
||||||
this.messages.splice(0, this.messages.length - Helper.config.maxHistory);
|
this.messages.splice(0, this.messages.length - Helper.config.maxHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!msg.self && this.id !== client.activeChannel) {
|
||||||
|
if (!this.firstUnread) {
|
||||||
|
this.firstUnread = msg.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.highlight) {
|
||||||
|
this.highlight = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Chan.prototype.sortUsers = function(irc) {
|
Chan.prototype.sortUsers = function(irc) {
|
||||||
|
@ -72,10 +72,6 @@ module.exports = function(irc, network) {
|
|||||||
|
|
||||||
if (!self && chan.id !== client.activeChannel) {
|
if (!self && chan.id !== client.activeChannel) {
|
||||||
chan.unread++;
|
chan.unread++;
|
||||||
|
|
||||||
if (highlight) {
|
|
||||||
chan.highlight = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = new Msg({
|
var msg = new Msg({
|
||||||
|
Loading…
Reference in New Issue
Block a user