Merge pull request #3008 from nextcloud/appmenu-experiment
Show apps in header
This commit is contained in:
commit
cd4ebe2777
|
@ -109,7 +109,7 @@
|
||||||
height: 34px;
|
height: 34px;
|
||||||
}
|
}
|
||||||
.header-appname-container {
|
.header-appname-container {
|
||||||
display: inline-block;
|
display: none;
|
||||||
padding-top: 22px;
|
padding-top: 22px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
@ -181,29 +181,31 @@
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: -27px;
|
margin-top: -26px;
|
||||||
padding: 7px 0 7px 5px;
|
padding: 7px 0 7px 5px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* do not show menu toggle on public share links as there is no menu */
|
/* do not show menu toggle on public share links as there is no menu */
|
||||||
#body-public #header .icon-caret {
|
#body-public #header .icon-caret {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NAVIGATION --------------------------------------------------------------- */
|
/* NAVIGATION --------------------------------------------------------------- */
|
||||||
|
nav {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
#navigation {
|
#navigation {
|
||||||
position: fixed;
|
position: relative;
|
||||||
top: 45px;
|
top: 45px;
|
||||||
left: 10px;
|
left: -100%;
|
||||||
width: 265px;
|
width: 265px;
|
||||||
max-height: 85%;
|
max-height: 85%;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
background-color: rgba(255, 255, 255, 0.97);
|
background-color: rgba(255, 255, 255, .97);
|
||||||
box-shadow: 0 1px 10px rgba(150, 150, 150, 0.75);
|
box-shadow: 0 1px 10px rgba(150, 150, 150, .75);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
|
@ -212,7 +214,48 @@
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
&:after {
|
&:after {
|
||||||
left: 47%;
|
left: 47%;
|
||||||
|
bottom: 100%;
|
||||||
|
border: solid transparent;
|
||||||
|
content: ' ';
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
border-color: rgba(0, 0, 0, 0);
|
||||||
|
border-bottom-color: rgba(255, 255, 255, .97);
|
||||||
|
border-width: 9px;
|
||||||
|
margin-left: -9px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* arrow look */
|
||||||
|
|
||||||
|
#expanddiv:after {
|
||||||
|
bottom: 100%;
|
||||||
|
border: solid transparent;
|
||||||
|
content: ' ';
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
border-color: rgba(0, 0, 0, 0);
|
||||||
|
border-bottom-color: rgba(255, 255, 255, .97);
|
||||||
|
border-width: 10px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* position of dropdown arrow */
|
||||||
|
|
||||||
|
#navigation:after {
|
||||||
|
left: 242px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#expanddiv:after {
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navigation {
|
||||||
|
box-sizing: border-box;
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
@ -307,6 +350,9 @@
|
||||||
#apps {
|
#apps {
|
||||||
max-height: calc(100vh - 100px);
|
max-height: calc(100vh - 100px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
.in-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER MENU -----------------------------------------------------------------*/
|
/* USER MENU -----------------------------------------------------------------*/
|
||||||
|
@ -375,7 +421,7 @@
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
display: none;
|
display: none;
|
||||||
background: rgb(255, 255, 255);
|
background: rgb(255, 255, 255);
|
||||||
box-shadow: 0 1px 10px rgba(150, 150, 150, 0.75);
|
box-shadow: 0 1px 10px rgba(150, 150, 150, .75);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
|
@ -405,3 +451,140 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* do not show display name when profile picture is present */
|
||||||
|
|
||||||
|
#header {
|
||||||
|
.avatardiv.avatardiv-shown + #expandDisplayName {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#expand {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#appmenu {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
clear: both;
|
||||||
|
height: 44px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
float: left;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top !important;
|
||||||
|
height: 20px;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
opacity: 0.6;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: top !important;
|
||||||
|
position: relative;
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li:hover a,
|
||||||
|
li a.active {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
li img,
|
||||||
|
.icon-more-white {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li span {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
overflow: visible;
|
||||||
|
background-color: rgba(255, 255, 255, .97);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: none;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
color: rgba(0, 0, 0, .6);
|
||||||
|
width: auto;
|
||||||
|
left: 50%;
|
||||||
|
top: 31px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
padding: 4px 10px;
|
||||||
|
-webkit-filter: drop-shadow(0 0 5px rgba(150, 150, 150, .75));
|
||||||
|
-moz-filter: drop-shadow(0 0 5px rgba(150, 150, 150, .75));
|
||||||
|
-ms-filter: drop-shadow(0 0 5px rgba(150, 150, 150, .75));
|
||||||
|
-o-filter: drop-shadow(0 0 5px rgba(150, 150, 150, .75));
|
||||||
|
filter: drop-shadow(0 0 5px rgba(150, 150, 150, .75));
|
||||||
|
}
|
||||||
|
|
||||||
|
li:hover span {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
li:hover a:before,
|
||||||
|
li a.active:before {
|
||||||
|
content: ' ';
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
border: 0 solid transparent;
|
||||||
|
border-bottom-color: white;
|
||||||
|
border-width: 10px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
left: 50%;
|
||||||
|
top: 12px;
|
||||||
|
z-index: 100;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
&.menu-open li:hover a:before,
|
||||||
|
&.menu-open li a.active:before,
|
||||||
|
&.menu-open li:hover span {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not show active indicator when hovering other icons */
|
||||||
|
&:hover li:not(:hover) a:before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* use popover menu on mobile and small screens */
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1369,6 +1369,10 @@ function initCore() {
|
||||||
* If the screen is bigger, the main menu is not a toggle any more.
|
* If the screen is bigger, the main menu is not a toggle any more.
|
||||||
*/
|
*/
|
||||||
function setupMainMenu() {
|
function setupMainMenu() {
|
||||||
|
|
||||||
|
// init the more-apps menu
|
||||||
|
OC.registerMenu($('#more-apps'), $('#navigation'));
|
||||||
|
|
||||||
// toggle the navigation
|
// toggle the navigation
|
||||||
var $toggle = $('#header .header-appname-container');
|
var $toggle = $('#header .header-appname-container');
|
||||||
var $navigation = $('#navigation');
|
var $navigation = $('#navigation');
|
||||||
|
@ -1438,13 +1442,20 @@ function initCore() {
|
||||||
// move triangle of apps dropdown to align with app name triangle
|
// move triangle of apps dropdown to align with app name triangle
|
||||||
// 2 is the additional offset between the triangles
|
// 2 is the additional offset between the triangles
|
||||||
if($('#navigation').length) {
|
if($('#navigation').length) {
|
||||||
$('#header #nextcloud + .menutoggle').one('click', function(){
|
$('#header #nextcloud + .menutoggle').on('click', function(){
|
||||||
|
$('#menu-css-helper').remove();
|
||||||
var caretPosition = $('.header-appname + .icon-caret').offset().left - 2;
|
var caretPosition = $('.header-appname + .icon-caret').offset().left - 2;
|
||||||
if(caretPosition > 255) {
|
if(caretPosition > 255) {
|
||||||
// if the app name is longer than the menu, just put the triangle in the middle
|
// if the app name is longer than the menu, just put the triangle in the middle
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
$('head').append('<style>#navigation:after { left: '+ caretPosition +'px; }</style>');
|
$('head').append('<style id="menu-css-helper">#navigation:after { left: '+ caretPosition +'px; }</style>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('#header #appmenu .menutoggle').on('click', function() {
|
||||||
|
$('#appmenu').toggleClass('menu-open');
|
||||||
|
if($('#appmenu').is(':visible')) {
|
||||||
|
$('#menu-css-helper').remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,88 @@
|
||||||
</h1>
|
</h1>
|
||||||
<div class="icon-caret"></div>
|
<div class="icon-caret"></div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div id="appmenu">
|
||||||
|
<ul>
|
||||||
|
<?php $headerIconCount = 8; ?>
|
||||||
|
<?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>
|
||||||
|
<?php p($entry['name']); ?>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<li id="more-apps" class="menutoggle<?php if (!(count($_['navigation']) > $headerIconCount || (OC_User::isAdminUser(OC_User::getUser()) && count($_['navigation'])>=$headerIconCount))): ?> hidden<?php endif; ?>">
|
||||||
|
<a href="#">
|
||||||
|
<div class="icon-more-white"></div>
|
||||||
|
<span><?php p($l->t('More apps')); ?></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php if(OC_User::isAdminUser(OC_User::getUser())): ?>
|
||||||
|
<li id="apps-management" <?php if(count($_['navigation'])>$headerIconCount-1): ?>class="hidden"<?php endif; ?>>
|
||||||
|
<a href="<?php print_unescaped(\OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')); ?>" tabindex="4"
|
||||||
|
<?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>>
|
||||||
|
<img src="<?php print_unescaped(image_path('settings', 'apps.svg') . '?v=' . $_['versionHash']); ?>" />
|
||||||
|
<div class="icon-loading-dark" style="display:none;"></div>
|
||||||
|
<span><?php p($l->t('Apps')); ?></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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; ?>
|
||||||
|
<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">
|
||||||
|
<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"></feColorMatrix></filter></defs>
|
||||||
|
<image x="0" y="0" width="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" 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>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php
|
||||||
|
/* show "More apps" link to app administration directly in app navigation, as last entry */
|
||||||
|
if(OC_User::isAdminUser(OC_User::getUser())):
|
||||||
|
?>
|
||||||
|
<li id="apps-management">
|
||||||
|
<a href="<?php print_unescaped(\OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')); ?>" tabindex="4"
|
||||||
|
<?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>>
|
||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" class="app-icon">
|
||||||
|
<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"></feColorMatrix></filter></defs>
|
||||||
|
<image x="0" y="0" width="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="<?php print_unescaped(image_path('settings', 'apps.svg') . '?v=' . $_['versionHash']); ?>"></image>
|
||||||
|
</svg>
|
||||||
|
<div class="icon-loading-dark" style="display:none;"></div>
|
||||||
|
<span>
|
||||||
|
<?php p($l->t('Apps')); ?>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div></nav>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
|
|
||||||
<div id="header-right">
|
<div id="header-right">
|
||||||
<form class="searchbox" action="#" method="post" role="search" novalidate>
|
<form class="searchbox" action="#" method="post" role="search" novalidate>
|
||||||
<label for="searchbox" class="hidden-visually">
|
<label for="searchbox" class="hidden-visually">
|
||||||
|
@ -102,52 +181,12 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div></header>
|
</div></header>
|
||||||
|
|
||||||
<nav role="navigation"><div id="navigation">
|
|
||||||
<div id="apps">
|
|
||||||
<ul>
|
|
||||||
<?php foreach($_['navigation'] 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; ?>>
|
|
||||||
<svg width="32" height="32" viewBox="0 0 32 32">
|
|
||||||
<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"></feColorMatrix></filter></defs>
|
|
||||||
<image x="0" y="0" width="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" 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>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<?php
|
|
||||||
/* show "More apps" link to app administration directly in app navigation, as last entry */
|
|
||||||
if(OC_User::isAdminUser(OC_User::getUser())):
|
|
||||||
?>
|
|
||||||
<li id="apps-management">
|
|
||||||
<a href="<?php print_unescaped(\OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')); ?>" tabindex="4"
|
|
||||||
<?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>>
|
|
||||||
<svg width="32" height="32" viewBox="0 0 32 32" class="app-icon">
|
|
||||||
<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"></feColorMatrix></filter></defs>
|
|
||||||
<image x="0" y="0" width="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="<?php print_unescaped(image_path('settings', 'apps.svg') . '?v=' . $_['versionHash']); ?>"></image>
|
|
||||||
</svg>
|
|
||||||
<div class="icon-loading-dark" style="display:none;"></div>
|
|
||||||
<span>
|
|
||||||
<?php p($l->t('Apps')); ?>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div></nav>
|
|
||||||
|
|
||||||
<div id="sudo-login-background" class="hidden"></div>
|
<div id="sudo-login-background" class="hidden"></div>
|
||||||
<form id="sudo-login-form" class="hidden">
|
<form id="sudo-login-form" class="hidden">
|
||||||
<?php p($l->t('This action requires you to confirm your password:')); ?><br>
|
<?php p($l->t('This action requires you to confirm your password:')); ?><br>
|
||||||
|
|
|
@ -76,6 +76,8 @@ class TemplateLayout extends \OC_Template {
|
||||||
$this->assign( 'appid', $appId );
|
$this->assign( 'appid', $appId );
|
||||||
$navigation = \OC_App::getNavigation();
|
$navigation = \OC_App::getNavigation();
|
||||||
$this->assign( 'navigation', $navigation);
|
$this->assign( 'navigation', $navigation);
|
||||||
|
$navigation = \OC_App::getHeaderNavigation();
|
||||||
|
$this->assign( 'headernavigation', $navigation);
|
||||||
$settingsNavigation = \OC_App::getSettingsNavigation();
|
$settingsNavigation = \OC_App::getSettingsNavigation();
|
||||||
$this->assign( 'settingsnavigation', $settingsNavigation);
|
$this->assign( 'settingsnavigation', $settingsNavigation);
|
||||||
foreach($navigation as $entry) {
|
foreach($navigation as $entry) {
|
||||||
|
|
|
@ -529,16 +529,10 @@ class OC_App {
|
||||||
|
|
||||||
// This is private as well. It simply works, so don't ask for more details
|
// This is private as well. It simply works, so don't ask for more details
|
||||||
private static function proceedNavigation($list) {
|
private static function proceedNavigation($list) {
|
||||||
$activeApp = OC::$server->getNavigationManager()->getActiveEntry();
|
$headerIconCount = 8;
|
||||||
foreach ($list as &$navEntry) {
|
if(OC_User::isAdminUser(OC_User::getUser())) {
|
||||||
if ($navEntry['id'] == $activeApp) {
|
$headerIconCount--;
|
||||||
$navEntry['active'] = true;
|
|
||||||
} else {
|
|
||||||
$navEntry['active'] = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
unset($navEntry);
|
|
||||||
|
|
||||||
usort($list, function($a, $b) {
|
usort($list, function($a, $b) {
|
||||||
if (isset($a['order']) && isset($b['order'])) {
|
if (isset($a['order']) && isset($b['order'])) {
|
||||||
return ($a['order'] < $b['order']) ? -1 : 1;
|
return ($a['order'] < $b['order']) ? -1 : 1;
|
||||||
|
@ -549,6 +543,63 @@ class OC_App {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$activeAppIndex = -1;
|
||||||
|
$activeApp = OC::$server->getNavigationManager()->getActiveEntry();
|
||||||
|
foreach ($list as $index => &$navEntry) {
|
||||||
|
if ($navEntry['id'] == $activeApp) {
|
||||||
|
$navEntry['active'] = true;
|
||||||
|
$activeAppIndex = $index;
|
||||||
|
} else {
|
||||||
|
$navEntry['active'] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($navEntry);
|
||||||
|
|
||||||
|
if($activeAppIndex > ($headerIconCount-1)) {
|
||||||
|
$active = $list[$activeAppIndex];
|
||||||
|
$lastInHeader = $list[$headerIconCount-1];
|
||||||
|
$list[$headerIconCount-1] = $active;
|
||||||
|
$list[$activeAppIndex] = $lastInHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($list as $index => &$navEntry) {
|
||||||
|
$navEntry['showInHeader'] = false;
|
||||||
|
if($index < $headerIconCount) {
|
||||||
|
$navEntry['showInHeader'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function proceedAppNavigation($entries) {
|
||||||
|
$headerIconCount = 8;
|
||||||
|
if(OC_User::isAdminUser(OC_User::getUser())) {
|
||||||
|
$headerIconCount--;
|
||||||
|
}
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,6 +792,22 @@ class OC_App {
|
||||||
return $navigation;
|
return $navigation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
$navigation = self::proceedAppNavigation($entries);
|
||||||
|
return $navigation;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the id of loaded app
|
* get the id of loaded app
|
||||||
*
|
*
|
||||||
|
|
|
@ -451,22 +451,39 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||||
|
|
||||||
rebuildNavigation: function() {
|
rebuildNavigation: function() {
|
||||||
$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php')).done(function(response){
|
$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php')).done(function(response){
|
||||||
if(response.status === 'success'){
|
if(response.status === 'success') {
|
||||||
var idsToKeep = {};
|
var addedApps = {};
|
||||||
var navEntries=response.nav_entries;
|
var navEntries = response.nav_entries;
|
||||||
var container = $('#apps ul');
|
var container = $('#apps ul');
|
||||||
for(var i=0; i< navEntries.length; i++){
|
|
||||||
var entry = navEntries[i];
|
|
||||||
idsToKeep[entry.id] = true;
|
|
||||||
|
|
||||||
if(container.children('li[data-id="'+entry.id+'"]').length === 0){
|
// remove disabled apps
|
||||||
var li=$('<li></li>');
|
for (var i = 0; i < navEntries.length; i++) {
|
||||||
|
var entry = navEntries[i];
|
||||||
|
if(container.children('li[data-id="' + entry.id + '"]').length === 0) {
|
||||||
|
addedApps[entry.id] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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'))) {
|
||||||
|
$(el).remove();
|
||||||
|
$('#appmenu li[data-id='+id+']').remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
li.attr('data-id', entry.id);
|
||||||
var img = '<svg width="32" height="32" viewBox="0 0 32 32">';
|
var img = '<svg width="32" height="32" viewBox="0 0 32 32">';
|
||||||
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 += '<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="32" height="32" preserveAspectRatio="xMinYMin meet" filter="url(#invert)" xlink:href="' + entry.icon + '" class="app-icon" /></svg>';
|
||||||
var a=$('<a></a>').attr('href', entry.href);
|
var a = $('<a></a>').attr('href', entry.href);
|
||||||
var filename=$('<span></span>');
|
var filename = $('<span></span>');
|
||||||
var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none');
|
var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none');
|
||||||
filename.text(entry.name);
|
filename.text(entry.name);
|
||||||
a.prepend(filename);
|
a.prepend(filename);
|
||||||
|
@ -474,19 +491,11 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||||
a.prepend(img);
|
a.prepend(img);
|
||||||
li.append(a);
|
li.append(a);
|
||||||
|
|
||||||
// append the new app as last item in the list
|
$('#navigation li[data-id=' + previousEntry.id + ']').after(li);
|
||||||
// which is the "add apps" entry with the id
|
|
||||||
// #apps-management
|
|
||||||
$('#apps-management').before(li);
|
|
||||||
|
|
||||||
// scroll the app navigation down
|
|
||||||
// so the newly added app is seen
|
|
||||||
$('#navigation').animate({
|
|
||||||
scrollTop: $('#navigation').height()
|
|
||||||
}, 'slow');
|
|
||||||
|
|
||||||
// draw attention to the newly added app entry
|
// draw attention to the newly added app entry
|
||||||
// by flashing it twice
|
// by flashing it twice
|
||||||
|
if(addedApps[entry.id]) {
|
||||||
$('#header .menutoggle')
|
$('#header .menutoggle')
|
||||||
.animate({opacity: 0.5})
|
.animate({opacity: 0.5})
|
||||||
.animate({opacity: 1})
|
.animate({opacity: 1})
|
||||||
|
@ -496,11 +505,47 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container.children('li[data-id]').each(function(index, el) {
|
if ($('#appmenu ul').children('li[data-id="' + entry.id + '"]').length === 0) {
|
||||||
if (!idsToKeep[$(el).data('id')]) {
|
// add apps to #appmenu until it is full
|
||||||
$(el).remove();
|
if ($('#appmenu li').not('.hidden').length < 8) {
|
||||||
|
var li = $('<li></li>');
|
||||||
|
li.attr('data-id', entry.id);
|
||||||
|
var img = '<img src="' + entry.icon + '" class="app-icon">';
|
||||||
|
var a = $('<a></a>').attr('href', entry.href);
|
||||||
|
var filename = $('<span></span>');
|
||||||
|
var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none');
|
||||||
|
filename.text(entry.name);
|
||||||
|
a.prepend(filename);
|
||||||
|
a.prepend(loading);
|
||||||
|
a.prepend(img);
|
||||||
|
li.append(a);
|
||||||
|
$('#appmenu li[data-id='+ previousEntry.id+']').after(li);
|
||||||
|
if(addedApps[entry.id]) {
|
||||||
|
li.animate({opacity: 0.5})
|
||||||
|
.animate({opacity: 1})
|
||||||
|
.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 > 7) {
|
||||||
|
$('#more-apps').show();
|
||||||
|
$('#apps-management').hide();
|
||||||
|
} else {
|
||||||
|
$('#more-apps').hide();
|
||||||
|
$('#apps-management').show();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue