Compare commits

..

7 Commits

Author SHA1 Message Date
Simon Vieille a0f4eddab0 release v1.6.3 2020-05-14 15:31:20 +02:00
Simon Vieille 24bf8496f3 fix issue #20: add shortcut to open and to hide the menu 2020-05-14 15:30:34 +02:00
Simon Vieille 8368562ed0 release v1.6.2 2020-05-14 13:28:39 +02:00
Simon Vieille 9a8f5517b6 add a cache for the top menu update (#19) 2020-05-13 12:25:11 +02:00
Simon Vieille bddd8e9c0c release v1.6.1 2020-05-12 19:48:44 +02:00
Simon Vieille 03dbe8eeed fix issue #19: add a hack to show external sites in the top menu with navigation 2020-05-12 19:45:46 +02:00
Simon Vieille 321e5b1178 add title on links 2020-05-12 09:25:43 +02:00
11 changed files with 218 additions and 76 deletions
+19 -34
View File
@@ -6,52 +6,26 @@ This application is rather suitable for instances that activate a lot of applica
Comptatible with AppOrder. Comptatible with AppOrder.
Installation * [Installation and upgrade](#user-content-installation-and-upgrade)
------------ * [How to contribute?](#user-content-how-to-contribute)
* [Preview](#user-content-preview)
Side menu is availabe from the app store. Installation and upgrade
------------------------
If you want to install it from source: go to https://gitnet.fr/deblan/side_menu/releases and download the last release (side_menu_vX.Y.Z.zip). Side menu is availabe from the app store. If you want to install it from source: go to https://gitnet.fr/deblan/side_menu/releases and download the last release (side_menu_vX.Y.Z.zip). Copy the content into `apps`.
Copy the archive to your Nextcloud server.
``` ```
$ cd /path/to/nextcloud/apps $ cd /path/to/nextcloud/apps
$ unzip -d side_menu /path/to/side_menu_vX.Y.Z.zip $ unzip -d side_menu /path/to/side_menu_vX.Y.Z.zip
``` ```
### Upgrade
Side menu can be upgraded from the app store.
If you want to install it from source: go to https://gitnet.fr/deblan/side_menu/releases and download the last release (side_menu_vX.Y.Z.zip).
Copy the archive to your Nextcloud server.
```
$ cd /path/to/nextcloud/apps
$ rm -frv side_menu
$ unzip -d side_menu /path/to/side_menu_vX.Y.Z.zip
```
Preview
-------
![](https://upload.deblan.org/u/2020-03/5e81b219.jpg)
![](https://upload.deblan.org/u/2020-03/5e7fab2b.jpg)
![](https://upload.deblan.org/u/2020-05/5eb6b76e.png)
![](https://upload.deblan.org/u/2020-05/5eb6b78a.png)
Configuration
-------------
Administrators can edit many settings using the administration page. Administrators can edit many settings using the administration page.
Users can disable the menu using the page of personal settings. Users can disable the menu using the page of personal settings.
Use the shortcut `Ctrl`+`o` to open and to hide the side menu. Use `tab` to navigate.
How to contribute? How to contribute?
------------------ ------------------
@@ -67,3 +41,14 @@ If you are a developer:
Build javascripts using `webpack --config ./webpack.js` (add `-w` to build them in real time). Build javascripts using `webpack --config ./webpack.js` (add `-w` to build them in real time).
Then commit and create a pull request. Then commit and create a pull request.
Preview
-------
![](https://upload.deblan.org/u/2020-03/5e81b219.jpg)
![](https://upload.deblan.org/u/2020-03/5e7fab2b.jpg)
![](https://upload.deblan.org/u/2020-05/5eb6b76e.png)
![](https://upload.deblan.org/u/2020-05/5eb6b78a.png)
+3 -1
View File
@@ -6,6 +6,8 @@
<description><![CDATA[Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface. <description><![CDATA[Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface.
This application is rather suitable for instances that activate a lot of applications. This application is rather suitable for instances that activate a lot of applications.
Use the shortcut `Ctrl`+`o` to open and to hide the side menu. Use `tab` to navigate.
Comptatible with AppOrder. Comptatible with AppOrder.
You can report a bug or request a feature by opening an issue. You can report a bug or request a feature by opening an issue.
@@ -13,7 +15,7 @@ You can report a bug or request a feature by opening an issue.
]]></description> ]]></description>
<licence>agpl</licence> <licence>agpl</licence>
<author mail="contact@deblan.fr" homepage="https://www.deblan.io/">Simon Vieille</author> <author mail="contact@deblan.fr" homepage="https://www.deblan.io/">Simon Vieille</author>
<version>1.6.0</version> <version>1.6.3</version>
<namespace>SideMenu</namespace> <namespace>SideMenu</namespace>
<category>customization</category> <category>customization</category>
<website>https://gitnet.fr/deblan/side_menu</website> <website>https://gitnet.fr/deblan/side_menu</website>
+9
View File
@@ -23,3 +23,12 @@
#side-menu-section select { #side-menu-section select {
margin: 10px 0 10px 0; margin: 10px 0 10px 0;
} }
.keyboard-key {
padding: 1px 9px;
margin: 0 2px;
background: #eee;
border: 1px solid #aaa;
color: #555;
border-radius: 3px;
}
+1 -1
View File
@@ -80,7 +80,7 @@
white-space: nowrap; white-space: nowrap;
} }
.side-menu-app a:hover, .side-menu-app.active a { .side-menu-app a:hover, .side-menu-app.active, .side-menu-app a:focus {
background: var(--side-menu-current-app-background-color, #444); background: var(--side-menu-current-app-background-color, #444);
} }
+1
View File
@@ -13,6 +13,7 @@
"dependencies": { "dependencies": {
"@nextcloud/axios": "^1.3.2", "@nextcloud/axios": "^1.3.2",
"@nextcloud/vue": "^1.4.0", "@nextcloud/vue": "^1.4.0",
"trim": "0.0.1",
"vue": "^2.6.11" "vue": "^2.6.11"
}, },
"browserslist": [ "browserslist": [
+14 -4
View File
@@ -26,7 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<ul class="side-menu-apps-list"> <ul class="side-menu-apps-list">
<li v-for="app in apps" v-bind:class="{'side-menu-app': true, 'active': app.active}"> <li v-for="app in apps" v-bind:class="{'side-menu-app': true, 'active': app.active}">
<a v-bind:href="app.href"> <a v-bind:href="app.href" v-bind:title="app.name">
<span class="side-menu-app-icon" v-html="app.icon"></span> <span class="side-menu-app-icon" v-html="app.icon"></span>
<span class="side-menu-app-text" v-html="app.name"></span> <span class="side-menu-app-text" v-html="app.name"></span>
</a> </a>
@@ -36,6 +36,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</template> </template>
<script> <script>
import trim from 'trim'
export default { export default {
name: 'SideMenu', name: 'SideMenu',
data() { data() {
@@ -52,9 +54,17 @@ export default {
for (let element of links) { for (let element of links) {
let href = element.getAttribute('href') let href = element.getAttribute('href')
var parent = element.parentNode
if (this.ignoreExternalSites && element.parentNode.getAttribute('data-id').indexOf('external_index') !== -1) { if (!parent) {
continue; continue
}
var dataId = parent.getAttribute('data-id')
dataId = dataId !== null ? dataId : ''
if (this.ignoreExternalSites && dataId.indexOf('external_index') !== -1) {
continue
} }
if (href !== '#') { if (href !== '#') {
@@ -71,7 +81,7 @@ export default {
this.apps.push({ this.apps.push({
href: href, href: href,
name: element.querySelector('span').innerHTML, name: trim(element.querySelector('span').innerHTML),
icon: svg, icon: svg,
active: element.classList.contains('active') active: element.classList.contains('active')
}); });
-1
View File
@@ -30,7 +30,6 @@ const appConfig = (name, value, callbacks) => {
OCP.AppConfig.setValue('side_menu', name, value, callbacks) OCP.AppConfig.setValue('side_menu', name, value, callbacks)
} }
const saveSettings = (key) => { const saveSettings = (key) => {
const element = elements.get(key) const element = elements.get(key)
const name = $(element).attr('name') const name = $(element).attr('name')
+8 -9
View File
@@ -12,11 +12,15 @@
#appmenu { #appmenu {
display: none; display: none;
} }
<?php endif; ?>
#appmenu + nav { #appmenu + nav {
display: none; display: none;
} }
<?php else: ?>
.app-hidden {
opacity: 0;
}
<?php endif; ?>
<?php if ($_['opener-only'] === true): ?> <?php if ($_['opener-only'] === true): ?>
#nextcloud { #nextcloud {
@@ -42,11 +46,6 @@
visibility: hidden; visibility: hidden;
} }
#side-menu.hide-opener .side-menu-apps-list {
/* height: calc(100vh);
top: 0; */
}
<?php if ($_['size-text'] === 'hidden'): ?> <?php if ($_['size-text'] === 'hidden'): ?>
#side-menu, .side-menu-apps-list { #side-menu, .side-menu-apps-list {
<?php if ($_['size-icon'] === 'big'): ?> <?php if ($_['size-icon'] === 'big'): ?>
+148 -26
View File
@@ -9,30 +9,6 @@
sideMenuContainer.attr('data-forcelighticon', '1') sideMenuContainer.attr('data-forcelighticon', '1')
<?php endif; ?> <?php endif; ?>
<?php if ($_['external-sites-in-top-menu']): ?>
sideMenuContainer.attr('data-externalsitesintopmenu', '1')
var externalSitesInTopMenu = function() {
var items = $('#appmenu').find('li')
items.each(function(i, item) {
var dataId = item.getAttribute('data-id')
if (dataId === null || dataId.indexOf('external_index') === -1) {
item.style.display = 'none'
item.classList.remove('hidden')
} else {
item.style.display = 'flex'
item.classList.add('hidden')
}
})
}
$(window).resize(externalSitesInTopMenu);
setInterval(externalSitesInTopMenu, 500);
<?php endif; ?>
body.on('side-menu.apps', function(e, apps) { body.on('side-menu.apps', function(e, apps) {
<?php if ($_['hide-when-no-apps']): ?> <?php if ($_['hide-when-no-apps']): ?>
sideMenu = $('#side-menu') sideMenu = $('#side-menu')
@@ -52,6 +28,18 @@
var headerMenuOpener = $('#header .side-menu-opener') var headerMenuOpener = $('#header .side-menu-opener')
var sideMenuOpener = $('#side-menu .side-menu-opener') var sideMenuOpener = $('#side-menu .side-menu-opener')
sideMenuFocus = function() {
var a = sideMenu.find('.side-menu-app.active a')
if (a.length === 0) {
a = sideMenu.find('.side-menu-app:first-child a')
}
if (a.length > 0) {
a.focus()
}
}
<?php if ($_['opener-hover']): ?> <?php if ($_['opener-hover']): ?>
var sideMenuMouseLeave = function() { var sideMenuMouseLeave = function() {
sideMenu sideMenu
@@ -67,6 +55,8 @@
sideMenu sideMenu
.addClass('open') .addClass('open')
.on('mouseenter', sideMenuMouseEnter) .on('mouseenter', sideMenuMouseEnter)
sideMenuFocus()
} }
if (!isTouchDevice) { if (!isTouchDevice) {
@@ -77,11 +67,23 @@
<?php endif; ?> <?php endif; ?>
headerMenuOpener.on('click', function() { headerMenuOpener.on('click', function() {
sideMenu.addClass('open'); sideMenu.addClass('open')
sideMenu.find('.side-menu-app.active a').focus()
}) })
sideMenuOpener.on('click', function() { sideMenuOpener.on('click', function() {
sideMenu.removeClass('open'); sideMenu.removeClass('open')
})
$(document).keydown(function(e) {
var key = e.key || e.keyCode
if ((key === 'o' || key === 79) && e.ctrlKey === true) {
e.preventDefault()
sideMenu.toggleClass('open')
sideMenuFocus()
}
}) })
}) })
@@ -93,4 +95,124 @@
<?php else: ?> <?php else: ?>
sideMenuOpener.insertAfter('#nextcloud') sideMenuOpener.insertAfter('#nextcloud')
<?php endif; ?> <?php endif; ?>
<?php if ($_['external-sites-in-top-menu']): ?>
sideMenuContainer.attr('data-externalsitesintopmenu', '1')
var menuCache = null
var updateTopMenu = function() {
var breakpointMobileWidth = 1024
var menu = $('#appmenu')
var apps = menu.find('li')
var minAppsDesktop = 8
var usePercentualAppMenuLimit = 0.9
var isMobile = $(window).width() < breakpointMobileWidth
var lastShownApp = null
var appShown = []
var moreApps = $('#more-apps')
var navigation = $('#navigation')
var navigationApps = $('#apps ul')
var appCount = null
var currentMenuCache = menu.html() + menu.next().html()
if (currentMenuCache === menuCache) {
return
}
navigationApps.html('')
apps.each(function(i, app) {
var dataId = app.getAttribute('data-id')
if (dataId === null) {
return
}
if (dataId.indexOf('external_index') === -1) {
app.classList.add('hidden')
app.classList.add('app-hidden')
} else {
app.classList.remove('hidden')
app.classList.add('app-external-site')
appShown.push(app)
navigationApps.append(app.outerHTML)
}
})
var rightHeaderWidth = $('.header-right').outerWidth()
var headerWidth = $('header').outerWidth()
var availableWidth = headerWidth - $('#nextcloud').outerWidth() - $('#header .side-menu-opener').outerWidth() - (rightHeaderWidth > 210 ? rightHeaderWidth : 210)
if (!isMobile) {
availableWidth = availableWidth * usePercentualAppMenuLimit
}
if (isMobile && appCount > minAppsDesktop) {
appCount = minAppsDesktop
} else if (!isMobile && appCount < minAppsDesktop) {
appCount = minAppsDesktop
} else {
appCount = Math.floor(availableWidth / $('#appmenu li').width())
}
if (appCount === 0) {
menu.addClass('hidden')
}
menu.removeClass('hidden')
menu.css('opacity', 1)
if (appShown.length - 1 - appCount >= 1) {
appCount--
}
moreApps.find('a').removeClass('active')
var k = 0
var notInHeader = 0
var name
$(appShown).each(function(i, app) {
app = $(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')
} else {
app.addClass('hidden')
notInHeader++
$('#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')
.removeClass('in-header')
.addClass('in-header')
}
}
k++
})
if (notInHeader === 0) {
moreApps.hide()
navigation.hide()
} else {
moreApps.show()
}
menuCache = menu.html() + menu.next().html()
}
setInterval(updateTopMenu, 50)
<?php endif; ?>
})(); })();
+12
View File
@@ -213,6 +213,9 @@ $choicesSizes = [
</select> </select>
</div> </div>
<p>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.</p>
<div> <div>
<label for="side-menu-opener" class="settings-hint"> <label for="side-menu-opener" class="settings-hint">
<?php p($l->t('Display the logo')); ?> <?php p($l->t('Display the logo')); ?>
@@ -271,6 +274,15 @@ $choicesSizes = [
</div> </div>
</div> </div>
<div class="section">
<h2>
<?php p($l->t('Tips')); ?>
</h2>
<p class="settings-hint">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.</p>
</div>
<div class="section"> <div class="section">
<input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>" class="side-menu-setting"> <input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>" class="side-menu-setting">
+3
View File
@@ -48,6 +48,9 @@ $choicesYesNo = [
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
<p>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.</p>
</div> </div>
<div class="section"> <div class="section">