Responsive app menu

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl 2017-03-28 15:04:56 +02:00
parent 8ef25a7628
commit 7548825743
No known key found for this signature in database
GPG key ID: 4C614C6ED2CDE6DF
5 changed files with 100 additions and 157 deletions

View file

@ -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,
@ -302,13 +296,12 @@ nav {
}
/* loading feedback for apps */
.app-loading {
.icon-loading-dark {
.icon-loading-small-dark {
display: inline !important;
position: absolute;
top: 20px;
left: 24px;
width: 32px;
height: 32px;
left: 12px;
width: 16px;
height: 16px;
}
.app-icon {
-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)';
@ -454,10 +447,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 {
@ -472,10 +468,10 @@ nav {
}
}
li:hover a,
li a.active {
opacity: 1;
}
li img,
@ -541,31 +537,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;
}
}
}
}

View file

@ -1482,6 +1482,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')) {

View file

@ -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>

View file

@ -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) {

View file

@ -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;
}
@ -722,21 +669,6 @@ class OC_App {
return self::proceedNavigation($entries);
}
/**
* 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
*