diff --git a/client/css/style.css b/client/css/style.css index 9aead5b6..d17e82d6 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -679,6 +679,7 @@ button { #chat .show-more { display: none; padding: 10px; + padding-bottom: 0; width: 100%; } @@ -711,6 +712,17 @@ button { word-wrap: break-word; } +#chat .unread-marker span { + padding: 0; + height: 1px; + border-color: #455164; + background-color: #455164; +} + +#chat .unread-marker:last-child { + display: none; +} + .inline-channel { cursor: pointer; } @@ -1625,10 +1637,6 @@ button { padding: 2px 0; } - #chat .msg:last-child { - height: auto; - } - #chat .time, #chat .from, #chat .text { @@ -1636,6 +1644,16 @@ button { display: inline; padding: 0; } + + #chat .unread-marker .time, + #chat .unread-marker .from { + display: none; + } + + #chat .unread-marker .text { + display: block; + width: 100%; + } } ::-webkit-scrollbar { diff --git a/client/js/lounge.js b/client/js/lounge.js index 47a990a7..b5347e06 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -285,7 +285,20 @@ $(function() { function renderChannelMessages(data) { 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) { @@ -313,12 +326,20 @@ $(function() { socket.on("msg", function(data) { var msg = buildChatMessage(data); var target = "#chan-" + data.chan; - chat.find(target + " .messages") + var container = chat.find(target + " .messages"); + + container .append(msg) .trigger("msg", [ target, data.msg ]); + + if (data.msg.self) { + container + .find(".unread-marker") + .appendTo(container); + } }); socket.on("more", function(data) { @@ -751,11 +772,17 @@ $(function() { } viewport.removeClass("lt"); - $("#windows .active") + var lastActive = $("#windows .active"); + + lastActive .removeClass("active") .find(".chat") .unsticky(); + lastActive + .find(".unread-marker") + .appendTo(lastActive.find(".messages")); + var chan = $(target) .addClass("active") .trigger("show") @@ -1029,14 +1056,14 @@ $(function() { setInterval(function() { chat.find(".chan:not(.active)").each(function() { 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"); } }); }, 1000 * 10); function clear() { - chat.find(".active .messages").empty(); + chat.find(".active .messages .msg:not(.unread-marker)").remove(); chat.find(".active .show-more").addClass("show"); } diff --git a/client/views/msg.tpl b/client/views/msg.tpl index 10c79e24..65737198 100644 --- a/client/views/msg.tpl +++ b/client/views/msg.tpl @@ -1,4 +1,4 @@ -
+
{{tz time}} diff --git a/client/views/msg_action.tpl b/client/views/msg_action.tpl index 2eb1fe85..9b56fdad 100644 --- a/client/views/msg_action.tpl +++ b/client/views/msg_action.tpl @@ -1,4 +1,4 @@ -
+
{{tz time}} diff --git a/client/views/unread_marker.tpl b/client/views/unread_marker.tpl new file mode 100644 index 00000000..9e24bc63 --- /dev/null +++ b/client/views/unread_marker.tpl @@ -0,0 +1,5 @@ +
+ + + +
diff --git a/src/client.js b/src/client.js index 9bb3ea62..f1b64b56 100644 --- a/src/client.js +++ b/src/client.js @@ -361,6 +361,7 @@ Client.prototype.more = function(data) { Client.prototype.open = function(data) { var target = this.find(data); if (target) { + target.chan.firstUnread = 0; target.chan.unread = 0; target.chan.highlight = false; this.activeChannel = target.chan.id; diff --git a/src/models/chan.js b/src/models/chan.js index f5481141..e64ac8ac 100644 --- a/src/models/chan.js +++ b/src/models/chan.js @@ -18,6 +18,7 @@ function Chan(attr) { name: "", topic: "", type: Chan.Type.CHANNEL, + firstUnread: 0, unread: 0, highlight: false, users: [] @@ -41,6 +42,16 @@ Chan.prototype.pushMessage = function(client, msg) { if (Helper.config.maxHistory >= 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) { diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 98c7c52a..bd1b5291 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -72,10 +72,6 @@ module.exports = function(irc, network) { if (!self && chan.id !== client.activeChannel) { chan.unread++; - - if (highlight) { - chan.highlight = true; - } } var msg = new Msg({