diff --git a/.eslintrc.json b/.eslintrc.json index ab665ac72e..7b83892ba3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -171,6 +171,7 @@ "unread_ops": false, "upload": false, "user_events": false, + "submessage": false, "Plotly": false, "emoji_codes": false, "drafts": false, diff --git a/frontend_tests/node_tests/submessage.js b/frontend_tests/node_tests/submessage.js new file mode 100644 index 0000000000..94b23a22ee --- /dev/null +++ b/frontend_tests/node_tests/submessage.js @@ -0,0 +1,58 @@ +zrequire('submessage'); + +set_global('channel', {}); + +(function test_get_message_events() { + var msg = {}; + + assert.equal(submessage.get_message_events(msg), undefined); + + msg = { + submessages: [], + }; + assert.equal(submessage.get_message_events(msg), undefined); + + var submessages = [ + {id: 222, sender_id: 99, content: '84'}, + {id: 9, sender_id: 33, content: '42'}, + ]; + + msg = { + locally_echoed: true, + submessages: submessages, + }; + assert.equal(submessage.get_message_events(msg), undefined); + + msg = { + submessages: submessages, + }; + assert.deepEqual(submessage.get_message_events(msg), [ + {sender_id: 33, data: 42}, + {sender_id: 99, data: 84}, + ]); +}()); + +(function test_make_server_callback() { + var message_id = 444; + var callback = submessage.make_server_callback(message_id); + var was_posted; + + channel.post = function (opts) { + was_posted = true; + assert.deepEqual(opts, { + url: '/json/submessage', + data: { + message_id: message_id, + msg_type: 'whatever', + content: '{"foo":32}', + }, + }); + }; + + callback({ + msg_type: 'whatever', + data: {foo: 32}, + }); + + assert(was_posted); +}()); diff --git a/static/js/echo.js b/static/js/echo.js index 7ddab68e61..baeced40ff 100644 --- a/static/js/echo.js +++ b/static/js/echo.js @@ -204,6 +204,8 @@ exports.process_from_server = function process_from_server(messages) { // the backend. client_message.timestamp = message.timestamp; + client_message.submessages = message.submessages; + msgs_to_rerender.push(client_message); delete waiting_for_ack[client_message.id]; }); diff --git a/static/js/message_list_view.js b/static/js/message_list_view.js index 6fc216a3d4..7630dca589 100644 --- a/static/js/message_list_view.js +++ b/static/js/message_list_view.js @@ -434,6 +434,10 @@ MessageListView.prototype = { var id = rows.id(row); message_edit.maybe_show_edit(row, id); + submessage.process_submessages({ + row: row, + message_id: id, + }); }); }, diff --git a/static/js/server_events_dispatch.js b/static/js/server_events_dispatch.js index 7ad53bebf6..90d8d64099 100644 --- a/static/js/server_events_dispatch.js +++ b/static/js/server_events_dispatch.js @@ -253,6 +253,15 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { } break; + case 'submessage': + submessage.handle_event({ + sender_id: event.sender_id, + msg_type: event.msg_type, + message_id: event.message_id, + data: event.data, + }); + break; + case 'subscription': if (event.op === 'add') { _.each(event.subscriptions, function (rec) { diff --git a/static/js/submessage.js b/static/js/submessage.js new file mode 100644 index 0000000000..7adf3cc4fc --- /dev/null +++ b/static/js/submessage.js @@ -0,0 +1,75 @@ +var submessage = (function () { + +var exports = {}; + +exports.get_message_events = function (message) { + if (message.locally_echoed) { + return; + } + + if (!message.submessages) { + return; + } + + if (message.submessages.length === 0) { + return; + } + + // The server should sort messages for us, but this is defensive. + message.submessages.sort(function (m1, m2) { + return parseInt(m1.id, 10) - parseInt(m2.id, 10); + }); + + var events = _.map(message.submessages, function (obj) { + return { + sender_id: obj.sender_id, + data: JSON.parse(obj.content), + }; + }); + + return events; +}; + +exports.process_submessages = function (in_opts) { + var message_id = in_opts.message_id; + var message = message_store.get(message_id); + + if (!message) { + return; + } + + var events = exports.get_message_events(message); + + if (!events) { + return; + } + + blueslip.info('submessages found for message id: ' + message_id); +}; + + +exports.handle_event = function (event) { + blueslip.info('handle submessage: ' + JSON.stringify(event)); +}; + +exports.make_server_callback = function (message_id) { + return function (opts) { + var url = '/json/submessage'; + + channel.post({ + url: url, + data: { + message_id: message_id, + msg_type: opts.msg_type, + content: JSON.stringify(opts.data), + }, + }); + }; +}; + +return exports; + +}()); +if (typeof module !== 'undefined') { + module.exports = submessage; +} diff --git a/zproject/settings.py b/zproject/settings.py index 0b7b801945..a1d5916600 100644 --- a/zproject/settings.py +++ b/zproject/settings.py @@ -947,6 +947,7 @@ JS_SPECS = { 'js/top_left_corner.js', 'js/stream_list.js', 'js/filter.js', + 'js/submessage.js', 'js/fetch_status.js', 'js/message_list_data.js', 'js/message_list_view.js',