mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-27 09:12:41 +01:00
10f1692b1b
Summary: Ref T7014. The main conpherence view is kind of broken without this in subtle ways because of /conpherence/ versus /conpherence/x/ init'ing things differently; this fixes that. Moves more normal view conpherence logic into threadManager. Makes all the display code happen outside of threadManager, setting us up for some display manager later maybe. Test Plan: sent messages, updated title, etc and the messages pane auto scrolled correctly! Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7014 Differential Revision: https://secure.phabricator.com/D12035
270 lines
7.1 KiB
JavaScript
270 lines
7.1 KiB
JavaScript
/**
|
|
* @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,
|
|
_didUpdateThreadCallback: JX.bag,
|
|
_willSendMessageCallback: JX.bag,
|
|
_didSendMessageCallback: JX.bag,
|
|
_willUpdateWorkflowCallback: JX.bag,
|
|
_didUpdateWorkflowCallback: JX.bag,
|
|
|
|
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;
|
|
},
|
|
|
|
setLoadedThreadID: function(id) {
|
|
this._loadedThreadID = id;
|
|
return this;
|
|
},
|
|
|
|
getLoadedThreadPHID: function() {
|
|
return this._loadedThreadPHID;
|
|
},
|
|
|
|
setLoadedThreadPHID: function(phid) {
|
|
this._loadedThreadPHID = phid;
|
|
return this;
|
|
},
|
|
|
|
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;
|
|
},
|
|
|
|
setDidUpdateThreadCallback: function(callback) {
|
|
this._didUpdateThreadCallback = callback;
|
|
return this;
|
|
},
|
|
|
|
setWillSendMessageCallback: function(callback) {
|
|
this._willSendMessageCallback = callback;
|
|
return this;
|
|
},
|
|
|
|
setDidSendMessageCallback: function(callback) {
|
|
this._didSendMessageCallback = callback;
|
|
return this;
|
|
},
|
|
|
|
setWillUpdateWorkflowCallback: function(callback) {
|
|
this._willUpdateWorkflowCallback = callback;
|
|
return this;
|
|
},
|
|
|
|
setDidUpdateWorkflowCallback: function(callback) {
|
|
this._didUpdateWorkflowCallback = callback;
|
|
return this;
|
|
},
|
|
|
|
_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;
|
|
},
|
|
|
|
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;
|
|
this._didUpdateThreadCallback(r);
|
|
}));
|
|
|
|
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);
|
|
this._willUpdateWorkflowCallback();
|
|
var workflow = new JX.Workflow.newFromLink(link)
|
|
.setData(params)
|
|
.setHandler(JX.bind(this, function(r) {
|
|
this._latestTransactionID = r.latest_transaction_id;
|
|
this._didUpdateWorkflowCallback(r);
|
|
}));
|
|
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');
|
|
}
|
|
},
|
|
|
|
statics: {
|
|
_instance: null,
|
|
|
|
getInstance: function() {
|
|
var self = JX.ConpherenceThreadManager;
|
|
if (!self._instance) {
|
|
return null;
|
|
}
|
|
return self._instance;
|
|
}
|
|
}
|
|
|
|
});
|