Conversation: store lastMessage/lastMessageStatus in memory only
This commit is contained in:
parent
f39a96bc76
commit
61f7b8360b
8 changed files with 126 additions and 85 deletions
|
@ -135,6 +135,8 @@
|
||||||
this.on('read', this.updateLastMessage);
|
this.on('read', this.updateLastMessage);
|
||||||
this.on('sent', this.updateLastMessage);
|
this.on('sent', this.updateLastMessage);
|
||||||
this.on('expired', this.onExpired);
|
this.on('expired', this.onExpired);
|
||||||
|
|
||||||
|
this.updateLastMessage();
|
||||||
},
|
},
|
||||||
|
|
||||||
isMe() {
|
isMe() {
|
||||||
|
@ -198,8 +200,8 @@
|
||||||
isSelected: this.isSelected,
|
isSelected: this.isSelected,
|
||||||
|
|
||||||
lastMessage: {
|
lastMessage: {
|
||||||
status: this.get('lastMessageStatus'),
|
status: this.lastMessageStatus,
|
||||||
text: this.get('lastMessage'),
|
text: this.lastMessage,
|
||||||
},
|
},
|
||||||
|
|
||||||
onClick: () => this.trigger('select', this),
|
onClick: () => this.trigger('select', this),
|
||||||
|
@ -899,6 +901,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateLastMessage() {
|
async updateLastMessage() {
|
||||||
|
if (!this.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const messages = await window.Signal.Data.getMessagesByConversation(
|
const messages = await window.Signal.Data.getMessagesByConversation(
|
||||||
this.id,
|
this.id,
|
||||||
{ limit: 1, MessageCollection: Whisper.MessageCollection }
|
{ limit: 1, MessageCollection: Whisper.MessageCollection }
|
||||||
|
@ -907,26 +913,41 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastMessage = messages.at(0);
|
const lastMessageModel = messages.at(0);
|
||||||
|
|
||||||
const lastMessageJSON = lastMessage ? lastMessage.toJSON() : null;
|
const lastMessageJSON = lastMessageModel
|
||||||
const lastMessageStatus = lastMessage
|
? lastMessageModel.toJSON()
|
||||||
? lastMessage.getMessagePropStatus()
|
: null;
|
||||||
|
const lastMessageStatusModel = lastMessageModel
|
||||||
|
? lastMessageModel.getMessagePropStatus()
|
||||||
: null;
|
: null;
|
||||||
const lastMessageUpdate = Conversation.createLastMessageUpdate({
|
const lastMessageUpdate = Conversation.createLastMessageUpdate({
|
||||||
currentLastMessageText: this.get('lastMessage') || null,
|
currentLastMessageText: this.get('lastMessage') || null,
|
||||||
currentTimestamp: this.get('timestamp') || null,
|
currentTimestamp: this.get('timestamp') || null,
|
||||||
lastMessage: lastMessageJSON,
|
lastMessage: lastMessageJSON,
|
||||||
lastMessageStatus,
|
lastMessageStatus: lastMessageStatusModel,
|
||||||
lastMessageNotificationText: lastMessage
|
lastMessageNotificationText: lastMessageModel
|
||||||
? lastMessage.getNotificationText()
|
? lastMessageModel.getNotificationText()
|
||||||
: null,
|
: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let hasChanged = false;
|
||||||
|
const { lastMessage, lastMessageStatus } = lastMessageUpdate;
|
||||||
|
lastMessageUpdate.lastMessage = null;
|
||||||
|
lastMessageUpdate.lastMessageStatus = null;
|
||||||
|
|
||||||
|
hasChanged = hasChanged || lastMessage !== this.lastMessage;
|
||||||
|
this.lastMessage = lastMessage;
|
||||||
|
|
||||||
|
hasChanged = hasChanged || lastMessageStatus !== this.lastMessageStatus;
|
||||||
|
this.lastMessageStatus = lastMessageStatus;
|
||||||
|
|
||||||
this.set(lastMessageUpdate);
|
this.set(lastMessageUpdate);
|
||||||
|
|
||||||
if (this.hasChanged('lastMessage') || this.hasChanged('timestamp')) {
|
if (this.hasChanged()) {
|
||||||
this.save();
|
this.save();
|
||||||
|
} else if (hasChanged) {
|
||||||
|
this.trigger('change');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
templateName: 'conversation-preview',
|
templateName: 'conversation-preview',
|
||||||
initialize() {
|
initialize() {
|
||||||
this.listenTo(this.model, 'destroy', this.remove);
|
this.listenTo(this.model, 'destroy', this.remove);
|
||||||
this.model.updateLastMessage();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
|
|
|
@ -60,25 +60,26 @@ function hexToArrayBuffer(str) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the database before running any tests */
|
function deleteDatabase() {
|
||||||
before(function(done) {
|
return new Promise((resolve, reject) => {
|
||||||
var idbReq = indexedDB.deleteDatabase('test');
|
var idbReq = indexedDB.deleteDatabase('test');
|
||||||
idbReq.onsuccess = function() {
|
idbReq.onsuccess = resolve;
|
||||||
done();
|
idbReq.error = reject;
|
||||||
};
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
/* Delete the database before running any tests */
|
||||||
|
before(async () => {
|
||||||
|
await deleteDatabase();
|
||||||
|
|
||||||
async function clearDatabase() {
|
|
||||||
await Signal.Migrations.Migrations0DatabaseWithAttachmentData.run({
|
await Signal.Migrations.Migrations0DatabaseWithAttachmentData.run({
|
||||||
Backbone,
|
Backbone,
|
||||||
databaseName: Whisper.Database.id,
|
databaseName: Whisper.Database.id,
|
||||||
logger: window.log,
|
logger: window.log,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const convos = new Whisper.ConversationCollection();
|
async function clearDatabase() {
|
||||||
await wrapDeferred(convos.fetch());
|
const db = await Whisper.Database.open();
|
||||||
await wrapDeferred(convos.destroyAll());
|
await Whisper.Database.clear();
|
||||||
const messages = new Whisper.MessageCollection();
|
|
||||||
await wrapDeferred(messages.fetch());
|
|
||||||
await wrapDeferred(messages.destroyAll());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,26 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('Fixtures', function() {
|
describe('Fixtures', function() {
|
||||||
before(function(done) {
|
before(function() {
|
||||||
// NetworkStatusView checks this method every five seconds while showing
|
// NetworkStatusView checks this method every five seconds while showing
|
||||||
window.getSocketStatus = function() {
|
window.getSocketStatus = function() {
|
||||||
return WebSocket.OPEN;
|
return WebSocket.OPEN;
|
||||||
};
|
};
|
||||||
|
|
||||||
Whisper.Fixtures()
|
|
||||||
.saveAll()
|
|
||||||
.then(function() {
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders', function(done) {
|
it('renders', async () => {
|
||||||
ConversationController.reset();
|
await Whisper.Fixtures().saveAll();
|
||||||
ConversationController.load()
|
|
||||||
.then(function() {
|
|
||||||
var view = new Whisper.InboxView({ window: window });
|
|
||||||
view.onEmpty();
|
|
||||||
view.$el.prependTo($('#render-light-theme'));
|
|
||||||
|
|
||||||
var view = new Whisper.InboxView({ window: window });
|
ConversationController.reset();
|
||||||
view.$el.removeClass('light-theme').addClass('dark-theme');
|
await ConversationController.load();
|
||||||
view.onEmpty();
|
|
||||||
view.$el.prependTo($('#render-dark-theme'));
|
var view = new Whisper.InboxView({ window: window });
|
||||||
})
|
view.onEmpty();
|
||||||
.then(done, done);
|
view.$el.prependTo($('#render-light-theme'));
|
||||||
|
|
||||||
|
var view = new Whisper.InboxView({ window: window });
|
||||||
|
view.$el.removeClass('light-theme').addClass('dark-theme');
|
||||||
|
view.onEmpty();
|
||||||
|
view.$el.prependTo($('#render-dark-theme'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,15 +36,15 @@
|
||||||
.then(done);
|
.then(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fetches persistent convos', function(done) {
|
it('fetches persistent convos', async () => {
|
||||||
var convos = new Whisper.ConversationCollection();
|
var convos = new Whisper.ConversationCollection();
|
||||||
assert.strictEqual(convos.length, 0);
|
assert.strictEqual(convos.length, 0);
|
||||||
convos.fetch().then(function() {
|
|
||||||
var m = convos.at(0).attributes;
|
await wrapDeferred(convos.fetch());
|
||||||
_.each(conversation_attributes, function(val, key) {
|
|
||||||
assert.deepEqual(m[key], val);
|
var m = convos.at(0).attributes;
|
||||||
});
|
_.each(conversation_attributes, function(val, key) {
|
||||||
done();
|
assert.deepEqual(m[key], val);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -226,14 +226,18 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Conversation search', function() {
|
describe('Conversation search', function() {
|
||||||
var convo = new Whisper.ConversationCollection().add({
|
let convo;
|
||||||
id: '+14155555555',
|
|
||||||
type: 'private',
|
beforeEach(function(done) {
|
||||||
name: 'John Doe',
|
convo = new Whisper.ConversationCollection().add({
|
||||||
});
|
id: '+14155555555',
|
||||||
before(function(done) {
|
type: 'private',
|
||||||
|
name: 'John Doe',
|
||||||
|
});
|
||||||
convo.save().then(done);
|
convo.save().then(done);
|
||||||
});
|
});
|
||||||
|
afterEach(clearDatabase);
|
||||||
|
|
||||||
function testSearch(queries, done) {
|
function testSearch(queries, done) {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
queries.map(function(query) {
|
queries.map(function(query) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ describe('AttachmentView', () => {
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await clearDatabase();
|
await clearDatabase();
|
||||||
|
|
||||||
convo = new Whisper.Conversation({ id: 'foo' });
|
convo = new Whisper.Conversation({ id: 'foo' });
|
||||||
message = convo.messageCollection.add({
|
message = convo.messageCollection.add({
|
||||||
conversationId: convo.id,
|
conversationId: convo.id,
|
||||||
|
|
|
@ -24,20 +24,26 @@ describe('ConversationSearchView', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Searching for left groups', function() {
|
describe('Searching for left groups', function() {
|
||||||
var convo = new Whisper.ConversationCollection().add({
|
let convo;
|
||||||
id: 'a-left-group',
|
|
||||||
name: 'i left this group',
|
|
||||||
members: [],
|
|
||||||
type: 'group',
|
|
||||||
left: true,
|
|
||||||
});
|
|
||||||
before(() => {
|
before(() => {
|
||||||
|
convo = new Whisper.ConversationCollection().add({
|
||||||
|
id: 'a-left-group',
|
||||||
|
name: 'i left this group',
|
||||||
|
members: [],
|
||||||
|
type: 'group',
|
||||||
|
left: true,
|
||||||
|
});
|
||||||
|
|
||||||
return wrapDeferred(convo.save());
|
return wrapDeferred(convo.save());
|
||||||
});
|
});
|
||||||
describe('with no messages', function() {
|
describe('with no messages', function() {
|
||||||
var input = $('<input>');
|
var input;
|
||||||
var view = new Whisper.ConversationSearchView({ input: input }).render();
|
var view;
|
||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
|
input = $('<input>');
|
||||||
|
view = new Whisper.ConversationSearchView({ input: input }).render();
|
||||||
view.$input.val('left');
|
view.$input.val('left');
|
||||||
view.filterContacts();
|
view.filterContacts();
|
||||||
view.typeahead_view.collection.on('reset', function() {
|
view.typeahead_view.collection.on('reset', function() {
|
||||||
|
@ -52,9 +58,11 @@ describe('ConversationSearchView', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('with messages', function() {
|
describe('with messages', function() {
|
||||||
var input = $('<input>');
|
var input;
|
||||||
var view = new Whisper.ConversationSearchView({ input: input }).render();
|
var view;
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
|
input = $('<input>');
|
||||||
|
view = new Whisper.ConversationSearchView({ input: input }).render();
|
||||||
convo.save({ lastMessage: 'asdf' }).then(function() {
|
convo.save({ lastMessage: 'asdf' }).then(function() {
|
||||||
view.$input.val('left');
|
view.$input.val('left');
|
||||||
view.filterContacts();
|
view.filterContacts();
|
||||||
|
@ -72,17 +80,22 @@ describe('ConversationSearchView', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Showing all contacts', function() {
|
describe('Showing all contacts', function() {
|
||||||
var input = $('<input>');
|
let input;
|
||||||
var view = new Whisper.ConversationSearchView({ input: input }).render();
|
let view;
|
||||||
view.showAllContacts = true;
|
let convo;
|
||||||
var convo = new Whisper.ConversationCollection().add({
|
|
||||||
id: 'a-left-group',
|
|
||||||
name: 'i left this group',
|
|
||||||
members: [],
|
|
||||||
type: 'group',
|
|
||||||
left: true,
|
|
||||||
});
|
|
||||||
before(() => {
|
before(() => {
|
||||||
|
input = $('<input>');
|
||||||
|
view = new Whisper.ConversationSearchView({ input: input }).render();
|
||||||
|
view.showAllContacts = true;
|
||||||
|
convo = new Whisper.ConversationCollection().add({
|
||||||
|
id: 'a-left-group',
|
||||||
|
name: 'i left this group',
|
||||||
|
members: [],
|
||||||
|
type: 'group',
|
||||||
|
left: true,
|
||||||
|
});
|
||||||
|
|
||||||
return wrapDeferred(convo.save());
|
return wrapDeferred(convo.save());
|
||||||
});
|
});
|
||||||
describe('with no messages', function() {
|
describe('with no messages', function() {
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
describe('InboxView', function() {
|
describe('InboxView', function() {
|
||||||
var inboxView = new Whisper.InboxView({
|
let inboxView;
|
||||||
model: {},
|
let conversation;
|
||||||
window: window,
|
|
||||||
initialLoadComplete: function() {},
|
|
||||||
}).render();
|
|
||||||
|
|
||||||
var conversation = new Whisper.Conversation({ id: '1234', type: 'private' });
|
before(() => {
|
||||||
|
inboxView = new Whisper.InboxView({
|
||||||
|
model: {},
|
||||||
|
window: window,
|
||||||
|
initialLoadComplete: function() {},
|
||||||
|
}).render();
|
||||||
|
|
||||||
|
conversation = new Whisper.Conversation({
|
||||||
|
id: '1234',
|
||||||
|
type: 'private',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('the conversation stack', function() {
|
describe('the conversation stack', function() {
|
||||||
it('should be rendered', function() {
|
it('should be rendered', function() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue