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 @@ -1403,6 +1403,7 @@ 'PHUI' => 'view/phui/PHUI.php', 'PHUIActionPanelExample' => 'applications/uiexample/examples/PHUIActionPanelExample.php', 'PHUIActionPanelView' => 'view/phui/PHUIActionPanelView.php', + 'PHUIApplicationMenuView' => 'view/layout/PHUIApplicationMenuView.php', 'PHUIBadgeBoxView' => 'view/phui/PHUIBadgeBoxView.php', 'PHUIBadgeExample' => 'applications/uiexample/examples/PHUIBadgeExample.php', 'PHUIBadgeMiniView' => 'view/phui/PHUIBadgeMiniView.php', @@ -5310,6 +5311,7 @@ 'PHUI' => 'Phobject', 'PHUIActionPanelExample' => 'PhabricatorUIExample', 'PHUIActionPanelView' => 'AphrontTagView', + 'PHUIApplicationMenuView' => 'Phobject', 'PHUIBadgeBoxView' => 'AphrontTagView', 'PHUIBadgeExample' => 'PhabricatorUIExample', 'PHUIBadgeMiniView' => 'AphrontTagView', @@ -7182,7 +7184,10 @@ 'PhabricatorStandardCustomFieldText' => 'PhabricatorStandardCustomField', 'PhabricatorStandardCustomFieldTokenizer' => 'PhabricatorStandardCustomFieldPHIDs', 'PhabricatorStandardCustomFieldUsers' => 'PhabricatorStandardCustomFieldTokenizer', - 'PhabricatorStandardPageView' => 'PhabricatorBarePageView', + 'PhabricatorStandardPageView' => array( + 'PhabricatorBarePageView', + 'AphrontResponseProducerInterface', + ), 'PhabricatorStandardSelectCustomFieldDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorStatusController' => 'PhabricatorController', 'PhabricatorStatusUIExample' => 'PhabricatorUIExample', diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -3,7 +3,6 @@ abstract class PhabricatorController extends AphrontController { private $handles; - private $extraQuicksandConfig = array(); public function shouldRequireLogin() { return true; @@ -62,15 +61,6 @@ return false; } - public function addExtraQuicksandConfig($config) { - $this->extraQuicksandConfig += $config; - return $this; - } - - private function getExtraQuicksandConfig() { - return $this->extraQuicksandConfig; - } - public function willBeginExecution() { $request = $this->getRequest(); @@ -285,32 +275,6 @@ } } - public function buildStandardPageView() { - $view = new PhabricatorStandardPageView(); - $view->setRequest($this->getRequest()); - $view->setController($this); - return $view; - } - - public function buildStandardPageResponse($view, array $data) { - $page = $this->buildStandardPageView(); - $page->appendChild($view); - return $this->buildPageResponse($page); - } - - private function buildPageResponse($page) { - if ($this->getRequest()->isQuicksand()) { - $response = id(new AphrontAjaxResponse()) - ->setContent($page->renderForQuicksand( - $this->getExtraQuicksandConfig())); - } else { - $response = id(new AphrontWebpageResponse()) - ->setContent($page->render()); - } - - return $response; - } - public function getApplicationURI($path = '') { if (!$this->getCurrentApplication()) { throw new Exception(pht('No application!')); @@ -318,62 +282,6 @@ return $this->getCurrentApplication()->getApplicationURI($path); } - public function buildApplicationPage($view, array $options) { - $page = $this->buildStandardPageView(); - - $title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ? - 'Phabricator' : - pht('Bacon Ice Cream for Breakfast'); - - $application = $this->getCurrentApplication(); - $page->setTitle(idx($options, 'title', $title)); - if ($application) { - $page->setApplicationName($application->getName()); - if ($application->getTitleGlyph()) { - $page->setGlyph($application->getTitleGlyph()); - } - } - - if (idx($options, 'class')) { - $page->addClass($options['class']); - } - - if (!($view instanceof AphrontSideNavFilterView)) { - $nav = new AphrontSideNavFilterView(); - $nav->appendChild($view); - $view = $nav; - } - - $user = $this->getRequest()->getUser(); - $view->setUser($user); - - $page->appendChild($view); - - $object_phids = idx($options, 'pageObjects', array()); - if ($object_phids) { - $page->appendPageObjects($object_phids); - foreach ($object_phids as $object_phid) { - PhabricatorFeedStoryNotification::updateObjectNotificationViews( - $user, - $object_phid); - } - } - - if (idx($options, 'device', true)) { - $page->setDeviceReady(true); - } - - $page->setShowFooter(idx($options, 'showFooter', true)); - $page->setShowChrome(idx($options, 'chrome', true)); - - $application_menu = $this->buildApplicationMenu(); - if ($application_menu) { - $page->setApplicationMenu($application_menu); - } - - return $this->buildPageResponse($page); - } - public function willSendResponse(AphrontResponse $response) { $request = $this->getRequest(); @@ -536,6 +444,35 @@ ->setSubmitURI($submit_uri); } + public function newPage() { + $page = id(new PhabricatorStandardPageView()) + ->setRequest($this->getRequest()) + ->setController($this); + + $application = $this->getCurrentApplication(); + if ($application) { + $page->setApplicationName($application->getName()); + if ($application->getTitleGlyph()) { + $page->setGlyph($application->getTitleGlyph()); + } + } + + $viewer = $this->getRequest()->getUser(); + if ($viewer) { + $page->setUser($viewer); + } + + // TODO: Remove after removing callsites to addExtraQuicksandConfig(). + $page->addQuicksandConfig($this->extraQuicksandConfig); + + return $page; + } + + public function newApplicationMenu() { + return id(new PHUIApplicationMenuView()) + ->setViewer($this->getRequest()->getUser()); + } + protected function buildTransactionTimeline( PhabricatorApplicationTransactionInterface $object, PhabricatorApplicationTransactionQuery $query, @@ -583,4 +520,81 @@ return $timeline; } + +/* -( Deprecated )--------------------------------------------------------- */ + + + /** + * DEPRECATED. + */ + private $extraQuicksandConfig = array(); + + + /** + * DEPRECATED. Use @{method:newPage} and call addQuicksandConfig(). + */ + public function addExtraQuicksandConfig($config) { + // TODO: When this method is removed, + $this->extraQuicksandConfig += $config; + return $this; + } + + + /** + * DEPRECATED. Use @{method:newPage}. + */ + public function buildStandardPageView() { + return $this->newPage(); + } + + + /** + * DEPRECATED. Use @{method:newPage}. + */ + public function buildStandardPageResponse($view, array $data) { + $page = $this->buildStandardPageView(); + $page->appendChild($view); + return $page->produceAphrontResponse(); + } + + + /** + * DEPRECATED. Use @{method:newPage}. + */ + public function buildApplicationPage($view, array $options) { + $page = $this->newPage(); + + $title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ? + 'Phabricator' : + pht('Bacon Ice Cream for Breakfast'); + + $page->setTitle(idx($options, 'title', $title)); + + if (idx($options, 'class')) { + $page->addClass($options['class']); + } + + if (!($view instanceof AphrontSideNavFilterView)) { + $nav = new AphrontSideNavFilterView(); + $nav->appendChild($view); + $view = $nav; + } + + $page->appendChild($view); + + $object_phids = idx($options, 'pageObjects', array()); + if ($object_phids) { + $page->setPageObjectPHIDs($object_phids); + } + + if (idx($options, 'device', true)) { + $page->setDeviceReady(true); + } + + $page->setShowFooter(idx($options, 'showFooter', true)); + $page->setShowChrome(idx($options, 'chrome', true)); + + return $page->produceAphrontResponse(); + } + } diff --git a/src/applications/paste/controller/PhabricatorPasteController.php b/src/applications/paste/controller/PhabricatorPasteController.php --- a/src/applications/paste/controller/PhabricatorPasteController.php +++ b/src/applications/paste/controller/PhabricatorPasteController.php @@ -2,39 +2,9 @@ abstract class PhabricatorPasteController extends PhabricatorController { - public function buildSideNavView($for_app = false) { - $user = $this->getRequest()->getUser(); - - $nav = new AphrontSideNavFilterView(); - $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); - - if ($for_app) { - $nav->addFilter('create', pht('Create Paste')); - } - - id(new PhabricatorPasteSearchEngine()) - ->setViewer($user) - ->addNavigationItems($nav->getMenu()); - - $nav->selectFilter(null); - - return $nav; - } - public function buildApplicationMenu() { - return $this->buildSideNavView(true)->getMenu(); - } - - protected function buildApplicationCrumbs() { - $crumbs = parent::buildApplicationCrumbs(); - - $crumbs->addAction( - id(new PHUIListItemView()) - ->setName(pht('Create Paste')) - ->setHref($this->getApplicationURI('create/')) - ->setIcon('fa-plus-square')); - - return $crumbs; + return $this->newApplicationMenu() + ->setSearchEngine(new PhabricatorPasteSearchEngine()); } public function buildSourceCodeView( diff --git a/src/applications/paste/controller/PhabricatorPasteEditController.php b/src/applications/paste/controller/PhabricatorPasteEditController.php --- a/src/applications/paste/controller/PhabricatorPasteEditController.php +++ b/src/applications/paste/controller/PhabricatorPasteEditController.php @@ -231,7 +231,7 @@ $form_box->setValidationException($validation_exception); } - $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); + $crumbs = $this->buildApplicationCrumbs(); if (!$is_create) { $crumbs->addTextCrumb('P'.$paste->getID(), '/P'.$paste->getID()); } diff --git a/src/applications/paste/controller/PhabricatorPasteListController.php b/src/applications/paste/controller/PhabricatorPasteListController.php --- a/src/applications/paste/controller/PhabricatorPasteListController.php +++ b/src/applications/paste/controller/PhabricatorPasteListController.php @@ -7,15 +7,21 @@ } public function handleRequest(AphrontRequest $request) { - $querykey = $request->getURIData('queryKey'); + return id(new PhabricatorPasteSearchEngine()) + ->setController($this) + ->buildResponse(); + } - $controller = id(new PhabricatorApplicationSearchController()) - ->setQueryKey($querykey) - ->setSearchEngine(new PhabricatorPasteSearchEngine()) - ->setNavigation($this->buildSideNavView()); + protected function buildApplicationCrumbs() { + $crumbs = parent::buildApplicationCrumbs(); - return $this->delegateToController($controller); - } + $crumbs->addAction( + id(new PHUIListItemView()) + ->setName(pht('Create Paste')) + ->setHref($this->getApplicationURI('create/')) + ->setIcon('fa-plus-square')); + return $crumbs; + } } diff --git a/src/applications/paste/controller/PhabricatorPasteViewController.php b/src/applications/paste/controller/PhabricatorPasteViewController.php --- a/src/applications/paste/controller/PhabricatorPasteViewController.php +++ b/src/applications/paste/controller/PhabricatorPasteViewController.php @@ -66,7 +66,7 @@ ), $source_code); - $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()) + $crumbs = $this->buildApplicationCrumbs() ->addTextCrumb('P'.$paste->getID(), '/P'.$paste->getID()); $timeline = $this->buildTransactionTimeline( @@ -89,18 +89,20 @@ ->setAction($this->getApplicationURI('/comment/'.$paste->getID().'/')) ->setSubmitButtonName(pht('Add Comment')); - return $this->buildApplicationPage( - array( - $crumbs, - $object_box, - $source_code, - $timeline, - $add_comment_form, - ), - array( - 'title' => $paste->getFullName(), - 'pageObjects' => array($paste->getPHID()), - )); + return $this->newPage() + ->setTitle($paste->getFullName()) + ->setCrumbs($crumbs) + ->setPageObjectPHIDs( + array( + $paste->getPHID(), + )) + ->appendChild( + array( + $object_box, + $source_code, + $timeline, + $add_comment_form, + )); } private function buildHeaderView(PhabricatorPaste $paste) { diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php --- a/src/applications/search/controller/PhabricatorApplicationSearchController.php +++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php @@ -58,11 +58,6 @@ throw new PhutilInvalidStateException('setEngine'); } - $nav = $this->getNavigation(); - if (!$nav) { - throw new PhutilInvalidStateException('setNavigation'); - } - $engine->setViewer($this->getRequest()->getUser()); $parent = $this->getDelegatingController(); @@ -85,6 +80,9 @@ $user = $request->getUser(); $engine = $this->getSearchEngine(); $nav = $this->getNavigation(); + if (!$nav) { + $nav = $this->buildNavigation(); + } if ($request->isFormPost()) { $saved_query = $engine->buildSavedQueryFromRequest($request); @@ -174,9 +172,10 @@ // we sort out T5307. $form->appendChild($submit); + $body = array(); if ($this->getPreface()) { - $nav->appendChild($this->getPreface()); + $body[] = $this->getPreface(); } if ($named_query) { @@ -202,7 +201,7 @@ $box->setForm($form); } - $nav->appendChild($box); + $body[] = $box; if ($run_query) { $box->setAnchor( @@ -257,7 +256,7 @@ ->addMargin(PHUI::MARGIN_LARGE) ->setBorder(true) ->appendChild($pager); - $nav->appendChild($pager_box); + $body[] = $pager_box; } } catch (PhabricatorTypeaheadInvalidTokenException $ex) { @@ -275,13 +274,12 @@ ->buildApplicationCrumbs() ->addTextCrumb($title); - $nav->setCrumbs($crumbs); - - return $this->buildApplicationPage( - $nav, - array( - 'title' => pht('Query: %s', $title), - )); + return $this->newPage() + ->setApplicationMenu($this->buildApplicationMenu()) + ->setTitle(pht('Query: %s', $title)) + ->setCrumbs($crumbs) + ->setNavigation($nav) + ->appendChild($body); } private function processEditRequest() { @@ -289,7 +287,11 @@ $request = $this->getRequest(); $user = $request->getUser(); $engine = $this->getSearchEngine(); + $nav = $this->getNavigation(); + if (!$nav) { + $nav = $this->buildNavigation(); + } $named_queries = $engine->loadAllNamedQueries(); @@ -357,23 +359,41 @@ ->addTextCrumb(pht('Saved Queries'), $engine->getQueryManagementURI()); $nav->selectFilter('query/edit'); - $nav->setCrumbs($crumbs); $box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Saved Queries')) ->setObjectList($list); - $nav->appendChild($box); - - return $parent->buildApplicationPage( - $nav, - array( - 'title' => pht('Saved Queries'), - )); + return $this->newPage() + ->setApplicationMenu($this->buildApplicationMenu()) + ->setTitle(pht('Saved Queries')) + ->setCrumbs($crumbs) + ->setNavigation($nav) + ->appendChild($box); } public function buildApplicationMenu() { - return $this->getDelegatingController()->buildApplicationMenu(); + $menu = $this->getDelegatingController() + ->buildApplicationMenu(); + + if ($menu instanceof PHUIApplicationMenuView) { + $menu->setSearchEngine($this->getSearchEngine()); + } + + return $menu; + } + + private function buildNavigation() { + $viewer = $this->getViewer(); + $engine = $this->getSearchEngine(); + + $nav = id(new AphrontSideNavFilterView()) + ->setUser($viewer) + ->setBaseURI(new PhutilURI($this->getApplicationURI())); + + $engine->addNavigationItems($nav->getMenu()); + + return $nav; } } diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php --- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php +++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php @@ -22,10 +22,32 @@ private $customFields = false; private $request; private $context; + private $controller; + private $namedQueries; const CONTEXT_LIST = 'list'; const CONTEXT_PANEL = 'panel'; + public function setController(PhabricatorController $controller) { + $this->controller = $controller; + return $this; + } + + public function getController() { + return $this->controller; + } + + public function buildResponse() { + $controller = $this->getController(); + $request = $controller->getRequest(); + + $search = id(new PhabricatorApplicationSearchController()) + ->setQueryKey($request->getURIData('queryKey')) + ->setSearchEngine($this); + + return $controller->delegateToController($search); + } + public function newResultObject() { // We may be able to get this automatically if newQuery() is implemented. $query = $this->newQuery(); @@ -459,33 +481,36 @@ public function loadAllNamedQueries() { $viewer = $this->requireViewer(); - - $named_queries = id(new PhabricatorNamedQueryQuery()) - ->setViewer($viewer) - ->withUserPHIDs(array($viewer->getPHID())) - ->withEngineClassNames(array(get_class($this))) - ->execute(); - $named_queries = mpull($named_queries, null, 'getQueryKey'); - $builtin = $this->getBuiltinQueries($viewer); - $builtin = mpull($builtin, null, 'getQueryKey'); - foreach ($named_queries as $key => $named_query) { - if ($named_query->getIsBuiltin()) { - if (isset($builtin[$key])) { - $named_queries[$key]->setQueryName($builtin[$key]->getQueryName()); - unset($builtin[$key]); - } else { - unset($named_queries[$key]); + if ($this->namedQueries === null) { + $named_queries = id(new PhabricatorNamedQueryQuery()) + ->setViewer($viewer) + ->withUserPHIDs(array($viewer->getPHID())) + ->withEngineClassNames(array(get_class($this))) + ->execute(); + $named_queries = mpull($named_queries, null, 'getQueryKey'); + + $builtin = mpull($builtin, null, 'getQueryKey'); + + foreach ($named_queries as $key => $named_query) { + if ($named_query->getIsBuiltin()) { + if (isset($builtin[$key])) { + $named_queries[$key]->setQueryName($builtin[$key]->getQueryName()); + unset($builtin[$key]); + } else { + unset($named_queries[$key]); + } } + + unset($builtin[$key]); } - unset($builtin[$key]); + $named_queries = msort($named_queries, 'getSortKey'); + $this->namedQueries = $named_queries; } - $named_queries = msort($named_queries, 'getSortKey'); - - return $named_queries + $builtin; + return $this->namedQueries + $builtin; } public function loadEnabledNamedQueries() { diff --git a/src/view/layout/PHUIApplicationMenuView.php b/src/view/layout/PHUIApplicationMenuView.php new file mode 100644 --- /dev/null +++ b/src/view/layout/PHUIApplicationMenuView.php @@ -0,0 +1,89 @@ +viewer = $viewer; + return $this; + } + + public function getViewer() { + return $this->viewer; + } + + public function addLabel($name) { + $item = id(new PHUIListItemView()) + ->setName($name); + + return $this->addItem($item); + } + + public function addLink($name, $href) { + $item = id(new PHUIListItemView()) + ->setName($name) + ->setHref($href); + + return $this->addItem($item); + } + + public function addItem(PHUIListItemView $item) { + $this->items[] = $item; + return $this; + } + + public function setSearchEngine(PhabricatorApplicationSearchEngine $engine) { + $this->searchEngine = $engine; + return $this; + } + + public function getSearchEngine() { + return $this->searchEngine; + } + + public function setCrumbs(PHUICrumbsView $crumbs) { + $this->crumbs = $crumbs; + return $this; + } + + public function getCrumbs() { + return $this->crumbs; + } + + public function buildListView() { + $viewer = $this->getViewer(); + + $view = id(new PHUIListView()) + ->setUser($viewer); + + $crumbs = $this->getCrumbs(); + if ($crumbs) { + $actions = $crumbs->getActions(); + if ($actions) { + $view->newLabel(pht('Create')); + foreach ($crumbs->getActions() as $action) { + $view->addMenuItem($action); + } + } + } + + $engine = $this->getSearchEngine(); + if ($engine) { + $engine + ->setViewer($viewer) + ->addNavigationItems($view); + } + + foreach ($this->items as $item) { + $view->addMenuItem($item); + } + + return $view; + } + +} diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -4,7 +4,8 @@ * This is a standard Phabricator page with menus, Javelin, DarkConsole, and * basic styles. */ -final class PhabricatorStandardPageView extends PhabricatorBarePageView { +final class PhabricatorStandardPageView extends PhabricatorBarePageView + implements AphrontResponseProducerInterface { private $baseURI; private $applicationName; @@ -17,6 +18,9 @@ private $applicationMenu; private $showFooter = true; private $showDurableColumn = true; + private $quicksandConfig = array(); + private $crumbs; + private $navigation; public function setShowFooter($show_footer) { $this->showFooter = $show_footer; @@ -27,7 +31,10 @@ return $this->showFooter; } - public function setApplicationMenu(PHUIListView $application_menu) { + public function setApplicationMenu($application_menu) { + // NOTE: For now, this can either be a PHUIListView or a + // PHUIApplicationMenuView. + $this->applicationMenu = $application_menu; return $this; } @@ -73,10 +80,9 @@ return $this; } - public function appendPageObjects(array $objs) { - foreach ($objs as $obj) { - $this->pageObjects[] = $obj; - } + public function setPageObjectPHIDs(array $phids) { + $this->pageObjects = $phids; + return $this; } public function setShowDurableColumn($show) { @@ -130,6 +136,32 @@ return (bool)$this->getUserPreference($column_key, 0); } + public function addQuicksandConfig(array $config) { + $this->quicksandConfig = $config + $this->quicksandConfig; + return $this; + } + + public function getQuicksandConfig() { + return $this->quicksandConfig; + } + + public function setCrumbs(PHUICrumbsView $crumbs) { + $this->crumbs = $crumbs; + return $this; + } + + public function getCrumbs() { + return $this->crumbs; + } + + public function setNavigation(AphrontSideNavFilterView $navigation) { + $this->navigation = $navigation; + return $this; + } + + public function getNavigation() { + return $this->navigation; + } public function getTitle() { $glyph_key = PhabricatorUserPreferences::PREFERENCE_TITLES; @@ -271,8 +303,18 @@ $menu->setController($this->getController()); } - if ($this->getApplicationMenu()) { - $menu->setApplicationMenu($this->getApplicationMenu()); + $application_menu = $this->getApplicationMenu(); + if ($application_menu) { + if ($application_menu instanceof PHUIApplicationMenuView) { + $crumbs = $this->getCrumbs(); + if ($crumbs) { + $application_menu->setCrumbs($crumbs); + } + + $application_menu = $application_menu->buildListView(); + } + + $menu->setApplicationMenu($application_menu); } $this->menuContent = $menu->render(); @@ -433,9 +475,26 @@ private function renderPageBodyContent() { $console = $this->getConsole(); + $body = parent::getBody(); + + $nav = $this->getNavigation(); + if ($nav) { + $crumbs = $this->getCrumbs(); + if ($crumbs) { + $nav->setCrumbs($crumbs); + } + $nav->appendChild($body); + $body = phutil_implode_html('', array($nav->render())); + } else { + $crumbs = $this->getCrumbs(); + if ($crumbs) { + $body = phutil_implode_html('', array($crumbs, $body)); + } + } + return array( ($console ? hsprintf('') : null), - parent::getBody(), + $body, $this->renderFooter(), ); } @@ -619,11 +678,13 @@ $foot); } - public function renderForQuicksand(array $extra_config) { + public function renderForQuicksand() { parent::willRenderPage(); $response = $this->renderPageBodyContent(); $response = $this->willSendResponse($response); + $extra_config = $this->getQuicksandConfig(); + return array( 'content' => hsprintf('%s', $response), ) + $this->buildQuicksandConfig() @@ -732,4 +793,37 @@ return $user->loadPreferences()->getPreference($key, $default); } + public function produceAphrontResponse() { + $controller = $this->getController(); + + if (!$this->getApplicationMenu()) { + $application_menu = $controller->buildApplicationMenu(); + if ($application_menu) { + $this->setApplicationMenu($application_menu); + } + } + + $viewer = $this->getUser(); + if ($viewer && $viewer->getPHID()) { + $object_phids = $this->pageObjects; + foreach ($object_phids as $object_phid) { + PhabricatorFeedStoryNotification::updateObjectNotificationViews( + $viewer, + $object_phid); + } + } + + if ($this->getRequest()->isQuicksand()) { + $content = $this->renderForQuicksand(); + $response = id(new AphrontAjaxResponse()) + ->setContent($content); + } else { + $content = $this->render(); + $response = id(new AphrontWebpageResponse()) + ->setContent($content); + } + + return $response; + } + } diff --git a/src/view/phui/PHUICrumbsView.php b/src/view/phui/PHUICrumbsView.php --- a/src/view/phui/PHUICrumbsView.php +++ b/src/view/phui/PHUICrumbsView.php @@ -41,6 +41,10 @@ return $this; } + public function getActions() { + return $this->actions; + } + public function render() { require_celerity_resource('phui-crumbs-view-css');