Page MenuHomePhabricator

D9700.id23293.diff
No OneTemporary

D9700.id23293.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,8 +7,8 @@
return array(
'names' =>
array(
- 'core.pkg.css' => '22e4fc33',
- 'core.pkg.js' => 'f5ba2408',
+ 'core.pkg.css' => 'f9c94804',
+ 'core.pkg.js' => '8c184823',
'darkconsole.pkg.js' => 'df001cab',
'differential.pkg.css' => '4a93db37',
'differential.pkg.js' => 'd1443567',
@@ -37,7 +37,7 @@
'rsrc/css/aphront/typeahead.css' => 'a989b5b3',
'rsrc/css/application/auth/auth.css' => '1e655982',
'rsrc/css/application/base/main-menu-view.css' => 'aceca0e9',
- 'rsrc/css/application/base/notification-menu.css' => 'cbff1b94',
+ 'rsrc/css/application/base/notification-menu.css' => '8ae4a008',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '8b7e271d',
'rsrc/css/application/base/standard-page-view.css' => '517cdfb1',
'rsrc/css/application/chatlog/chatlog.css' => '852140ff',
@@ -346,9 +346,10 @@
'rsrc/image/texture/table_header.png' => '5c433037',
'rsrc/image/texture/table_header_hover.png' => '038ec3b9',
'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
- 'rsrc/js/application/aphlict/Aphlict.js' => 'da12704d',
- 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '862ea0fe',
+ 'rsrc/js/application/aphlict/Aphlict.js' => '4a07e8e3',
+ 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'f51afce0',
'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'a826c925',
+ 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => '58f7803f',
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de',
'rsrc/js/application/conpherence/behavior-menu.js' => 'f0a41b9f',
@@ -490,7 +491,7 @@
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
'rsrc/js/phuix/PHUIXActionView.js' => '6e8cefa4',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca',
- 'rsrc/swf/aphlict.swf' => 'ef64606d',
+ 'rsrc/swf/aphlict.swf' => 'e5a24c72',
),
'symbols' =>
array(
@@ -539,10 +540,11 @@
'herald-rule-editor' => '6c9e6fb8',
'herald-test-css' => '778b008e',
'inline-comment-summary-css' => '8cfd34e8',
- 'javelin-aphlict' => 'da12704d',
+ 'javelin-aphlict' => '4a07e8e3',
'javelin-behavior' => '8a3ed18b',
- 'javelin-behavior-aphlict-dropdown' => '862ea0fe',
+ 'javelin-behavior-aphlict-dropdown' => 'f51afce0',
'javelin-behavior-aphlict-listen' => 'a826c925',
+ 'javelin-behavior-aphlict-status' => '58f7803f',
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
'javelin-behavior-aphront-crop' => 'fa0f4fc2',
'javelin-behavior-aphront-drag-and-drop-textarea' => '92eb531d',
@@ -725,7 +727,7 @@
'phabricator-nav-view-css' => '9283c2df',
'phabricator-notification' => '0c6946e7',
'phabricator-notification-css' => 'ef2c9b34',
- 'phabricator-notification-menu-css' => 'cbff1b94',
+ 'phabricator-notification-menu-css' => '8ae4a008',
'phabricator-object-selector-css' => '029a133d',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '41ed7994',
@@ -1190,6 +1192,11 @@
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
+ '4a07e8e3' =>
+ array(
+ 0 => 'javelin-install',
+ 1 => 'javelin-util',
+ ),
'4d94d9c3' =>
array(
0 => 'javelin-behavior',
@@ -1235,6 +1242,13 @@
2 => 'javelin-vector',
3 => 'javelin-dom',
),
+ '58f7803f' =>
+ array(
+ 0 => 'javelin-behavior',
+ 1 => 'javelin-aphlict',
+ 2 => 'phabricator-phtize',
+ 3 => 'javelin-dom',
+ ),
'59b251eb' =>
array(
0 => 'javelin-behavior',
@@ -1477,16 +1491,6 @@
3 => 'javelin-workflow',
4 => 'javelin-stratcom',
),
- '862ea0fe' =>
- array(
- 0 => 'javelin-behavior',
- 1 => 'javelin-request',
- 2 => 'javelin-stratcom',
- 3 => 'javelin-vector',
- 4 => 'javelin-dom',
- 5 => 'javelin-uri',
- 6 => 'javelin-behavior-device',
- ),
'880fa5ac' =>
array(
0 => 'javelin-behavior',
@@ -1921,11 +1925,6 @@
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
- 'da12704d' =>
- array(
- 0 => 'javelin-install',
- 1 => 'javelin-util',
- ),
'dd7e8ef5' =>
array(
0 => 'javelin-behavior',
@@ -2038,6 +2037,16 @@
5 => 'phuix-action-view',
6 => 'javelin-workflow',
),
+ 'f51afce0' =>
+ array(
+ 0 => 'javelin-behavior',
+ 1 => 'javelin-request',
+ 2 => 'javelin-stratcom',
+ 3 => 'javelin-vector',
+ 4 => 'javelin-dom',
+ 5 => 'javelin-uri',
+ 6 => 'javelin-behavior-device',
+ ),
'f588412e' =>
array(
0 => 'javelin-behavior',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1803,6 +1803,7 @@
'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php',
'PhabricatorNotificationQuery' => 'applications/notification/PhabricatorNotificationQuery.php',
'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php',
+ 'PhabricatorNotificationStatusView' => 'applications/notification/view/PhabricatorNotificationStatusView.php',
'PhabricatorNotificationTestController' => 'applications/notification/controller/PhabricatorNotificationTestController.php',
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
'PhabricatorOAuthClientAuthorizationQuery' => 'applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php',
@@ -4631,6 +4632,7 @@
'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController',
+ 'PhabricatorNotificationStatusView' => 'AphrontTagView',
'PhabricatorNotificationTestController' => 'PhabricatorNotificationController',
'PhabricatorOAuthClientAuthorization' =>
array(
diff --git a/src/applications/notification/controller/PhabricatorNotificationPanelController.php b/src/applications/notification/controller/PhabricatorNotificationPanelController.php
--- a/src/applications/notification/controller/PhabricatorNotificationPanelController.php
+++ b/src/applications/notification/controller/PhabricatorNotificationPanelController.php
@@ -25,16 +25,31 @@
pht('You have no notifications.'));
}
+ $notifications_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => '/notification/',
+ ),
+ pht('Notifications'));
+
+ $connection_status = new PhabricatorNotificationStatusView();
+
+ $header = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-notification-header',
+ ),
+ array(
+ $connection_status,
+ $notifications_link,
+ ));
+
$content = hsprintf(
- '<div class="phabricator-notification-header">%s %s</div>'.
'%s'.
- '<div class="phabricator-notification-view-all">%s</div>',
- phutil_tag(
- 'a',
- array(
- 'href' => '/notification/',
- ),
- pht('Notifications')),
+ '%s'.
+ '<div class="phabricator-notification-view-all">%s %s %s</div>',
+ $header,
+ $content,
javelin_tag(
'a',
array(
@@ -43,7 +58,7 @@
'class' => 'phabricator-notification-clear-all'
),
pht('Mark All Read')),
- $content,
+ " \xC2\xB7 ",
phutil_tag(
'a',
array(
diff --git a/src/applications/notification/view/PhabricatorNotificationStatusView.php b/src/applications/notification/view/PhabricatorNotificationStatusView.php
new file mode 100644
--- /dev/null
+++ b/src/applications/notification/view/PhabricatorNotificationStatusView.php
@@ -0,0 +1,34 @@
+<?php
+
+final class PhabricatorNotificationStatusView extends AphrontTagView {
+
+ protected function getTagAttributes() {
+ if (!$this->getID()) {
+ $this->setID(celerity_generate_unique_node_id());
+ }
+
+ Javelin::initBehavior(
+ 'aphlict-status',
+ array(
+ 'nodeID' => $this->getID(),
+ 'pht' => array(
+ 'setup' => pht('Setting Up Client'),
+ 'start' => pht('Starting Client'),
+ 'ready' => pht('Ready to Connect'),
+ 'connecting' => pht('Connecting...'),
+ 'connected' => pht('Connected'),
+ 'error' => pht('Connection Error'),
+ 'client' => pht('Connected Locally'),
+
+ 'error.flash.xdomain' => pht(
+ 'Unable to connect to Flash Policy Server. Check that the '.
+ 'notification server is running and port 843 is not firewalled.'),
+ ),
+ ));
+
+ return array(
+ 'class' => 'aphlict-connection-status',
+ );
+ }
+
+}
diff --git a/support/aphlict/client/src/Aphlict.as b/support/aphlict/client/src/Aphlict.as
--- a/support/aphlict/client/src/Aphlict.as
+++ b/support/aphlict/client/src/Aphlict.as
@@ -42,10 +42,6 @@
this.externalInvoke('log', message);
}
- final protected function setStatus(status:String):void {
- this.externalInvoke('status', {type: status});
- }
-
}
}
diff --git a/support/aphlict/client/src/AphlictClient.as b/support/aphlict/client/src/AphlictClient.as
--- a/support/aphlict/client/src/AphlictClient.as
+++ b/support/aphlict/client/src/AphlictClient.as
@@ -41,6 +41,7 @@
UncaughtErrorEvent.UNCAUGHT_ERROR,
this.uncaughtErrorHandler);
+ ExternalInterface.marshallExceptions = true;
ExternalInterface.addCallback('connect', this.externalConnect);
this.setStatus('ready');
@@ -150,6 +151,10 @@
this.externalInvoke('receive', msg);
}
+ public function setStatus(status:String, code:String = null):void {
+ this.externalInvoke('status', {type: status, code: code});
+ }
+
}
}
diff --git a/support/aphlict/client/src/AphlictMaster.as b/support/aphlict/client/src/AphlictMaster.as
--- a/support/aphlict/client/src/AphlictMaster.as
+++ b/support/aphlict/client/src/AphlictMaster.as
@@ -48,6 +48,9 @@
private var socket:Socket;
private var readBuffer:ByteArray;
+ private var status:String;
+ private var statusCode:String;
+
public function AphlictMaster(server:String, port:Number) {
super();
@@ -75,6 +78,8 @@
if (!this.clients[client]) {
this.log('Registering client: ' + client);
this.clients[client] = new Date().getTime();
+
+ this.send.send(client, 'setStatus', this.status, this.statusCode);
}
}
@@ -106,6 +111,8 @@
}
private function connectToServer():void {
+ this.setStatusOnClients('connecting');
+
var socket:Socket = new Socket();
socket.addEventListener(Event.CONNECT, didConnectSocket);
@@ -124,7 +131,7 @@
}
private function didConnectSocket(event:Event):void {
- this.externalInvoke('connected');
+ this.setStatusOnClients('connected');
// Send subscriptions
var phids = new Array();
@@ -146,7 +153,15 @@
}
private function didSecurityErrorSocket(event:SecurityErrorEvent):void {
- this.externalInvoke('error', event.text);
+ var text = event.text;
+
+ // This is really gross but there doesn't seem to be anything else
+ // on the object which gives us an error code.
+ if (text.match(/^Error #2048/)) {
+ this.setStatusOnClients('error', 'error.flash.xdomain');
+ }
+
+ this.error(text);
}
public function subscribe(client:String, phids:Array):void {
@@ -280,6 +295,18 @@
}
}
+ private function setStatusOnClients(
+ status:String,
+ code:String = null):void {
+
+ this.status = status;
+ this.statusCode = code;
+
+ for (var client:String in this.clients) {
+ this.send.send(client, 'setStatus', status, code);
+ }
+ }
+
}
}
diff --git a/webroot/rsrc/css/application/base/notification-menu.css b/webroot/rsrc/css/application/base/notification-menu.css
--- a/webroot/rsrc/css/application/base/notification-menu.css
+++ b/webroot/rsrc/css/application/base/notification-menu.css
@@ -97,3 +97,17 @@
padding: 8px;
font-size: 12px;
}
+
+.phabricator-notification-menu .aphlict-connection-status {
+ float: right;
+ font-weight: normal;
+ color: {$lightgreytext};
+}
+
+.aphlict-connection-status .aphlict-connection-status-connected {
+ color: {$green};
+}
+
+.aphlict-connection-status .aphlict-connection-status-error {
+ color: {$red};
+}
diff --git a/webroot/rsrc/js/application/aphlict/Aphlict.js b/webroot/rsrc/js/application/aphlict/Aphlict.js
--- a/webroot/rsrc/js/application/aphlict/Aphlict.js
+++ b/webroot/rsrc/js/application/aphlict/Aphlict.js
@@ -28,7 +28,7 @@
construct: function(id, server, port, subscriptions) {
if (__DEV__) {
if (JX.Aphlict._instance) {
- JX.$E('Aphlict object is a singleton!');
+ JX.$E('Aphlict object is a singleton.');
}
}
@@ -36,17 +36,24 @@
this._server = server;
this._port = port;
this._subscriptions = subscriptions;
+ this._setStatus('setup');
JX.Aphlict._instance = this;
},
+ events: ['didChangeStatus'],
+
members: {
_id: null,
_server: null,
_port: null,
_subscriptions: null,
+ _status: null,
+ _statusCode: null,
start: function(node, uri) {
+ this._setStatus('start');
+
// NOTE: This is grotesque, but seems to work everywhere.
node.innerHTML =
'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">' +
@@ -72,6 +79,20 @@
this._server,
this._port,
this._subscriptions);
+ },
+
+ getStatus: function() {
+ return this._status;
+ },
+
+ getStatusCode: function() {
+ return this._statusCode;
+ },
+
+ _setStatus: function(status, code) {
+ this._status = status;
+ this._statusCode = code || null;
+ this.invoke('didChangeStatus');
}
},
@@ -98,6 +119,7 @@
}
if (type == 'status') {
+ client._setStatus(message.type, message.code);
switch (message.type) {
case 'ready':
client._didStartFlash();
diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
--- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
+++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
@@ -73,6 +73,12 @@
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;
diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-status.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-status.js
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-status.js
@@ -0,0 +1,47 @@
+/**
+ * @provides javelin-behavior-aphlict-status
+ * @requires javelin-behavior
+ * javelin-aphlict
+ * phabricator-phtize
+ * javelin-dom
+ * @javelin
+ */
+
+JX.behavior('aphlict-status', function(config) {
+ var pht = JX.phtize(config.pht);
+
+ function update() {
+ var client = JX.Aphlict.getInstance();
+ if (!client) {
+ return;
+ }
+
+ var node;
+ try {
+ node = JX.$(config.nodeID);
+ } catch (ignored) {
+ return;
+ }
+
+ var tip = null;
+ var status = client.getStatus();
+
+ if (status == 'error') {
+ tip = pht(client.getStatusCode());
+ }
+
+ var status_node = JX.$N(
+ 'span',
+ {
+ className: 'aphlict-connection-status-' + status,
+ sigil: tip ? 'has-tooltip' : null,
+ meta: tip ? {tip: tip, align: 'S', size: 300} : {}
+ },
+ pht(status));
+
+ JX.DOM.setContent(node, status_node);
+ }
+
+ JX.Aphlict.listen('didChangeStatus', update);
+ update();
+});
diff --git a/webroot/rsrc/swf/aphlict.swf b/webroot/rsrc/swf/aphlict.swf
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 0
Hc$@<O00001

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 11:28 PM (5 d, 11 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7226604
Default Alt Text
D9700.id23293.diff (16 KB)

Event Timeline