Separate messages from different days.

This commit is contained in:
JC Brand 2012-12-06 12:49:03 +02:00
parent 7ae4bed223
commit f1bfc51152
2 changed files with 89 additions and 31 deletions

View File

@ -145,7 +145,7 @@ input.new-chatroom-name {
white-space: nowrap; white-space: nowrap;
} }
.chat-event { .chat-event, .chat-date {
color: #808080; color: #808080;
} }

View File

@ -79,22 +79,39 @@
}(this, function ($, store, _, console) { }(this, function ($, store, _, console) {
var xmppchat = {}; var xmppchat = {};
xmppchat.msg_counter = 0;
// IE <= 8 Doesn't have toISOStringMethod xmppchat.toISOString = function (date) {
if (!Date.toISOString) { if (typeof date.toISOString !== 'undefined') {
Date.prototype.toISOString = function () { return date.toISOString();
var d = new Date(); } else {
// IE <= 8 Doesn't have toISOStringMethod
pad = function (num) { pad = function (num) {
return (num < 10) ? '0' + num : '' + num; return (num < 10) ? '0' + num : '' + num;
}; };
return d.getUTCFullYear() + '-' + return date.getUTCFullYear() + '-' +
pad(d.getUTCMonth() + 1) + '-' + pad(date.getUTCMonth() + 1) + '-' +
pad(d.getUTCDate()) + 'T' + pad(date.getUTCDate()) + 'T' +
pad(d.getUTCHours()) + ':' + pad(date.getUTCHours()) + ':' +
pad(d.getUTCMinutes()) + ':' + pad(date.getUTCMinutes()) + ':' +
pad(d.getUTCSeconds()) + '.000Z'; pad(date.getUTCSeconds()) + '.000Z';
}; }
} };
xmppchat.updateMsgCounter = function () {
this.msg_counter += 1;
if (this.msg_counter > 0) {
if (document.title.search(/^Messages \(\d\) /) === -1) {
document.title = "Messages (" + this.msg_counter + ") " + document.title;
} else {
document.title = document.title.replace(/^Messages \(\d\) /, "Messages (" + this.msg_counter + ") ");
}
window.blur();
window.focus();
} else if (document.title.search(/^\(\d\) /) !== -1) {
document.title = document.title.replace(/^Messages \(\d\) /, "");
}
};
xmppchat.collections = { xmppchat.collections = {
/* FIXME: XEP-0136 specifies 'urn:xmpp:archive' but the mod_archive_odbc /* FIXME: XEP-0136 specifies 'urn:xmpp:archive' but the mod_archive_odbc
@ -149,7 +166,7 @@
addMessage: function (jid, msg, direction) { addMessage: function (jid, msg, direction) {
var bare_jid = Strophe.getBareJidFromJid(jid), var bare_jid = Strophe.getBareJidFromJid(jid),
now = (new Date()).toISOString(), now = xmppchat.toISOString(new Date()),
msgs = store.get(hex_sha1(this.get('own_jid')+bare_jid)) || []; msgs = store.get(hex_sha1(this.get('own_jid')+bare_jid)) || [];
if (msgs.length >= 30) { if (msgs.length >= 30) {
msgs.shift(); msgs.shift();
@ -168,6 +185,14 @@
return decrypted_msgs; return decrypted_msgs;
}, },
getLastMessage: function (jid) {
var bare_jid = Strophe.getBareJidFromJid(jid);
var msgs = store.get(hex_sha1(this.get('own_jid')+bare_jid)) || [];
if (msgs.length) {
return sjcl.decrypt(hex_sha1(this.get('own_jid')), msgs[msgs.length-1]);
}
},
getOpenChats: function () { getOpenChats: function () {
var key = hex_sha1(this.get('own_jid')+'-open-chats'), var key = hex_sha1(this.get('own_jid')+'-open-chats'),
chats = store.get(key) || [], chats = store.get(key) || [],
@ -248,6 +273,14 @@
minutes = now.getMinutes().toString(), minutes = now.getMinutes().toString(),
$chat_content = $(this.el).find('.chat-content'); $chat_content = $(this.el).find('.chat-content');
var msg = xmppchat.storage.getLastMessage(this.model.get('jid'));
if (typeof msg !== 'undefined') {
var prev_date = new Date(Date.parse(msg.split(' ', 2)[0]));
if (this.isDifferentDay(prev_date, now)) {
$chat_content.append($('<div class="chat-date">&nbsp;</div>'));
$chat_content.append($('<div class="chat-date"></div>').text(now.toString().substring(0,15)));
}
}
message = this.autoLink(message); message = this.autoLink(message);
if (minutes.length==1) {minutes = '0'+minutes;} if (minutes.length==1) {minutes = '0'+minutes;}
$chat_content.find('div.chat-event').remove(); $chat_content.find('div.chat-event').remove();
@ -261,10 +294,10 @@
$chat_content.scrollTop($chat_content[0].scrollHeight); $chat_content.scrollTop($chat_content[0].scrollHeight);
}, },
insertStatusNotification: function (user_id, message) { insertStatusNotification: function (message, replace) {
var $chat_content = this.$el.find('.chat-content'); var $chat_content = this.$el.find('.chat-content');
$chat_content.find('div.chat-event').remove().end() $chat_content.find('div.chat-event').remove().end()
.append($('<div class="chat-event"></div>').text(user_id+' '+message)); .append($('<div class="chat-event"></div>').text(message));
$chat_content.scrollTop($chat_content[0].scrollHeight); $chat_content.scrollTop($chat_content[0].scrollHeight);
}, },
@ -287,7 +320,7 @@
} }
if (!body) { if (!body) {
if (composing.length > 0) { if (composing.length > 0) {
this.insertStatusNotification(fullname, 'is typing'); this.insertStatusNotification(fullname+' '+'is typing');
return; return;
} }
} else { } else {
@ -320,21 +353,44 @@
})); }));
$chat_content.scrollTop($chat_content[0].scrollHeight); $chat_content.scrollTop($chat_content[0].scrollHeight);
} }
xmppchat.updateMsgCounter();
},
isDifferentDay: function (prev_date, next_date) {
return ((next_date.getDate() != prev_date.getDate()) || (next_date.getFullYear() != prev_date.getFullYear()) || (next_date.getMonth() != prev_date.getMonth()));
}, },
insertClientStoredMessages: function () { insertClientStoredMessages: function () {
var msgs = xmppchat.storage.getMessages(this.model.get('jid')), var msgs = xmppchat.storage.getMessages(this.model.get('jid')),
$content = this.$el.find('.chat-content'), i; $content = this.$el.find('.chat-content'),
prev_date, this_date, now, separator, i;
for (i=0; i<_.size(msgs); i++) { for (i=0; i<_.size(msgs); i++) {
var msg = msgs[i], var msg = msgs[i],
msg_array = msg.split(' ', 2), msg_array = msg.split(' ', 2),
date = msg_array[0]; date = msg_array[0];
if (i === 0) {
this_date = new Date(Date.parse(date));
if (this.isDifferentDay(this_date, new Date())) {
$content.append($('<div class="chat-date"></div>').text(this_date.toString().substring(0,15)));
}
} else {
prev_date = this_date;
this_date = new Date(Date.parse(date));
if (this.isDifferentDay(prev_date, this_date)) {
$content.append($('<div class="chat-date">&nbsp;</div>'));
$content.append($('<div class="chat-date"></div>').text(this_date.toString().substring(0,15)));
}
}
msg = this.autoLink(String(msg).replace(/(.*?\s.*?\s)/, '')); msg = this.autoLink(String(msg).replace(/(.*?\s.*?\s)/, ''));
if (msg_array[1] == 'to') { if (msg_array[1] == 'to') {
$content.append( $content.append(
this.message_template({ this.message_template({
'sender': 'me', 'sender': 'me',
'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5), 'time': this_date.toLocaleTimeString().substring(0,5),
'message': msg, 'message': msg,
'username': 'me', 'username': 'me',
'extra_classes': 'delayed' 'extra_classes': 'delayed'
@ -343,7 +399,7 @@
$content.append( $content.append(
this.message_template({ this.message_template({
'sender': 'them', 'sender': 'them',
'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5), 'time': this_date.toLocaleTimeString().substring(0,5),
'message': msg, 'message': msg,
'username': this.model.get('fullname').split(' ')[0], 'username': this.model.get('fullname').split(' ')[0],
'extra_classes': 'delayed' 'extra_classes': 'delayed'
@ -356,7 +412,7 @@
// TODO: Look in ChatPartners to see what resources we have for the recipient. // TODO: Look in ChatPartners to see what resources we have for the recipient.
// if we have one resource, we sent to only that resources, if we have multiple // if we have one resource, we sent to only that resources, if we have multiple
// we send to the bare jid. // we send to the bare jid.
var timestamp = new Date().getTime(); var timestamp = (new Date()).getTime();
var bare_jid = this.model.get('jid'); var bare_jid = this.model.get('jid');
var message = $msg({from: xmppchat.connection.bare_jid, to: bare_jid, type: 'chat', id: timestamp}) var message = $msg({from: xmppchat.connection.bare_jid, to: bare_jid, type: 'chat', id: timestamp})
.c('body').t(text).up() .c('body').t(text).up()
@ -371,8 +427,8 @@
xmppchat.connection.send(message); xmppchat.connection.send(message);
xmppchat.connection.send(forwarded); xmppchat.connection.send(forwarded);
xmppchat.storage.addMessage(bare_jid, text, 'to');
this.appendMessage(text); this.appendMessage(text);
xmppchat.storage.addMessage(bare_jid, text, 'to');
}, },
keyPressed: function (ev) { keyPressed: function (ev) {
@ -423,11 +479,11 @@
if (_.has(changed.changes, 'presence_type')) { if (_.has(changed.changes, 'presence_type')) {
if (this.$el.is(':visible')) { if (this.$el.is(':visible')) {
if (item.get('presence_type') === 'offline') { if (item.get('presence_type') === 'offline') {
this.insertStatusNotification(this.model.get('fullname'), 'has gone offline'); this.insertStatusNotification(this.model.get('fullname')+' '+'has gone offline');
} else if (item.get('presence_type') === 'away') { } else if (item.get('presence_type') === 'away') {
this.insertStatusNotification(this.model.get('fullname'), 'has gone away'); this.insertStatusNotification(this.model.get('fullname')+' '+'has gone away');
} else if ((item.get('presence_type') === 'busy') || (item.get('presence_type') === 'dnd')) { } else if ((item.get('presence_type') === 'busy') || (item.get('presence_type') === 'dnd')) {
this.insertStatusNotification(this.model.get('fullname'), 'is busy'); this.insertStatusNotification(this.model.get('fullname')+' '+'is busy');
} else if (item.get('presence_type') === 'online') { } else if (item.get('presence_type') === 'online') {
this.$el.find('div.chat-event').remove(); this.$el.find('div.chat-event').remove();
} }
@ -842,7 +898,7 @@
} }
if (!body) { if (!body) {
if (composing.length > 0) { if (composing.length > 0) {
this.insertStatusNotification(sender, 'is typing'); this.insertStatusNotification(sender+' '+'is typing');
return true; return true;
} }
} else { } else {
@ -1425,7 +1481,7 @@
} }
} }
return true; return true;
}, }
}); });
xmppchat.RosterView= (function (roster, _, $, console) { xmppchat.RosterView= (function (roster, _, $, console) {
@ -1466,7 +1522,8 @@
children = $(this.el).children(), children = $(this.el).children(),
my_contacts = this.$el.find('#xmpp-contacts').hide(), my_contacts = this.$el.find('#xmpp-contacts').hide(),
contact_requests = this.$el.find('#xmpp-contact-requests').hide(), contact_requests = this.$el.find('#xmpp-contact-requests').hide(),
pending_contacts = this.$el.find('#pending-xmpp-contacts').hide(); pending_contacts = this.$el.find('#pending-xmpp-contacts').hide(),
$count, num;
for (var i=0; i<models.length; i++) { for (var i=0; i<models.length; i++) {
var model = models[i], var model = models[i],
@ -1489,7 +1546,8 @@
h.show(); h.show();
} }
}); });
$('#online-count').text(this.model.getNumOnlineContacts()); $count = $('#online-count');
$count.text(this.model.getNumOnlineContacts());
} }
}); });
var view = new View(); var view = new View();
@ -1675,8 +1733,8 @@
$(document).unbind('jarnxmpp.connected'); $(document).unbind('jarnxmpp.connected');
$(document).bind('jarnxmpp.connected', $.proxy(function (ev, connection) { $(document).bind('jarnxmpp.connected', $.proxy(function (ev, connection) {
this.connection = connection this.connection = connection
this.connection.xmlInput = function (body) { console.log(body); }; // this.connection.xmlInput = function (body) { console.log(body); };
this.connection.xmlOutput = function (body) { console.log(body); }; // this.connection.xmlOutput = function (body) { console.log(body); };
this.connection.bare_jid = Strophe.getBareJidFromJid(this.connection.jid); this.connection.bare_jid = Strophe.getBareJidFromJid(this.connection.jid);
this.connection.domain = Strophe.getDomainFromJid(this.connection.jid); this.connection.domain = Strophe.getDomainFromJid(this.connection.jid);
this.connection.muc_domain = 'conference.' + this.connection.domain; this.connection.muc_domain = 'conference.' + this.connection.domain;