2015-03-10 20:20:29 +01:00
|
|
|
/**
|
|
|
|
* @provides conpherence-thread-manager
|
|
|
|
* @requires javelin-dom
|
|
|
|
* javelin-util
|
|
|
|
* javelin-stratcom
|
|
|
|
* javelin-install
|
|
|
|
* javelin-workflow
|
|
|
|
* javelin-router
|
|
|
|
* javelin-behavior-device
|
|
|
|
* javelin-vector
|
|
|
|
*/
|
|
|
|
JX.install('ConpherenceThreadManager', {
|
|
|
|
|
|
|
|
construct : function() {
|
|
|
|
if (__DEV__) {
|
|
|
|
if (JX.ConpherenceThreadManager._instance) {
|
|
|
|
JX.$E('ConpherenceThreadManager object is a singleton.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
JX.ConpherenceThreadManager._instance = this;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
members: {
|
|
|
|
_loadThreadURI: null,
|
|
|
|
_loadedThreadID: null,
|
|
|
|
_loadedThreadPHID: null,
|
|
|
|
_latestTransactionID: null,
|
|
|
|
_updating: null,
|
|
|
|
_minimalDisplay: false,
|
|
|
|
_willLoadThreadCallback: JX.bag,
|
|
|
|
_didLoadThreadCallback: JX.bag,
|
2015-03-10 21:53:30 +01:00
|
|
|
_didUpdateThreadCallback: JX.bag,
|
2015-03-10 20:20:29 +01:00
|
|
|
_willSendMessageCallback: JX.bag,
|
|
|
|
_didSendMessageCallback: JX.bag,
|
2015-03-10 21:53:30 +01:00
|
|
|
_willUpdateWorkflowCallback: JX.bag,
|
|
|
|
_didUpdateWorkflowCallback: JX.bag,
|
2015-03-10 20:20:29 +01:00
|
|
|
|
|
|
|
setLoadThreadURI: function(uri) {
|
|
|
|
this._loadThreadURI = uri;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
getLoadThreadURI: function() {
|
|
|
|
return this._loadThreadURI;
|
|
|
|
},
|
|
|
|
|
|
|
|
isThreadLoaded: function() {
|
|
|
|
return Boolean(this._loadedThreadID);
|
|
|
|
},
|
|
|
|
|
|
|
|
isThreadIDLoaded: function(thread_id) {
|
|
|
|
return this._loadedThreadID == thread_id;
|
|
|
|
},
|
|
|
|
|
|
|
|
getLoadedThreadID: function() {
|
|
|
|
return this._loadedThreadID;
|
|
|
|
},
|
|
|
|
|
2015-03-10 21:53:30 +01:00
|
|
|
setLoadedThreadID: function(id) {
|
|
|
|
this._loadedThreadID = id;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2015-03-10 20:20:29 +01:00
|
|
|
getLoadedThreadPHID: function() {
|
|
|
|
return this._loadedThreadPHID;
|
|
|
|
},
|
|
|
|
|
2015-03-10 21:53:30 +01:00
|
|
|
setLoadedThreadPHID: function(phid) {
|
|
|
|
this._loadedThreadPHID = phid;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2015-03-10 20:20:29 +01:00
|
|
|
getLatestTransactionID: function() {
|
|
|
|
return this._latestTransactionID;
|
|
|
|
},
|
|
|
|
|
|
|
|
setLatestTransactionID: function(id) {
|
|
|
|
this._latestTransactionID = id;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setMinimalDisplay: function(bool) {
|
|
|
|
this._minimalDisplay = bool;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setWillLoadThreadCallback: function(callback) {
|
|
|
|
this._willLoadThreadCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setDidLoadThreadCallback: function(callback) {
|
|
|
|
this._didLoadThreadCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2015-03-10 21:53:30 +01:00
|
|
|
setDidUpdateThreadCallback: function(callback) {
|
|
|
|
this._didUpdateThreadCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2015-03-10 20:20:29 +01:00
|
|
|
setWillSendMessageCallback: function(callback) {
|
|
|
|
this._willSendMessageCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setDidSendMessageCallback: function(callback) {
|
|
|
|
this._didSendMessageCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2015-03-10 21:53:30 +01:00
|
|
|
setWillUpdateWorkflowCallback: function(callback) {
|
|
|
|
this._willUpdateWorkflowCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
setDidUpdateWorkflowCallback: function(callback) {
|
|
|
|
this._didUpdateWorkflowCallback = callback;
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2015-03-10 20:20:29 +01:00
|
|
|
_getParams: function(base_params) {
|
|
|
|
if (this._minimalDisplay) {
|
|
|
|
base_params.minimal_display = true;
|
|
|
|
}
|
|
|
|
if (this._latestTransactionID) {
|
|
|
|
base_params.latest_transaction_id = this._latestTransactionID;
|
|
|
|
}
|
|
|
|
return base_params;
|
|
|
|
},
|
2015-03-10 21:53:30 +01:00
|
|
|
|
2015-03-10 20:20:29 +01:00
|
|
|
start: function() {
|
|
|
|
JX.Stratcom.listen(
|
|
|
|
'aphlict-server-message',
|
|
|
|
null,
|
|
|
|
JX.bind(this, function(e) {
|
|
|
|
var message = e.getData();
|
|
|
|
|
|
|
|
if (message.type != 'message') {
|
|
|
|
// Not a message event.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (message.threadPHID != this._loadedThreadPHID) {
|
|
|
|
// Message event for some thread other than the visible one.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (message.messageID <= this._latestTransactionID) {
|
|
|
|
// Message event for something we already know about.
|
|
|
|
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 (this._updating &&
|
|
|
|
this._updating.threadPHID == this._loadedThreadPHID) {
|
|
|
|
if (message.messageID > this._updating.knownID) {
|
|
|
|
this._updating.knownID = message.messageID;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this._updateThread();
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
|
|
|
_updateThread: function() {
|
|
|
|
var params = this._getParams({
|
|
|
|
action: 'load',
|
|
|
|
});
|
|
|
|
|
|
|
|
var uri = '/conpherence/update/' + this._loadedThreadID + '/';
|
|
|
|
|
|
|
|
var workflow = new JX.Workflow(uri)
|
|
|
|
.setData(params)
|
|
|
|
.setHandler(JX.bind(this, function(r) {
|
|
|
|
this._latestTransactionID = r.latest_transaction_id;
|
2015-03-10 21:53:30 +01:00
|
|
|
this._didUpdateThreadCallback(r);
|
2015-03-10 20:20:29 +01:00
|
|
|
}));
|
|
|
|
|
|
|
|
this.syncWorkflow(workflow, 'finally');
|
|
|
|
},
|
|
|
|
|
|
|
|
syncWorkflow: function(workflow, stage) {
|
|
|
|
this._updating = {
|
|
|
|
threadPHID: this._loadedThreadPHID,
|
|
|
|
knownID: this._latestTransactionID
|
|
|
|
};
|
|
|
|
workflow.listen(stage, JX.bind(this, function() {
|
|
|
|
// TODO - do we need to handle if we switch threads somehow?
|
|
|
|
var need_sync = (this._updating.knownID > this._latestTransactionID);
|
|
|
|
this._updating = null;
|
|
|
|
if (need_sync) {
|
|
|
|
this._updateThread();
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
workflow.start();
|
|
|
|
},
|
|
|
|
|
|
|
|
runUpdateWorkflowFromLink: function(link, params) {
|
|
|
|
params = this._getParams(params);
|
2015-03-10 21:53:30 +01:00
|
|
|
this._willUpdateWorkflowCallback();
|
2015-03-10 20:20:29 +01:00
|
|
|
var workflow = new JX.Workflow.newFromLink(link)
|
|
|
|
.setData(params)
|
|
|
|
.setHandler(JX.bind(this, function(r) {
|
|
|
|
this._latestTransactionID = r.latest_transaction_id;
|
2015-03-10 21:53:30 +01:00
|
|
|
this._didUpdateWorkflowCallback(r);
|
2015-03-10 20:20:29 +01:00
|
|
|
}));
|
|
|
|
this.syncWorkflow(workflow, params.stage);
|
|
|
|
},
|
|
|
|
|
|
|
|
loadThreadByID: function(thread_id) {
|
|
|
|
if (this.isThreadLoaded() &&
|
|
|
|
this.isThreadIDLoaded(thread_id)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._willLoadThreadCallback();
|
|
|
|
|
|
|
|
var params = {};
|
|
|
|
// We pick a thread from the server if not specified
|
|
|
|
if (thread_id) {
|
|
|
|
params.id = thread_id;
|
|
|
|
}
|
|
|
|
params = this._getParams(params);
|
|
|
|
|
|
|
|
var handler = JX.bind(this, function(r) {
|
|
|
|
this._loadedThreadID = r.threadID;
|
|
|
|
this._loadedThreadPHID = r.threadPHID;
|
|
|
|
this._latestTransactionID = r.latestTransactionID;
|
|
|
|
|
|
|
|
this._didLoadThreadCallback(r);
|
|
|
|
});
|
|
|
|
|
|
|
|
// should this be sync'd too?
|
|
|
|
new JX.Workflow(this.getLoadThreadURI())
|
|
|
|
.setData(params)
|
|
|
|
.setHandler(handler)
|
|
|
|
.start();
|
|
|
|
},
|
|
|
|
|
|
|
|
sendMessage: function(form, params) {
|
|
|
|
params = this._getParams(params);
|
|
|
|
|
|
|
|
this._willSendMessageCallback();
|
|
|
|
var workflow = JX.Workflow.newFromForm(form, params)
|
|
|
|
.setHandler(JX.bind(this, function(r) {
|
|
|
|
this._latestTransactionID = r.latest_transaction_id;
|
|
|
|
this._didSendMessageCallback(r);
|
|
|
|
}));
|
|
|
|
this.syncWorkflow(workflow, 'finally');
|
2015-03-11 23:54:07 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
handleDraftKeydown: function(e) {
|
|
|
|
var form = e.getNode('tag:form');
|
|
|
|
var data = e.getNodeData('tag:form');
|
|
|
|
|
|
|
|
if (!data.preview) {
|
|
|
|
var uri = '/conpherence/update/' + this._loadedThreadID + '/';
|
|
|
|
data.preview = new JX.PhabricatorShapedRequest(
|
|
|
|
uri,
|
|
|
|
JX.bag,
|
|
|
|
JX.bind(this, function () {
|
|
|
|
var data = JX.DOM.convertFormToDictionary(form);
|
|
|
|
data.action = 'draft';
|
|
|
|
data = this._getParams(data);
|
|
|
|
return data;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
data.preview.trigger();
|
2015-03-10 20:20:29 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
statics: {
|
|
|
|
_instance: null,
|
|
|
|
|
|
|
|
getInstance: function() {
|
|
|
|
var self = JX.ConpherenceThreadManager;
|
|
|
|
if (!self._instance) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return self._instance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|