Merge branch 'feature/fixed-left-menu' into develop

This commit is contained in:
Simon Vieille 2020-09-03 09:49:41 +02:00
commit 612a94fd06
12 changed files with 182 additions and 38 deletions

View file

@ -50,8 +50,8 @@
display: none;
}
#side-menu.hide-opener .side-menu-opener, .side-menu-opener.hide {
display: none;
#side-menu.hide-opener .side-menu-opener, .side-menu-opener.hide, #side-menu.hide {
display: none !important;
}
.side-menu-apps-list {
@ -180,6 +180,54 @@
margin-top: -2px;
}
.side-menu-always-displayed #header,
.side-menu-always-displayed body {
width: calc(100% - 50px) !important;
}
.side-menu-always-displayed body {
position: absolute;
left: 50px;
}
.side-menu-always-displayed #side-menu {
display: block;
}
.side-menu-always-displayed .side-menu-apps-list {
top: 49px;
}
.side-menu-always-displayed #side-menu,
.side-menu-always-displayed .side-menu-header,
.side-menu-always-displayed .side-menu-apps-list {
width: 50px;
}
.side-menu-always-displayed #side-menu .side-menu-app-text,
.side-menu-always-displayed #header .side-menu-opener,
.side-menu-always-displayed .side-menu-logo {
display: none;
}
.side-menu-always-displayed #side-menu.open,
.side-menu-always-displayed #side-menu.open .side-menu-apps-list,
.side-menu-always-displayed #side-menu.open .side-menu-header,
.side-menu-always-displayed #side-menu:hover,
.side-menu-always-displayed #side-menu:hover .side-menu-apps-list,
.side-menu-always-displayed #side-menu:hover .side-menu-header {
width: 100%;
}
.side-menu-always-displayed #side-menu.open .side-menu-app-text,
.side-menu-always-displayed #side-menu:hover .side-menu-app-text {
display: inline;
}
.side-menu-always-displayed .app-navigation--close {
transform: translateX(calc(-100% + 50px)) !important;
}
@media screen and (max-width: 1024px) {
#side-menu.side-menu-big {
max-width: 290px;

View file

@ -82,6 +82,7 @@ class CssController extends Controller
'external-sites-in-top-menu' => (bool) $this->config->getAppValue('side_menu', 'external-sites-in-top-menu', 0),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'),
'always-displayed' => (bool) $this->config->getAppValue('side_menu', 'always-displayed', '0'),
'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'),
'top-menu-apps' => $topMenuApps,
];

View file

@ -70,6 +70,7 @@ class JsController extends Controller
'force-light-icon' => (bool) $this->config->getAppValue('side_menu', 'force-light-icon', '0'),
'hide-when-no-apps' => (bool) $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'),
'loader-enabled' => (bool) $this->config->getAppValue('side_menu', 'loader-enabled', '1'),
'always-displayed' => (bool) $this->config->getAppValue('side_menu', 'always-displayed', '0'),
'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'),
'top-menu-apps' => $topMenuApps,
];

View file

@ -74,6 +74,7 @@ class Admin implements ISettings
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'),
'cache' => $this->config->getAppValue('side_menu', 'cache', '0'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'),
'always-displayed' => $this->config->getAppValue('side_menu', 'always-displayed', '0'),
'big-menu' => $this->config->getAppValue('side_menu', 'big-menu', '0'),
'display-logo' => $this->config->getAppValue('side_menu', 'display-logo', '1'),
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'),

View file

@ -46,3 +46,7 @@
"Icons and texts": "Symbole und Texte"
"Loader enabled": "Loader aktiviert"
"Tips": "Tipps"
"Always displayed": "Wird immer angezeigt"
"The logo will be hidden when the menu is always displayed.": "Das Logo wird ausgeblendet, wenn das Menü immer angezeigt wird."
"This is the automatic behavior when the menu is always displayed.": "Dies ist das automatische Verhalten, wenn das Menü immer angezeigt wird."
"Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens."

View file

@ -46,3 +46,7 @@
"Icons and texts": "Icônes et textes"
"Loader enabled": "Activation de l'indicateur de chargement"
"Tips": "Astuces"
"Always displayed": "Toujours affiché"
"The logo will be hidden when the menu is always displayed.": "Le logo sera masque si le menu est toujours affiché."
"This is the automatic behavior when the menu is always displayed.": "C'est le comportement automatique lorsque le menu est toujours affiché."
"Not compatible with touch screens.": "Incompatible avec les écrans tactiles."

View file

@ -22,13 +22,13 @@
}
<?php endif; ?>
<?php if ($_['opener-only'] === true): ?>
<?php if ($_['opener-only']): ?>
#nextcloud {
display: none;
}
<?php endif; ?>
<?php if ($_['display-logo'] === false): ?>
<?php if ($_['display-logo']): ?>
.side-menu-logo {
display: none;
}

