Changeset View
Changeset View
Standalone View
Standalone View
webroot/rsrc/js/application/conpherence/behavior-pontificate.js
/** | /** | ||||
* @provides javelin-behavior-conpherence-pontificate | * @provides javelin-behavior-conpherence-pontificate | ||||
* @requires javelin-behavior | * @requires javelin-behavior | ||||
* javelin-dom | * javelin-dom | ||||
* javelin-util | * javelin-util | ||||
* javelin-workflow | * javelin-workflow | ||||
* javelin-stratcom | * javelin-stratcom | ||||
*/ | */ | ||||
JX.behavior('conpherence-pontificate', function() { | JX.behavior('conpherence-pontificate', function() { | ||||
// 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; | |||||
} | |||||
JX.Stratcom.listen('aphlict-receive-message', null, function(e) { | JX.Stratcom.listen('aphlict-receive-message', null, function(e) { | ||||
var message = e.getData(); | var message = e.getData(); | ||||
if (message.type != 'message') { | if (message.type != 'message') { | ||||
// Not a message event. | // Not a message event. | ||||
return; | return; | ||||
} | } | ||||
// TODO: This is really, really gross. | var data = get_thread_data(); | ||||
var infonode = JX.DOM.find(document, 'input', 'latest-transaction-id'); | |||||
var data = JX.Stratcom.getData(infonode); | |||||
var latest_id = infonode.value; | |||||
var thread_phid = data.threadPHID; | |||||
var thread_id = data.threadID; | |||||
if (message.threadPHID != thread_phid) { | if (message.threadPHID != data.threadPHID) { | ||||
// Message event for some thread other than the visible one. | // Message event for some thread other than the visible one. | ||||
return; | return; | ||||
} | } | ||||
if (message.messageID <= latest_id) { | if (message.messageID <= data.latestID) { | ||||
// Message event for something we already know about. | // Message event for something we already know about. | ||||
return; | return; | ||||
} | } | ||||
// 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) { | |||||
var params = { | var params = { | ||||
action: 'load', | action: 'load', | ||||
latest_transaction_id: latest_id | latest_transaction_id: data.latestID | ||||
}; | }; | ||||
new JX.Workflow('/conpherence/update/' + thread_id + '/') | var uri = '/conpherence/update/' + data.threadID + '/'; | ||||
var workflow = new JX.Workflow(uri) | |||||
.setData(params) | .setData(params) | ||||
.setHandler(function(r) { | .setHandler(function(r) { | ||||
var messages = JX.DOM.find(document, 'div', 'conpherence-messages'); | var messages = JX.DOM.find(document, 'div', 'conpherence-messages'); | ||||
JX.DOM.appendContent(messages, JX.$H(r.transactions)); | JX.DOM.appendContent(messages, JX.$H(r.transactions)); | ||||
messages.scrollTop = messages.scrollHeight; | messages.scrollTop = messages.scrollHeight; | ||||
// TODO: Continued grossness from above. | update_latest_transaction_id(r.latest_transaction_id); | ||||
infonode.value = r.latest_transaction_id; | }); | ||||
}) | |||||
.start(); | sync_workflow(workflow, data); | ||||
} | |||||
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(); | |||||
} | |||||
var onsubmit = function(e) { | var onsubmit = function(e) { | ||||
e.kill(); | e.kill(); | ||||
var form = e.getNode('tag:form'); | var form = e.getNode('tag:form'); | ||||
var root = e.getNode('conpherence-layout'); | var root = e.getNode('conpherence-layout'); | ||||
var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane'); | var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane'); | ||||
var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); | var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); | ||||
var messages = JX.DOM.find(messages_root, 'div', 'conpherence-messages'); | var messages = JX.DOM.find(messages_root, 'div', 'conpherence-messages'); | ||||
var fileWidget = null; | var fileWidget = null; | ||||
try { | try { | ||||
fileWidget = JX.DOM.find(root, 'div', 'widgets-files'); | fileWidget = JX.DOM.find(root, 'div', 'widgets-files'); | ||||
} catch (ex) { | } catch (ex) { | ||||
// Ignore; maybe no files widget | // Ignore; maybe no files widget | ||||
} | } | ||||
JX.DOM.alterClass(form_root, 'loading', true); | JX.DOM.alterClass(form_root, 'loading', true); | ||||
JX.Workflow.newFromForm(form) | var workflow = JX.Workflow.newFromForm(form) | ||||
.setHandler(JX.bind(this, function(r) { | .setHandler(JX.bind(this, function(r) { | ||||
JX.DOM.appendContent(messages, JX.$H(r.transactions)); | JX.DOM.appendContent(messages, JX.$H(r.transactions)); | ||||
messages.scrollTop = messages.scrollHeight; | messages.scrollTop = messages.scrollHeight; | ||||
if (fileWidget) { | if (fileWidget) { | ||||
JX.DOM.setContent( | JX.DOM.setContent( | ||||
fileWidget, | fileWidget, | ||||
JX.$H(r.file_widget) | JX.$H(r.file_widget) | ||||
); | ); | ||||
} | } | ||||
var latest_transaction_dom = JX.DOM.find( | update_latest_transaction_id(r.latest_transaction_id); | ||||
root, | |||||
'input', | |||||
'latest-transaction-id'); | |||||
latest_transaction_dom.value = r.latest_transaction_id; | |||||
var textarea = JX.DOM.find(form, 'textarea'); | var textarea = JX.DOM.find(form, 'textarea'); | ||||
textarea.value = ''; | textarea.value = ''; | ||||
JX.Stratcom.invoke( | JX.Stratcom.invoke( | ||||
'conpherence-selectthread', | 'conpherence-selectthread', | ||||
null, | null, | ||||
{ id : r.conpherence_phid + '-nav-item' } | { id : r.conpherence_phid + '-nav-item' } | ||||
); | ); | ||||
JX.DOM.alterClass(form_root, 'loading', false); | JX.DOM.alterClass(form_root, 'loading', false); | ||||
})) | })); | ||||
.start(); | |||||
sync_workflow(workflow, get_thread_data()); | |||||
}; | }; | ||||
JX.Stratcom.listen( | JX.Stratcom.listen( | ||||
['submit', 'didSyntheticSubmit'], | ['submit', 'didSyntheticSubmit'], | ||||
'conpherence-pontificate', | 'conpherence-pontificate', | ||||
onsubmit); | onsubmit); | ||||
}); | }); |