From f04da3d52e46ad692a2a5529cca92296d9ef76fd Mon Sep 17 00:00:00 2001 From: Akhil Date: Thu, 1 Jun 2017 05:42:57 +0000 Subject: [PATCH] typeahead: Add recent_senders module. In recent_senders module, added a data structure to hold timestamps of users' latest message in a topic. Also added a function to compare 2 users based on above timestamp. Added a function to process messages for the data structure and a call in add_message_metadata. Also added node tests for insertion of data into recent_senders.senders. --- .eslintrc.json | 1 + frontend_tests/node_tests/recent_senders.js | 74 +++++++++++++++++++++ static/js/message_store.js | 2 + static/js/recent_senders.js | 42 ++++++++++++ zproject/settings.py | 1 + 5 files changed, 120 insertions(+) create mode 100644 frontend_tests/node_tests/recent_senders.js create mode 100644 static/js/recent_senders.js diff --git a/.eslintrc.json b/.eslintrc.json index c3ecda0dc0..9694032bcf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -136,6 +136,7 @@ "current_msg_list": true, "home_msg_list": false, "pm_list": false, + "recent_senders": false, "unread_ui": false, "unread_ops": false, "user_events": false, diff --git a/frontend_tests/node_tests/recent_senders.js b/frontend_tests/node_tests/recent_senders.js new file mode 100644 index 0000000000..2618554526 --- /dev/null +++ b/frontend_tests/node_tests/recent_senders.js @@ -0,0 +1,74 @@ +var assert = require('assert'); +var rs = require('js/recent_senders.js'); +var _ = require('node_modules/underscore/underscore.js'); + +(function test_process_message_for_senders() { + var stream1 = 1; + var stream2 = 2; + + var topic1 = "topic-1"; + var topic2 = "topic-2"; + + var sender1 = 1; + var sender2 = 2; + var sender3 = 3; + + // New stream + var message1 = { + stream_id: stream1, + timestamp: _.uniqueId(), + subject: topic1, + sender_id: sender1, + }; + var message2 = { + stream_id: stream2, + timestamp: _.uniqueId(), + subject: topic1, + sender_id: sender2, + }; + rs.process_message_for_senders(message1); + rs.process_message_for_senders(message2); + + assert.equal( + rs.compare_by_recency({user_id: sender1}, {user_id: sender2}, stream1, topic1) < 0, + true); + assert.equal( + rs.compare_by_recency({user_id: sender1}, {user_id: sender2}, stream2, topic1) > 0, + true); + + // New topic + var message3 = { + stream_id: stream1, + timestamp: _.uniqueId(), + subject: topic2, + sender_id: sender3, + }; + rs.process_message_for_senders(message3); + assert.equal( + rs.compare_by_recency({user_id: sender3}, {user_id: sender2}, stream1, topic2) < 0, + true); + + // New sender + var message4 = { + stream_id: stream1, + timestamp: _.uniqueId(), + subject: topic1, + sender_id: sender2, + }; + rs.process_message_for_senders(message4); + assert.equal( + rs.compare_by_recency({user_id: sender1}, {user_id: sender2}, stream1, topic1) > 0, + true); + + // More recent message + var message5 = { + stream_id: stream1, + timestamp: _.uniqueId(), + subject: topic1, + sender_id: sender1, + }; + rs.process_message_for_senders(message5); + assert.equal( + rs.compare_by_recency({user_id: sender1}, {user_id: sender2}, stream1, topic1) < 0, + true); +}()); diff --git a/static/js/message_store.js b/static/js/message_store.js index 5dbeea87d5..9e783815a7 100644 --- a/static/js/message_store.js +++ b/static/js/message_store.js @@ -148,6 +148,8 @@ exports.add_message_metadata = function (message) { stream_data.process_message_for_recent_topics(message); exports.set_topic_edit_properties(message); + + recent_senders.process_message_for_senders(message); break; case 'private': diff --git a/static/js/recent_senders.js b/static/js/recent_senders.js new file mode 100644 index 0000000000..f8e6cb6601 --- /dev/null +++ b/static/js/recent_senders.js @@ -0,0 +1,42 @@ +var recent_senders = (function () { + +var exports = {}; + +var senders = new Dict(); // key is stream-id, value is Dict + +exports.process_message_for_senders = function (message) { + var stream_id = message.stream_id.toString(); + var topic_dict = senders.get(stream_id) || new Dict({fold_case: true}); + var sender_timestamps = topic_dict.get(message.subject) || new Dict(); + var old_timestamp = sender_timestamps.get(message.sender_id); + + if (old_timestamp === undefined || old_timestamp < message.timestamp) { + sender_timestamps.set(message.sender_id, message.timestamp); + } + + topic_dict.set(message.subject, sender_timestamps); + senders.set(stream_id, topic_dict); +}; + +exports.compare_by_recency = function (user_a, user_b, stream_id, topic) { + stream_id = stream_id.toString(); + + var topic_dict = senders.get(stream_id); + if (topic_dict !== undefined) { + var sender_timestamps = topic_dict.get(topic); + if (sender_timestamps !== undefined) { + var b_timestamp = sender_timestamps.get(user_b.user_id) || Number.NEGATIVE_INFINITY; + var a_timestamp = sender_timestamps.get(user_a.user_id) || Number.NEGATIVE_INFINITY; + return b_timestamp - a_timestamp; + } + } + + return 0; +}; + +return exports; +}()); + +if (typeof module !== 'undefined') { + module.exports = recent_senders; +} diff --git a/zproject/settings.py b/zproject/settings.py index f3a87fd8b4..114af82d02 100644 --- a/zproject/settings.py +++ b/zproject/settings.py @@ -875,6 +875,7 @@ JS_SPECS = { 'js/unread.js', 'js/topic_list.js', 'js/pm_list.js', + 'js/recent_senders.js', 'js/stream_sort.js', 'js/topic_generator.js', 'js/stream_list.js',