mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 17:02:41 +01:00
688c506ecf
Summary: Fixes T7724. Things are a bit tricky here as sometimes we don't want to display the help icon at all...! Change things such that we always render at least the icon, though it may have the style set to hidden if appropriate. Instrument quicksand javascript to then load the proper help dropdown if it can. Do this generally so other aphlict dropdowns could work pretty easily. Test Plan: started on home and noted no help. clicked maniphest and saw maniphest help. clicked home and saw no help again. clicked differential and saw differential help. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7724 Differential Revision: https://secure.phabricator.com/D12499
223 lines
5.5 KiB
JavaScript
223 lines
5.5 KiB
JavaScript
/**
|
|
* @provides javelin-behavior-aphlict-dropdown
|
|
* @requires javelin-behavior
|
|
* javelin-request
|
|
* javelin-stratcom
|
|
* javelin-vector
|
|
* javelin-dom
|
|
* javelin-uri
|
|
* javelin-behavior-device
|
|
* phabricator-title
|
|
*/
|
|
|
|
JX.behavior('aphlict-dropdown', function(config, statics) {
|
|
// Track the current globally visible menu.
|
|
statics.visible = statics.visible || null;
|
|
|
|
var dropdown = JX.$(config.dropdownID);
|
|
var bubble = JX.$(config.bubbleID);
|
|
var icon = JX.DOM.scry(bubble, 'span', 'menu-icon')[0];
|
|
|
|
var count;
|
|
if (config.countID) {
|
|
count = JX.$(config.countID);
|
|
}
|
|
|
|
var request = null;
|
|
var dirty = config.local ? false : true;
|
|
|
|
JX.Title.setCount(config.countType, config.countNumber);
|
|
|
|
function _updateCount(number) {
|
|
JX.Title.setCount(config.countType, number);
|
|
|
|
JX.DOM.setContent(count, number);
|
|
if (number === 0) {
|
|
JX.DOM.alterClass(bubble, config.unreadClass, false);
|
|
} else {
|
|
JX.DOM.alterClass(bubble, config.unreadClass, true);
|
|
}
|
|
}
|
|
|
|
function refresh() {
|
|
if (dirty) {
|
|
JX.DOM.setContent(dropdown, config.loadingText);
|
|
JX.DOM.alterClass(
|
|
dropdown,
|
|
'phabricator-notification-menu-loading',
|
|
true);
|
|
}
|
|
|
|
if (request) {
|
|
// Already fetching.
|
|
return;
|
|
}
|
|
|
|
request = new JX.Request(config.uri, function(response) {
|
|
var number = response.number;
|
|
_updateCount(number);
|
|
dirty = false;
|
|
JX.DOM.alterClass(
|
|
dropdown,
|
|
'phabricator-notification-menu-loading',
|
|
false);
|
|
JX.DOM.setContent(dropdown, JX.$H(response.content));
|
|
request = null;
|
|
});
|
|
request.send();
|
|
}
|
|
|
|
JX.Stratcom.listen(
|
|
'quicksand-redraw',
|
|
null,
|
|
function (e) {
|
|
var data = e.getData();
|
|
if (config.local && config.applicationClass) {
|
|
var local_dropdowns = data.newResponse.aphlictDropdowns;
|
|
if (local_dropdowns[config.applicationClass]) {
|
|
JX.DOM.replace(
|
|
dropdown,
|
|
JX.$H(local_dropdowns[config.applicationClass]));
|
|
dropdown = JX.$(config.dropdownID);
|
|
if (dropdown.childNodes.length === 0) {
|
|
JX.DOM.hide(bubble);
|
|
} else {
|
|
JX.DOM.show(bubble);
|
|
}
|
|
} else {
|
|
JX.DOM.hide(bubble);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!data.fromServer) {
|
|
return;
|
|
}
|
|
var updated = false;
|
|
var new_data = data.newResponse.aphlictDropdownData;
|
|
for (var ii = 0; ii < new_data.length; ii++) {
|
|
if (new_data[ii].countType != config.countType) {
|
|
continue;
|
|
}
|
|
if (!new_data[ii].isInstalled) {
|
|
continue;
|
|
}
|
|
updated = true;
|
|
_updateCount(parseInt(new_data[ii].count));
|
|
}
|
|
if (updated) {
|
|
dirty = true;
|
|
}
|
|
});
|
|
|
|
function set_visible(menu, icon) {
|
|
if (menu) {
|
|
statics.visible = {menu: menu, icon: icon};
|
|
if (icon) {
|
|
JX.DOM.alterClass(icon, 'white', true);
|
|
}
|
|
} else {
|
|
if (statics.visible) {
|
|
JX.DOM.hide(statics.visible.menu);
|
|
if (statics.visible.icon) {
|
|
JX.DOM.alterClass(statics.visible.icon, 'white', false);
|
|
}
|
|
}
|
|
statics.visible = null;
|
|
}
|
|
}
|
|
|
|
JX.Stratcom.listen(
|
|
'click',
|
|
null,
|
|
function(e) {
|
|
if (!e.getNode('phabricator-notification-menu')) {
|
|
// Click outside the dropdown; hide it.
|
|
set_visible(null);
|
|
return;
|
|
}
|
|
|
|
if (e.getNode('tag:a')) {
|
|
// User clicked a link, just follow the link.
|
|
return;
|
|
}
|
|
|
|
if (!e.getNode('notification')) {
|
|
// User clicked somewhere in the dead area of the menu, like the header
|
|
// or footer.
|
|
return;
|
|
}
|
|
|
|
// If the user clicked a notification (but missed a link) and it has a
|
|
// primary URI, go there.
|
|
var href = e.getNodeData('notification').href;
|
|
if (href) {
|
|
JX.$U(href).go();
|
|
e.kill();
|
|
}
|
|
});
|
|
|
|
JX.DOM.listen(
|
|
bubble,
|
|
'click',
|
|
null,
|
|
function(e) {
|
|
if (!e.isNormalClick()) {
|
|
return;
|
|
}
|
|
|
|
if (config.desktop && JX.Device.getDevice() != 'desktop') {
|
|
return;
|
|
}
|
|
|
|
e.kill();
|
|
|
|
// If a menu is currently open, close it.
|
|
if (statics.visible) {
|
|
var previously_visible = statics.visible;
|
|
set_visible(null);
|
|
|
|
// If the menu we just closed was the menu attached to the clicked
|
|
// icon, we're all done -- clicking the icon for an open menu just
|
|
// closes it. Otherwise, we closed some other menu and still need to
|
|
// open the one the user just clicked.
|
|
if (previously_visible.menu === dropdown) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dirty) {
|
|
refresh();
|
|
}
|
|
|
|
var p = JX.$V(bubble);
|
|
JX.DOM.show(dropdown);
|
|
|
|
p.y = null;
|
|
if (config.containerDivID) {
|
|
var pc = JX.$V(JX.$(config.containerDivID));
|
|
p.x -= (JX.Vector.getDim(dropdown).x - JX.Vector.getDim(bubble).x +
|
|
pc.x);
|
|
} else if (config.right) {
|
|
p.x -= (JX.Vector.getDim(dropdown).x - JX.Vector.getDim(bubble).x);
|
|
} else {
|
|
p.x -= 6;
|
|
}
|
|
p.setPos(dropdown);
|
|
|
|
set_visible(dropdown, icon);
|
|
}
|
|
);
|
|
|
|
JX.Stratcom.listen('notification-panel-update', null, function() {
|
|
if (config.local) {
|
|
return;
|
|
}
|
|
dirty = true;
|
|
refresh();
|
|
});
|
|
|
|
JX.Stratcom.listen('notification-panel-close', null, function() {
|
|
set_visible(null);
|
|
});
|
|
});
|