Add multiple notifications and notification types
Summary: - Allow more than one notification to be shown. - Allow notifications to be customized with extra classes. Test Plan: {F12776} Reviewers: allenjohnashton, ddfisher, keebuhm, jungejason Reviewed By: jungejason CC: aran Maniphest Tasks: T944 Differential Revision: https://secure.phabricator.com/D2758
This commit is contained in:
parent
513abf00cf
commit
1053a50f67
|
@ -1355,13 +1355,14 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'javelin-behavior-phabricator-notification-example' =>
|
'javelin-behavior-phabricator-notification-example' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/0b8fadf5/rsrc/js/application/uiexample/notification-example.js',
|
'uri' => '/res/df97e4b3/rsrc/js/application/uiexample/notification-example.js',
|
||||||
'type' => 'js',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
0 => 'phabricator-notification',
|
0 => 'phabricator-notification',
|
||||||
1 => 'javelin-stratcom',
|
1 => 'javelin-stratcom',
|
||||||
2 => 'javelin-behavior',
|
2 => 'javelin-behavior',
|
||||||
|
3 => 'javelin-uri',
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/uiexample/notification-example.js',
|
'disk' => '/rsrc/js/application/uiexample/notification-example.js',
|
||||||
),
|
),
|
||||||
|
@ -2181,19 +2182,20 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'phabricator-notification' =>
|
'phabricator-notification' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/253b3262/rsrc/js/application/core/Notification.js',
|
'uri' => '/res/cacd79f1/rsrc/js/application/core/Notification.js',
|
||||||
'type' => 'js',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-install',
|
0 => 'javelin-install',
|
||||||
1 => 'javelin-dom',
|
1 => 'javelin-dom',
|
||||||
2 => 'javelin-stratcom',
|
2 => 'javelin-stratcom',
|
||||||
|
3 => 'javelin-util',
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/core/Notification.js',
|
'disk' => '/rsrc/js/application/core/Notification.js',
|
||||||
),
|
),
|
||||||
'phabricator-notification-css' =>
|
'phabricator-notification-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/423a14d1/rsrc/css/aphront/notification.css',
|
'uri' => '/res/7452322a/rsrc/css/aphront/notification.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
bottom: 24px;
|
bottom: 24px;
|
||||||
left: 24px;
|
left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jx-notification {
|
||||||
width: 240px;
|
width: 240px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
|
|
||||||
|
@ -21,4 +24,10 @@
|
||||||
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.25);
|
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.25);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jx-notification-alert {
|
||||||
|
background: #ffffa0;
|
||||||
|
border: 1px solid #aaaa60;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* @requires javelin-install
|
* @requires javelin-install
|
||||||
* javelin-dom
|
* javelin-dom
|
||||||
* javelin-stratcom
|
* javelin-stratcom
|
||||||
|
* javelin-util
|
||||||
* @provides phabricator-notification
|
* @provides phabricator-notification
|
||||||
* @javelin
|
* @javelin
|
||||||
*/
|
*/
|
||||||
|
@ -22,29 +23,37 @@ JX.install('Notification', {
|
||||||
members : {
|
members : {
|
||||||
show : function() {
|
show : function() {
|
||||||
var self = JX.Notification;
|
var self = JX.Notification;
|
||||||
|
self._show(this);
|
||||||
|
|
||||||
self.close();
|
if (this.getDuration()) {
|
||||||
self._installListener();
|
setTimeout(JX.bind(self, self._hide, this), this.getDuration());
|
||||||
self._active = this;
|
}
|
||||||
|
},
|
||||||
var container = JX.$N(
|
_render : function() {
|
||||||
|
return JX.$N(
|
||||||
'div',
|
'div',
|
||||||
{
|
{
|
||||||
className: 'jx-notification-container',
|
className: 'jx-notification ' + this.getClassName(),
|
||||||
sigil: 'jx-notification'
|
sigil: 'jx-notification'
|
||||||
},
|
},
|
||||||
this.getContent());
|
this.getContent());
|
||||||
document.body.appendChild(container);
|
|
||||||
|
|
||||||
self._container = container;
|
|
||||||
|
|
||||||
if (this.getDuration()) {
|
|
||||||
self._timeout = setTimeout(self.close, this.getDuration());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
properties : {
|
properties : {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional class name(s) to add to the rendered notification.
|
||||||
|
*
|
||||||
|
* @param string Class name(s).
|
||||||
|
*/
|
||||||
|
className : null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification content.
|
||||||
|
*
|
||||||
|
* @param mixed Content.
|
||||||
|
*/
|
||||||
content : null,
|
content : null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,12 +63,42 @@ JX.install('Notification', {
|
||||||
* @param int Notification duration, in milliseconds.
|
* @param int Notification duration, in milliseconds.
|
||||||
*/
|
*/
|
||||||
duration : 12000
|
duration : 12000
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
statics : {
|
statics : {
|
||||||
_container : null,
|
_container : null,
|
||||||
_listening : false,
|
_listening : false,
|
||||||
_active : null,
|
_active : [],
|
||||||
|
_show : function(notification) {
|
||||||
|
var self = JX.Notification;
|
||||||
|
|
||||||
|
self._installListener();
|
||||||
|
self._active.push({
|
||||||
|
object: notification,
|
||||||
|
render: notification._render()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Don't show more than a few notifications at once because it's silly.
|
||||||
|
while (self._active.length > 5) {
|
||||||
|
self._hide(self._active[0].object);
|
||||||
|
}
|
||||||
|
|
||||||
|
self._redraw();
|
||||||
|
},
|
||||||
|
_hide : function(notification) {
|
||||||
|
var self = JX.Notification;
|
||||||
|
|
||||||
|
for (var ii = 0; ii < self._active.length; ii++) {
|
||||||
|
if (self._active[ii].object === notification) {
|
||||||
|
notification.invoke('close');
|
||||||
|
self._active.splice(ii, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self._redraw();
|
||||||
|
},
|
||||||
_installListener : function() {
|
_installListener : function() {
|
||||||
var self = JX.Notification;
|
var self = JX.Notification;
|
||||||
|
|
||||||
|
@ -78,27 +117,46 @@ JX.install('Notification', {
|
||||||
// the activate event for the active notification and dismiss it if it
|
// the activate event for the active notification and dismiss it if it
|
||||||
// isn't handled.
|
// isn't handled.
|
||||||
|
|
||||||
var activation = self._active.invoke('activate');
|
var target = e.getNode('jx-notification');
|
||||||
if (activation.getPrevented()) {
|
for (var ii = 0; ii < self._active.length; ii++) {
|
||||||
|
var n = self._active[ii];
|
||||||
|
if (n.render === target) {
|
||||||
|
var activation = n.object.invoke('activate');
|
||||||
|
if (!activation.getPrevented()) {
|
||||||
|
self._hide(n.object);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.close();
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
close : function() {
|
_redraw : function() {
|
||||||
var self = JX.Notification;
|
var self = JX.Notification;
|
||||||
|
|
||||||
|
if (!self._active.length) {
|
||||||
if (self._container) {
|
if (self._container) {
|
||||||
JX.DOM.remove(self._container);
|
JX.DOM.remove(self._container);
|
||||||
self._container = null;
|
self._container = null;
|
||||||
|
}
|
||||||
self._active.invoke('close');
|
return;
|
||||||
self._active = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self._timeout && clearTimeout(self._timeout);
|
if (!self._container) {
|
||||||
self._timeout = null;
|
self._container = JX.$N(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
className: 'jx-notification-container'
|
||||||
|
});
|
||||||
|
document.body.appendChild(self._container);
|
||||||
|
}
|
||||||
|
|
||||||
|
var notifications = [];
|
||||||
|
for (var ii = 0; ii < self._active.length; ii++) {
|
||||||
|
notifications.push(self._active[ii].render);
|
||||||
|
}
|
||||||
|
|
||||||
|
JX.DOM.setContent(self._container, notifications);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* @requires phabricator-notification
|
* @requires phabricator-notification
|
||||||
* javelin-stratcom
|
* javelin-stratcom
|
||||||
* javelin-behavior
|
* javelin-behavior
|
||||||
|
* javelin-uri
|
||||||
* @provides javelin-behavior-phabricator-notification-example
|
* @provides javelin-behavior-phabricator-notification-example
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -12,8 +13,9 @@ JX.behavior('phabricator-notification-example', function(config) {
|
||||||
function(e) {
|
function(e) {
|
||||||
e.kill();
|
e.kill();
|
||||||
|
|
||||||
var notification = new JX.Notification()
|
var notification = new JX.Notification();
|
||||||
.setContent('It is ' + new Date().toString());
|
if (Math.random() > 0.1) {
|
||||||
|
notification.setContent('It is ' + new Date().toString());
|
||||||
|
|
||||||
notification.listen(
|
notification.listen(
|
||||||
'activate',
|
'activate',
|
||||||
|
@ -22,7 +24,18 @@ JX.behavior('phabricator-notification-example', function(config) {
|
||||||
e.kill();
|
e.kill();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
notification
|
||||||
|
.setContent('Alert! Click to reload!')
|
||||||
|
.setDuration(0)
|
||||||
|
.setClassName('jx-notification-alert');
|
||||||
|
|
||||||
|
notification.listen(
|
||||||
|
'activate',
|
||||||
|
function(e) {
|
||||||
|
new JX.$U().go();
|
||||||
|
});
|
||||||
|
}
|
||||||
notification.show()
|
notification.show()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue