mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 16:52:41 +01:00
Switch to new menubar
Summary: - Looks better (can probably still use some tweaks), especially search. - Moves logout from weird footer location to main menu. - Reactive: on tablets and phones, the menu adjusts to remain useful. - Fixed position on desktops for future side nav changes. - Adds an icon header thing that's currently hard-coded but will be application-driven soon. Test Plan: Used menu on desktop, tablet, phone, logged in / logged out, toggled darkconsole. Will add some screenshots. Reviewers: btrahan, chad Reviewed By: btrahan CC: aran Maniphest Tasks: T1569 Differential Revision: https://secure.phabricator.com/D3105
This commit is contained in:
parent
998d43e828
commit
3c7944d297
21 changed files with 988 additions and 419 deletions
|
@ -21,6 +21,13 @@ celerity_register_resource_map(array(
|
|||
'disk' => '/rsrc/image/avatar.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/bolt.png' =>
|
||||
array(
|
||||
'hash' => 'f8c30376f30cf5a8675a5e683400684a',
|
||||
'uri' => '/res/f8c30376/rsrc/image/bolt.png',
|
||||
'disk' => '/rsrc/image/bolt.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/credit_cards.png' =>
|
||||
array(
|
||||
'hash' => '681448de424ea159b6ea68af04c046ae',
|
||||
|
@ -343,6 +350,20 @@ celerity_register_resource_map(array(
|
|||
'disk' => '/rsrc/image/icon/unsubscribe.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/lines.png' =>
|
||||
array(
|
||||
'hash' => '0eb5778b34dd4fcee53b9924b88e0828',
|
||||
'uri' => '/res/0eb5778b/rsrc/image/lines.png',
|
||||
'disk' => '/rsrc/image/lines.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/logo_grey.png' =>
|
||||
array(
|
||||
'hash' => '6cff2a21538eeae471f0ea00cb7bc15d',
|
||||
'uri' => '/res/6cff2a21/rsrc/image/logo_grey.png',
|
||||
'disk' => '/rsrc/image/logo_grey.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/notification_menu.png' =>
|
||||
array(
|
||||
'hash' => 'f3834ad08a16fc631cd46ceb5db4fb0e',
|
||||
|
@ -371,6 +392,13 @@ celerity_register_resource_map(array(
|
|||
'disk' => '/rsrc/image/phabricator_logo_admin.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/search.png' =>
|
||||
array(
|
||||
'hash' => '8c9b0f3000081c1322cd45c4e1b2260c',
|
||||
'uri' => '/res/8c9b0f30/rsrc/image/search.png',
|
||||
'disk' => '/rsrc/image/search.png',
|
||||
'type' => 'png',
|
||||
),
|
||||
'/rsrc/image/sprite.png' =>
|
||||
array(
|
||||
'hash' => '8c6200d3191c0deea30f22e7b8166b15',
|
||||
|
@ -758,7 +786,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-aphlict-dropdown' =>
|
||||
array(
|
||||
'uri' => '/res/425c08fd/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
|
||||
'uri' => '/res/dc8f194b/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -772,7 +800,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-aphlict-listen' =>
|
||||
array(
|
||||
'uri' => '/res/c716b386/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
|
||||
'uri' => '/res/0743d3f3/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1349,7 +1377,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' =>
|
||||
array(
|
||||
'uri' => '/res/06a151d8/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
||||
'uri' => '/res/c5eb65cd/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1462,7 +1490,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-placeholder' =>
|
||||
array(
|
||||
'uri' => '/res/85f097cb/rsrc/js/application/core/behavior-placeholder.js',
|
||||
'uri' => '/res/7dc26990/rsrc/js/application/core/behavior-placeholder.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2178,7 +2206,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-glyph-css' =>
|
||||
array(
|
||||
'uri' => '/res/52f0dc90/rsrc/css/application/base/glyph.css',
|
||||
'uri' => '/res/1c8a36a8/rsrc/css/application/base/glyph.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2220,6 +2248,15 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/core/KeyboardShortcutManager.js',
|
||||
),
|
||||
'phabricator-main-menu-view' =>
|
||||
array(
|
||||
'uri' => '/res/1475552c/rsrc/css/application/base/main-menu-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/css/application/base/main-menu-view.css',
|
||||
),
|
||||
'phabricator-menu-item' =>
|
||||
array(
|
||||
'uri' => '/res/32fc2325/rsrc/js/application/core/DropdownMenuItem.js',
|
||||
|
@ -2253,6 +2290,15 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/css/aphront/notification.css',
|
||||
),
|
||||
'phabricator-notification-menu-css' =>
|
||||
array(
|
||||
'uri' => '/res/fc8a7fb9/rsrc/css/application/base/notification-menu.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/css/application/base/notification-menu.css',
|
||||
),
|
||||
'phabricator-object-selector-css' =>
|
||||
array(
|
||||
'uri' => '/res/7eb4c705/rsrc/css/application/objectselector/object-selector.css',
|
||||
|
@ -2364,7 +2410,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-standard-page-view' =>
|
||||
array(
|
||||
'uri' => '/res/48118f6f/rsrc/css/application/base/standard-page-view.css',
|
||||
'uri' => '/res/4c0444c2/rsrc/css/application/base/standard-page-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2619,7 +2665,7 @@ celerity_register_resource_map(array(
|
|||
), array(
|
||||
'packages' =>
|
||||
array(
|
||||
'12ecfc95' =>
|
||||
'abce9c99' =>
|
||||
array(
|
||||
'name' => 'core.pkg.css',
|
||||
'symbols' =>
|
||||
|
@ -2648,10 +2694,10 @@ celerity_register_resource_map(array(
|
|||
21 => 'phabricator-flag-css',
|
||||
22 => 'aphront-error-view-css',
|
||||
),
|
||||
'uri' => '/res/pkg/12ecfc95/core.pkg.css',
|
||||
'uri' => '/res/pkg/abce9c99/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'f363b322' =>
|
||||
'971b021e' =>
|
||||
array(
|
||||
'name' => 'core.pkg.js',
|
||||
'symbols' =>
|
||||
|
@ -2674,7 +2720,7 @@ celerity_register_resource_map(array(
|
|||
15 => 'javelin-behavior-phabricator-tooltips',
|
||||
16 => 'phabricator-prefab',
|
||||
),
|
||||
'uri' => '/res/pkg/f363b322/core.pkg.js',
|
||||
'uri' => '/res/pkg/971b021e/core.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'96bc37d6' =>
|
||||
|
@ -2815,20 +2861,20 @@ celerity_register_resource_map(array(
|
|||
'reverse' =>
|
||||
array(
|
||||
'aphront-attached-file-view-css' => '7839ae2d',
|
||||
'aphront-crumbs-view-css' => '12ecfc95',
|
||||
'aphront-dialog-view-css' => '12ecfc95',
|
||||
'aphront-error-view-css' => '12ecfc95',
|
||||
'aphront-form-view-css' => '12ecfc95',
|
||||
'aphront-crumbs-view-css' => 'abce9c99',
|
||||
'aphront-dialog-view-css' => 'abce9c99',
|
||||
'aphront-error-view-css' => 'abce9c99',
|
||||
'aphront-form-view-css' => 'abce9c99',
|
||||
'aphront-headsup-action-list-view-css' => '96bc37d6',
|
||||
'aphront-headsup-view-css' => '12ecfc95',
|
||||
'aphront-list-filter-view-css' => '12ecfc95',
|
||||
'aphront-pager-view-css' => '12ecfc95',
|
||||
'aphront-panel-view-css' => '12ecfc95',
|
||||
'aphront-side-nav-view-css' => '12ecfc95',
|
||||
'aphront-table-view-css' => '12ecfc95',
|
||||
'aphront-tokenizer-control-css' => '12ecfc95',
|
||||
'aphront-tooltip-css' => '12ecfc95',
|
||||
'aphront-typeahead-control-css' => '12ecfc95',
|
||||
'aphront-headsup-view-css' => 'abce9c99',
|
||||
'aphront-list-filter-view-css' => 'abce9c99',
|
||||
'aphront-pager-view-css' => 'abce9c99',
|
||||
'aphront-panel-view-css' => 'abce9c99',
|
||||
'aphront-side-nav-view-css' => 'abce9c99',
|
||||
'aphront-table-view-css' => 'abce9c99',
|
||||
'aphront-tokenizer-control-css' => 'abce9c99',
|
||||
'aphront-tooltip-css' => 'abce9c99',
|
||||
'aphront-typeahead-control-css' => 'abce9c99',
|
||||
'differential-changeset-view-css' => '96bc37d6',
|
||||
'differential-core-view-css' => '96bc37d6',
|
||||
'differential-inline-comment-editor' => 'f4bbbd84',
|
||||
|
@ -2846,7 +2892,7 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-aphront-basic-tokenizer' => '97f65640',
|
||||
'javelin-behavior-aphront-drag-and-drop' => 'f4bbbd84',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => 'f4bbbd84',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => 'f363b322',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => '971b021e',
|
||||
'javelin-behavior-audit-preview' => '5e68be89',
|
||||
'javelin-behavior-buoyant' => 'f4bbbd84',
|
||||
'javelin-behavior-differential-accept-with-errors' => 'f4bbbd84',
|
||||
|
@ -2866,20 +2912,20 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-maniphest-transaction-controls' => '7707de41',
|
||||
'javelin-behavior-maniphest-transaction-expand' => '7707de41',
|
||||
'javelin-behavior-maniphest-transaction-preview' => '7707de41',
|
||||
'javelin-behavior-phabricator-autofocus' => 'f363b322',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => 'f363b322',
|
||||
'javelin-behavior-phabricator-autofocus' => '971b021e',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => '971b021e',
|
||||
'javelin-behavior-phabricator-object-selector' => 'f4bbbd84',
|
||||
'javelin-behavior-phabricator-oncopy' => 'f363b322',
|
||||
'javelin-behavior-phabricator-tooltips' => 'f363b322',
|
||||
'javelin-behavior-phabricator-watch-anchor' => 'f363b322',
|
||||
'javelin-behavior-refresh-csrf' => 'f363b322',
|
||||
'javelin-behavior-phabricator-oncopy' => '971b021e',
|
||||
'javelin-behavior-phabricator-tooltips' => '971b021e',
|
||||
'javelin-behavior-phabricator-watch-anchor' => '971b021e',
|
||||
'javelin-behavior-refresh-csrf' => '971b021e',
|
||||
'javelin-behavior-repository-crossreference' => 'f4bbbd84',
|
||||
'javelin-behavior-workflow' => 'f363b322',
|
||||
'javelin-behavior-workflow' => '971b021e',
|
||||
'javelin-dom' => '6fb20113',
|
||||
'javelin-event' => '6fb20113',
|
||||
'javelin-install' => '6fb20113',
|
||||
'javelin-json' => '6fb20113',
|
||||
'javelin-mask' => 'f363b322',
|
||||
'javelin-mask' => '971b021e',
|
||||
'javelin-request' => '6fb20113',
|
||||
'javelin-stratcom' => '6fb20113',
|
||||
'javelin-tokenizer' => '97f65640',
|
||||
|
@ -2891,30 +2937,30 @@ celerity_register_resource_map(array(
|
|||
'javelin-uri' => '6fb20113',
|
||||
'javelin-util' => '6fb20113',
|
||||
'javelin-vector' => '6fb20113',
|
||||
'javelin-workflow' => 'f363b322',
|
||||
'javelin-workflow' => '971b021e',
|
||||
'maniphest-task-summary-css' => '7839ae2d',
|
||||
'maniphest-transaction-detail-css' => '7839ae2d',
|
||||
'phabricator-app-buttons-css' => '12ecfc95',
|
||||
'phabricator-app-buttons-css' => 'abce9c99',
|
||||
'phabricator-content-source-view-css' => '96bc37d6',
|
||||
'phabricator-core-buttons-css' => '12ecfc95',
|
||||
'phabricator-core-css' => '12ecfc95',
|
||||
'phabricator-directory-css' => '12ecfc95',
|
||||
'phabricator-core-buttons-css' => 'abce9c99',
|
||||
'phabricator-core-css' => 'abce9c99',
|
||||
'phabricator-directory-css' => 'abce9c99',
|
||||
'phabricator-drag-and-drop-file-upload' => 'f4bbbd84',
|
||||
'phabricator-dropdown-menu' => 'f363b322',
|
||||
'phabricator-flag-css' => '12ecfc95',
|
||||
'phabricator-jump-nav' => '12ecfc95',
|
||||
'phabricator-keyboard-shortcut' => 'f363b322',
|
||||
'phabricator-keyboard-shortcut-manager' => 'f363b322',
|
||||
'phabricator-menu-item' => 'f363b322',
|
||||
'phabricator-dropdown-menu' => '971b021e',
|
||||
'phabricator-flag-css' => 'abce9c99',
|
||||
'phabricator-jump-nav' => 'abce9c99',
|
||||
'phabricator-keyboard-shortcut' => '971b021e',
|
||||
'phabricator-keyboard-shortcut-manager' => '971b021e',
|
||||
'phabricator-menu-item' => '971b021e',
|
||||
'phabricator-object-selector-css' => '96bc37d6',
|
||||
'phabricator-paste-file-upload' => 'f363b322',
|
||||
'phabricator-prefab' => 'f363b322',
|
||||
'phabricator-paste-file-upload' => '971b021e',
|
||||
'phabricator-prefab' => '971b021e',
|
||||
'phabricator-project-tag-css' => '7839ae2d',
|
||||
'phabricator-remarkup-css' => '12ecfc95',
|
||||
'phabricator-remarkup-css' => 'abce9c99',
|
||||
'phabricator-shaped-request' => 'f4bbbd84',
|
||||
'phabricator-standard-page-view' => '12ecfc95',
|
||||
'phabricator-tooltip' => 'f363b322',
|
||||
'phabricator-transaction-view-css' => '12ecfc95',
|
||||
'syntax-highlighting-css' => '12ecfc95',
|
||||
'phabricator-standard-page-view' => 'abce9c99',
|
||||
'phabricator-tooltip' => '971b021e',
|
||||
'phabricator-transaction-view-css' => 'abce9c99',
|
||||
'syntax-highlighting-css' => 'abce9c99',
|
||||
),
|
||||
));
|
||||
|
|
|
@ -752,6 +752,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
|
||||
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
|
||||
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.php',
|
||||
'PhabricatorMainMenuGroupView' => 'view/page/menu/PhabricatorMainMenuGroupView.php',
|
||||
'PhabricatorMainMenuIconView' => 'view/page/menu/PhabricatorMainMenuIconView.php',
|
||||
'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php',
|
||||
'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php',
|
||||
'PhabricatorMarkupCache' => 'applications/cache/storage/PhabricatorMarkupCache.php',
|
||||
'PhabricatorMarkupEngine' => 'infrastructure/markup/PhabricatorMarkupEngine.php',
|
||||
'PhabricatorMarkupInterface' => 'infrastructure/markup/PhabricatorMarkupInterface.php',
|
||||
|
@ -1781,6 +1785,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
|
||||
'PhabricatorMainMenuGroupView' => 'AphrontView',
|
||||
'PhabricatorMainMenuIconView' => 'AphrontView',
|
||||
'PhabricatorMainMenuSearchView' => 'AphrontView',
|
||||
'PhabricatorMainMenuView' => 'AphrontView',
|
||||
'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
|
||||
'PhabricatorMetaMTAController' => 'PhabricatorController',
|
||||
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
|
||||
|
|
|
@ -110,7 +110,9 @@ final class DifferentialChangesetListView extends AphrontView {
|
|||
|
||||
$changesets = $this->changesets;
|
||||
|
||||
Javelin::initBehavior('buoyant', array());
|
||||
// TODO: Restore this once we make it through the redesign, it has funky
|
||||
// interactions with things and there are various reports that it's slow.
|
||||
// Javelin::initBehavior('buoyant', array());
|
||||
|
||||
Javelin::initBehavior('differential-toggle-files', array());
|
||||
|
||||
|
|
|
@ -37,4 +37,19 @@ final class PhabricatorSearchScope {
|
|||
);
|
||||
}
|
||||
|
||||
public static function getScopePlaceholder($scope) {
|
||||
switch ($scope) {
|
||||
case self::SCOPE_OPEN_TASKS:
|
||||
return pht('Search Open Tasks');
|
||||
case self::SCOPE_WIKI:
|
||||
return pht('Search Wiki Documents');
|
||||
case self::SCOPE_OPEN_REVISIONS:
|
||||
return pht('Search Open Revisions');
|
||||
case self::SCOPE_COMMITS:
|
||||
return pht('Search Commits');
|
||||
default:
|
||||
return pht('Search');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,9 +62,11 @@ abstract class AphrontPageView extends AphrontView {
|
|||
$this->willRenderPage();
|
||||
|
||||
$title = phutil_escape_html($this->getTitle());
|
||||
$head = $this->getHead();
|
||||
$body = $this->getBody();
|
||||
$tail = $this->getTail();
|
||||
// NOTE: Render HEAD last so we can pick up resources required by the other
|
||||
// parts.
|
||||
$head = $this->getHead();
|
||||
|
||||
$body_classes = $this->getBodyClasses();
|
||||
|
||||
|
|
|
@ -149,9 +149,6 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
require_celerity_resource('phabricator-core-css');
|
||||
require_celerity_resource('phabricator-core-buttons-css');
|
||||
require_celerity_resource('phabricator-standard-page-view');
|
||||
if (PhabricatorEnv::getEnvConfig('notification.enabled')) {
|
||||
require_celerity_resource('phabricator-notification-css');
|
||||
}
|
||||
|
||||
$current_token = null;
|
||||
$request = $this->getRequest();
|
||||
|
@ -172,19 +169,6 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
'current' => $current_token,
|
||||
));
|
||||
|
||||
$pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT;
|
||||
if ($user) {
|
||||
$shortcut = $user->loadPreferences()->getPreference($pref_shortcut, 1);
|
||||
} else {
|
||||
$shortcut = 1;
|
||||
}
|
||||
Javelin::initBehavior(
|
||||
'phabricator-keyboard-shortcuts',
|
||||
array(
|
||||
'helpURI' => '/help/keyboardshortcut/',
|
||||
'search_shortcut' => $shortcut,
|
||||
));
|
||||
|
||||
if ($console) {
|
||||
require_celerity_resource('aphront-dark-console-css');
|
||||
Javelin::initBehavior(
|
||||
|
@ -317,7 +301,12 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
'method' => 'post',
|
||||
'style' => 'display: inline',
|
||||
),
|
||||
'<input type="text" name="query" id="standard-search-box" />'.
|
||||
'<div class="menu-section menu-section-search">'.
|
||||
'<div class="menu-search-container">'.
|
||||
'<input type="text" name="query" id="standard-search-box" />'.
|
||||
'<button id="standard-search-button">Search</button>'.
|
||||
'</div>'.
|
||||
'</div>'.
|
||||
' in '.
|
||||
AphrontFormSelectControl::renderSelectTag(
|
||||
$this->getSearchDefaultScope(),
|
||||
|
@ -362,19 +351,6 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
$foot_links[] = $link;
|
||||
}
|
||||
|
||||
if ($user && $user->getPHID()) {
|
||||
// This ends up very early in tab order at the top of the page and there's
|
||||
// a bunch of junk up there anyway, just shove it down here.
|
||||
$foot_links[] = phabricator_render_form(
|
||||
$user,
|
||||
array(
|
||||
'action' => '/logout/',
|
||||
'method' => 'post',
|
||||
'style' => 'display: inline',
|
||||
),
|
||||
'<button class="link">Logout</button>');
|
||||
}
|
||||
|
||||
$foot_links = implode(' · ', $foot_links);
|
||||
|
||||
$admin_class = null;
|
||||
|
@ -382,119 +358,10 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
$admin_class = 'phabricator-admin-page-view';
|
||||
}
|
||||
|
||||
$notification_indicator = '';
|
||||
$notification_dropdown = '';
|
||||
$notification_container = '';
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('notification.enabled') &&
|
||||
$user &&
|
||||
$user->isLoggedIn()) {
|
||||
|
||||
$aphlict_object_id = 'aphlictswfobject';
|
||||
|
||||
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
|
||||
$client_uri = new PhutilURI($client_uri);
|
||||
if ($client_uri->getDomain() == 'localhost') {
|
||||
$this_host = $this->getRequest()->getHost();
|
||||
$this_host = new PhutilURI('http://'.$this_host.'/');
|
||||
$client_uri->setDomain($this_host->getDomain());
|
||||
}
|
||||
|
||||
$enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
|
||||
|
||||
Javelin::initBehavior(
|
||||
'aphlict-listen',
|
||||
array(
|
||||
'id' => $aphlict_object_id,
|
||||
'server' => $client_uri->getDomain(),
|
||||
'port' => $client_uri->getPort(),
|
||||
'debug' => $enable_debug,
|
||||
'pageObjects' => array_fill_keys($this->pageObjects, true),
|
||||
));
|
||||
|
||||
Javelin::initBehavior('aphlict-dropdown', array());
|
||||
|
||||
$notification_count = id(new PhabricatorFeedStoryNotification())
|
||||
->countUnread($user);
|
||||
|
||||
$indicator_classes = array(
|
||||
'phabricator-notification-indicator',
|
||||
);
|
||||
if ($notification_count) {
|
||||
$indicator_classes[] = 'phabricator-notification-indicator-unread';
|
||||
}
|
||||
|
||||
$notification_indicator = javelin_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'phabricator-notification-indicator',
|
||||
'class' => implode(' ', $indicator_classes),
|
||||
),
|
||||
$notification_count);
|
||||
|
||||
$notification_indicator = javelin_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'phabricator-notification-menu',
|
||||
'class' => 'phabricator-icon-menu icon-menu-notifications',
|
||||
'sigil' => 'aphlict-indicator',
|
||||
),
|
||||
$notification_indicator);
|
||||
|
||||
$notification_indicator = javelin_render_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'phabricator-icon-menu-cell',
|
||||
),
|
||||
$notification_indicator);
|
||||
|
||||
$notification_container =
|
||||
'<div id="aphlictswf-container" style="height:0px; width:0px;">'.
|
||||
'</div>';
|
||||
$notification_dropdown =
|
||||
javelin_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'sigil' => 'aphlict-dropdown',
|
||||
'id' => 'phabricator-notification-dropdown',
|
||||
'style' => 'display: none',
|
||||
),
|
||||
'');
|
||||
}
|
||||
|
||||
$header_chrome = null;
|
||||
$footer_chrome = null;
|
||||
if ($this->getShowChrome()) {
|
||||
$header_chrome =
|
||||
'<table class="phabricator-standard-header">'.
|
||||
'<tr>'.
|
||||
'<td class="phabricator-logo">'.
|
||||
'<a class="logo-standard" href="/"> </a>'.
|
||||
'</td>'.
|
||||
$notification_indicator.
|
||||
'<td>'.
|
||||
'<table class="phabricator-primary-navigation">'.
|
||||
'<tr>'.
|
||||
'<th>'.
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $this->getBaseURI(),
|
||||
'class' => 'phabricator-head-appname',
|
||||
),
|
||||
phutil_escape_html($this->getApplicationName())).
|
||||
'</th>'.
|
||||
$tabs.
|
||||
'</tr>'.
|
||||
'</table>'.
|
||||
'</td>'.
|
||||
'<td class="phabricator-login-details">'.
|
||||
$login_stuff.
|
||||
'</td>'.
|
||||
'</tr>'.
|
||||
'</table>'.
|
||||
$notification_dropdown.
|
||||
$notification_container;
|
||||
$header_chrome = $this->renderMainMenu();
|
||||
$footer_chrome =
|
||||
'<div class="phabricator-page-foot">'.
|
||||
$foot_links.
|
||||
|
@ -531,8 +398,6 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
$classes = implode(' ', $classes);
|
||||
|
||||
return
|
||||
($console ? '<darkconsole />' : null).
|
||||
$developer_warning.
|
||||
phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
|
@ -540,15 +405,58 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
'class' => $classes,
|
||||
),
|
||||
$header_chrome.
|
||||
$this->bodyContent.
|
||||
'<div style="clear: both;"></div>').
|
||||
'<div class="phabricator-standard-page-body">'.
|
||||
($console ? '<darkconsole />' : null).
|
||||
$developer_warning.
|
||||
$this->bodyContent.
|
||||
'<div style="clear: both;"></div>'.
|
||||
'</div>').
|
||||
$footer_chrome;
|
||||
}
|
||||
|
||||
protected function getTail() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$container = null;
|
||||
if (PhabricatorEnv::getEnvConfig('notification.enabled') &&
|
||||
$user->isLoggedIn()) {
|
||||
|
||||
$aphlict_object_id = celerity_generate_unique_node_id();
|
||||
$aphlict_container_id = celerity_generate_unique_node_id();
|
||||
|
||||
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
|
||||
$client_uri = new PhutilURI($client_uri);
|
||||
if ($client_uri->getDomain() == 'localhost') {
|
||||
$this_host = $this->getRequest()->getHost();
|
||||
$this_host = new PhutilURI('http://'.$this_host.'/');
|
||||
$client_uri->setDomain($this_host->getDomain());
|
||||
}
|
||||
|
||||
$enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
|
||||
Javelin::initBehavior(
|
||||
'aphlict-listen',
|
||||
array(
|
||||
'id' => $aphlict_object_id,
|
||||
'containerID' => $aphlict_container_id,
|
||||
'server' => $client_uri->getDomain(),
|
||||
'port' => $client_uri->getPort(),
|
||||
'debug' => $enable_debug,
|
||||
'pageObjects' => array_fill_keys($this->pageObjects, true),
|
||||
));
|
||||
$container = phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $aphlict_container_id,
|
||||
'style' => 'position: absolute; width: 0; height: 0;',
|
||||
),
|
||||
'asdb');
|
||||
}
|
||||
|
||||
$response = CelerityAPI::getStaticResourceResponse();
|
||||
return
|
||||
$response->renderResourcesOfType('js').
|
||||
$container.
|
||||
$response->renderHTMLFooter();
|
||||
}
|
||||
|
||||
|
@ -568,4 +476,55 @@ final class PhabricatorStandardPageView extends AphrontPageView {
|
|||
}
|
||||
return $this->getRequest()->getApplicationConfiguration()->getConsole();
|
||||
}
|
||||
|
||||
private function renderMainMenu() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$menu = new PhabricatorMainMenuView();
|
||||
$menu->setUser($user);
|
||||
|
||||
$keyboard_config = array(
|
||||
'helpURI' => '/help/keyboardshortcut/',
|
||||
);
|
||||
|
||||
if ($user->isLoggedIn()) {
|
||||
$search = new PhabricatorMainMenuSearchView();
|
||||
$search->setUser($user);
|
||||
$search->setScope($this->getSearchDefaultScope());
|
||||
$menu->appendChild($search);
|
||||
|
||||
$pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT;
|
||||
if ($user->loadPreferences()->getPreference($pref_shortcut, true)) {
|
||||
$keyboard_config['searchID'] = $search->getID();
|
||||
}
|
||||
}
|
||||
|
||||
Javelin::initBehavior('phabricator-keyboard-shortcuts', $keyboard_config);
|
||||
|
||||
if ($user->isLoggedIn()) {
|
||||
require_celerity_resource('phabricator-glyph-css');
|
||||
|
||||
$item = new PhabricatorMainMenuIconView();
|
||||
$item->setName($user->getUsername());
|
||||
$item->addClass('glyph glyph-profile');
|
||||
$item->setHref('/p/'.$user->getUsername().'/');
|
||||
$menu->appendChild($item);
|
||||
|
||||
$item = new PhabricatorMainMenuIconView();
|
||||
$item->setName(pht('Settings'));
|
||||
$item->addClass('glyph glyph-settings');
|
||||
$item->setHref('/settings/');
|
||||
$menu->appendChild($item);
|
||||
|
||||
$item = new PhabricatorMainMenuIconView();
|
||||
$item->setName(pht('Log Out'));
|
||||
$item->addClass('glyph glyph-logout');
|
||||
$item->setHref('/logout/');
|
||||
$menu->appendChild($item);
|
||||
}
|
||||
|
||||
return $menu->render();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
55
src/view/page/menu/PhabricatorMainMenuGroupView.php
Normal file
55
src/view/page/menu/PhabricatorMainMenuGroupView.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorMainMenuGroupView extends AphrontView {
|
||||
|
||||
private $collapsible = true;
|
||||
private $classes = array();
|
||||
|
||||
public function addClass($class) {
|
||||
$this->classes[] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCollapsible($collapsible) {
|
||||
$this->collapsible = $collapsible;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$classes = array(
|
||||
'phabricator-main-menu-group',
|
||||
);
|
||||
|
||||
if ($this->collapsible) {
|
||||
$classes[] = 'phabricator-main-menu-collapsible';
|
||||
}
|
||||
|
||||
if ($this->classes) {
|
||||
$classes = array_merge($classes, $this->classes);
|
||||
}
|
||||
|
||||
return phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => implode(' ', $classes),
|
||||
),
|
||||
$this->renderChildren());
|
||||
}
|
||||
|
||||
}
|
79
src/view/page/menu/PhabricatorMainMenuIconView.php
Normal file
79
src/view/page/menu/PhabricatorMainMenuIconView.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorMainMenuIconView extends AphrontView {
|
||||
|
||||
private $classes = array();
|
||||
private $href;
|
||||
private $name;
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setHref($href) {
|
||||
$this->href = $href;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHref() {
|
||||
return $this->href;
|
||||
}
|
||||
|
||||
public function addClass($class) {
|
||||
$this->classes[] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function render() {
|
||||
$name = $this->getName();
|
||||
$href = $this->getHref();
|
||||
|
||||
$classes = $this->classes;
|
||||
$classes[] = 'phabricator-main-menu-icon';
|
||||
|
||||
$label = javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $href,
|
||||
'class' => 'phabricator-main-menu-icon-label',
|
||||
),
|
||||
phutil_escape_html($name));
|
||||
|
||||
$item = javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $href,
|
||||
'class' => implode(' ', $classes),
|
||||
),
|
||||
'');
|
||||
|
||||
$group = new PhabricatorMainMenuGroupView();
|
||||
$group->appendChild($item);
|
||||
$group->appendChild($label);
|
||||
|
||||
return $group->render();
|
||||
}
|
||||
|
||||
}
|
90
src/view/page/menu/PhabricatorMainMenuSearchView.php
Normal file
90
src/view/page/menu/PhabricatorMainMenuSearchView.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorMainMenuSearchView extends AphrontView {
|
||||
|
||||
private $user;
|
||||
private $scope;
|
||||
private $id;
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setScope($scope) {
|
||||
$this->scope = $scope;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getID() {
|
||||
if (!$this->id) {
|
||||
$this->id = celerity_generate_unique_node_id();
|
||||
}
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$user = $this->user;
|
||||
|
||||
$search_id = $this->getID();
|
||||
|
||||
$input = phutil_render_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'query',
|
||||
'id' => $search_id,
|
||||
));
|
||||
|
||||
$scope = $this->scope;
|
||||
|
||||
Javelin::initBehavior(
|
||||
'placeholder',
|
||||
array(
|
||||
'id' => $search_id,
|
||||
'text' => PhabricatorSearchScope::getScopePlaceholder($scope),
|
||||
));
|
||||
|
||||
$scope_input = phutil_render_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'scope',
|
||||
'value' => $scope,
|
||||
));
|
||||
|
||||
$form = phabricator_render_form(
|
||||
$user,
|
||||
array(
|
||||
'action' => '/search/',
|
||||
'method' => 'POST',
|
||||
),
|
||||
'<div class="phabricator-main-menu-search-container">'.
|
||||
$input.
|
||||
'<button>Search</button>'.
|
||||
$scope_input.
|
||||
'</div>');
|
||||
|
||||
$group = new PhabricatorMainMenuGroupView();
|
||||
$group->addClass('phabricator-main-menu-search');
|
||||
$group->appendChild($form);
|
||||
return $group->render();
|
||||
}
|
||||
|
||||
}
|
149
src/view/page/menu/PhabricatorMainMenuView.php
Normal file
149
src/view/page/menu/PhabricatorMainMenuView.php
Normal file
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class PhabricatorMainMenuView extends AphrontView {
|
||||
|
||||
private $user;
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$user = $this->user;
|
||||
|
||||
require_celerity_resource('phabricator-main-menu-view');
|
||||
|
||||
$header_id = celerity_generate_unique_node_id();
|
||||
$extra = '';
|
||||
|
||||
$group = new PhabricatorMainMenuGroupView();
|
||||
$group->addClass('phabricator-main-menu-group-logo');
|
||||
$group->setCollapsible(false);
|
||||
|
||||
$group->appendChild(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu-logo',
|
||||
'href' => '/',
|
||||
),
|
||||
'<span>Phabricator</span>'));
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('notification.enabled') &&
|
||||
$user->isLoggedIn()) {
|
||||
list($menu, $dropdown) = $this->renderNotificationMenu();
|
||||
$group->appendChild($menu);
|
||||
$extra .= $dropdown;
|
||||
}
|
||||
|
||||
$group->appendChild(
|
||||
javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu-expand-button',
|
||||
'sigil' => 'jx-toggle-class',
|
||||
'meta' => array(
|
||||
'map' => array(
|
||||
$header_id => 'phabricator-main-menu-reveal',
|
||||
),
|
||||
),
|
||||
),
|
||||
'<span>Expand</span>'));
|
||||
$logo = $group->render();
|
||||
|
||||
return phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu',
|
||||
'id' => $header_id,
|
||||
),
|
||||
$logo.$this->renderChildren()).
|
||||
$extra;
|
||||
}
|
||||
|
||||
private function renderNotificationMenu() {
|
||||
$user = $this->user;
|
||||
|
||||
require_celerity_resource('phabricator-notification-css');
|
||||
require_celerity_resource('phabricator-notification-menu-css');
|
||||
|
||||
$indicator_id = celerity_generate_unique_node_id();
|
||||
$dropdown_id = celerity_generate_unique_node_id();
|
||||
$menu_id = celerity_generate_unique_node_id();
|
||||
|
||||
$notification_count = id(new PhabricatorFeedStoryNotification())
|
||||
->countUnread($user);
|
||||
|
||||
$classes = array(
|
||||
'phabricator-main-menu-alert-indicator',
|
||||
);
|
||||
if ($notification_count) {
|
||||
$classes[] = 'phabricator-main-menu-alert-indicator-unread';
|
||||
}
|
||||
|
||||
$notification_indicator = javelin_render_tag(
|
||||
'span',
|
||||
array(
|
||||
'id' => $indicator_id,
|
||||
'class' => implode(' ', $classes),
|
||||
),
|
||||
$notification_count);
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'phabricator-main-menu-alert-item';
|
||||
$classes[] = 'phabricator-main-menu-alert-item-notification';
|
||||
|
||||
$notification_icon = javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/notification/',
|
||||
'class' => implode(' ', $classes),
|
||||
'id' => $menu_id,
|
||||
),
|
||||
$notification_indicator);
|
||||
|
||||
$notification_menu = javelin_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu-alert',
|
||||
),
|
||||
$notification_icon);
|
||||
|
||||
Javelin::initBehavior(
|
||||
'aphlict-dropdown',
|
||||
array(
|
||||
'menuID' => $menu_id,
|
||||
'indicatorID' => $indicator_id,
|
||||
'dropdownID' => $dropdown_id,
|
||||
));
|
||||
|
||||
$notification_dropdown = javelin_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $dropdown_id,
|
||||
'class' => 'phabricator-notification-menu',
|
||||
'sigil' => 'phabricator-notification-menu',
|
||||
'style' => 'display: none;',
|
||||
),
|
||||
'');
|
||||
|
||||
return array($notification_menu, $notification_dropdown);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,61 +13,61 @@
|
|||
}
|
||||
|
||||
.glyph-profile-active {
|
||||
background-position: 0 -56px;
|
||||
background-position: 0 -28px;
|
||||
}
|
||||
|
||||
.glyph-profile:hover {
|
||||
background-position: 0 -112px;
|
||||
background-position: 0 -56px;
|
||||
}
|
||||
|
||||
|
||||
.glyph-settings {
|
||||
background-position: -56px 0;
|
||||
background-position: -28px 0;
|
||||
}
|
||||
|
||||
.glyph-settings-active {
|
||||
background-position: -56px -56px;
|
||||
background-position: -28px -28px;
|
||||
}
|
||||
|
||||
.glyph-settings:hover {
|
||||
background-position: -56px -112px;
|
||||
background-position: -28px -56px;
|
||||
}
|
||||
|
||||
|
||||
.glyph-logout {
|
||||
background-position: -112px 0;
|
||||
background-position: -56px 0;
|
||||
}
|
||||
|
||||
.glyph-logout-active {
|
||||
background-position: -112px -56px;
|
||||
background-position: -56px -28px;
|
||||
}
|
||||
|
||||
.glyph-logout:hover {
|
||||
background-position: -112px -112px;
|
||||
background-position: -56px -56px;
|
||||
}
|
||||
|
||||
|
||||
.glyph-notification {
|
||||
background-position: -168px 0;
|
||||
background-position: -84px 0;
|
||||
}
|
||||
|
||||
.glyph-notification-active {
|
||||
background-position: -168px -56px;
|
||||
background-position: -84px -28px;
|
||||
}
|
||||
|
||||
.glyph-notification:hover {
|
||||
background-position: -168px -112px;
|
||||
background-position: -84px -56px;
|
||||
}
|
||||
|
||||
|
||||
.glyph-menu {
|
||||
background-position: -224px 0;
|
||||
background-position: -112px 0;
|
||||
}
|
||||
|
||||
.glyph-menu-active {
|
||||
background-position: -224px -56px;
|
||||
background-position: -112px -28px;
|
||||
}
|
||||
|
||||
.glyph-menu:hover {
|
||||
background-position: -224px -112px;
|
||||
background-position: -112px -56px;
|
||||
}
|
||||
|
|
301
webroot/rsrc/css/application/base/main-menu-view.css
Normal file
301
webroot/rsrc/css/application/base/main-menu-view.css
Normal file
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
* @provides phabricator-main-menu-view
|
||||
*/
|
||||
|
||||
|
||||
/* - Main Menu -----------------------------------------------------------------
|
||||
|
||||
Main menu at the top of every page that has chrome. It reacts to resolution
|
||||
changes in order to behave reasonably on tablets and phones.
|
||||
|
||||
*/
|
||||
|
||||
.phabricator-main-menu {
|
||||
background: #33393d;
|
||||
position: relative;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.25);
|
||||
overflow: hidden;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.phabricator-main-menu a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-main-menu {
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 6;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-standard-page-body {
|
||||
margin-top: 44px;
|
||||
}
|
||||
|
||||
|
||||
/* - Main Menu Group -----------------------------------------------------------
|
||||
|
||||
Container representing a single item on the main menu. For desktops these lay
|
||||
out horizontally; on phones they switch to vertical.
|
||||
|
||||
*/
|
||||
|
||||
.device-desktop .phabricator-main-menu-group {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-main-menu-group,
|
||||
.device-phone .phabricator-main-menu-group {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid #33393d;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
/* - Logo ----------------------------------------------------------------------
|
||||
|
||||
The "Phabricator" logo group in the main menu. On tablet and phone devices,
|
||||
this shows a "reveal" button to expand/collapse the rest of the menu.
|
||||
|
||||
*/
|
||||
|
||||
.phabricator-main-menu-group-logo {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-logo {
|
||||
display: inline-block;
|
||||
height: 44px;
|
||||
width: 180px;
|
||||
margin-right: 12px;
|
||||
background: 12px 9px url(/rsrc/image/logo_grey.png) no-repeat;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-logo span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* - Expand/Collapse Button ----------------------------------------------------
|
||||
|
||||
On phones, the menu switches to a vertical layout and uses a button to expand
|
||||
or collapse the items.
|
||||
|
||||
*/
|
||||
|
||||
.phabricator-main-menu-expand-button {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 28px;
|
||||
text-align: center;
|
||||
background: #22292d url(/rsrc/image/lines.png) no-repeat 8px 6px;
|
||||
border-radius: 6px;
|
||||
|
||||
border: 1px solid #111111;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
|
||||
0 1px 0 rgba(255, 255, 255, 0.075);
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-main-menu-expand-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-main-menu-expand-button,
|
||||
.device-phone .phabricator-main-menu-expand-button {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-expand-button span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-reveal .phabricator-main-menu-expand-button {
|
||||
background-color: #55595d;
|
||||
}
|
||||
|
||||
|
||||
/* - Icon Menus ----------------------------------------------------------------
|
||||
|
||||
These are the small icons for actions like "Settings" and "Log Out" which
|
||||
appear on the right side of the main menu. On tablets and phones these layout
|
||||
vertically.
|
||||
|
||||
*/
|
||||
|
||||
.phabricator-main-menu-icon {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin: 9px;
|
||||
display: inline-block;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-main-menu-icon-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-main-menu-icon-label,
|
||||
.device-phone .phabricator-main-menu-icon-label {
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
margin-left: 40px;
|
||||
height: 26px;
|
||||
margin: 15px 9px 3px 60px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-main-menu-icon,
|
||||
.device-phone .phabricator-main-menu-icon {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border: 0;
|
||||
margin-left: 24px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* - Search --------------------------------------------------------------------
|
||||
|
||||
The main search input in the menu bar.
|
||||
|
||||
*/
|
||||
|
||||
.device-desktop .phabricator-main-menu-search {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search-container {
|
||||
padding: 10px 0;
|
||||
position: relative;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-main-menu-search-container {
|
||||
margin: 0 8px 0 50px;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-main-menu-search-container,
|
||||
.device-phone .phabricator-main-menu-search-container {
|
||||
margin: 0 18px 0 60px;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search input {
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
|
||||
width: 100%;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
|
||||
border: 1px solid #333333;
|
||||
border-radius: 12px;
|
||||
background: #727272;
|
||||
height: 12px;
|
||||
line-height: 12px;
|
||||
box-shadow: 0px 1px 1px rgba(128, 128, 128, 0.25);
|
||||
padding: 6px 32px 6px 10px;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search input:focus {
|
||||
background: #c9c9c9;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search input.jx-placeholder {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-search button {
|
||||
position: absolute;
|
||||
color: transparent;
|
||||
background: transparent 5px 6px url(/rsrc/image/search.png) no-repeat;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
top: 11px;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
|
||||
/* - Collapsible ---------------------------------------------------------------
|
||||
|
||||
By default, groups are collapsible, which means they'll be hidden on phones
|
||||
and respond to the menu toggle button.
|
||||
|
||||
*/
|
||||
|
||||
.device-tablet .phabricator-main-menu-collapsible,
|
||||
.device-phone .phabricator-main-menu-collapsible {
|
||||
background: #44494d;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-reveal {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-main-menu-reveal .phabricator-main-menu-collapsible,
|
||||
.device-phone .phabricator-main-menu-reveal .phabricator-main-menu-collapsible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
/* - Alert ---------------------------------------------------------------------
|
||||
|
||||
Alert menus are like icon menus but don't obey collapse rules.
|
||||
|
||||
*/
|
||||
|
||||
.phabricator-main-menu-alert {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-alert-item {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin: 9px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-alert-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-alert-indicator-unread {
|
||||
position: absolute;
|
||||
display: block;
|
||||
|
||||
right: 0px;
|
||||
top: 2px;
|
||||
padding: 1px 4px 2px;
|
||||
|
||||
background: #dd3333;
|
||||
|
||||
border: 1px solid #aa0000;
|
||||
font-size: 11px;
|
||||
|
||||
box-shadow: 0px 0px 6px rgba(255, 255, 255, 0.5);
|
||||
border-radius: 6px;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.phabricator-main-menu-alert-item-notification {
|
||||
background: url(/rsrc/image/bolt.png) no-repeat;
|
||||
}
|
52
webroot/rsrc/css/application/base/notification-menu.css
Normal file
52
webroot/rsrc/css/application/base/notification-menu.css
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @provides phabricator-notification-menu-css
|
||||
*/
|
||||
|
||||
.phabricator-notification-menu {
|
||||
background: #ffffff;
|
||||
font-size: 11px;
|
||||
word-wrap: break-word;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.device-desktop .phabricator-notification-menu {
|
||||
position: fixed;
|
||||
width: 360px;
|
||||
top: 42px;
|
||||
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.5);
|
||||
z-index: 9;
|
||||
|
||||
border: 1px solid #33393d;
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.device-tablet .phabricator-notification-menu,
|
||||
.device-phone .phabricator-notification-menu {
|
||||
border-bottom: 1px solid #222222;
|
||||
}
|
||||
|
||||
|
||||
.phabricator-notification {
|
||||
padding: 6px 6px;
|
||||
margin: 1px 0;
|
||||
}
|
||||
|
||||
.no-notifications {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.phabricator-notification-list {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.phabricator-notification-list .phabricator-notification-unread,
|
||||
.phabricator-notification-menu .phabricator-notification-unread {
|
||||
background: #aacfef;
|
||||
}
|
||||
|
||||
.view-all-notifications {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background: #eeeeee;
|
||||
border-top: 1px solid #dddddd;
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
* @provides phabricator-standard-page-view
|
||||
*/
|
||||
|
||||
|
||||
.phabricator-standard-page {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
@ -10,95 +9,8 @@
|
|||
.phabricator-chromeless-page .phabricator-standard-page {
|
||||
background: transparent;
|
||||
border-width: 0px;
|
||||
|
||||
-webkit-box-shadow: none;
|
||||
-mox-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.phabricator-standard-header {
|
||||
background: #005588;
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.phabricator-standard-header td {
|
||||
vertical-align: bottom;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.phabricator-primary-navigation {
|
||||
padding-top: 24px;
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.phabricator-standard-header a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.phabricator-primary-navigation th,
|
||||
.phabricator-primary-navigation td {
|
||||
vertical-align: bottom;
|
||||
font-size: 13px;
|
||||
border-bottom: 6px solid transparent;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.phabricator-logo {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.phabricator-logo a {
|
||||
display: block;
|
||||
width: 220px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.phabricator-logo a.logo-standard {
|
||||
background: url(/rsrc/image/phabricator_logo.png) no-repeat -220px 0;
|
||||
}
|
||||
|
||||
.phabricator-admin-page-view .phabricator-logo a.logo-standard {
|
||||
background-image: url(/rsrc/image/phabricator_logo_admin.png);
|
||||
}
|
||||
|
||||
.phabricator-logo a.logo-standard:hover {
|
||||
background-position: -220px -40px;
|
||||
}
|
||||
|
||||
.phabricator-primary-navigation td {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.phabricator-primary-navigation td.phabricator-selected-tab {
|
||||
border-bottom-color: #ffffff;
|
||||
background: #336699;
|
||||
}
|
||||
|
||||
|
||||
.phabricator-standard-header .phabricator-head-appname {
|
||||
padding: 0 1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
td.phabricator-login-details {
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
padding: 0px 24px;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
.phabricator-page-foot {
|
||||
text-align: right;
|
||||
margin: 2em;
|
||||
|
@ -108,14 +20,6 @@ td.phabricator-login-details {
|
|||
color: #666666;
|
||||
}
|
||||
|
||||
.phabricator-admin-page-view .phabricator-standard-header {
|
||||
background: #aa0000;
|
||||
}
|
||||
|
||||
.phabricator-admin-page-view td.phabricator-selected-tab {
|
||||
background: #cc3333;
|
||||
}
|
||||
|
||||
.keyboard-shortcut-help td,
|
||||
.keyboard-shortcut-help th {
|
||||
padding: 8px;
|
||||
|
@ -216,99 +120,10 @@ a.handle-disabled {
|
|||
|
||||
}
|
||||
|
||||
.phabricator-icon-menu {
|
||||
height: 40px;
|
||||
width: 60px;
|
||||
left: -22px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.phabricator-icon-menu-cell {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.phabricator-admin-page-view .icon-menu-notifications {
|
||||
background: url(/rsrc/image/notification_menu_admin.png);
|
||||
}
|
||||
|
||||
.icon-menu-notifications {
|
||||
background: url(/rsrc/image/notification_menu.png);
|
||||
}
|
||||
|
||||
.phabricator-icon-menu:hover {
|
||||
background-position: 0 -40px;
|
||||
}
|
||||
|
||||
.phabricator-notification-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.phabricator-notification-indicator-unread {
|
||||
display: block;
|
||||
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 2px;
|
||||
padding: 1px 3px;
|
||||
|
||||
background: #dd3333;
|
||||
|
||||
border: 1px solid #aa0000;
|
||||
font-size: 11px;
|
||||
|
||||
box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
|
||||
#phabricator-notification-dropdown {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
|
||||
border: 1px solid #99c4d7;
|
||||
border-top-width: 0;
|
||||
background: #fdfdff;
|
||||
|
||||
width: 360px;
|
||||
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
|
||||
|
||||
font-size: 11px;
|
||||
|
||||
z-index: 3;
|
||||
|
||||
word-wrap: break-word;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.phabricator-notification {
|
||||
padding: 6px 6px;
|
||||
margin: 1px 0;
|
||||
}
|
||||
|
||||
.no-notifications {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.phabricator-notification-list {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.phabricator-notification-list .phabricator-notification-unread,
|
||||
#phabricator-notification-dropdown .phabricator-notification-unread {
|
||||
background: #aacfef;
|
||||
}
|
||||
|
||||
.view-all-notifications {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background: #eeeeee;
|
||||
border-top: 1px solid #dddddd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder text added to inputs by the "placeholder" behavior.
|
||||
*/
|
||||
.jx-placeholder {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
|
|
BIN
webroot/rsrc/image/bolt.png
Normal file
BIN
webroot/rsrc/image/bolt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 351 B |
BIN
webroot/rsrc/image/lines.png
Normal file
BIN
webroot/rsrc/image/lines.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
webroot/rsrc/image/logo_grey.png
Normal file
BIN
webroot/rsrc/image/logo_grey.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
webroot/rsrc/image/search.png
Normal file
BIN
webroot/rsrc/image/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 276 B |
|
@ -8,9 +8,9 @@
|
|||
*/
|
||||
|
||||
JX.behavior('aphlict-dropdown', function(config) {
|
||||
var dropdown = JX.$('phabricator-notification-dropdown');
|
||||
var indicator = JX.$('phabricator-notification-indicator');
|
||||
var menu = JX.$('phabricator-notification-menu');
|
||||
var dropdown = JX.$(config.dropdownID);
|
||||
var indicator = JX.$(config.indicatorID);
|
||||
var menu = JX.$(config.menuID);
|
||||
var visible = false;
|
||||
var request = null;
|
||||
|
||||
|
@ -18,15 +18,14 @@ JX.behavior('aphlict-dropdown', function(config) {
|
|||
if (request) { //already fetching
|
||||
return;
|
||||
}
|
||||
|
||||
request = new JX.Request('/notification/panel/', function(response) {
|
||||
JX.DOM.setContent(indicator, response.number);
|
||||
if (response.number == 0) {
|
||||
JX.DOM.alterClass(indicator,
|
||||
"phabricator-notification-indicator-unread", false);
|
||||
"phabricator-main-menu-alert-indicator-unread", false);
|
||||
} else {
|
||||
JX.DOM.alterClass(indicator,
|
||||
"phabricator-notification-indicator-unread", true);
|
||||
"phabricator-main-menu-alert-indicator-unread", true);
|
||||
}
|
||||
JX.DOM.setContent(dropdown, JX.$H(response.content));
|
||||
request = null;
|
||||
|
@ -34,16 +33,14 @@ JX.behavior('aphlict-dropdown', function(config) {
|
|||
request.send();
|
||||
}
|
||||
|
||||
//populate panel
|
||||
refresh();
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'click',
|
||||
null,
|
||||
function(e) {
|
||||
if(e.getNode('aphlict-dropdown') ||
|
||||
e.getNode('aphlict-indicator')) {
|
||||
// Click is inside the dropdown, or on indicator
|
||||
if(e.getNode('phabricator-notification-menu')) {
|
||||
// Click is inside the dropdown.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ JX.behavior('aphlict-listen', function(config) {
|
|||
.start();
|
||||
}
|
||||
|
||||
|
||||
// Respond to a notification from the Aphlict notification server. We send
|
||||
// a request to Phabricator to get notification details.
|
||||
function onaphlictmessage(type, message) {
|
||||
|
@ -80,12 +79,12 @@ JX.behavior('aphlict-listen', function(config) {
|
|||
JX.Stratcom.listen('aphlict-component-ready', null, onready);
|
||||
|
||||
// Add Flash object to page
|
||||
JX.$("aphlictswf-container").innerHTML =
|
||||
JX.$(config.containerID).innerHTML =
|
||||
'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">'
|
||||
+ '<param name="movie" value="/rsrc/swf/aphlict.swf" />'
|
||||
+ '<param name="allowScriptAccess" value="always" />'
|
||||
+ '<param name="wmode" value="opaque" />'
|
||||
+ '<embed src="/rsrc/swf/aphlict.swf" wmode="opaque"'
|
||||
+ 'width="0" height="0" id="aphlictswfobject">'
|
||||
+ 'width="0" height="0" id="' + config.id + '">'
|
||||
+ '</embed></object>'; //Evan sanctioned
|
||||
});
|
||||
|
|
|
@ -30,14 +30,14 @@ JX.behavior('phabricator-keyboard-shortcuts', function(config) {
|
|||
})
|
||||
.register();
|
||||
|
||||
if (config.search_shortcut) {
|
||||
desc = 'Give keyboard focus to the search box.';
|
||||
new JX.KeyboardShortcut('/', desc)
|
||||
.setHandler(function() {
|
||||
var search = JX.$("standard-search-box");
|
||||
search.focus();
|
||||
search.select();
|
||||
})
|
||||
.register();
|
||||
}
|
||||
if (config.searchID) {
|
||||
desc = 'Give keyboard focus to the search box.';
|
||||
new JX.KeyboardShortcut('/', desc)
|
||||
.setHandler(function() {
|
||||
var search = JX.$(config.searchID);
|
||||
search.focus();
|
||||
search.select();
|
||||
})
|
||||
.register();
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue