MUC: Querying an archive fragment

This commit is contained in:
Sebastien Hut 2015-02-09 00:21:00 +01:00
parent 3edfe3da21
commit 87e2cb8a27
4 changed files with 208 additions and 58 deletions

View File

@ -281,30 +281,37 @@ module.exports = HumanModel.define({
this.lastInteraction = newInteraction;
}
},
fetchHistory: function () {
fetchHistory: function (old) {
var self = this;
app.whenConnected(function () {
var filter = {
'with': self.jid,
rsm: {
count: 20,
max: old ? 40 : 50,
before: true
}
};
var lastMessage = self.messages.last();
if (lastMessage && lastMessage.archivedId) {
filter.rsm.after = lastMessage.archivedId;
}
if (self.lastHistoryFetch && !isNaN(self.lastHistoryFetch.valueOf())) {
if (self.lastInteraction > self.lastHistoryFetch) {
filter.start = self.lastInteraction;
} else {
filter.start = self.lastHistoryFetch;
}
if (old) {
var firstMessage = self.messages.first();
if (firstMessage && firstMessage.archivedId) {
filter.rsm.before = firstMessage.archivedId;
}
} else {
filter.end = new Date(Date.now());
var lastMessage = self.messages.last();
if (lastMessage && lastMessage.archivedId) {
filter.rsm.after = lastMessage.archivedId;
}
if (self.lastHistoryFetch && !isNaN(self.lastHistoryFetch.valueOf())) {
if (self.lastInteraction > self.lastHistoryFetch) {
filter.start = self.lastInteraction;
} else {
filter.start = self.lastHistoryFetch;
}
} else {
filter.end = new Date(Date.now());
}
}
client.getHistory(filter, function (err, res) {
@ -313,7 +320,7 @@ module.exports = HumanModel.define({
self.lastHistoryFetch = new Date(Date.now());
var results = res.mamQuery.results || [];
results.reverse();
if (!old) results.reverse();
results.forEach(function (result) {
var msg = result.mam.forwarded.message;

View File

@ -10,7 +10,6 @@ var Resources = require('./resources');
var Messages = require('./messages');
var Message = require('./message');
module.exports = HumanModel.define({
initialize: function (attrs) {
if (attrs.jid) {
@ -138,12 +137,64 @@ module.exports = HumanModel.define({
this.resources.reset();
client.joinRoom(this.jid, this.nick, {
history: {
maxstanzas: 50
//since: this.lastInteraction
joinMuc: {
history: {
maxstanzas: 50
}
}
});
},
fetchHistory: function() {
var self = this;
app.whenConnected(function () {
var filter = {
'to': self.jid,
rsm: {
max: 40,
before: true
}
};
var firstMessage = self.messages.first();
if (firstMessage && firstMessage.created) {
var end = new Date(firstMessage.created - 1);
filter.end = end.toISOString();
}
client.getHistory(filter, function (err, res) {
if (err) return;
self.lastHistoryFetch = new Date(Date.now());
var results = res.mamQuery.results || [];
results.forEach(function (result) {
var msg = result.mam.forwarded.message;
msg.mid = msg.id;
delete msg.id;
if (!msg.delay) {
msg.delay = result.mam.forwarded.delay;
}
if (msg.replace) {
var original = Message.idLookup(msg.from[msg.type == 'groupchat' ? 'full' : 'bare'], msg.replace);
// Drop the message if editing a previous, but
// keep it if it didn't actually change an
// existing message.
if (original && original.correct(msg)) return;
}
var message = new Message(msg);
message.archivedId = result.mam.id;
message.acked = true;
self.addMessage(message, false);
});
});
});
},
leave: function () {
this.resources.reset();
client.leaveRoom(this.jid, this.nick);

View File

@ -22,7 +22,7 @@ module.exports = BasePage.extend({
this.listenTo(this, 'pageunloaded', this.handlePageUnloaded);
this.listenTo(this.model.messages, 'change', this.refreshModel);
this.listenTo(this.model.messages, 'sort', this.renderCollection);
//this.listenTo(this.model.messages, 'sort', this.renderCollection);
this.render();
},
@ -52,6 +52,16 @@ module.exports = BasePage.extend({
show: function (animation) {
BasePage.prototype.show.apply(this, [animation]);
this.sendChatState('active');
this.firstChanged = true;
var self = this;
$('.messages').scroll(function() {
if (self.firstChanged && $(".messages li:first-child").offset().top > 0) {
self.firstChanged = false;
self.model.fetchHistory(true);
}
});
this.$chatInput.focus();
},
hide: function () {
@ -209,35 +219,71 @@ module.exports = BasePage.extend({
refreshModel: function (model) {
var existing = this.$('#chat' + model.cid);
existing.replaceWith(model.partialTemplateHtml);
existing = this.$('#chat' + model.cid);
embedIt(existing);
},
handleJingleResourcesChanged: function (model, val) {
var resources = val || this.model.jingleResources;
this.$('button.call').prop('disabled', !resources.length);
},
appendModel: function (model, preload) {
var newEl, first, last, newDay = false;
var newEl, first, last;
var msgDate = Date.create(model.timestamp);
var messageDay = msgDate.format('{month} {ord}, {yyyy}');
var messageDay = Date.create(model.timestamp).format('{month} {ord}, {yyyy}');
if (messageDay !== this.lastDate) {
var dayDivider = $(templates.includes.dayDivider({day_name: messageDay}));
this.staydown.append(dayDivider[0]);
this.lastDate = messageDay;
newDay = true;
}
if (this.firstModel === undefined || msgDate > Date.create(this.firstModel.timestamp)) {
if (this.firstModel === undefined) {
this.firstModel = model;
this.firstDate = messageDay;
}
var isGrouped = !newDay && model.shouldGroupWith(this.lastModel);
if (isGrouped) {
newEl = $(model.partialTemplateHtml);
last = this.$messageList.find('li').last();
last.find('.messageWrapper').append(newEl);
last.addClass('chatGroup');
this.staydown.checkdown();
} else {
newEl = $(model.templateHtml);
this.staydown.append(newEl[0]);
this.lastModel = model;
if (messageDay !== this.lastDate) {
var dayDivider = $(templates.includes.dayDivider({day_name: messageDay}));
this.staydown.append(dayDivider[0]);
this.lastDate = messageDay;
}
var isGrouped = model.shouldGroupWith(this.lastModel);
if (isGrouped) {
newEl = $(model.partialTemplateHtml);
last = this.$messageList.find('li').last();
last.find('.messageWrapper').append(newEl);
last.addClass('chatGroup');
this.staydown.checkdown();
} else {
newEl = $(model.templateHtml);
this.staydown.append(newEl[0]);
this.lastModel = model;
}
if (!model.pending) embedIt(newEl);
}
else {
var scrollDown = this.$messageList.prop('scrollHeight') - this.$messageList.scrollTop();
var firstEl = this.$messageList.find('li').first();
if (messageDay !== this.firstDate) {
var dayDivider = $(templates.includes.dayDivider({day_name: messageDay}));
firstEl.before(dayDivider[0]);
var firstEl = this.$messageList.find('li').first();
this.firstDate = messageDay;
}
var isGrouped = model.shouldGroupWith(this.firstModel);
if (isGrouped) {
newEl = $(model.partialTemplateHtml);
first = this.$messageList.find('li').first().next();
first.find('.messageWrapper div:first').after(newEl);
first.addClass('chatGroup');
} else {
newEl = $(model.templateHtml);
firstEl.after(newEl[0]);
this.firstModel = model;
}
if (!model.pending) embedIt(newEl);
this.$messageList.scrollTop(this.$messageList.prop('scrollHeight') - scrollDown);
this.firstChanged = true;
}
embedIt(newEl);
},
handleAcceptClick: function (e) {
e.preventDefault();

View File

@ -48,6 +48,16 @@ module.exports = BasePage.extend({
to: this.model.jid,
chatState: 'active'
});
this.firstChanged = true;
var self = this;
$('.messages').scroll(function() {
if (self.firstChanged && $(".messages li:first-child").offset().top > 0) {
self.firstChanged = false;
self.model.fetchHistory();
}
});
this.$chatInput.focus();
},
hide: function () {
@ -83,6 +93,7 @@ module.exports = BasePage.extend({
},
renderMessages: function () {
var self = this;
this.firstDate = '';
this.lastDate = '';
this.model.messages.each(function (model, i) {
self.appendModel(model);
@ -238,27 +249,62 @@ module.exports = BasePage.extend({
},
appendModel: function (model, preload) {
var newEl, first, last;
var msgDate = Date.create(model.timestamp);
var messageDay = msgDate.format('{month} {ord}, {yyyy}');
var messageDay = Date.create(model.timestamp).format('{month} {ord}, {yyyy}');
if (messageDay !== this.lastDate) {
var dayDivider = $(templates.includes.dayDivider({day_name: messageDay}));
this.staydown.append(dayDivider[0]);
this.lastDate = messageDay;
}
if (this.firstModel === undefined || msgDate > Date.create(this.firstModel.timestamp)) {
if (this.firstModel === undefined) {
this.firstModel = model;
this.firstDate = messageDay;
}
var isGrouped = model.shouldGroupWith(this.lastModel);
if (isGrouped) {
newEl = $(model.partialTemplateHtml);
last = this.$messageList.find('li').last();
last.find('.messageWrapper').append(newEl);
last.addClass('chatGroup');
this.staydown.checkdown();
} else {
newEl = $(model.templateHtml);
this.staydown.append(newEl[0]);
this.lastModel = model;
if (messageDay !== this.lastDate) {
var dayDivider = $(templates.includes.dayDivider({day_name: messageDay}));
this.staydown.append(dayDivider[0]);
this.lastDate = messageDay;
}
var isGrouped = model.shouldGroupWith(this.lastModel);
if (isGrouped) {
newEl = $(model.partialTemplateHtml);
last = this.$messageList.find('li').last();
last.find('.messageWrapper').append(newEl);
last.addClass('chatGroup');
this.staydown.checkdown();
} else {
newEl = $(model.templateHtml);
this.staydown.append(newEl[0]);
this.lastModel = model;
}
if (!model.pending) embedIt(newEl);
}
else {
var scrollDown = this.$messageList.prop('scrollHeight') - this.$messageList.scrollTop();
var firstEl = this.$messageList.find('li').first();
if (messageDay !== this.firstDate) {
var dayDivider = $(templates.includes.dayDivider({day_name: messageDay}));
firstEl.before(dayDivider[0]);
var firstEl = this.$messageList.find('li').first();
this.firstDate = messageDay;
}
var isGrouped = model.shouldGroupWith(this.firstModel);
if (isGrouped) {
newEl = $(model.partialTemplateHtml);
first = this.$messageList.find('li').first().next();
first.find('.messageWrapper div:first').after(newEl);
first.addClass('chatGroup');
} else {
newEl = $(model.templateHtml);
firstEl.after(newEl[0]);
this.firstModel = model;
}
if (!model.pending) embedIt(newEl);
this.$messageList.scrollTop(this.$messageList.prop('scrollHeight') - scrollDown);
this.firstChanged = true;
}
embedIt(newEl);
},
refreshModel: function (model) {
var existing = this.$('#chat' + model.cid);