Path: blob/master/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
12242 views
/**1* @provides javelin-behavior-aphlict-dropdown2* @requires javelin-behavior3* javelin-request4* javelin-stratcom5* javelin-vector6* javelin-dom7* javelin-uri8* javelin-behavior-device9* phabricator-title10* phabricator-favicon11*/1213JX.behavior('aphlict-dropdown', function(config, statics) {14// Track the current globally visible menu.15statics.visible = statics.visible || null;1617var dropdown = JX.$(config.dropdownID);18var bubble = JX.$(config.bubbleID);19var icon = JX.DOM.scry(bubble, 'span', 'menu-icon')[0];20var favicon = config.favicon;21var message_favicon = config.message_favicon;2223var count;24if (config.countID) {25count = JX.$(config.countID);26}2728var request = null;29var dirty = config.local ? false : true;3031function _updateFavicon(new_count) {32if ((config.countType == 'messages') && (new_count)) {33JX.Favicon.setFavicon(message_favicon);34} else if (config.countType == 'messages') {35JX.Favicon.setFavicon(favicon);36}37}3839if (config.countType) {40JX.Title.setCount(config.countType, config.countNumber);41_updateFavicon(config.countNumber);42}4344function _updateCount(number) {45if (config.countType) {46JX.Title.setCount(config.countType, number);47_updateFavicon(number);48} else {49return;50}5152JX.DOM.setContent(count, number);53if (number === 0) {54JX.DOM.alterClass(bubble, config.unreadClass, false);55} else {56JX.DOM.alterClass(bubble, config.unreadClass, true);57}58}5960function refresh() {61if (dirty) {62JX.DOM.setContent(dropdown, config.loadingText);63JX.DOM.alterClass(64dropdown,65'phabricator-notification-menu-loading',66true);67}6869if (request) {70// Already fetching.71return;72}7374request = new JX.Request(config.uri, function(response) {75var number = response.number;76_updateCount(number);77dirty = false;78JX.DOM.alterClass(79dropdown,80'phabricator-notification-menu-loading',81false);82JX.DOM.setContent(dropdown, JX.$H(response.content));83request = null;84});85request.send();86}8788JX.Stratcom.listen(89'quicksand-redraw',90null,91function (e) {92var data = e.getData();93if (!data.fromServer) {94return;95}96var new_data = data.newResponse.aphlictDropdownData;97update_counts(new_data);98});99100JX.Stratcom.listen(101'conpherence-redraw-aphlict',102null,103function (e) {104update_counts(e.getData());105});106107function update_counts(new_data) {108var updated = false;109for (var ii = 0; ii < new_data.length; ii++) {110if (new_data[ii].countType != config.countType) {111continue;112}113if (!new_data[ii].isInstalled) {114continue;115}116updated = true;117_updateCount(parseInt(new_data[ii].count));118}119if (updated) {120dirty = true;121}122}123124function set_visible(menu, icon) {125if (menu) {126statics.visible = {menu: menu, icon: icon};127if (icon) {128JX.DOM.alterClass(icon, 'menu-icon-selected', true);129}130} else {131if (statics.visible) {132JX.DOM.hide(statics.visible.menu);133if (statics.visible.icon) {134JX.DOM.alterClass(statics.visible.icon, 'menu-icon-selected', false);135}136}137statics.visible = null;138}139}140141JX.Stratcom.listen(142'click',143null,144function(e) {145if (!e.getNode('phabricator-notification-menu')) {146// Click outside the dropdown; hide it.147set_visible(null);148return;149}150151if (e.getNode('tag:a')) {152// User clicked a link. Hide the menu, then follow the link.153set_visible(null);154return;155}156157if (!e.getNode('notification')) {158// User clicked somewhere in the dead area of the menu, like the header159// or footer.160return;161}162163// If the user clicked a notification (but missed a link) and it has a164// primary URI, go there.165var href = e.getNodeData('notification').href;166if (href) {167JX.$U(href).go();168e.kill();169set_visible(null);170}171});172173JX.DOM.listen(174bubble,175'click',176null,177function(e) {178if (!e.isNormalClick()) {179return;180}181182if (config.desktop && JX.Device.getDevice() != 'desktop') {183return;184}185186e.kill();187188// If a menu is currently open, close it.189if (statics.visible) {190var previously_visible = statics.visible;191set_visible(null);192193// If the menu we just closed was the menu attached to the clicked194// icon, we're all done -- clicking the icon for an open menu just195// closes it. Otherwise, we closed some other menu and still need to196// open the one the user just clicked.197if (previously_visible.menu === dropdown) {198return;199}200}201202if (dirty) {203refresh();204}205206var p = JX.$V(bubble);207JX.DOM.show(dropdown);208209p.y = null;210if (config.containerDivID) {211var pc = JX.$V(JX.$(config.containerDivID));212p.x -= (JX.Vector.getDim(dropdown).x - JX.Vector.getDim(bubble).x +213pc.x);214} else if (config.right) {215p.x -= (JX.Vector.getDim(dropdown).x - JX.Vector.getDim(bubble).x);216} else {217p.x -= 6;218}219p.setPos(dropdown);220221set_visible(dropdown, icon);222}223);224225JX.Stratcom.listen('notification-panel-update', null, function() {226if (config.local) {227return;228}229dirty = true;230refresh();231});232233JX.Stratcom.listen('notification-panel-close', null, function() {234set_visible(null);235});236});237238239