View file

@ -0,0 +1,44 @@
var alwaysDisplayed = function() {
var elements = document.querySelectorAll('*');
var fixedElements = []
for (var i in elements) {
var element = elements[i]
if (typeof element !== 'object') {
continue
}
var position = window.getComputedStyle(element, null).getPropertyValue('position');
if (position !== 'fixed') {
continue
}
var id = element.getAttribute('id')
if (id === 'header' || id === 'side-menu' || id === 'side-menu-loader') {
continue
}
if (element.classList.contains('oc-dialog')) {
continue
}
if (jQuery(element).parents('#side-menu').length) {
continue
}
fixedElements.push(element)
}
for (var i in fixedElements) {
var element = fixedElements[i]
var value = window.getComputedStyle(element, null).getPropertyValue('left')
var intValue = parseInt(value.replace('px', ''))
element.style.setProperty('transform', 'translateX(' + (intValue + 50) + 'px)')
}
}
alwaysDisplayed()

View file

@ -1,5 +1,5 @@
var pageLoader = $('<div id="side-menu-loader">')
var pageLoaderBar = $('<div id="side-menu-loader-bar">')
var pageLoader = jQuery('<div id="side-menu-loader">')
var pageLoaderBar = jQuery('<div id="side-menu-loader-bar">')
body.append(pageLoader)
pageLoader.append(pageLoaderBar)

View file

