1
by Richard Sellam
Import upstream version 0~git20141023 |
1 |
/**
|
2 |
* @provides javelin-behavior-conpherence-menu
|
|
3 |
* @requires javelin-behavior
|
|
4 |
* javelin-dom
|
|
5 |
* javelin-util
|
|
6 |
* javelin-stratcom
|
|
7 |
* javelin-workflow
|
|
8 |
* javelin-behavior-device
|
|
9 |
* javelin-history
|
|
10 |
* javelin-vector
|
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
11 |
* javelin-scrollbar
|
12 |
* phabricator-title
|
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
13 |
* phabricator-shaped-request
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
14 |
* conpherence-thread-manager
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
15 |
*/
|
16 |
||
17 |
JX.behavior('conpherence-menu', function(config) { |
|
18 |
/**
|
|
19 |
* State for displayed thread.
|
|
20 |
*/
|
|
21 |
var _thread = { |
|
22 |
selected: null, |
|
23 |
visible: null, |
|
24 |
node: null |
|
25 |
};
|
|
26 |
||
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
27 |
var scrollbar = null; |
28 |
||
29 |
// TODO - move more logic into the ThreadManager
|
|
30 |
var threadManager = new JX.ConpherenceThreadManager(); |
|
0.15.3
by Richard Sellam
Import upstream version 0~git20150525 |
31 |
threadManager.setMessagesRootCallback(function() { |
32 |
return scrollbar.getContentNode(); |
|
33 |
});
|
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
34 |
threadManager.setWillLoadThreadCallback(function() { |
35 |
markThreadLoading(true); |
|
36 |
});
|
|
37 |
threadManager.setDidLoadThreadCallback(function(r) { |
|
38 |
var header = JX.$H(r.header); |
|
0.15.3
by Richard Sellam
Import upstream version 0~git20150525 |
39 |
var messages = JX.$H(r.transactions); |
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
40 |
var form = JX.$H(r.form); |
41 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
42 |
var header_root = JX.DOM.find(root, 'div', 'conpherence-header-pane'); |
|
43 |
var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); |
|
44 |
JX.DOM.setContent(header_root, header); |
|
45 |
JX.DOM.setContent(scrollbar.getContentNode(), messages); |
|
46 |
JX.DOM.setContent(form_root, form); |
|
47 |
||
48 |
markThreadLoading(false); |
|
49 |
||
50 |
didRedrawThread(true); |
|
51 |
});
|
|
52 |
||
53 |
threadManager.setDidUpdateThreadCallback(function(r) { |
|
54 |
_scrollMessageWindow(); |
|
55 |
});
|
|
56 |
||
57 |
threadManager.setWillSendMessageCallback(function () { |
|
58 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
59 |
var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); |
|
60 |
markThreadLoading(true); |
|
61 |
JX.DOM.alterClass(form_root, 'loading', true); |
|
62 |
});
|
|
63 |
||
64 |
threadManager.setDidSendMessageCallback(function (r, non_update) { |
|
65 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
66 |
var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); |
|
67 |
var textarea = JX.DOM.find(form_root, 'textarea'); |
|
68 |
if (!non_update) { |
|
69 |
var fileWidget = null; |
|
70 |
try { |
|
71 |
fileWidget = JX.DOM.find(root, 'div', 'widgets-files'); |
|
72 |
} catch (ex) { |
|
73 |
// Ignore; maybe no files widget
|
|
74 |
}
|
|
75 |
if (fileWidget) { |
|
76 |
JX.DOM.setContent( |
|
77 |
fileWidget, |
|
78 |
JX.$H(r.file_widget)); |
|
79 |
}
|
|
0.15.3
by Richard Sellam
Import upstream version 0~git20150525 |
80 |
|
81 |
_scrollMessageWindow(); |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
82 |
textarea.value = ''; |
83 |
}
|
|
84 |
markThreadLoading(false); |
|
85 |
||
86 |
setTimeout(function() { JX.DOM.focus(textarea); }, 100); |
|
87 |
});
|
|
88 |
threadManager.start(); |
|
89 |
||
1
by Richard Sellam
Import upstream version 0~git20141023 |
90 |
/**
|
91 |
* Current role of this behavior. The two possible roles are to show a 'list'
|
|
92 |
* of threads or a specific 'thread'. On devices, this behavior stays in the
|
|
93 |
* 'list' role indefinitely, treating clicks normally and the next page
|
|
94 |
* loads the behavior with role = 'thread'. On desktop, this behavior
|
|
95 |
* auto-loads a thread as part of the 'list' role. As the thread loads the
|
|
96 |
* role is changed to 'thread'.
|
|
97 |
*/
|
|
98 |
var _currentRole = null; |
|
99 |
||
100 |
/**
|
|
101 |
* When _oldDevice is null the code is executing for the first time.
|
|
102 |
*/
|
|
103 |
var _oldDevice = null; |
|
104 |
||
105 |
/**
|
|
106 |
* Initializes this behavior based on all the configuraton jonx and the
|
|
107 |
* result of JX.Device.getDevice();
|
|
108 |
*/
|
|
109 |
function init() { |
|
110 |
_currentRole = config.role; |
|
111 |
||
112 |
if (_currentRole == 'thread') { |
|
113 |
markThreadsLoading(true); |
|
114 |
} else { |
|
115 |
markThreadLoading(true); |
|
116 |
}
|
|
117 |
markWidgetLoading(true); |
|
118 |
onDeviceChange(); |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
119 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
120 |
var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane'); |
|
121 |
var messages = JX.DOM.find(messages_root, 'div', 'conpherence-messages'); |
|
122 |
scrollbar = new JX.Scrollbar(messages); |
|
123 |
scrollbar.setAsScrollFrame(); |
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
124 |
}
|
125 |
init(); |
|
126 |
||
127 |
/**
|
|
128 |
* Selecting threads
|
|
129 |
*/
|
|
130 |
function selectThreadByID(id, update_page_data) { |
|
131 |
var thread = JX.$(id); |
|
132 |
selectThread(thread, update_page_data); |
|
133 |
}
|
|
134 |
||
135 |
function selectThread(node, update_page_data) { |
|
136 |
if (_thread.node) { |
|
137 |
JX.DOM.alterClass(_thread.node, 'conpherence-selected', false); |
|
138 |
}
|
|
139 |
||
140 |
JX.DOM.alterClass(node, 'conpherence-selected', true); |
|
141 |
JX.DOM.alterClass(node, 'hide-unread-count', true); |
|
142 |
||
143 |
_thread.node = node; |
|
144 |
||
145 |
var data = JX.Stratcom.getData(node); |
|
146 |
_thread.selected = data.threadID; |
|
147 |
||
148 |
if (update_page_data) { |
|
149 |
updatePageData(data); |
|
150 |
}
|
|
151 |
||
152 |
redrawThread(); |
|
153 |
}
|
|
154 |
||
155 |
function updatePageData(data) { |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
156 |
var uri = '/Z' + _thread.selected; |
157 |
JX.History.replace(uri); |
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
158 |
if (data.title) { |
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
159 |
JX.Title.setTitle(data.title); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
160 |
} else if (_thread.node) { |
161 |
var threadData = JX.Stratcom.getData(_thread.node); |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
162 |
JX.Title.setTitle(threadData.title); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
163 |
}
|
164 |
}
|
|
165 |
||
166 |
JX.Stratcom.listen( |
|
167 |
'conpherence-update-page-data', |
|
168 |
null, |
|
169 |
function (e) { |
|
170 |
updatePageData(e.getData()); |
|
171 |
}
|
|
172 |
);
|
|
173 |
||
174 |
function redrawThread() { |
|
175 |
if (!_thread.node) { |
|
176 |
return; |
|
177 |
}
|
|
178 |
||
179 |
if (_thread.visible == _thread.selected) { |
|
180 |
return; |
|
181 |
}
|
|
182 |
||
183 |
var data = JX.Stratcom.getData(_thread.node); |
|
184 |
||
185 |
if (_thread.visible !== null || !config.hasThread) { |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
186 |
threadManager.setLoadThreadURI('/conpherence/' + data.threadID + '/'); |
187 |
threadManager.loadThreadByID(data.threadID); |
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
188 |
} else if (config.hasThread) { |
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
189 |
// we loaded the thread via the server so let the thread manager know
|
190 |
threadManager.setLoadedThreadID(config.selectedThreadID); |
|
191 |
threadManager.setLoadedThreadPHID(config.selectedThreadPHID); |
|
192 |
threadManager.setLatestTransactionID(config.latestTransactionID); |
|
193 |
threadManager.setCanEditLoadedThread(config.canEditSelectedThread); |
|
0.15.3
by Richard Sellam
Import upstream version 0~git20150525 |
194 |
threadManager.cacheCurrentTransactions(); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
195 |
_scrollMessageWindow(); |
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
196 |
_focusTextarea(); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
197 |
} else { |
198 |
didRedrawThread(); |
|
199 |
}
|
|
200 |
||
201 |
if (_thread.visible !== null || !config.hasWidgets) { |
|
202 |
reloadWidget(data); |
|
203 |
} else { |
|
204 |
JX.Stratcom.invoke( |
|
205 |
'conpherence-update-widgets', |
|
206 |
null, |
|
207 |
{
|
|
208 |
widget : getDefaultWidget(), |
|
209 |
buildSelectors : false, |
|
210 |
toggleWidget : true, |
|
211 |
threadID : _thread.selected |
|
212 |
});
|
|
213 |
}
|
|
214 |
||
215 |
_thread.visible = _thread.selected; |
|
216 |
}
|
|
217 |
||
218 |
function markThreadsLoading(loading) { |
|
219 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
220 |
var menu = JX.DOM.find(root, 'div', 'conpherence-menu-pane'); |
|
221 |
JX.DOM.alterClass(menu, 'loading', loading); |
|
222 |
}
|
|
223 |
||
224 |
function markThreadLoading(loading) { |
|
225 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
226 |
var header_root = JX.DOM.find(root, 'div', 'conpherence-header-pane'); |
|
227 |
var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane'); |
|
228 |
var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); |
|
229 |
||
230 |
JX.DOM.alterClass(header_root, 'loading', loading); |
|
231 |
JX.DOM.alterClass(messages_root, 'loading', loading); |
|
232 |
JX.DOM.alterClass(form_root, 'loading', loading); |
|
233 |
||
234 |
try { |
|
235 |
var textarea = JX.DOM.find(form, 'textarea'); |
|
236 |
textarea.disabled = loading; |
|
237 |
var button = JX.DOM.find(form, 'button'); |
|
238 |
button.disabled = loading; |
|
239 |
} catch (ex) { |
|
240 |
// haven't loaded it yet!
|
|
241 |
}
|
|
242 |
}
|
|
243 |
||
244 |
function markWidgetLoading(loading) { |
|
245 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
246 |
var widgets_root = JX.DOM.find(root, 'div', 'conpherence-widget-pane'); |
|
247 |
||
248 |
JX.DOM.alterClass(widgets_root, 'loading', loading); |
|
249 |
}
|
|
250 |
||
251 |
function reloadWidget(data) { |
|
252 |
markWidgetLoading(true); |
|
253 |
if (!data.widget) { |
|
254 |
data.widget = getDefaultWidget(); |
|
255 |
}
|
|
256 |
var widget_uri = config.baseURI + 'widget/' + data.threadID + '/'; |
|
257 |
new JX.Workflow(widget_uri, {}) |
|
258 |
.setHandler(JX.bind(null, onWidgetResponse, data.threadID, data.widget)) |
|
259 |
.start(); |
|
260 |
}
|
|
261 |
JX.Stratcom.listen( |
|
262 |
'conpherence-reload-widget', |
|
263 |
null, |
|
264 |
function (e) { |
|
265 |
var data = e.getData(); |
|
266 |
if (data.threadID != _thread.selected) { |
|
267 |
return; |
|
268 |
}
|
|
269 |
reloadWidget(data); |
|
270 |
}
|
|
271 |
);
|
|
272 |
||
273 |
function onWidgetResponse(thread_id, widget, response) { |
|
274 |
// we got impatient and this is no longer the right answer :/
|
|
275 |
if (_thread.selected != thread_id) { |
|
276 |
return; |
|
277 |
}
|
|
278 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
279 |
var widgets_root = JX.DOM.find(root, 'div', 'conpherence-widgets-holder'); |
|
280 |
JX.DOM.setContent(widgets_root, JX.$H(response.widgets)); |
|
281 |
||
282 |
JX.Stratcom.invoke( |
|
283 |
'conpherence-update-widgets', |
|
284 |
null, |
|
285 |
{
|
|
286 |
widget : widget, |
|
287 |
buildSelectors : true, |
|
288 |
toggleWidget : true, |
|
289 |
threadID : _thread.selected |
|
290 |
});
|
|
291 |
||
292 |
markWidgetLoading(false); |
|
293 |
}
|
|
294 |
||
295 |
function getDefaultWidget() { |
|
296 |
var device = JX.Device.getDevice(); |
|
297 |
var widget = 'conpherence-message-pane'; |
|
298 |
if (device == 'desktop') { |
|
299 |
widget = 'widgets-people'; |
|
0.15.4
by Richard Sellam
Import upstream version 0~git20150613 |
300 |
var uri = JX.$U(location.href); |
301 |
var params = uri.getQueryParams(); |
|
302 |
if ('settings' in params) { |
|
303 |
widget = 'widgets-settings'; |
|
304 |
}
|
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
305 |
}
|
306 |
return widget; |
|
307 |
}
|
|
308 |
||
309 |
/**
|
|
310 |
* This function is a wee bit tricky. Internally, we want to scroll the
|
|
311 |
* message window and let other stuff - notably widgets - redraw / build if
|
|
312 |
* necessary. Externally, we want a hook to scroll the message window
|
|
313 |
* - notably when the widget selector is used to invoke the message pane.
|
|
314 |
* The following three functions get 'er done.
|
|
315 |
*/
|
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
316 |
function didRedrawThread(build_device_widget_selector) { |
317 |
_scrollMessageWindow(); |
|
318 |
_focusTextarea(); |
|
319 |
JX.Stratcom.invoke( |
|
320 |
'conpherence-did-redraw-thread', |
|
321 |
null, |
|
322 |
{
|
|
323 |
widget : getDefaultWidget(), |
|
324 |
threadID : _thread.selected, |
|
325 |
buildDeviceWidgetSelector : build_device_widget_selector |
|
326 |
});
|
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
327 |
}
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
328 |
|
329 |
var _firstScroll = true; |
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
330 |
function _scrollMessageWindow() { |
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
331 |
if (_firstScroll) { |
332 |
_firstScroll = false; |
|
333 |
||
334 |
// We want to let the standard #anchor tech take over after we make sure
|
|
335 |
// we don't have to present the user with a "load older message?" dialog
|
|
336 |
if (window.location.hash) { |
|
337 |
var hash = window.location.hash.replace(/^#/, ''); |
|
338 |
try { |
|
339 |
JX.$('anchor-' + hash); |
|
340 |
} catch (ex) { |
|
341 |
var uri = '/conpherence/' + |
|
342 |
_thread.selected + '/' + hash + '/'; |
|
343 |
threadManager.setLoadThreadURI(uri); |
|
344 |
threadManager.loadThreadByID(_thread.selected, true); |
|
345 |
_firstScroll = true; |
|
346 |
return; |
|
347 |
}
|
|
348 |
return; |
|
349 |
}
|
|
350 |
}
|
|
351 |
scrollbar.scrollTo(scrollbar.getViewportNode().scrollHeight); |
|
352 |
}
|
|
353 |
function _focusTextarea() { |
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
354 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
355 |
var form_root = JX.DOM.find(root, 'div', 'conpherence-form'); |
356 |
try { |
|
357 |
var textarea = JX.DOM.find(form_root, 'textarea'); |
|
358 |
// We may have a draft so do this JS trick so we end up focused at the
|
|
359 |
// end of the draft.
|
|
360 |
var textarea_value = textarea.value; |
|
361 |
textarea.value = ''; |
|
362 |
JX.DOM.focus(textarea); |
|
363 |
textarea.value = textarea_value; |
|
364 |
} catch (ex) { |
|
365 |
// no textarea? no problem
|
|
366 |
}
|
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
367 |
}
|
368 |
JX.Stratcom.listen( |
|
369 |
'conpherence-redraw-thread', |
|
370 |
null, |
|
371 |
function () { |
|
372 |
_scrollMessageWindow(); |
|
373 |
}
|
|
374 |
);
|
|
375 |
||
376 |
JX.Stratcom.listen( |
|
377 |
'click', |
|
378 |
'conpherence-menu-click', |
|
379 |
function(e) { |
|
380 |
if (!e.isNormalClick()) { |
|
381 |
return; |
|
382 |
}
|
|
383 |
||
384 |
// On devices, just follow the link normally.
|
|
385 |
if (JX.Device.getDevice() != 'desktop') { |
|
386 |
return; |
|
387 |
}
|
|
388 |
||
389 |
e.kill(); |
|
390 |
selectThread(e.getNode('conpherence-menu-click'), true); |
|
391 |
});
|
|
392 |
||
393 |
JX.Stratcom.listen('click', 'conpherence-edit-metadata', function (e) { |
|
394 |
e.kill(); |
|
395 |
var root = e.getNode('conpherence-layout'); |
|
396 |
var form = JX.DOM.find(root, 'form', 'conpherence-pontificate'); |
|
397 |
var data = e.getNodeData('conpherence-edit-metadata'); |
|
398 |
var header = JX.DOM.find(root, 'div', 'conpherence-header-pane'); |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
399 |
var messages = scrollbar.getContentNode(); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
400 |
|
401 |
new JX.Workflow.newFromForm(form, data) |
|
402 |
.setHandler(JX.bind(this, function(r) { |
|
403 |
JX.DOM.appendContent(messages, JX.$H(r.transactions)); |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
404 |
_scrollMessageWindow(); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
405 |
|
406 |
JX.DOM.setContent( |
|
407 |
header, |
|
408 |
JX.$H(r.header) |
|
409 |
);
|
|
410 |
||
411 |
try { |
|
412 |
// update the menu entry
|
|
413 |
JX.DOM.replace( |
|
414 |
JX.$(r.conpherence_phid + '-nav-item'), |
|
415 |
JX.$H(r.nav_item) |
|
416 |
);
|
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
417 |
selectThreadByID(r.conpherence_phid + '-nav-item'); |
1
by Richard Sellam
Import upstream version 0~git20141023 |
418 |
} catch (ex) { |
419 |
// Ignore; this view may not have a menu.
|
|
420 |
}
|
|
421 |
}))
|
|
422 |
.start(); |
|
423 |
});
|
|
424 |
||
425 |
/**
|
|
426 |
* On devices, we just show a thread list, so we don't want to automatically
|
|
427 |
* select or load any threads. On desktop, we automatically select the first
|
|
428 |
* thread, changing the _currentRole from list to thread.
|
|
429 |
*/
|
|
430 |
function onDeviceChange() { |
|
431 |
var new_device = JX.Device.getDevice(); |
|
432 |
if (new_device === _oldDevice) { |
|
433 |
return; |
|
434 |
}
|
|
435 |
||
436 |
if (_oldDevice === null) { |
|
437 |
_oldDevice = new_device; |
|
438 |
if (_currentRole == 'list') { |
|
439 |
if (new_device != 'desktop') { |
|
440 |
return; |
|
441 |
}
|
|
442 |
} else { |
|
443 |
loadThreads(); |
|
444 |
return; |
|
445 |
}
|
|
446 |
}
|
|
447 |
var update_toggled_widget = |
|
448 |
new_device == 'desktop' || _oldDevice == 'desktop'; |
|
449 |
_oldDevice = new_device; |
|
450 |
||
451 |
if (_thread.visible !== null && update_toggled_widget) { |
|
452 |
JX.Stratcom.invoke( |
|
453 |
'conpherence-did-redraw-thread', |
|
454 |
null, |
|
455 |
{
|
|
456 |
widget : getDefaultWidget(), |
|
457 |
threadID : _thread.selected |
|
458 |
});
|
|
459 |
}
|
|
460 |
||
461 |
if (_currentRole == 'list' && new_device == 'desktop') { |
|
462 |
// this selects a thread and loads it
|
|
463 |
didLoadThreads(); |
|
464 |
_currentRole = 'thread'; |
|
465 |
var root = JX.DOM.find(document, 'div', 'conpherence-layout'); |
|
466 |
JX.DOM.alterClass(root, 'conpherence-role-list', false); |
|
467 |
JX.DOM.alterClass(root, 'conpherence-role-thread', true); |
|
468 |
}
|
|
469 |
}
|
|
470 |
JX.Stratcom.listen('phabricator-device-change', null, onDeviceChange); |
|
471 |
||
472 |
function loadThreads() { |
|
473 |
markThreadsLoading(true); |
|
474 |
var uri = config.baseURI + 'thread/' + config.selectedThreadID + '/'; |
|
475 |
new JX.Workflow(uri) |
|
476 |
.setHandler(onLoadThreadsResponse) |
|
477 |
.start(); |
|
478 |
}
|
|
479 |
||
480 |
function onLoadThreadsResponse(r) { |
|
481 |
var layout = JX.$(config.layoutID); |
|
482 |
var menu = JX.DOM.find(layout, 'div', 'conpherence-menu-pane'); |
|
483 |
JX.DOM.setContent(menu, JX.$H(r)); |
|
484 |
||
485 |
config.selectedID && selectThreadByID(config.selectedID); |
|
486 |
||
487 |
markThreadsLoading(false); |
|
488 |
}
|
|
489 |
||
490 |
function didLoadThreads() { |
|
491 |
// If there's no thread selected yet, select the current thread or the
|
|
492 |
// first thread.
|
|
493 |
if (!_thread.selected) { |
|
494 |
if (config.selectedID) { |
|
495 |
selectThreadByID(config.selectedID, true); |
|
496 |
} else { |
|
497 |
var layout = JX.$(config.layoutID); |
|
498 |
var threads = JX.DOM.scry(layout, 'a', 'conpherence-menu-click'); |
|
499 |
if (threads.length) { |
|
500 |
selectThread(threads[0]); |
|
501 |
} else { |
|
502 |
var nothreads = JX.DOM.find(layout, 'div', 'conpherence-no-threads'); |
|
503 |
nothreads.style.display = 'block'; |
|
504 |
markThreadLoading(false); |
|
505 |
markWidgetLoading(false); |
|
506 |
}
|
|
507 |
}
|
|
508 |
}
|
|
509 |
}
|
|
510 |
||
511 |
JX.Stratcom.listen( |
|
512 |
['click'], |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
513 |
'conpherence-menu-see-more', |
514 |
function (e) { |
|
515 |
e.kill(); |
|
516 |
var sigil = e.getNodeData('conpherence-menu-see-more').moreSigil; |
|
517 |
var root = JX.$('conpherence-menu-pane'); |
|
518 |
var more = JX.DOM.scry(root, 'li', sigil); |
|
519 |
for (var i = 0; i < more.length; i++) { |
|
520 |
JX.DOM.alterClass(more[i], 'hidden', false); |
|
521 |
}
|
|
522 |
JX.DOM.hide(e.getNode('conpherence-menu-see-more')); |
|
523 |
});
|
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
524 |
|
525 |
JX.Stratcom.listen( |
|
526 |
['keydown'], |
|
527 |
'conpherence-pontificate', |
|
0.15.2
by Richard Sellam
Import upstream version 0~git20150428 |
528 |
function (e) { |
529 |
threadManager.handleDraftKeydown(e); |
|
530 |
});
|
|
1
by Richard Sellam
Import upstream version 0~git20141023 |
531 |
|
532 |
});
|