diff options
author | Lukas Reschke <lukas@statuscode.ch> | 2017-04-25 19:42:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-25 19:42:01 +0200 |
commit | db94b5d4af711f6e18aac0c9d4b0357a3b9123d1 (patch) | |
tree | 94765548709d2ee9612c715d0f1e775e56bf773a | |
parent | 51da0442d9604f9285d02b56f2b1f669701da90b (diff) | |
parent | 27b19aaba1c9a710bb2b1d3338a74ba05ea0678e (diff) | |
download | nextcloud-server-db94b5d4af711f6e18aac0c9d4b0357a3b9123d1.tar.gz nextcloud-server-db94b5d4af711f6e18aac0c9d4b0357a3b9123d1.zip |
Merge pull request #4439 from nextcloud/appmenu-responsive
Responsive app menu
-rw-r--r-- | core/css/header.scss | 100 | ||||
-rw-r--r-- | core/js/js.js | 62 | ||||
-rw-r--r-- | core/templates/layout.user.php | 63 | ||||
-rw-r--r-- | lib/private/TemplateLayout.php | 2 | ||||
-rw-r--r-- | lib/private/legacy/app.php | 68 | ||||
-rw-r--r-- | settings/js/apps.js | 25 |
6 files changed, 135 insertions, 185 deletions
diff --git a/core/css/header.scss b/core/css/header.scss index 93be1dba18b..619852faf60 100644 --- a/core/css/header.scss +++ b/core/css/header.scss @@ -191,17 +191,18 @@ /* NAVIGATION --------------------------------------------------------------- */ nav { - margin-top: auto; + display: inline-block; + width: 44px; + height: 44px; + margin-left: -54px; } #navigation { position: relative; top: 45px; left: -100%; - width: 265px; - max-height: 85%; + width: 160px; margin-top: 0; - padding-bottom: 10px; background-color: $color-main-background; box-shadow: 0 1px 10px $color-box-shadow; border-radius: 3px; @@ -242,12 +243,6 @@ nav { margin-left: -10px; } -/* position of dropdown arrow */ - -#navigation:after { - left: 242px; -} - #navigation { box-sizing: border-box; * { @@ -258,18 +253,14 @@ nav { } a { position: relative; - width: 80px; - height: 80px; - display: inline-block; - text-align: center; - padding: 20px 0; + display: block; + padding: 10px 12px; + height:40px; + vertical-align: text-bottom; span { display: inline-block; - font-size: 13px; padding-bottom: 0; - padding-left: 0; - width: 80px; - text-align: center; + padding-left: 10px; color: $color-main-text; white-space: nowrap; overflow: hidden; @@ -280,6 +271,9 @@ nav { -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=50)'; opacity: .5; } + svg { + margin-bottom: 2px; + } &:hover svg, &:focus svg, &:hover span, @@ -300,20 +294,21 @@ nav { max-height: 32px; max-width: 32px; } - /* loading feedback for apps */ - .app-loading { - .icon-loading-dark { - display: inline !important; - position: absolute; - top: 20px; - left: 24px; - width: 32px; - height: 32px; - } - .app-icon { - -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)'; - opacity: 0; - } + +} + +/* loading feedback for apps */ +.app-loading { + .icon-loading-small-dark { + display: inline !important; + position: absolute; + left: 12px; + width: 16px; + height: 16px; + } + .app-icon { + -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)'; + opacity: 0; } } @@ -454,10 +449,13 @@ nav { width: auto; clear: both; height: 44px; - flex-shrink: 0; li { float: left; + display: inline-block; + position: relative; + vertical-align: top !important; + height: 45px; cursor: pointer; a { @@ -471,11 +469,14 @@ nav { opacity: .6; } } + .app-loading .icon-loading-small-dark { + top:12px; + } + li:hover a, li a.active { opacity: 1; - } li img, @@ -541,31 +542,4 @@ nav { li.hidden { display: none; } - -} - -/* use popover menu on mobile and small screens */ -@media only screen and (max-width: 680px) { - - #header .header-appname-container { - display: inline-block !important; - } - - #appmenu { - display: none; - } - - #apps .in-header { - display: inline-block; - } - - #navigation { - position: fixed; - top: 45px; - left: 10px; - &:after { - left: 214px; - } - } - -} +}
\ No newline at end of file diff --git a/core/js/js.js b/core/js/js.js index 883431b2b02..95c00dd6448 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1398,6 +1398,7 @@ function initCore() { // toggle the navigation var $toggle = $('#header .header-appname-container'); var $navigation = $('#navigation'); + var $appmenu = $('#appmenu'); // init the menu OC.registerMenu($toggle, $navigation); @@ -1427,6 +1428,20 @@ function initCore() { OC.hideMenus(function(){return false}); } }); + + $appmenu.delegate('a', 'click', function(event) { + var $app = $(event.target); + if(!$app.is('a')) { + $app = $app.closest('a'); + } + if(event.which === 1 && !event.ctrlKey && !event.metaKey) { + $app.addClass('app-loading'); + } else { + // Close navigation when opening app in + // a new tab + OC.hideMenus(function(){return false}); + } + }); } function setupUserMenu() { @@ -1482,6 +1497,53 @@ function initCore() { }); } + var resizeMenu = function() { + var maxApps = 8; + var appList = $('#appmenu li'); + var availableWidth = $('#header-left').width() - $('#nextcloud').width() - 44; + var appCount = Math.floor((availableWidth)/44); + console.log(appCount); + // show a maximum of 8 apps + if(appCount >= maxApps) { + appCount = maxApps; + } + // show at least 2 apps in the popover + if(appList.length-1-appCount >= 1) { + appCount--; + } + + $('#more-apps a').removeClass('active'); + var lastShownApp; + for (var k = 0; k < appList.length-1; k++) { + var name = $(appList[k]).data('id'); + if(k < appCount) { + $(appList[k]).removeClass('hidden'); + $('#apps li[data-id=' + name + ']').addClass('in-header'); + lastShownApp = appList[k]; + } else { + $(appList[k]).addClass('hidden'); + $('#apps li[data-id=' + name + ']').removeClass('in-header'); + // move active app to last position if it is active + if(appCount > 0 && $(appList[k]).children('a').hasClass('active')) { + $(lastShownApp).addClass('hidden'); + $('#apps li[data-id=' + $(lastShownApp).data('id') + ']').removeClass('in-header'); + $(appList[k]).removeClass('hidden'); + $('#apps li[data-id=' + name + ']').addClass('in-header'); + } + } + } + + // show/hide more apps icon + if($('#apps li:not(.in-header)').length === 0) { + $('#more-apps').hide(); + $('#navigation').hide(); + } else { + $('#more-apps').show(); + } + }; + $(window).resize(resizeMenu); + resizeMenu(); + // just add snapper for logged in users if($('#app-navigation').length && !$('html').hasClass('lte9')) { diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index 40e47c7e582..91b7eb3490b 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -60,54 +60,51 @@ <div class="icon-caret"></div> </a> - <div id="appmenu"> - <ul> - <?php foreach($_['headernavigation'] as $entry): ?> - <li data-id="<?php p($entry['id']); ?>"> - <a href="<?php print_unescaped($entry['href']); ?>" tabindex="3" - <?php if( $entry['active'] ): ?> class="active"<?php endif; ?>> - <img src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>" class="app-icon" /> - <div class="icon-loading-dark" style="display:none;"></div> - <span> + <ul id="appmenu"> + <?php foreach ($_['navigation'] as $entry): ?> + <li data-id="<?php p($entry['id']); ?>" class="hidden"> + <a href="<?php print_unescaped($entry['href']); ?>" + tabindex="3" + <?php if ($entry['active']): ?> class="active"<?php endif; ?>> + <img src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>" + class="app-icon"/> + <div class="icon-loading-small-dark" + style="display:none;"></div> + <span> <?php p($entry['name']); ?> </span> - </a> - </li> - <?php endforeach; ?> - <li id="more-apps" class="menutoggle<?php if (count($_['navigation']) <= 8): ?> hidden<?php endif; ?>"> - <a href="#"> - <div class="icon-more-white"></div> - <span><?php p($l->t('More apps')); ?></span> - </a> - </li> - </ul> - </div> + </a> + </li> + <?php endforeach; ?> + <li id="more-apps" class="menutoggle"> + <a href="#"> + <div class="icon-more-white"></div> + <span><?php p($l->t('More apps')); ?></span> + </a> + </li> + </ul> - <nav role="navigation"><div id="navigation"> + <nav role="navigation"> + <div id="navigation"> <div id="apps"> <ul> <?php foreach($_['navigation'] as $entry): ?> - <?php if($entry['showInHeader']): ?> - <li data-id="<?php p($entry['id']); ?>" class="in-header"> - <?php else: ?> - <li data-id="<?php p($entry['id']); ?>"> - <?php endif; ?> + <li data-id="<?php p($entry['id']); ?>"> <a href="<?php print_unescaped($entry['href']); ?>" tabindex="3" <?php if( $entry['active'] ): ?> class="active"<?php endif; ?>> - <svg width="32" height="32" viewBox="0 0 32 32"> + <svg width="16" height="16" viewBox="0 0 16 16"> <defs><filter id="invert-<?php p($entry['id']); ?>"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"></feColorMatrix></filter></defs> - <image x="0" y="0" width="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert-<?php p($entry['id']); ?>)" xlink:href="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>" class="app-icon"></image> + <image x="0" y="0" width="16" height="16" preserveAspectRatio="xMinYMin meet" filter="url(#invert-<?php p($entry['id']); ?>)" xlink:href="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>" class="app-icon"></image> </svg> - <div class="icon-loading-dark" style="display:none;"></div> - <span> - <?php p($entry['name']); ?> - </span> + <div class="icon-loading-small-dark" style="display:none;"></div> + <span><?php p($entry['name']); ?></span> </a> </li> <?php endforeach; ?> </ul> </div> - </div></nav> + </div> + </nav> </div> diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index d7249a44293..f7bb23cd3de 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -79,8 +79,6 @@ class TemplateLayout extends \OC_Template { $this->assign( 'appid', $appId ); $navigation = \OC_App::getNavigation(); $this->assign( 'navigation', $navigation); - $navigation = \OC_App::getHeaderNavigation(); - $this->assign( 'headernavigation', $navigation); $settingsNavigation = \OC_App::getSettingsNavigation(); $this->assign( 'settingsnavigation', $settingsNavigation); foreach($navigation as $entry) { diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index e6b811aa845..3800b8b770e 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -468,69 +468,16 @@ class OC_App { } }); - $activeAppIndex = -1; $activeApp = OC::$server->getNavigationManager()->getActiveEntry(); foreach ($list as $index => &$navEntry) { - $navEntry['showInHeader'] = true; if ($navEntry['id'] == $activeApp) { $navEntry['active'] = true; - $activeAppIndex = $index; } else { $navEntry['active'] = false; } } unset($navEntry); - if (count($list) <= 8) { - return $list; - } - - $headerIconCount = 7; - if($activeAppIndex > ($headerIconCount-1)) { - $active = $list[$activeAppIndex]; - $lastInHeader = $list[$headerIconCount-1]; - $list[$headerIconCount-1] = $active; - $list[$activeAppIndex] = $lastInHeader; - } - - foreach ($list as $index => &$navEntry) { - if($index >= $headerIconCount) { - $navEntry['showInHeader'] = false; - } - } - - return $list; - } - - public static function proceedAppNavigation($entries) { - $activeAppIndex = -1; - $list = self::proceedNavigation($entries); - - $activeApp = OC::$server->getNavigationManager()->getActiveEntry(); - foreach ($list as $index => &$navEntry) { - if ($navEntry['id'] == $activeApp) { - $navEntry['active'] = true; - $activeAppIndex = $index; - } else { - $navEntry['active'] = false; - } - } - - - if (count($list) <= 8) { - return $list; - } - - $headerIconCount = 7; - // move active item to last position - if($activeAppIndex > ($headerIconCount-1)) { - $active = $list[$activeAppIndex]; - $lastInHeader = $list[$headerIconCount-1]; - $list[$headerIconCount-1] = $active; - $list[$activeAppIndex] = $lastInHeader; - } - $list = array_slice($list, 0, $headerIconCount); - return $list; } @@ -723,21 +670,6 @@ class OC_App { } /** - * Returns the navigation inside the header bar - * - * @return array - * - * This function returns an array containing all entries added. The - * entries are sorted by the key 'order' ascending. Additional to the keys - * given for each app the following keys exist: - * - active: boolean, signals if the user is on this navigation entry - */ - public static function getHeaderNavigation() { - $entries = OC::$server->getNavigationManager()->getAll(); - return self::proceedAppNavigation($entries); - } - - /** * Returns the Settings Navigation * * @return string[] diff --git a/settings/js/apps.js b/settings/js/apps.js index 6da8c395ecb..3326886951f 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -487,22 +487,22 @@ OC.Settings.Apps = OC.Settings.Apps || { container.children('li[data-id]').each(function (index, el) { var id = $(el).data('id'); // remove all apps that are not in the correct order - if ((navEntries[index] && navEntries[index].id !== $(el).data('id'))) { + if (!navEntries[index] || (navEntries[index] && navEntries[index].id !== $(el).data('id'))) { $(el).remove(); $('#appmenu li[data-id='+id+']').remove(); } }); - var previousEntry; + var previousEntry = {}; // add enabled apps to #navigation and #appmenu for (var i = 0; i < navEntries.length; i++) { var entry = navEntries[i]; if (container.children('li[data-id="' + entry.id + '"]').length === 0) { var li = $('<li></li>'); li.attr('data-id', entry.id); - var img = '<svg width="32" height="32" viewBox="0 0 32 32">'; + var img = '<svg width="16" height="16" viewBox="0 0 16 16">'; img += '<defs><filter id="invert"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" /></filter></defs>'; - img += '<image x="0" y="0" width="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="' + entry.icon + '" class="app-icon" /></svg>'; + img += '<image x="0" y="0" width="16" height="16" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="' + entry.icon + '" class="app-icon" /></svg>'; var a = $('<a></a>').attr('href', entry.href); var filename = $('<span></span>'); var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none'); @@ -526,9 +526,7 @@ OC.Settings.Apps = OC.Settings.Apps || { } } - if ($('#appmenu ul').children('li[data-id="' + entry.id + '"]').length === 0) { - // add apps to #appmenu until it is full - if ($('#appmenu li').not('.hidden').length < 8) { + if ($('#appmenu').children('li[data-id="' + entry.id + '"]').length === 0) { var li = $('<li></li>'); li.attr('data-id', entry.id); var img = '<img src="' + entry.icon + '" class="app-icon">'; @@ -547,22 +545,11 @@ OC.Settings.Apps = OC.Settings.Apps || { .animate({opacity: 0.5}) .animate({opacity: 1}); } - } } previousEntry = entry; - // do not show apps from #appmenu in #navigation - if(i <= 7) { - $('#navigation li').eq(i).addClass('in-header'); - } else { - $('#navigation li').eq(i).removeClass('in-header'); - } } - if (navEntries.length > 8) { - $('#more-apps').show(); - } else { - $('#more-apps').hide(); - } + $(window).trigger('resize'); } }); }, |