@ -2,16 +2,16 @@ var menuCache = null
var updateTopMenu = function() {
var breakpointMobileWidth = 1024
var menu = $('#appmenu')
var menu = jQuery('#appmenu')
var apps = menu.find('li')
var minAppsDesktop = 8
var usePercentualAppMenuLimit = 0.8
var isMobile = $(window).width() < breakpointMobileWidth
var isMobile = jQuery(window).width() < breakpointMobileWidth
var lastShownApp = null
var appShown = []
var moreApps = $('#more-apps')
var navigation = $('#navigation')
var navigationApps = $('#apps ul')
var moreApps = jQuery('#more-apps')
var navigation = jQuery('#navigation')
var navigationApps = jQuery('#apps ul')
var appCount = null
var currentMenuCache = menu.html() + menu.next().html()
@ -40,17 +40,17 @@ var updateTopMenu = function() {
}
})
var rightHeaderWidth = $('.header-right').outerWidth()
var headerWidth = $('header').outerWidth()
var availableWidth = headerWidth - $('#nextcloud').outerWidth()
- $('#header .side-menu-opener').outerWidth()
var rightHeaderWidth = jQuery('.header-right').outerWidth()
var headerWidth = jQuery('header').outerWidth()
var availableWidth = headerWidth - jQuery('#nextcloud').outerWidth()
- jQuery('#header .side-menu-opener').outerWidth()
- (rightHeaderWidth > 230 ? rightHeaderWidth : 230)
if (!isMobile) {
availableWidth = availableWidth * usePercentualAppMenuLimit
}
appCount = Math.floor(availableWidth / $('#appmenu li').width())
appCount = Math.floor(availableWidth / jQuery('#appmenu li').width())
if (isMobile && appCount > minAppsDesktop) {
appCount = minAppsDesktop
@ -75,27 +75,27 @@ var updateTopMenu = function() {
var notInHeader = 0
var name
$(appShown).each(function(i, app) {
app = $(app)
jQuery(appShown).each(function(i, app) {
app = jQuery(app)
name = app.data('id')
if (k < appCount && appCount > 0) {
app.removeClass('hidden')
lastShownApp = app
$('#apps li[data-id=' + name + '].app-external-site').addClass('in-header')
jQuery('#apps li[data-id=' + name + '].app-external-site').addClass('in-header')
} else {
app.addClass('hidden')
notInHeader++
$('#apps li[data-id=' + name + '].app-external-site').removeClass('in-header')
jQuery('#apps li[data-id=' + name + '].app-external-site').removeClass('in-header')
if (appCount > 0 && app.children('a').hasClass('active')) {
lastShownApp.addClass('hidden')
app.removeClass('hidden')
notInHeader++
$('#apps li[data-id=' + name + '].app-external-site')
jQuery('#apps li[data-id=' + name + '].app-external-site')
.removeClass('in-header')
.addClass('in-header')
}
@ -104,8 +104,8 @@ var updateTopMenu = function() {
k++
})
$('#apps li.app-external-site').each(function(i, app) {
app = $(app)
jQuery('#apps li.app-external-site').each(function(i, app) {
app = jQuery(app)
var appId = app.attr('data-id')
if (app.hasClass('in-header')) {

View file

@ -1,8 +1,9 @@
(function() {
var sideMenuContainer = $('<div id="side-menu-container">')
var sideMenuOpener = $('<button class="side-menu-opener"></button>')
var sideMenu = $('<div id="side-menu">')
var body = $('body')
var sideMenuContainer = jQuery('<div id="side-menu-container">')
var sideMenuOpener = jQuery('<button class="side-menu-opener"></button>')
var sideMenu = jQuery('<div id="side-menu">')
var body = jQuery('body')
var html = jQuery('html')
var isTouchDevice = window.matchMedia("(pointer: coarse)").matches
<?php if ($_['big-menu']): ?>
@ -15,22 +16,32 @@
body.on('side-menu.apps', function(e, apps) {
<?php if ($_['hide-when-no-apps']): ?>
sideMenu = $('#side-menu')
sideMenu = jQuery('#side-menu')
if (apps.length === 0) {
sideMenu.removeClass('open')
sideMenu.addClass('hide')
sideMenuOpener.addClass('hide')
} else {
sideMenu.removeClass('hide')
sideMenuOpener.removeClass('hide')
}
<?php if ($_['always-displayed'] && !$_['big-menu']): ?>
if (apps.length === 0) {
html.removeClass('side-menu-always-displayed');
} else {
html.addClass('side-menu-always-displayed');
}
<?php endif; ?>
<?php endif; ?>
})
body.on('side-menu.ready', function() {
sideMenu = $('#side-menu')
sideMenu = jQuery('#side-menu')
var headerMenuOpener = $('#header .side-menu-opener')
var sideMenuOpener = $('#side-menu .side-menu-opener')
var headerMenuOpener = jQuery('#header .side-menu-opener')
var sideMenuOpener = jQuery('#side-menu .side-menu-opener')
sideMenuFocus = function() {
var a = sideMenu.find('.side-menu-app.active a')
@ -75,11 +86,17 @@
sideMenu.find('.side-menu-app.active a').focus()
})
sideMenuOpener.on('click', function() {
sideMenu.removeClass('open')
})
<?php if ($_['always-displayed'] && !$_['big-menu']): ?>
sideMenuOpener.on('click', function() {
sideMenu.toggleClass('open')
})
<?php else: ?>
sideMenuOpener.on('click', function() {
sideMenu.removeClass('open')
})
<?php endif; ?>
$(document).keydown(function(e) {
jQuery(document).keydown(function(e) {
var key = e.key || e.keyCode
if ((key === 'o' || key === 79) && e.ctrlKey === true) {
@ -109,4 +126,8 @@
<?php require_once __DIR__.'/_topMenuApps.js'; ?>
<?php endif; ?>
<?php if ($_['always-displayed'] && !$_['big-menu']): ?>
<?php require_once __DIR__.'/_alwaysDisplayed.js'; ?>
<?php endif; ?>
})();

View file

@ -245,9 +245,7 @@ $choicesSizes = [
</label>
</div>
<p>
<em><?php echo $l->t('Use the shortcut <span class="keyboard-key">Ctrl</span>+<span class="keyboard-key">o</span> to open and to hide the side menu. Use <span class="keyboard-key">tab</span> to navigate.'); ?></em>
</p>
<p><em><?php p($l->t('This is the automatic behavior when the menu is always displayed.')); ?></em></p>
<div>
<select id="side-menu-opener-hover" name="opener-hover" class="side-menu-setting">
@ -259,6 +257,27 @@ $choicesSizes = [
</select>
</div>
<div>
<label for="side-menu-big-menu">
<?php p($l->t('Always displayed')); ?>
<small><span class="warning"><?php p($l->t('Experimental')); ?></span></small>
</label>
</div>
<p><em><?php p($l->t('This feature is not compatible with the <code>big menu</code> display.')); ?></em></p>
<p><em><?php p($l->t('Not compatible with touch screens.')); ?></em></p>
<div>
<select id="side-menu-always-displayed" name="always-displayed" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['always-displayed']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-big-menu">
<?php p($l->t('Display the big menu')); ?>
@ -284,6 +303,7 @@ $choicesSizes = [
</div>
<p><em><?php p($l->t('This feature is not compatible with the <code>big menu</code> display.')); ?></em></p>
<p><em><?php p($l->t('The logo will be hidden when the menu is always displayed.')); ?></em></p>
<div>
<select id="side-menu-display-logo" name="display-logo" class="side-menu-setting">