From f910e38ecc1b62fbab75ee9ee0448c05a9e98512 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 7 Dec 2012 13:34:44 -0800 Subject: [PATCH] Provide a mobile application menu Summary: Adds a right-hand-side application menu, based roughly on `frame_v3.png`. This has the same icon as the left menu until we get real design in, but is functionally reasonable. Test Plan: {F26170} {F26169} Reviewers: chad Reviewed By: chad CC: aran Maniphest Tasks: T1960 Differential Revision: https://secure.phabricator.com/D4061 --- .../base/controller/PhabricatorController.php | 9 ++ .../controller/PhabricatorPasteController.php | 4 + src/view/layout/AphrontSideNavFilterView.php | 6 +- src/view/layout/PhabricatorMenuView.php | 21 ++++ src/view/page/PhabricatorStandardPageView.php | 21 +++- .../page/menu/PhabricatorMainMenuView.php | 56 ++++++++- .../css/application/base/main-menu-view.css | 117 +++++++++++++----- 7 files changed, 200 insertions(+), 34 deletions(-) diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index 7616344273..b53c8c22ea 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -169,6 +169,11 @@ abstract class PhabricatorController extends AphrontController { $view->appendChild($page->renderFooter()); } + $application_menu = $this->buildApplicationMenu(); + if ($application_menu) { + $page->setApplicationMenu($application_menu); + } + $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } @@ -238,4 +243,8 @@ abstract class PhabricatorController extends AphrontController { return implode('
', $items); } + protected function buildApplicationMenu() { + return null; + } + } diff --git a/src/applications/paste/controller/PhabricatorPasteController.php b/src/applications/paste/controller/PhabricatorPasteController.php index de0d7345c9..8237f7c694 100644 --- a/src/applications/paste/controller/PhabricatorPasteController.php +++ b/src/applications/paste/controller/PhabricatorPasteController.php @@ -31,4 +31,8 @@ abstract class PhabricatorPasteController extends PhabricatorController { return $nav; } + public function buildApplicationMenu() { + return $this->buildSideNavView(null)->getMenu(); + } + } diff --git a/src/view/layout/AphrontSideNavFilterView.php b/src/view/layout/AphrontSideNavFilterView.php index f57600923f..0da3ecad0a 100644 --- a/src/view/layout/AphrontSideNavFilterView.php +++ b/src/view/layout/AphrontSideNavFilterView.php @@ -31,7 +31,7 @@ final class AphrontSideNavFilterView extends AphrontView { private $menu; public function __construct() { - $this->menu = id(new PhabricatorMenuView()); + $this->menu = new PhabricatorMenuView(); } public function setActive($active) { @@ -59,6 +59,10 @@ final class AphrontSideNavFilterView extends AphrontView { return $this; } + public function getMenu() { + return $this->menu; + } + public function addFilter( $key, $name, diff --git a/src/view/layout/PhabricatorMenuView.php b/src/view/layout/PhabricatorMenuView.php index fbafbdb23c..d2517e60be 100644 --- a/src/view/layout/PhabricatorMenuView.php +++ b/src/view/layout/PhabricatorMenuView.php @@ -11,6 +11,27 @@ final class PhabricatorMenuView extends AphrontView { return $this; } + public function newLabel($name) { + $item = id(new PhabricatorMenuItemView()) + ->setType(PhabricatorMenuItemView::TYPE_LABEL) + ->setName($name); + + $this->addMenuItem($item); + + return $item; + } + + public function newLink($name, $href) { + $item = id(new PhabricatorMenuItemView()) + ->setType(PhabricatorMenuItemView::TYPE_LINK) + ->setName($name) + ->setHref($href); + + $this->addMenuItem($item); + + return $item; + } + public function addMenuItem(PhabricatorMenuItemView $item) { $key = $item->getKey(); if ($key !== null) { diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index 70e9c8bb22..062a9a8bfb 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -15,6 +15,16 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { private $disableConsole; private $searchDefaultScope; private $pageObjects = array(); + private $applicationMenu; + + public function setApplicationMenu(PhabricatorMenuView $application_menu) { + $this->applicationMenu = $application_menu; + return $this; + } + + public function getApplicationMenu() { + return $this->applicationMenu; + } public function setApplicationName($application_name) { $this->applicationName = $application_name; @@ -142,11 +152,16 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView { require_celerity_resource('javelin-behavior-error-log'); } - $this->menuContent = id(new PhabricatorMainMenuView()) + $menu = id(new PhabricatorMainMenuView()) ->setUser($request->getUser()) ->setController($this->getController()) - ->setDefaultSearchScope($this->getSearchDefaultScope()) - ->render(); + ->setDefaultSearchScope($this->getSearchDefaultScope()); + + if ($this->getApplicationMenu()) { + $menu->setApplicationMenu($this->getApplicationMenu()); + } + + $this->menuContent = $menu->render(); } diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index 131ad377c5..a833960e4d 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -5,6 +5,17 @@ final class PhabricatorMainMenuView extends AphrontView { private $user; private $defaultSearchScope; private $controller; + private $applicationMenu; + + + public function setApplicationMenu(PhabricatorMenuView $application_menu) { + $this->applicationMenu = $application_menu; + return $this; + } + + public function getApplicationMenu() { + return $this->applicationMenu; + } public function setController(PhabricatorController $controller) { $this->controller = $controller; @@ -84,6 +95,12 @@ final class PhabricatorMainMenuView extends AphrontView { $actions = ''; + $application_menu = $this->getApplicationMenu(); + if ($application_menu) { + $application_menu->addClass('phabricator-dark-menu'); + $application_menu->addClass('phabricator-application-menu'); + } + return phutil_render_tag( 'div', array( @@ -92,8 +109,12 @@ final class PhabricatorMainMenuView extends AphrontView { ), self::renderSingleView( array( - $logo, + $this->renderPhabricatorMenuButton($header_id), + $this->renderApplicationMenuButton($header_id), + $this->renderPhabricatorLogo(), + $alerts, $phabricator_menu, + $application_menu, ))). self::renderSingleView($menus); } @@ -130,6 +151,38 @@ final class PhabricatorMainMenuView extends AphrontView { return $result; } + private function renderPhabricatorMenuButton($header_id) { + return javelin_render_tag( + 'a', + array( + 'class' => 'phabricator-main-menu-expand-button '. + 'phabricator-expand-core-menu', + 'sigil' => 'jx-toggle-class', + 'meta' => array( + 'map' => array( + $header_id => 'phabricator-core-menu-expanded', + ), + ), + ), + ''); + } + + public function renderApplicationMenuButton($header_id) { + return javelin_render_tag( + 'a', + array( + 'class' => 'phabricator-main-menu-expand-button '. + 'phabricator-expand-application-menu', + 'sigil' => 'jx-toggle-class', + 'meta' => array( + 'map' => array( + $header_id => 'phabricator-application-menu-expanded', + ), + ), + ), + ''); + } + private function renderPhabricatorMenu() { $user = $this->getUser(); $controller = $this->getController(); @@ -162,6 +215,7 @@ final class PhabricatorMainMenuView extends AphrontView { $view = new PhabricatorMenuView(); + $view->addClass('phabricator-dark-menu'); $view->addClass('phabricator-core-menu'); $search = $this->renderSearch(); diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index b701454b14..2e7de7a188 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -53,8 +53,7 @@ .phabricator-main-menu-expand-button { position: absolute; - right: 10px; - top: 10px; + top: 7px; display: block; width: 40px; height: 28px; @@ -67,6 +66,14 @@ 0 1px 0 rgba(255, 255, 255, 0.075); } +.phabricator-expand-core-menu { + left: 10px; +} + +.phabricator-expand-application-menu { + right: 10px; +} + .device-desktop .phabricator-main-menu-expand-button { display: none; } @@ -76,11 +83,14 @@ display: block; } -.phabricator-core-menu-expand .phabricator-main-menu-expand-button { +.phabricator-core-menu-expanded .phabricator-expand-core-menu, +.phabricator-application-menu-expanded .phabricator-expand-application-menu { background-color: #55595d; } + + /* - Search -------------------------------------------------------------------- The main search input in the menu bar. @@ -257,8 +267,48 @@ a:hover .phabricator-main-search-typeahead-result .result-type { display: block; } +/* - Dark Menu ----------------------------------------------------------------- + + Styles shared between the "core" menu (left button on mobile) and + "application" menu (right button on mobile). These styles give the menu a + white-on-black appearance. + +*/ + +.device-phone .phabricator-dark-menu, +.device-tablet .phabricator-dark-menu, +.device-phone .phabricator-dark-menu a.phabricator-menu-item-type-link, +.device-tablet .phabricator-dark-menu a.phabricator-menu-item-type-link { + color: #ffffff; +} + +.device-phone .phabricator-dark-menu .phabricator-menu-item-view, +.device-tablet .phabricator-dark-menu .phabricator-menu-item-view { + display: block; + padding: 4px 0; + border-width: 1px 0; + border-style: solid; + border-color: #35383b transparent #282b2d; +} + +.device-phone .phabricator-dark-menu .phabricator-menu-item-type-label, +.device-tablet .phabricator-dark-menu .phabricator-menu-item-type-label { + text-transform: uppercase; + font-size: 11px; + background: #151719; + padding-left: 12px; +} + +.device-phone .phabricator-dark-menu .phabricator-menu-item-type-spacer, +.device-tablet .phabricator-dark-menu .phabricator-menu-item-type-spacer { + display: none; +} + + /* - Core Menu ----------------------------------------------------------------- + Styles unique to the core menu (left button on mobile). + */ .phabricator-core-menu-icon { @@ -277,35 +327,11 @@ a:hover .phabricator-main-search-typeahead-result .result-type { display: none; } -.device-phone .phabricator-core-menu-expand .phabricator-core-menu, -.device-tablet .phabricator-core-menu-expand .phabricator-core-menu { +.device-phone .phabricator-core-menu-expanded .phabricator-core-menu, +.device-tablet .phabricator-core-menu-expanded .phabricator-core-menu { display: block; } -.device-phone .phabricator-core-menu, -.device-tablet .phabricator-core-menu, -.device-phone .phabricator-core-menu a.phabricator-menu-item-type-link, -.device-tablet .phabricator-core-menu a.phabricator-menu-item-type-link { - color: #ffffff; -} - -.device-phone .phabricator-core-menu .phabricator-menu-item-view, -.device-tablet .phabricator-core-menu .phabricator-menu-item-view { - display: block; - padding: 4px 0; - border-width: 1px 0; - border-style: solid; - border-color: #35383b transparent #282b2d; -} - -.device-phone .phabricator-core-menu .phabricator-menu-item-type-label, -.device-tablet .phabricator-core-menu .phabricator-menu-item-type-label { - text-transform: uppercase; - font-size: 11px; - background: #151719; - padding-left: 12px; -} - .device-phone .phabricator-core-menu .phabricator-menu-item-type-link, .device-tablet .phabricator-core-menu .phabricator-menu-item-type-link { font-size: 15px; @@ -359,3 +385,36 @@ a:hover .phabricator-main-search-typeahead-result .result-type { border-color: #44494d; margin: 0 8px; } + + +/* - Application Menu ---------------------------------------------------------- + + Styles unique to the application menu (right button on mobile). + +*/ + +.device-phone .phabricator-application-menu-expanded + .phabricator-application-menu, +.device-tablet .phabricator-application-menu-expanded + .phabricator-application-menu { + display: block; + padding-top: 44px; +} + +.phabricator-application-menu { + display: none; +} + +.phabricator-application-menu .phabricator-menu-item-type-link + .phabricator-menu-item-name { + padding-left: 12px; +} + +.device-phone .phabricator-application-menu-expanded + .phabricator-application-menu, +.device-tablet .phabricator-application-menu-expanded + .phabricator-application-menu { + display: block; + padding-top: 44px; +} +