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 @@ -1759,6 +1759,7 @@ 'PhabricatorNotificationListController' => 'applications/notification/controller/PhabricatorNotificationListController.php', 'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php', 'PhabricatorNotificationQuery' => 'applications/notification/query/PhabricatorNotificationQuery.php', + 'PhabricatorNotificationSearchEngine' => 'applications/notification/query/PhabricatorNotificationSearchEngine.php', 'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php', 'PhabricatorNotificationStatusView' => 'applications/notification/view/PhabricatorNotificationStatusView.php', 'PhabricatorNotificationTestController' => 'applications/notification/controller/PhabricatorNotificationTestController.php', @@ -4591,6 +4592,7 @@ 'PhabricatorNotificationListController' => 'PhabricatorNotificationController', 'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController', 'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorNotificationSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController', 'PhabricatorNotificationStatusView' => 'AphrontTagView', 'PhabricatorNotificationTestController' => 'PhabricatorNotificationController', diff --git a/src/applications/notification/application/PhabricatorNotificationsApplication.php b/src/applications/notification/application/PhabricatorNotificationsApplication.php --- a/src/applications/notification/application/PhabricatorNotificationsApplication.php +++ b/src/applications/notification/application/PhabricatorNotificationsApplication.php @@ -17,7 +17,7 @@ public function getRoutes() { return array( '/notification/' => array( - '(?:(?Pall|unread)/)?' + '(?:query/(?P[^/]+)/)?' => 'PhabricatorNotificationListController', 'panel/' => 'PhabricatorNotificationPanelController', 'individual/' => 'PhabricatorNotificationIndividualController', diff --git a/src/applications/notification/controller/PhabricatorNotificationIndividualController.php b/src/applications/notification/controller/PhabricatorNotificationIndividualController.php --- a/src/applications/notification/controller/PhabricatorNotificationIndividualController.php +++ b/src/applications/notification/controller/PhabricatorNotificationIndividualController.php @@ -9,7 +9,7 @@ $stories = id(new PhabricatorNotificationQuery()) ->setViewer($user) - ->setUserPHID($user->getPHID()) + ->withUserPHIDs(array($user->getPHID())) ->withKeys(array($request->getStr('key'))) ->execute(); diff --git a/src/applications/notification/controller/PhabricatorNotificationListController.php b/src/applications/notification/controller/PhabricatorNotificationListController.php --- a/src/applications/notification/controller/PhabricatorNotificationListController.php +++ b/src/applications/notification/controller/PhabricatorNotificationListController.php @@ -3,89 +3,34 @@ final class PhabricatorNotificationListController extends PhabricatorNotificationController { - private $filter; + private $queryKey; public function willProcessRequest(array $data) { - $this->filter = idx($data, 'filter'); + $this->queryKey = idx($data, 'queryKey'); } public function processRequest() { $request = $this->getRequest(); - $user = $request->getUser(); + $controller = id(new PhabricatorApplicationSearchController($request)) + ->setQueryKey($this->queryKey) + ->setSearchEngine(new PhabricatorNotificationSearchEngine()) + ->setNavigation($this->buildSideNavView()); - $nav = new AphrontSideNavFilterView(); - $nav->setBaseURI(new PhutilURI('/notification/')); - $nav->addFilter('all', pht('All Notifications')); - $nav->addFilter('unread', pht('Unread Notifications')); - $filter = $nav->selectFilter($this->filter, 'all'); - - $pager = new AphrontPagerView(); - $pager->setURI($request->getRequestURI(), 'offset'); - $pager->setOffset($request->getInt('offset')); - - $query = new PhabricatorNotificationQuery(); - $query->setViewer($user); - $query->setUserPHID($user->getPHID()); - - switch ($filter) { - case 'unread': - $query->withUnread(true); - $header = pht('Unread Notifications'); - $no_data = pht('You have no unread notifications.'); - break; - default: - $header = pht('Notifications'); - $no_data = pht('You have no notifications.'); - break; - } - - $image = id(new PHUIIconView()) - ->setIconFont('fa-eye-slash'); - $button = id(new PHUIButtonView()) - ->setTag('a') - ->addSigil('workflow') - ->setColor(PHUIButtonView::SIMPLE) - ->setIcon($image) - ->setText(pht('Mark All Read')); - - $notifications = $query->executeWithOffsetPager($pager); - $clear_uri = id(new PhutilURI('/notification/clear/')); - if ($notifications) { - $builder = new PhabricatorNotificationBuilder($notifications); - $builder->setUser($user); - $view = $builder->buildView()->render(); - $clear_uri->setQueryParam( - 'chronoKey', - head($notifications)->getChronologicalKey()); - } else { - $view = phutil_tag_div( - 'phabricator-notification no-notifications', - $no_data); - $button->setDisabled(true); - } - $button->setHref((string) $clear_uri); - - $view = id(new PHUIBoxView()) - ->addPadding(PHUI::PADDING_MEDIUM) - ->addClass('phabricator-notification-list') - ->appendChild($view); + return $this->delegateToController($controller); + } - $notif_header = id(new PHUIHeaderView()) - ->setHeader($header) - ->addActionLink($button); + public function buildSideNavView() { + $user = $this->getRequest()->getUser(); - $box = id(new PHUIObjectBoxView()) - ->setHeader($notif_header) - ->appendChild($view); + $nav = new AphrontSideNavFilterView(); + $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); - $nav->appendChild($box); - $nav->appendChild($pager); + id(new PhabricatorNotificationSearchEngine()) + ->setViewer($user) + ->addNavigationItems($nav->getMenu()); + $nav->selectFilter(null); - return $this->buildApplicationPage( - $nav, - array( - 'title' => pht('Notifications'), - )); + return $nav; } } 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 @@ -8,10 +8,10 @@ $request = $this->getRequest(); $user = $request->getUser(); - $query = new PhabricatorNotificationQuery(); - $query->setViewer($user); - $query->setUserPHID($user->getPHID()); - $query->setLimit(15); + $query = id(new PhabricatorNotificationQuery()) + ->setViewer($user) + ->withUserPHIDs(array($user->getPHID())) + ->setLimit(15); $stories = $query->execute(); diff --git a/src/applications/notification/query/PhabricatorNotificationQuery.php b/src/applications/notification/query/PhabricatorNotificationQuery.php --- a/src/applications/notification/query/PhabricatorNotificationQuery.php +++ b/src/applications/notification/query/PhabricatorNotificationQuery.php @@ -7,7 +7,7 @@ final class PhabricatorNotificationQuery extends PhabricatorCursorPagedPolicyAwareQuery { - private $userPHID; + private $userPHIDs; private $keys; private $unread; @@ -15,8 +15,8 @@ /* -( Configuring the Query )---------------------------------------------- */ - public function setUserPHID($user_phid) { - $this->userPHID = $user_phid; + public function withUserPHIDs(array $user_phids) { + $this->userPHIDs = $user_phids; return $this; } @@ -46,10 +46,6 @@ protected function loadPage() { - if (!$this->userPHID) { - throw new Exception('Call setUser() before executing the query'); - } - $story_table = new PhabricatorFeedStoryData(); $notification_table = new PhabricatorFeedStoryNotification(); @@ -83,11 +79,11 @@ private function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); - if ($this->userPHID) { + if ($this->userPHIDs !== null) { $where[] = qsprintf( $conn_r, - 'notif.userPHID = %s', - $this->userPHID); + 'notif.userPHID IN (%Ls)', + $this->userPHIDs); } if ($this->unread !== null) { diff --git a/src/applications/notification/query/PhabricatorNotificationSearchEngine.php b/src/applications/notification/query/PhabricatorNotificationSearchEngine.php new file mode 100644 --- /dev/null +++ b/src/applications/notification/query/PhabricatorNotificationSearchEngine.php @@ -0,0 +1,139 @@ +setParameter( + 'unread', + $this->readBoolFromRequest($request, 'unread')); + + return $saved; + } + + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { + $query = id(new PhabricatorNotificationQuery()) + ->withUserPHIDs(array($this->requireViewer()->getPHID())); + + if ($saved->getParameter('unread')) { + $query->withUnread(true); + } + + return $query; + } + + public function buildSearchForm( + AphrontFormView $form, + PhabricatorSavedQuery $saved) { + + $unread = $saved->getParameter('unread'); + + $form->appendChild( + id(new AphrontFormCheckboxControl()) + ->setLabel(pht('Unread')) + ->addCheckbox( + 'unread', + 1, + pht('Show only unread notifications.'), + $unread)); + } + + protected function getURI($path) { + return '/notification/'.$path; + } + + public function getBuiltinQueryNames() { + + $names = array( + 'all' => pht('All Notifications'), + 'unread' => pht('Unread Notifications'), + ); + + return $names; + } + + public function buildSavedQueryFromBuiltin($query_key) { + $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); + + switch ($query_key) { + case 'all': + return $query; + case 'unread': + return $query->setParameter('unread', true); + } + + return parent::buildSavedQueryFromBuiltin($query_key); + } + + protected function renderResultList( + array $notifications, + PhabricatorSavedQuery $query, + array $handles) { + assert_instances_of($notifications, 'PhabricatorFeedStory'); + + $viewer = $this->requireViewer(); + + $image = id(new PHUIIconView()) + ->setIconFont('fa-eye-slash'); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->addSigil('workflow') + ->setColor(PHUIButtonView::SIMPLE) + ->setIcon($image) + ->setText(pht('Mark All Read')); + + switch ($query->getQueryKey()) { + case 'unread': + $header = pht('Unread Notifications'); + $no_data = pht('You have no unread notifications.'); + break; + default: + $header = pht('Notifications'); + $no_data = pht('You have no notifications.'); + break; + } + + $clear_uri = id(new PhutilURI('/notification/clear/')); + if ($notifications) { + $builder = id(new PhabricatorNotificationBuilder($notifications)) + ->setUser($viewer); + + $view = $builder->buildView(); + $clear_uri->setQueryParam( + 'chronoKey', + head($notifications)->getChronologicalKey()); + } else { + $view = phutil_tag_div( + 'phabricator-notification no-notifications', + $no_data); + $button->setDisabled(true); + } + $button->setHref((string)$clear_uri); + + $view = id(new PHUIBoxView()) + ->addPadding(PHUI::PADDING_MEDIUM) + ->addClass('phabricator-notification-list') + ->appendChild($view); + + $notif_header = id(new PHUIHeaderView()) + ->setHeader($header) + ->addActionLink($button); + + return id(new PHUIObjectBoxView()) + ->setHeader($notif_header) + ->appendChild($view); + } + +}