Path: blob/master/webroot/rsrc/js/application/conpherence/behavior-durable-column.js
12242 views
/**1* @provides javelin-behavior-durable-column2* @requires javelin-behavior3* javelin-dom4* javelin-stratcom5* javelin-behavior-device6* javelin-scrollbar7* javelin-quicksand8* phabricator-keyboard-shortcut9* conpherence-thread-manager10*/1112JX.behavior('durable-column', function(config, statics) {13// TODO: Currently, updating the column sends the entire column back. This14// includes the `durable-column` behavior itself, which tries to re-initialize15// the column. Detect this and bail.16//17// If ThreadManager gets separated into a UI part and a thread part (which18// seems likely), responses may no longer ship back the entire column. This19// might let us remove this check.20if (statics.initialized) {21return;22} else {23statics.initialized = true;24}2526var userVisible = config.visible;27var userMinimize = config.minimize;28var show = null;29var loadThreadID = null;30var scrollbar = null;3132var margin = JX.Scrollbar.getScrollbarControlMargin();3334var quick = JX.$('phabricator-standard-page-body');3536function _getColumnNode() {37return JX.$('conpherence-durable-column');38}3940function _getColumnScrollNode() {41var column = _getColumnNode();42return JX.DOM.find(column, 'div', 'conpherence-durable-column-main');43}4445function _updateColumnVisibility() {46var new_value = (userVisible);47if (new_value !== show) {48show = new_value;49_drawColumn(show);50}51}5253function _toggleColumn() {54userVisible = !userVisible;55_updateColumnVisibility();5657new JX.Request(config.visibleURI)58.setData({value: (show ? 1 : 0)})59.send();60}6162function _minimizeColumn(e) {63e.kill();64userMinimize = !userMinimize;65JX.DOM.alterClass(document.body, 'minimize-column', userMinimize);66JX.Stratcom.invoke('resize');6768if (!userMinimize) {69var messages = _getColumnMessagesNode();70scrollbar.scrollTo(messages.scrollHeight);71}7273new JX.Request(config.minimizeURI)74.setData({value: (userMinimize ? 1 : 0)})75.send();76}7778function _drawColumn(visible) {79JX.DOM.alterClass(80document.body,81'with-durable-column',82visible);8384var column = _getColumnNode();85if (visible) {86JX.DOM.show(column);87threadManager.loadThreadByID(loadThreadID);88} else {89JX.DOM.hide(column);90}91JX.Quicksand.setFrame(visible ? quick : null);9293JX.Stratcom.invoke('resize');94}9596JX.Stratcom.listen(97'click',98'conpherence-persist-column',99_toggleColumn);100101JX.Stratcom.listen(102'click',103'conpherence-minimize-window',104_minimizeColumn);105106scrollbar = new JX.Scrollbar(_getColumnScrollNode());107108JX.Quicksand.setFrame(userVisible ? quick : null);109JX.Quicksand.start(config.quicksandConfig);110111/* Conpherence Thread Manager configuration - lots of display112* callbacks.113*/114115var threadManager = new JX.ConpherenceThreadManager();116threadManager.setMessagesRootCallback(function() {117return _getColumnMessagesNode();118});119threadManager.setLoadThreadURI('/conpherence/columnview/');120threadManager.setWillLoadThreadCallback(function() {121_markLoading(true);122});123threadManager.setDidLoadThreadCallback(function(r) {124var column = _getColumnNode();125var new_column = JX.$H(r.content);126JX.DOM.replace(column, new_column);127if (show) {128JX.DOM.show(_getColumnNode());129} else {130JX.DOM.hide(_getColumnNode());131}132var messages = _getColumnMessagesNode();133scrollbar = new JX.Scrollbar(_getColumnScrollNode());134scrollbar.scrollTo(messages.scrollHeight);135_markLoading(false);136loadThreadID = threadManager.getLoadedThreadID();137});138threadManager.setDidUpdateThreadCallback(function(r) {139var messages = _getColumnMessagesNode();140scrollbar.scrollTo(messages.scrollHeight);141});142143threadManager.setWillSendMessageCallback(function() {144// Wipe the textarea immediately so the user can start typing more text.145var textarea = _getColumnTextareaNode();146textarea.value = '';147_focusColumnTextareaNode();148});149150threadManager.setDidSendMessageCallback(function(r, non_update) {151if (non_update) {152return;153}154var messages = _getColumnMessagesNode();155scrollbar.scrollTo(messages.scrollHeight);156});157158threadManager.setWillUpdateWorkflowCallback(function() {159JX.Stratcom.invoke('notification-panel-close');160});161threadManager.setDidUpdateWorkflowCallback(function(r) {162var messages = _getColumnMessagesNode();163scrollbar.scrollTo(messages.scrollHeight);164JX.DOM.setContent(_getColumnTitleNode(), r.conpherence_title);165});166threadManager.start();167168JX.Stratcom.listen(169'click',170'conpherence-durable-column-header-action',171function (e) {172e.kill();173var data = e.getNodeData('conpherence-durable-column-header-action');174var action = data.action;175var link = e.getNode('tag:a');176var params = null;177178switch (action) {179case 'go_edit':180threadManager.runUpdateWorkflowFromLink(181link,182{183action: action,184force_ajax: true,185stage: 'submit'186});187break;188case 'add_person':189threadManager.runUpdateWorkflowFromLink(190link,191{192action: action,193stage: 'submit'194});195break;196case 'go_conpherence':197JX.$U(link.href).go();198break;199case 'hide_column':200JX.Stratcom.invoke('notification-panel-close');201_toggleColumn();202break;203}204});205206JX.Stratcom.listen(207'click',208'conpherence-durable-column-thread-icon',209function (e) {210e.kill();211var icons = JX.DOM.scry(212JX.$('conpherence-durable-column'),213'a',214'conpherence-durable-column-thread-icon');215var data = e.getNodeData('conpherence-durable-column-thread-icon');216var cdata = null;217for (var i = 0; i < icons.length; i++) {218cdata = JX.Stratcom.getData(icons[i]);219JX.DOM.alterClass(220icons[i],221'selected',222cdata.threadID == data.threadID);223}224JX.DOM.setContent(_getColumnTitleNode(), JX.$H(data.threadTitle));225threadManager.loadThreadByID(data.threadID);226});227228JX.Stratcom.listen('resize', null, _updateColumnVisibility);229230function _getColumnBodyNode() {231var column = JX.$('conpherence-durable-column');232return JX.DOM.find(233column,234'div',235'conpherence-durable-column-body');236}237238function _getColumnMessagesNode() {239var column = JX.$('conpherence-durable-column');240return JX.DOM.find(241column,242'div',243'conpherence-durable-column-transactions');244}245246function _getColumnTitleNode() {247var column = JX.$('conpherence-durable-column');248return JX.DOM.find(249column,250'div',251'conpherence-durable-column-header-text');252}253254function _getColumnFormNode() {255var column = JX.$('conpherence-durable-column');256return JX.DOM.find(257column,258'form',259'conpherence-message-form');260}261262function _getColumnTextareaNode() {263var column = JX.$('conpherence-durable-column');264return JX.DOM.find(265column,266'textarea',267'conpherence-durable-column-textarea');268}269270function _focusColumnTextareaNode() {271var textarea = _getColumnTextareaNode();272setTimeout(function() { JX.DOM.focus(textarea); }, 1);273}274275function _markLoading(loading) {276var column = _getColumnNode();277JX.DOM.alterClass(column, 'loading', loading);278}279280function _sendMessage(e) {281e.kill();282var form = _getColumnFormNode();283threadManager.sendMessage(form, {});284}285286JX.Stratcom.listen(287'click',288'conpherence-send-message',289_sendMessage);290291JX.Stratcom.listen(292['submit', 'didSyntheticSubmit'],293'conpherence-message-form',294_sendMessage);295296// Send on enter if the shift key is not held.297JX.Stratcom.listen(298'keydown',299'conpherence-message-form',300function(e) {301if (e.getSpecialKey() != 'return') {302return;303}304305var raw = e.getRawEvent();306if (raw.shiftKey) {307// If the shift key is pressed, let the browser write a newline into308// the textarea.309return;310}311312// From here on, interpret this as a "send" action, not a literal313// newline.314e.kill();315316_sendMessage(e);317});318319JX.Stratcom.listen(320['keydown'],321'conpherence-durable-column-textarea',322function (e) {323threadManager.handleDraftKeydown(e);324});325326// HTML5 placeholders are rendered as long as the input is empty, even if the327// input is currently focused. This is undesirable for the chat input,328// especially immediately after sending a message. Hide the placeholder while329// the input is focused.330JX.Stratcom.listen(331['focus', 'blur'],332'conpherence-durable-column-textarea',333function (e) {334var node = e.getTarget();335if (e.getType() == 'focus') {336if (node.placeholder) {337node.placeholderStorage = node.placeholder;338node.placeholder = '';339}340} else {341if (node.placeholderStorage) {342node.placeholder = node.placeholderStorage;343node.placeholderStorage = '';344}345}346});347348JX.Stratcom.listen(349'quicksand-redraw',350null,351function (e) {352var new_data = e.getData().newResponse;353var new_classes = new_data.bodyClasses;354if (userMinimize) {355new_classes = new_classes + ' minimize-column';356}357document.body.className = new_classes;358JX.Title.setTitle(new_data.title);359});360361_updateColumnVisibility();362363});364365366