diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,8 +9,8 @@ 'names' => array( 'conpherence.pkg.css' => 'ff161f2d', 'conpherence.pkg.js' => 'b5b51108', - 'core.pkg.css' => 'ab24402f', - 'core.pkg.js' => '5d80e0db', + 'core.pkg.css' => '2abc4421', + 'core.pkg.js' => '24e21794', 'darkconsole.pkg.js' => '1f9a31bc', 'differential.pkg.css' => '4ec4a37a', 'differential.pkg.js' => 'd4ab0e81', @@ -40,7 +40,7 @@ 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', 'rsrc/css/application/auth/auth.css' => '0877ed6e', 'rsrc/css/application/base/main-menu-view.css' => '16053029', - 'rsrc/css/application/base/notification-menu.css' => '6a697e43', + 'rsrc/css/application/base/notification-menu.css' => '5497b55e', 'rsrc/css/application/base/phui-theme.css' => '9f261c6b', 'rsrc/css/application/base/standard-page-view.css' => 'eb5b80c5', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', @@ -373,7 +373,7 @@ 'rsrc/image/texture/table_header_hover.png' => '038ec3b9', 'rsrc/image/texture/table_header_tall.png' => 'd56b434f', 'rsrc/js/application/aphlict/Aphlict.js' => 'e1d4b11a', - 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'caade6f2', + 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '648e7d00', 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '3c547a81', 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => '5e2634b9', 'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'd5a2d665', @@ -584,7 +584,7 @@ 'inline-comment-summary-css' => '51efda3a', 'javelin-aphlict' => 'e1d4b11a', 'javelin-behavior' => '61cbc29a', - 'javelin-behavior-aphlict-dropdown' => 'caade6f2', + 'javelin-behavior-aphlict-dropdown' => '648e7d00', 'javelin-behavior-aphlict-listen' => '3c547a81', 'javelin-behavior-aphlict-status' => '5e2634b9', 'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884', @@ -791,7 +791,7 @@ 'phabricator-nav-view-css' => 'faf6a6fc', 'phabricator-notification' => 'ccf1cbf8', 'phabricator-notification-css' => '3f6c89c9', - 'phabricator-notification-menu-css' => '6a697e43', + 'phabricator-notification-menu-css' => '5497b55e', 'phabricator-object-selector-css' => '85ee8ce6', 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => 'c5af80a2', @@ -1375,6 +1375,17 @@ 'javelin-workflow', 'javelin-dom', ), + '648e7d00' => array( + 'javelin-behavior', + 'javelin-request', + 'javelin-stratcom', + 'javelin-vector', + 'javelin-dom', + 'javelin-uri', + 'javelin-behavior-device', + 'phabricator-title', + 'phabricator-favicon', + ), '680ea2c8' => array( 'javelin-install', 'javelin-dom', @@ -1943,17 +1954,6 @@ 'phabricator-shaped-request', 'conpherence-thread-manager', ), - 'caade6f2' => array( - 'javelin-behavior', - 'javelin-request', - 'javelin-stratcom', - 'javelin-vector', - 'javelin-dom', - 'javelin-uri', - 'javelin-behavior-device', - 'phabricator-title', - 'phabricator-favicon', - ), 'cae95e89' => array( 'syntax-default-css', ), diff --git a/src/applications/notification/controller/PhabricatorNotificationClearController.php b/src/applications/notification/controller/PhabricatorNotificationClearController.php --- a/src/applications/notification/controller/PhabricatorNotificationClearController.php +++ b/src/applications/notification/controller/PhabricatorNotificationClearController.php @@ -6,52 +6,28 @@ public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $chrono_key = $request->getStr('chronoKey'); + $redirect = $request->getBool('redirect'); - if ($request->isDialogFormPost()) { - $table = new PhabricatorFeedStoryNotification(); + $table = new PhabricatorFeedStoryNotification(); - queryfx( - $table->establishConnection('w'), - 'UPDATE %T SET hasViewed = 1 '. - 'WHERE userPHID = %s AND hasViewed = 0 and chronologicalKey <= %s', - $table->getTableName(), - $viewer->getPHID(), - $chrono_key); + queryfx( + $table->establishConnection('w'), + 'UPDATE %T SET hasViewed = 1 '. + 'WHERE userPHID = %s AND hasViewed = 0 and chronologicalKey <= %s', + $table->getTableName(), + $viewer->getPHID(), + $chrono_key); - PhabricatorUserCache::clearCache( - PhabricatorUserNotificationCountCacheType::KEY_COUNT, - $viewer->getPHID()); + PhabricatorUserCache::clearCache( + PhabricatorUserNotificationCountCacheType::KEY_COUNT, + $viewer->getPHID()); + // Redirect back to page if on ApplicationSearch + if ($redirect) { return id(new AphrontReloadResponse()) ->setURI('/notification/'); } - $dialog = new AphrontDialogView(); - $dialog->setUser($viewer); - $dialog->addCancelButton('/notification/'); - if ($chrono_key) { - $dialog->setTitle(pht('Really mark all notifications as read?')); - $dialog->addHiddenInput('chronoKey', $chrono_key); - - $is_serious = - PhabricatorEnv::getEnvConfig('phabricator.serious-business'); - if ($is_serious) { - $dialog->appendChild( - pht( - 'All unread notifications will be marked as read. You can not '. - 'undo this action.')); - } else { - $dialog->appendChild( - pht( - "You can't ignore your problems forever, you know.")); - } - - $dialog->addSubmitButton(pht('Mark All Read')); - } else { - $dialog->setTitle(pht('No notifications to mark as read.')); - $dialog->appendChild(pht('You have no unread notifications.')); - } - - return id(new AphrontDialogResponse())->setDialog($dialog); + return id(new AphrontAjaxResponse())->setContent(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 @@ -14,28 +14,29 @@ $stories = $query->execute(); $clear_ui_class = 'phabricator-notification-clear-all'; - $clear_uri = id(new PhutilURI('/notification/clear/')); + $clear_ui = null; if ($stories) { $builder = id(new PhabricatorNotificationBuilder($stories)) ->setUser($viewer); - $notifications_view = $builder->buildView(); $content = $notifications_view->render(); - $clear_uri->setQueryParam( - 'chronoKey', - head($stories)->getChronologicalKey()); + } else { $content = phutil_tag_div( 'phabricator-notification no-notifications', pht('You have no notifications.')); $clear_ui_class .= ' disabled'; } - $clear_ui = javelin_tag( - 'a', + + $chrono_key = head($stories)->getChronologicalKey(); + $clear_ui = phabricator_form( + $viewer, array( - 'sigil' => 'workflow', - 'href' => (string)$clear_uri, + 'method' => 'POST', + 'action' => '/notification/clear/?chronoKey='.$chrono_key, + 'sigil' => 'notifications-clear-all-form', 'class' => $clear_ui_class, + 'id' => 'notifications-mark-read', ), pht('Mark All Read')); diff --git a/src/applications/notification/query/PhabricatorNotificationSearchEngine.php b/src/applications/notification/query/PhabricatorNotificationSearchEngine.php --- a/src/applications/notification/query/PhabricatorNotificationSearchEngine.php +++ b/src/applications/notification/query/PhabricatorNotificationSearchEngine.php @@ -107,6 +107,7 @@ $clear_uri = id(new PhutilURI('/notification/clear/')); if ($notifications) { + $chrono_key = head($notifications)->getChronologicalKey(); $builder = id(new PhabricatorNotificationBuilder($notifications)) ->setUser($viewer); @@ -114,6 +115,9 @@ $clear_uri->setQueryParam( 'chronoKey', head($notifications)->getChronologicalKey()); + $clear_uri->setQueryParam( + 'redirect', + true); } else { $view = phutil_tag_div( 'phabricator-notification no-notifications', 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 @@ -100,6 +100,15 @@ color: {$anchor}; float: right; font-weight: normal; + cursor: pointer; +} + +.phabricator-notification-header .phabricator-notification-clear-all.disabled { + color: {$greytext}; +} + +.phabricator-notification-header .phabricator-notification-clear-all:hover { + text-decoration: underline; } .phabricator-notification-footer { 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 @@ -20,6 +20,7 @@ var icon = JX.DOM.scry(bubble, 'span', 'menu-icon')[0]; var favicon = config.favicon; var message_favicon = config.message_favicon; + var count_type = config.countType; var count; if (config.countID) { @@ -30,25 +31,21 @@ var dirty = config.local ? false : true; function _updateFavicon(new_count) { - if ((config.countType == 'messages') && (new_count)) { + if ((count_type == 'messages') && (new_count)) { JX.Favicon.setFavicon(message_favicon); - } else if (config.countType == 'messages') { + } else if (count_type == 'messages') { JX.Favicon.setFavicon(favicon); } } - if (config.countType) { - JX.Title.setCount(config.countType, config.countNumber); + if (count_type) { + JX.Title.setCount(count_type, config.countNumber); _updateFavicon(config.countNumber); } - function _updateCount(number) { - if (config.countType) { - JX.Title.setCount(config.countType, number); - _updateFavicon(number); - } else { - return; - } + function _updateCount(number, type) { + JX.Title.setCount(type, number); + _updateFavicon(number); JX.DOM.setContent(count, number); if (number === 0) { @@ -74,7 +71,7 @@ request = new JX.Request(config.uri, function(response) { var number = response.number; - _updateCount(number); + _updateCount(number, count_type); dirty = false; JX.DOM.alterClass( dropdown, @@ -108,14 +105,14 @@ function update_counts(new_data) { var updated = false; for (var ii = 0; ii < new_data.length; ii++) { - if (new_data[ii].countType != config.countType) { + if (new_data[ii].countType != count_type) { continue; } if (!new_data[ii].isInstalled) { continue; } updated = true; - _updateCount(parseInt(new_data[ii].count)); + _updateCount(parseInt(new_data[ii].count), count_type); } if (updated) { dirty = true; @@ -234,4 +231,21 @@ JX.Stratcom.listen('notification-panel-close', null, function() { set_visible(null); }); + + function _clearAllNotifications(e) { + e.kill(); + count_type = 'notifications'; + _updateCount(0, count_type); + var form = e.getNode('tag:form'); + new JX.Request(form.getAttribute('action')).send(); + dirty = true; + refresh(); + } + + JX.Stratcom.listen( + 'click', + 'notifications-clear-all-form', + _clearAllNotifications); + + });