2013-03-06 00:45:36 +01:00
|
|
|
/**
|
|
|
|
* @provides javelin-behavior-conpherence-pontificate
|
|
|
|
* @requires javelin-behavior
|
|
|
|
* javelin-dom
|
2013-03-08 19:40:06 +01:00
|
|
|
* javelin-util
|
|
|
|
* javelin-workflow
|
2013-03-31 23:41:13 +02:00
|
|
|
* javelin-stratcom
|
2013-03-06 00:45:36 +01:00
|
|
|
*/
|
|
|
|
|
2014-06-23 19:27:47 +02:00
|
|
|
JX.behavior('conpherence-pontificate', function() {
|
2014-06-11 22:52:15 +02:00
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
// TODO: This isn't very clean. When you submit a message, you may get a
|
|
|
|
// notification about it back before you get the rendered message back. To
|
|
|
|
// prevent this, we keep track of whether we're currently updating the
|
|
|
|
// thread. If we are, we hold further updates until the response comes
|
|
|
|
// back.
|
|
|
|
|
|
|
|
// After the response returns, we'll do another update if we know about
|
|
|
|
// a transaction newer than the one we got back from the server.
|
|
|
|
var updating = null;
|
|
|
|
|
|
|
|
function get_thread_data() {
|
|
|
|
// TODO: This is really, really gross.
|
|
|
|
var infonode = JX.DOM.find(document, 'input', 'latest-transaction-id');
|
|
|
|
var data = JX.Stratcom.getData(infonode);
|
|
|
|
data.latestID = infonode.value;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
function update_latest_transaction_id(id) {
|
|
|
|
// TODO: Continued grossness from above.
|
|
|
|
var infonode = JX.DOM.find(document, 'input', 'latest-transaction-id');
|
|
|
|
infonode.value = id;
|
|
|
|
}
|
|
|
|
|
Multiplex AJAX calls
Summary: Fixes T5344. Essentially, we only make the AJAX request to `/notification/individual/` if we are the leader tab (i.e. only one tab will make this request). Once a response has been received from the server (containing the contents of the notification), we broadcast the message contents back to all other tabs for rendering.
Test Plan:
Opened two tabs on `/notification/status/` and clicked "Send Test Notification".
**Before**
```lang=bash, name=tail -f /var/log/phabricator-access.log | grep /notification/individual/
[Tue, 13 Jan 2015 20:10:37 +1100] 17033 phabricator 10.0.0.1 josh PhabricatorNotificationIndividualController - /notification/individual/-200 236036
[Tue, 13 Jan 2015 20:10:37 +1100] 17657 phabricator 10.0.0.1 josh PhabricatorNotificationIndividualController - /notification/individual/-200 24130
```
**After**
```lang=bash, name=tail -f /var/log/phabricator-access.log | grep /notification/individual/
[Tue, 13 Jan 2015 20:11:15 +1100] 17657 phabricator 10.0.0.1 josh PhabricatorNotificationIndividualController - /notification/individual/-200 180217
```
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin, epriestley
Maniphest Tasks: T5344
Differential Revision: https://secure.phabricator.com/D11360
2015-01-15 21:05:31 +01:00
|
|
|
JX.Stratcom.listen('aphlict-server-message', null, function(e) {
|
2014-06-11 22:52:15 +02:00
|
|
|
var message = e.getData();
|
|
|
|
|
|
|
|
if (message.type != 'message') {
|
|
|
|
// Not a message event.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
var data = get_thread_data();
|
2014-06-11 22:52:15 +02:00
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
if (message.threadPHID != data.threadPHID) {
|
2014-06-11 22:52:15 +02:00
|
|
|
// Message event for some thread other than the visible one.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
if (message.messageID <= data.latestID) {
|
2014-06-11 22:52:15 +02:00
|
|
|
// Message event for something we already know about.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
// If we're currently updating, wait for the update to complete.
|
|
|
|
// If this notification tells us about a message which is newer than the
|
|
|
|
// newest one we know to exist, keep track of it so we can update once
|
|
|
|
// the in-flight update finishes.
|
|
|
|
if (updating && updating.threadPHID == data.threadPHID) {
|
|
|
|
if (message.messageID > updating.knownID) {
|
|
|
|
updating.knownID = message.messageID;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
update_thread(data);
|
|
|
|
});
|
|
|
|
|
|
|
|
function update_thread(data) {
|
2014-06-11 22:52:15 +02:00
|
|
|
var params = {
|
|
|
|
action: 'load',
|
2015-01-08 18:44:02 +01:00
|
|
|
latest_transaction_id: data.latestID
|
2014-06-11 22:52:15 +02:00
|
|
|
};
|
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
var uri = '/conpherence/update/' + data.threadID + '/';
|
|
|
|
|
|
|
|
var workflow = new JX.Workflow(uri)
|
2014-06-11 22:52:15 +02:00
|
|
|
.setData(params)
|
|
|
|
.setHandler(function(r) {
|
|
|
|
var messages = JX.DOM.find(document, 'div', 'conpherence-messages');
|
|
|
|
JX.DOM.appendContent(messages, JX.$H(r.transactions));
|
|
|
|
messages.scrollTop = messages.scrollHeight;
|
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
update_latest_transaction_id(r.latest_transaction_id);
|
|
|
|
});
|
|
|
|
|
|
|
|
sync_workflow(workflow, data);
|
|
|
|
}
|
2014-06-11 22:52:15 +02:00
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
function sync_workflow(workflow, data) {
|
|
|
|
updating = {
|
|
|
|
threadPHID: data.threadPHID,
|
|
|
|
knownID: data.latestID
|
|
|
|
};
|
|
|
|
|
|
|
|
workflow.listen('finally', function() {
|
|
|
|
var new_data = get_thread_data();
|
|
|
|
var need_sync = (updating.knownID > new_data.latestID);
|
|
|
|
|
|
|
|
updating = null;
|
|
|
|
|
|
|
|
if (need_sync) {
|
|
|
|
update_thread(new_data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
workflow.start();
|
|
|
|
}
|
2014-06-11 22:52:15 +02:00
|
|
|
|
2013-03-06 00:45:36 +01:00
|
|
|
var onsubmit = function(e) {
|
|
|
|
e.kill();
|
2013-03-31 23:41:13 +02:00
|
|
|
|
|
|
|
var form = e.getNode('tag:form');
|
|
|
|
|
|
|
|
var root = e.getNode('conpherence-layout');
|
2013-05-29 21:46:06 +02:00
|
|
|
var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane');
|
|
|
|
var form_root = JX.DOM.find(root, 'div', 'conpherence-form');
|
|
|
|
var messages = JX.DOM.find(messages_root, 'div', 'conpherence-messages');
|
2013-04-08 20:13:35 +02:00
|
|
|
var fileWidget = null;
|
|
|
|
try {
|
|
|
|
fileWidget = JX.DOM.find(root, 'div', 'widgets-files');
|
|
|
|
} catch (ex) {
|
|
|
|
// Ignore; maybe no files widget
|
|
|
|
}
|
2013-05-29 21:46:06 +02:00
|
|
|
JX.DOM.alterClass(form_root, 'loading', true);
|
2013-03-31 23:41:13 +02:00
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
var workflow = JX.Workflow.newFromForm(form)
|
2013-03-06 00:45:36 +01:00
|
|
|
.setHandler(JX.bind(this, function(r) {
|
|
|
|
JX.DOM.appendContent(messages, JX.$H(r.transactions));
|
|
|
|
messages.scrollTop = messages.scrollHeight;
|
2013-03-31 23:41:13 +02:00
|
|
|
|
2013-04-08 20:13:35 +02:00
|
|
|
if (fileWidget) {
|
|
|
|
JX.DOM.setContent(
|
|
|
|
fileWidget,
|
|
|
|
JX.$H(r.file_widget)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2015-01-08 18:44:02 +01:00
|
|
|
update_latest_transaction_id(r.latest_transaction_id);
|
2013-03-06 00:45:36 +01:00
|
|
|
|
|
|
|
var textarea = JX.DOM.find(form, 'textarea');
|
|
|
|
textarea.value = '';
|
2013-04-10 20:37:04 +02:00
|
|
|
|
2013-05-29 21:46:06 +02:00
|
|
|
JX.DOM.alterClass(form_root, 'loading', false);
|
2015-02-26 00:14:27 +01:00
|
|
|
|
|
|
|
setTimeout(function() { JX.DOM.focus(textarea); }, 100);
|
2015-01-08 18:44:02 +01:00
|
|
|
}));
|
|
|
|
|
|
|
|
sync_workflow(workflow, get_thread_data());
|
2013-03-06 00:45:36 +01:00
|
|
|
};
|
|
|
|
|
2013-03-31 23:41:33 +02:00
|
|
|
JX.Stratcom.listen(
|
|
|
|
['submit', 'didSyntheticSubmit'],
|
|
|
|
'conpherence-pontificate',
|
|
|
|
onsubmit);
|
2013-03-06 00:45:36 +01:00
|
|
|
|
|
|
|
});
|