mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 10:12:41 +01:00
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
This commit is contained in:
parent
e3f6bbfff8
commit
f910e38ecc
7 changed files with 200 additions and 34 deletions
|
@ -169,6 +169,11 @@ abstract class PhabricatorController extends AphrontController {
|
||||||
$view->appendChild($page->renderFooter());
|
$view->appendChild($page->renderFooter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$application_menu = $this->buildApplicationMenu();
|
||||||
|
if ($application_menu) {
|
||||||
|
$page->setApplicationMenu($application_menu);
|
||||||
|
}
|
||||||
|
|
||||||
$response = new AphrontWebpageResponse();
|
$response = new AphrontWebpageResponse();
|
||||||
return $response->setContent($page->render());
|
return $response->setContent($page->render());
|
||||||
}
|
}
|
||||||
|
@ -238,4 +243,8 @@ abstract class PhabricatorController extends AphrontController {
|
||||||
return implode('<br />', $items);
|
return implode('<br />', $items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function buildApplicationMenu() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,8 @@ abstract class PhabricatorPasteController extends PhabricatorController {
|
||||||
return $nav;
|
return $nav;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildApplicationMenu() {
|
||||||
|
return $this->buildSideNavView(null)->getMenu();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ final class AphrontSideNavFilterView extends AphrontView {
|
||||||
private $menu;
|
private $menu;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->menu = id(new PhabricatorMenuView());
|
$this->menu = new PhabricatorMenuView();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setActive($active) {
|
public function setActive($active) {
|
||||||
|
@ -59,6 +59,10 @@ final class AphrontSideNavFilterView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMenu() {
|
||||||
|
return $this->menu;
|
||||||
|
}
|
||||||
|
|
||||||
public function addFilter(
|
public function addFilter(
|
||||||
$key,
|
$key,
|
||||||
$name,
|
$name,
|
||||||
|
|
|
@ -11,6 +11,27 @@ final class PhabricatorMenuView extends AphrontView {
|
||||||
return $this;
|
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) {
|
public function addMenuItem(PhabricatorMenuItemView $item) {
|
||||||
$key = $item->getKey();
|
$key = $item->getKey();
|
||||||
if ($key !== null) {
|
if ($key !== null) {
|
||||||
|
|
|
@ -15,6 +15,16 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
private $disableConsole;
|
private $disableConsole;
|
||||||
private $searchDefaultScope;
|
private $searchDefaultScope;
|
||||||
private $pageObjects = array();
|
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) {
|
public function setApplicationName($application_name) {
|
||||||
$this->applicationName = $application_name;
|
$this->applicationName = $application_name;
|
||||||
|
@ -142,11 +152,16 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
require_celerity_resource('javelin-behavior-error-log');
|
require_celerity_resource('javelin-behavior-error-log');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->menuContent = id(new PhabricatorMainMenuView())
|
$menu = id(new PhabricatorMainMenuView())
|
||||||
->setUser($request->getUser())
|
->setUser($request->getUser())
|
||||||
->setController($this->getController())
|
->setController($this->getController())
|
||||||
->setDefaultSearchScope($this->getSearchDefaultScope())
|
->setDefaultSearchScope($this->getSearchDefaultScope());
|
||||||
->render();
|
|
||||||
|
if ($this->getApplicationMenu()) {
|
||||||
|
$menu->setApplicationMenu($this->getApplicationMenu());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->menuContent = $menu->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,17 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
private $user;
|
private $user;
|
||||||
private $defaultSearchScope;
|
private $defaultSearchScope;
|
||||||
private $controller;
|
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) {
|
public function setController(PhabricatorController $controller) {
|
||||||
$this->controller = $controller;
|
$this->controller = $controller;
|
||||||
|
@ -84,6 +95,12 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
|
|
||||||
$actions = '';
|
$actions = '';
|
||||||
|
|
||||||
|
$application_menu = $this->getApplicationMenu();
|
||||||
|
if ($application_menu) {
|
||||||
|
$application_menu->addClass('phabricator-dark-menu');
|
||||||
|
$application_menu->addClass('phabricator-application-menu');
|
||||||
|
}
|
||||||
|
|
||||||
return phutil_render_tag(
|
return phutil_render_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
|
@ -92,8 +109,12 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
),
|
),
|
||||||
self::renderSingleView(
|
self::renderSingleView(
|
||||||
array(
|
array(
|
||||||
$logo,
|
$this->renderPhabricatorMenuButton($header_id),
|
||||||
|
$this->renderApplicationMenuButton($header_id),
|
||||||
|
$this->renderPhabricatorLogo(),
|
||||||
|
$alerts,
|
||||||
$phabricator_menu,
|
$phabricator_menu,
|
||||||
|
$application_menu,
|
||||||
))).
|
))).
|
||||||
self::renderSingleView($menus);
|
self::renderSingleView($menus);
|
||||||
}
|
}
|
||||||
|
@ -130,6 +151,38 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
return $result;
|
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() {
|
private function renderPhabricatorMenu() {
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
$controller = $this->getController();
|
$controller = $this->getController();
|
||||||
|
@ -162,6 +215,7 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
|
|
||||||
|
|
||||||
$view = new PhabricatorMenuView();
|
$view = new PhabricatorMenuView();
|
||||||
|
$view->addClass('phabricator-dark-menu');
|
||||||
$view->addClass('phabricator-core-menu');
|
$view->addClass('phabricator-core-menu');
|
||||||
|
|
||||||
$search = $this->renderSearch();
|
$search = $this->renderSearch();
|
||||||
|
|
|
@ -53,8 +53,7 @@
|
||||||
|
|
||||||
.phabricator-main-menu-expand-button {
|
.phabricator-main-menu-expand-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px;
|
top: 7px;
|
||||||
top: 10px;
|
|
||||||
display: block;
|
display: block;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
|
@ -67,6 +66,14 @@
|
||||||
0 1px 0 rgba(255, 255, 255, 0.075);
|
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 {
|
.device-desktop .phabricator-main-menu-expand-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -76,11 +83,14 @@
|
||||||
display: block;
|
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;
|
background-color: #55595d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* - Search --------------------------------------------------------------------
|
/* - Search --------------------------------------------------------------------
|
||||||
|
|
||||||
The main search input in the menu bar.
|
The main search input in the menu bar.
|
||||||
|
@ -257,8 +267,48 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
|
||||||
display: block;
|
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 -----------------------------------------------------------------
|
/* - Core Menu -----------------------------------------------------------------
|
||||||
|
|
||||||
|
Styles unique to the core menu (left button on mobile).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.phabricator-core-menu-icon {
|
.phabricator-core-menu-icon {
|
||||||
|
@ -277,35 +327,11 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-phone .phabricator-core-menu-expand .phabricator-core-menu,
|
.device-phone .phabricator-core-menu-expanded .phabricator-core-menu,
|
||||||
.device-tablet .phabricator-core-menu-expand .phabricator-core-menu {
|
.device-tablet .phabricator-core-menu-expanded .phabricator-core-menu {
|
||||||
display: block;
|
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-phone .phabricator-core-menu .phabricator-menu-item-type-link,
|
||||||
.device-tablet .phabricator-core-menu .phabricator-menu-item-type-link {
|
.device-tablet .phabricator-core-menu .phabricator-menu-item-type-link {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
@ -359,3 +385,36 @@ a:hover .phabricator-main-search-typeahead-result .result-type {
|
||||||
border-color: #44494d;
|
border-color: #44494d;
|
||||||
margin: 0 8px;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue