Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #13903 from borjasalguero/performance_getthreads_mall
Browse files Browse the repository at this point in the history
Bug 929919 - [Messaging] getThreads optimization r=julienw
  • Loading branch information
borjasalguero committed Nov 28, 2013
2 parents 44c2053 + 8115e89 commit 15494b9
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 242 deletions.
28 changes: 8 additions & 20 deletions apps/sms/js/message_manager.js
Expand Up @@ -48,21 +48,14 @@ var MessageManager = {
var message = e.message;
var threadId = message.threadId;

if (Threads.has(threadId)) {
Threads.get(message.threadId).messages.push(message);
}
Threads.registerMessage(message);

if (window.location.hash === '#new') {
// If we are in 'new' we go to right to thread view
if (threadId === Threads.currentId) {
ThreadUI.onMessageSending(message);
} else {
window.location.hash = '#thread=' + threadId;
} else if (threadId === Threads.currentId) {
ThreadUI.appendMessage(message);
ThreadUI.forceScrollViewToBottom();
}

MessageManager.getThreads(function() {
ThreadListUI.updateThread(message);
});
ThreadListUI.onMessageSending(message);
},

onMessageFailed: function mm_onMessageFailed(e) {
Expand All @@ -79,7 +72,6 @@ var MessageManager = {

onMessageReceived: function mm_onMessageReceived(e) {
var message = e.message;
var threadId;

if (message.messageClass && message.messageClass === 'class-0') {
return;
Expand All @@ -93,14 +85,10 @@ var MessageManager = {
return;
}

threadId = message.threadId;

if (Threads.has(threadId)) {
Threads.get(threadId).messages.push(message);
}
Threads.registerMessage(message);

if (threadId === Threads.currentId) {
//Append message and mark as read
if (message.threadId === Threads.currentId) {
// Mark as read in Gecko
this.markMessagesRead([message.id], function() {
ThreadListUI.updateThread(message);
});
Expand Down
68 changes: 23 additions & 45 deletions apps/sms/js/thread_list_ui.js
Expand Up @@ -408,60 +408,38 @@ var ThreadListUI = {
}
},

// This method fills the gap while we wait for next 'getThreads' request,
// letting us rendering the new thread with a better performance.
createThreadMockup: function thlui_createThreadMockup(message, options) {
// Given a message we create a thread as a mockup. This let us render the
// thread without requesting Gecko, so we increase the performance and we
// reduce Gecko requests.
return {
id: message.threadId,
participants: [message.sender || message.receiver],
body: message.body,
timestamp: message.timestamp,
unreadCount: (options && !options.read) ? 1 : 0,
lastMessageType: message.type || 'sms'
};
},

updateThread: function thlui_updateThread(message, options) {
var thread = this.createThreadMockup(message, options);
var thread = Threads.createThreadMockup(message, options);
// We remove the previous one in order to place the new one properly
var existingThreadElement = document.getElementById('thread-' + thread.id);
if (existingThreadElement) {
this.removeThread(thread.id);
}
ThreadListUI.appendThread(thread);
ThreadListUI.setEmpty(false);
FixedHeader.refresh();
},

onMessageReceived: function thlui_onMessageReceived(message) {
var threadMockup = this.createThreadMockup(message);
var threadId = message.threadId;

if (!Threads.get(threadId)) {
Threads.set(threadId, threadMockup);
Threads.get(threadId).messages.push(message);
}

if (this.container.querySelector('ul')) {
var timestamp = threadMockup.timestamp.getTime();
var previousThread = document.getElementById('thread-' + threadId);
if (previousThread && previousThread.dataset.time > timestamp) {
// If the received SMS it's older that the latest one
// We need only to update the 'unread status'
this.mark(threadId, 'unread');
return;
// New message is older than the latest one?
var timestamp = message.timestamp.getTime();
if (existingThreadElement &&
existingThreadElement.dataset.time > timestamp) {
// If the received SMS it's older that the latest one
// We need only to update the 'unread status' if needed
if (options && !options.read) {
this.mark(thread.id, 'unread');
}

this.updateThread(message, {read: false});
this.setEmpty(false);
} else {
this.renderThreads([threadMockup]);
if (existingThreadElement) {
this.removeThread(thread.id);
}
this.appendThread(thread);
this.setEmpty(false);
FixedHeader.refresh();
}
},

onMessageSending: function thlui_onMessageSending(message) {
this.updateThread(message);
},

onMessageReceived: function thlui_onMessageReceived(message) {
this.updateThread(message, {read: false});
},

appendThread: function thlui_appendThread(thread) {
var timestamp = thread.timestamp.getTime();
// We create the DOM element of the thread
Expand Down
14 changes: 12 additions & 2 deletions apps/sms/js/thread_ui.js
Expand Up @@ -479,15 +479,25 @@ var ThreadUI = global.ThreadUI = {
}
},

onMessageReceived: function thui_onMessageReceived(message) {
// Function for handling when a new message (sent/received)
// is detected
onMessage: function onMessage(message) {
this.appendMessage(message);
this.scrollViewToBottom();
TimeHeaders.updateAll();
},

onMessageReceived: function thui_onMessageReceived(message) {
this.onMessage(message);
if (this.isScrolledManually) {
this.showNewMessageNotice(message);
}
},

onMessageSending: function thui_onMessageReceived(message) {
this.onMessage(message);
this.forceScrollViewToBottom();
},

onNewMessageNoticeClick: function thui_onNewMessageNoticeClick(event) {
event.preventDefault();
this.hideNewMessageNotice();
Expand Down
24 changes: 24 additions & 0 deletions apps/sms/js/threads.js
Expand Up @@ -24,6 +24,30 @@
}

var Threads = exports.Threads = {
// TODO: https://bugzilla.mozilla.org/show_bug.cgi?id=943778
// This method fills the gap while we wait for next 'getThreads' request,
// letting us rendering the new thread with a better performance.
createThreadMockup: function(message, options) {
// Given a message we create a thread as a mockup. This let us render the
// thread without requesting Gecko, so we increase the performance and we
// reduce Gecko requests.
return {
id: message.threadId,
participants: [message.sender || message.receiver],
body: message.body,
timestamp: message.timestamp,
unreadCount: (options && !options.read) ? 1 : 0,
lastMessageType: message.type || 'sms'
};
},
registerMessage: function(message) {
var threadMockup = this.createThreadMockup(message);
var threadId = message.threadId;
if (!this.has(threadId)) {
this.set(threadId, threadMockup);
}
this.get(threadId).messages.push(message);
},
set: function(id, thread) {
var old;
id = +id;
Expand Down
5 changes: 3 additions & 2 deletions apps/sms/test/unit/message_manager_test.js
Expand Up @@ -61,7 +61,8 @@ suite('message_manager.js >', function() {
suite('on message sent > ', function() {

setup(function() {
this.sinon.spy(ThreadUI, 'appendMessage');
this.sinon.spy(ThreadUI, 'onMessageSending');
this.sinon.stub(Threads, 'registerMessage');
});

test('message is shown in the current thread if it belongs to the thread',
Expand All @@ -70,7 +71,7 @@ suite('message_manager.js >', function() {
// ensure the threadId is different
Threads.currentId = sms.threadId + 1;
MessageManager.onMessageSending({ message: sms });
assert.isFalse(ThreadUI.appendMessage.called);
assert.isFalse(ThreadUI.onMessageSending.calledOnce);
}
);
});
Expand Down
1 change: 1 addition & 0 deletions apps/sms/test/unit/mock_message_manager.js
Expand Up @@ -12,6 +12,7 @@ var MockMessageManager = {
launchComposer: function() {},
handleActivity: function() {},
handleForward: function() {},
registerMessage: function() {},
sendSMS: function() {
return {};
},
Expand Down
2 changes: 1 addition & 1 deletion apps/sms/test/unit/mock_thread_list_ui.js
Expand Up @@ -22,7 +22,7 @@ var MockThreadListUI = {
renderThreads: function() {},
createThread: function() {},
insertThreadContainer: function() {},
createThreadMockup: function() {},
onMessageSending: function() {},
onMessageReceived: function() {},
appendThread: function() {},
createThreadContainer: function() {},
Expand Down
1 change: 1 addition & 0 deletions apps/sms/test/unit/mock_thread_ui.js
Expand Up @@ -67,6 +67,7 @@ var MockThreadUI = {
handleEvent: function() {},
cleanFields: function() {},
onSendClick: function() {},
onMessageSending: function() {},
onMessageSent: function() {},
onMessageFailed: function() {},
onDeliverySuccess: function() {},
Expand Down
11 changes: 11 additions & 0 deletions apps/sms/test/unit/mock_threads.js
Expand Up @@ -4,12 +4,23 @@

var MockThreads = {
currentId: null,
createThreadMockup: function() {

},
registerMessage: function() {

},
mTeardown: function mt_mTeardown() {
this.currentId = null;
},

has: function() {
return false;
},
set: function() {

},
get: function() {
return {};
}
};
22 changes: 22 additions & 0 deletions apps/sms/test/unit/notify_test.js
Expand Up @@ -80,6 +80,17 @@ suite('check the ringtone and vibrate function', function() {
Notify.vibrate();

assert.ok(Audio.prototype.play.called);

// As document is not shown in the test, we launch the
// event of visibility
var visibilityEvent = new CustomEvent(
'visibilitychange',
{
bubbles: true
}
);

window.dispatchEvent(visibilityEvent);
assert.ok(navigator.vibrate.called);

assert.ok(Audio.called);
Expand Down Expand Up @@ -127,6 +138,17 @@ suite('check the ringtone and vibrate function', function() {
Notify.ringtone();
Notify.vibrate();

// As document is not shown in the test, we launch the
// event of visibility
var visibilityEvent = new CustomEvent(
'visibilitychange',
{
bubbles: true
}
);

window.dispatchEvent(visibilityEvent);

assert.ok(!Audio.prototype.play.called);
assert.ok(navigator.vibrate.called);

Expand Down

0 comments on commit 15494b9

Please sign in to comment.