Compare commits

...

29 Commits

Author SHA1 Message Date
Simon Vieille ef22990f4b release v1.3.4 2020-04-27 08:48:48 +02:00
Simon Vieille c84ce6a615 release v1.4.0 2020-04-26 23:46:38 +02:00
Simon Vieille 9b060d1a4b fix #13: add option to show only the opener 2020-04-26 23:45:33 +02:00
Simon Vieille 26e737e2d7 fix #13: add alternate hamburger icon 2020-04-26 23:32:30 +02:00
Simon Vieille 67f27e0ef4 fix #13: add alternate hamburger icon 2020-04-26 23:30:43 +02:00
Simon Vieille 58661508d4 indentation 2020-04-25 16:29:52 +02:00
Simon Vieille 5509b69908 fix #11 2020-04-25 16:04:54 +02:00
Simon Vieille 51eccde659 add gitignore 2020-04-25 16:03:51 +02:00
Simon Vieille d0c072bee5 release v1.3.3 2020-04-25 14:30:02 +02:00
Simon Vieille 95f7eb5980 add options to select the size of icons and texts or hide them 2020-04-25 14:25:51 +02:00
Simon Vieille 18314b260f add 2nd background color 2020-04-25 13:25:41 +02:00
Simon Vieille e3c159b4d6 add 2nd background color 2020-04-25 13:05:01 +02:00
Simon Vieille a48611edf4 indentation 2020-04-22 19:35:56 +02:00
Simon Vieille 5dde7ca850 add padding on icons 2020-04-22 19:30:04 +02:00
Simon Vieille db2f7becae add documentation 2020-04-22 00:42:47 +02:00
Simon Vieille 1715ae5d52 release v1.3.2 2020-04-20 19:52:02 +02:00
Simon Vieille 847fa23345 add support message 2020-04-20 19:51:54 +02:00
Simon Vieille 0495046d02 fix #9: apply a patch to correctly generate an image path 2020-04-20 19:24:37 +02:00
Simon Vieille 0474ef55e8 release v1.3.1 2020-04-20 14:07:59 +02:00
Simon Vieille 7c9653943a remove extension from routes (css, js) 2020-04-20 14:05:08 +02:00
Simon Vieille 457bfc282b add opener-position option (issue #3) 2020-04-20 14:04:06 +02:00
Simon Vieille 84c78538f0 fix typo 2020-04-17 14:16:15 +02:00
Simon Vieille f0d17a61bd release v1.3.0 2020-04-17 13:59:42 +02:00
Simon Vieille fdbeaf6677 Merge branch 'feature/menu-position' into develop 2020-04-17 13:58:55 +02:00
Simon Vieille 9d18b33715 add styles 2020-04-17 13:58:45 +02:00
Simon Vieille bfb2b5d819 remove main.js from webpack and add styles 2020-04-17 13:58:34 +02:00
Simon Vieille a6e789c859 add option: enabled hover on opener 2020-04-17 13:58:01 +02:00
Simon Vieille 0cceb03213 add js script using a controller 2020-04-17 13:57:23 +02:00
Simon Vieille 91db830ea7 update screenshot 2020-04-17 13:56:37 +02:00
19 changed files with 556 additions and 173 deletions
+2
View File
@@ -0,0 +1,2 @@
/js
/node_modules
+33
View File
@@ -0,0 +1,33 @@
## Feature
### Description
...
### Benefits
...
---
## Issue
### Environment
* Side menu version: ...
* PHP version: ...
* Web server (Nginx, Apache2): ...
### Steps to reproduce
* ...
* ...
* ...
### Observed Results
...
### Expected Results
...
+11 -4
View File
@@ -1,8 +1,8 @@
🤙 Nextcloud app / Side menu 🎨 🤙 Nextcloud app / Side menu 🎨
=============================== ===============================
Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface.
This application moves the top menu of Nextcloud to the left side. This application is rather suitable for instances that activate a lot of applications.
Comptatible with AppOrder. Comptatible with AppOrder.
@@ -39,13 +39,20 @@ $ unzip -d side_menu /path/to/side_menu_vX.Y.Z.zip
![](https://upload.deblan.org/u/2020-03/5e81b219.jpg) ![](https://upload.deblan.org/u/2020-03/5e81b219.jpg)
![](https://upload.deblan.org/u/2020-04/5e8ee1f7.jpg) ![](https://upload.deblan.org/u/2020-04/5ea68025.png)
How to contribute? How to contribute?
------------------ ------------------
Fork the repository, go to `apps/`, clone your repository and run `npm install` inside. You can report a bug or request a feature by opening an issue: https://gitnet.fr/deblan/side_menu/issues
If you are a developer:
* fork the repository
* install an instance of Nextcloud
* go to `apps/` and clone your repository
* go to `apps/side_menu` and run `npm install`
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).
+20 -10
View File
@@ -24,6 +24,11 @@ use OCP\Util;
$config = \OC::$server->getConfig(); $config = \OC::$server->getConfig();
$cspnm = \OC::$server->getContentSecurityPolicyNonceManager(); $cspnm = \OC::$server->getContentSecurityPolicyNonceManager();
Util::addScript('side_menu', 'sideMenu');
Util::addStyle('side_menu', 'sideMenu');
$stylesheet = \OC::$server->getURLGenerator()->linkToRoute( $stylesheet = \OC::$server->getURLGenerator()->linkToRoute(
'side_menu.Css.stylesheet', 'side_menu.Css.stylesheet',
[ [
@@ -31,6 +36,13 @@ $stylesheet = \OC::$server->getURLGenerator()->linkToRoute(
] ]
); );
$script = \OC::$server->getURLGenerator()->linkToRoute(
'side_menu.Js.script',
[
'v' => $config->getAppValue('side_menu', 'cache', '0'),
]
);
Util::addHeader( Util::addHeader(
'link', 'link',
[ [
@@ -40,13 +52,11 @@ Util::addHeader(
'' ''
); );
Util::addScript('side_menu', 'main'); Util::addHeader(
Util::addScript('side_menu', 'sideMenu'); 'script',
Util::addStyle('side_menu', 'sideMenu'); [
// whitelist the URL to allow loading JS from this external domain 'src' => $script,
// $CSPManager = \OC::$server->getContentSecurityPolicyManager(); 'nonce' => $cspnm->getNonce(),
// $policy = new ContentSecurityPolicy(); ],
// $policy->addAllowedScriptDomain($url); ''
// $policy->addAllowedImageDomain($url); );
// $policy->addAllowedConnectDomain($url);
// $CSPManager->addDefaultPolicy($policy);
+10 -3
View File
@@ -3,10 +3,17 @@
<id>side_menu</id> <id>side_menu</id>
<name>Side menu</name> <name>Side menu</name>
<summary>Move the top menu to the left side.</summary> <summary>Move the top menu to the left side.</summary>
<description>Move the top menu to the left side.</description> <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.
Comptatible with AppOrder.
You can report a bug or request a feature by opening an issue
]]></description>
<licence>agpl</licence> <licence>agpl</licence>
<author mail="dev+sidemenu@deblan.fr" homepage="https://www.deblan.io/">Simon Vieille</author> <author mail="dev+sidemenu@deblan.fr" homepage="https://www.deblan.io/">Simon Vieille</author>
<version>1.2.4</version> <version>1.3.4</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>
@@ -14,7 +21,7 @@
<repository type="git">https://gitnet.fr/deblan/side_menu</repository> <repository type="git">https://gitnet.fr/deblan/side_menu</repository>
<screenshot>https://upload.deblan.org/u/2020-03/5e7fab2b.jpg</screenshot> <screenshot>https://upload.deblan.org/u/2020-03/5e7fab2b.jpg</screenshot>
<screenshot>https://upload.deblan.org/u/2020-03/5e81b219.jpg</screenshot> <screenshot>https://upload.deblan.org/u/2020-03/5e81b219.jpg</screenshot>
<screenshot>https://upload.deblan.org/u/2020-04/5e8ee1f7.jpg</screenshot> <screenshot>https://upload.deblan.org/u/2020-04/5ea68025.png</screenshot>
<dependencies> <dependencies>
<nextcloud min-version="18" max-version="18"/> <nextcloud min-version="18" max-version="18"/>
</dependencies> </dependencies>
+2 -1
View File
@@ -19,6 +19,7 @@
return [ return [
'routes' => [ 'routes' => [
['name' => 'Css#stylesheet', 'url' => '/css/stylesheet.css', 'verb' => 'GET'], ['name' => 'Css#stylesheet', 'url' => '/css/stylesheet', 'verb' => 'GET'],
['name' => 'Js#script', 'url' => '/js/script', 'verb' => 'GET'],
], ],
]; ];
+16 -3
View File
@@ -26,7 +26,7 @@
height: 100vh; height: 100vh;
width: 100%; width: 100%;
max-width: 250px; max-width: 250px;
background: var(--side-menu-background-color, #333); background: linear-gradient(90deg, var(--side-menu-background-color, #333) 0%, var(--side-menu-background-color-to, #333) 100%);
z-index: 3000; z-index: 3000;
color: var(--side-menu-text-color, #fff); color: var(--side-menu-text-color, #fff);
box-shadow: rgba(0, 0, 0, 0.22) 0px 25.6px 57.6px 0px, rgba(0, 0, 0, 0.18) 0px 4.8px 14.4px 0px; box-shadow: rgba(0, 0, 0, 0.22) 0px 25.6px 57.6px 0px, rgba(0, 0, 0, 0.18) 0px 4.8px 14.4px 0px;
@@ -37,6 +37,10 @@
display: block; display: block;
} }
#header .side-menu-opener {
margin-left: 5px;
}
.side-menu-opener { .side-menu-opener {
background: var(--side-menu-opener, url('../img/side-menu-opener.svg')); background: var(--side-menu-opener, url('../img/side-menu-opener.svg'));
height: 40px; height: 40px;
@@ -45,6 +49,10 @@
border: 0; border: 0;
} }
#side-menu.hide-opener .side-menu-opener {
display: none;
}
.side-menu-apps-list { .side-menu-apps-list {
height: calc(100vh - 150px); height: calc(100vh - 150px);
z-index: 2200; z-index: 2200;
@@ -59,13 +67,14 @@
width: 20px; width: 20px;
vertical-align: middle; vertical-align: middle;
margin-right: 10px; margin-right: 10px;
padding-top: 3px;
} }
.side-menu-app a { .side-menu-app a {
line-height: 30px; line-height: 30px;
color: var(--side-menu-text-color, #fff); color: var(--side-menu-text-color, #fff);
display: block; display: block;
padding: 7px 0 7px 15px; padding: 7px 0 5px 15px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
@@ -89,8 +98,12 @@
width: 100%; width: 100%;
z-index: 2300; z-index: 2300;
max-width: 250px; max-width: 250px;
background: var(--side-menu-background-color, #333);
position: fixed; position: fixed;
padding-top: 2px; padding-top: 2px;
padding-left: 5px;
top: 0; top: 0;
} }
#side-menu.hide-opener .side-menu-logo {
margin-top: 20px;
}
+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 10.583 10.583">
<rect overflow="visible" style="marker:none" width="4.806" height="1.256" x="2.888" y="2.787" rx="0" ry=".472" color="#000" fill="#fff" fill-opacity=".855" paint-order="stroke markers fill"/>
<rect overflow="visible" style="marker:none" width="4.806" height="1.256" x="2.888" y="4.655" rx="0" ry=".472" color="#000" fill="#fff" fill-opacity=".855" paint-order="stroke markers fill"/>
<rect overflow="visible" style="marker:none" width="4.806" height="1.256" x="2.888" y="6.54" rx="0" ry=".472" color="#000" fill="#fff" fill-opacity=".855" paint-order="stroke markers fill"/>
<path style="marker:none" d="M1.243.71A.469.469 0 0 0 .881.88a.469.469 0 0 0-.171.362V9.34c0 .146.067.275.171.362a.469.469 0 0 0 .362.171H9.34a.469.469 0 0 0 .362-.171.469.469 0 0 0 .171-.362V1.243a.469.469 0 0 0-.171-.362A.469.469 0 0 0 9.34.71zm.723 1.256h6.65v6.65h-6.65z" color="#000" overflow="visible" fill="#fff" fill-opacity=".855" paint-order="stroke markers fill"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+7 -5
View File
@@ -51,19 +51,21 @@ class CssController extends Controller
*/ */
public function stylesheet() public function stylesheet()
{ {
$requestUri = $this->request->server['REQUEST_URI']; $backgroundColor = $this->config->getAppValue('side_menu', 'background-color', '#333333');
$assetsRoot = str_replace('/index.php', '', $requestUri); $backgroundColorTo = $this->config->getAppValue('side_menu', 'background-color-to', $backgroundColor);
$assetsRoot = preg_replace('#apps/side_menu/.*#s', 'apps/side_menu', $assetsRoot);
$parameters = [ $parameters = [
'vars' => [ 'vars' => [
'background-color' => $this->config->getAppValue('side_menu', 'background-color', '#333333'), 'background-color' => $backgroundColor,
'background-color-to' => $backgroundColorTo,
'current-app-background-color' => $this->config->getAppValue('side_menu', 'current-app-background-color', '#444444'), 'current-app-background-color' => $this->config->getAppValue('side_menu', 'current-app-background-color', '#444444'),
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'), 'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'), 'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'),
], ],
'display-logo' => (bool) $this->config->getAppValue('side_menu', 'display-logo', 1), 'display-logo' => (bool) $this->config->getAppValue('side_menu', 'display-logo', 1),
'assetsRoot' => $assetsRoot, 'opener-only' => (bool) $this->config->getAppValue('side_menu', 'opener-only', 0),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'),
]; ];
$response = new TemplateResponse('side_menu', 'css/stylesheet', $parameters, 'blank'); $response = new TemplateResponse('side_menu', 'css/stylesheet', $parameters, 'blank');
+64
View File
@@ -0,0 +1,64 @@
<?php
/**
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace OCA\SideMenu\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\Response;
use OCP\IConfig;
use OCP\IRequest;
class JsController extends Controller
{
/** @var \OCP\IConfig */
protected $config;
/**
* @param string $appName
* @param IRequest $request
* @param IConfig $config
*/
public function __construct($appName, IRequest $request, IConfig $config)
{
parent::__construct($appName, $request);
$this->config = $config;
}
/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
*
* @return Response
*/
public function script()
{
$parameters = [
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'),
'opener-hover' => (bool) $this->config->getAppValue('side_menu', 'opener-hover', '0'),
];
$response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank');
$response->addHeader('Content-Type', 'text/javascript');
return $response;
}
}
+10 -1
View File
@@ -47,13 +47,22 @@ class Admin implements ISettings
*/ */
public function getForm() public function getForm()
{ {
$backgroundColor = $this->config->getAppValue('side_menu', 'background-color', '#333333');
$backgroundColorTo = $this->config->getAppValue('side_menu', 'background-color-to', $backgroundColor);
$parameters = [ $parameters = [
'background-color' => $this->config->getAppValue('side_menu', 'background-color', '#333333'), 'background-color' => $backgroundColor,
'background-color-to' => $backgroundColorTo,
'current-app-background-color' => $this->config->getAppValue('side_menu', 'current-app-background-color', '#444444'), 'current-app-background-color' => $this->config->getAppValue('side_menu', 'current-app-background-color', '#444444'),
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'), 'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'),
'cache' => $this->config->getAppValue('side_menu', 'cache', '0'), 'cache' => $this->config->getAppValue('side_menu', 'cache', '0'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'), 'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'),
'display-logo' => $this->config->getAppValue('side_menu', 'display-logo', '1'), 'display-logo' => $this->config->getAppValue('side_menu', 'display-logo', '1'),
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'),
'opener-hover' => $this->config->getAppValue('side_menu', 'opener-hover', '0'),
'opener-only' => $this->config->getAppValue('side_menu', 'opener-only', '0'),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'),
]; ];
return new TemplateResponse('side_menu', 'settings/admin-form', $parameters, ''); return new TemplateResponse('side_menu', 'settings/admin-form', $parameters, '');
+1
View File
@@ -30,6 +30,7 @@ const mountSideMenuComponent = () => {
if (sideMenuContainer) { if (sideMenuContainer) {
sideMenu.$mount('#side-menu') sideMenu.$mount('#side-menu')
$('body').trigger('side-menu.ready')
} else { } else {
window.setTimeout(mountSideMenuComponent, 50) window.setTimeout(mountSideMenuComponent, 50)
} }
+22 -16
View File
@@ -28,8 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<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">
<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>
{{ app.name }}
</a> </a>
</li> </li>
</ul> </ul>
@@ -54,28 +53,32 @@ export default {
let href = element.getAttribute('href') let href = element.getAttribute('href')
if (href !== '#') { if (href !== '#') {
let svg = element.querySelector('svg').outerHTML
svg = svg.replace(/(height|width)="20"/, '')
this.apps.push({ this.apps.push({
href: href, href: href,
name: element.querySelector('span').innerHTML, name: element.querySelector('span').innerHTML,
icon: element.querySelector('svg').outerHTML, icon: svg,
active: element.classList.contains('active') active: element.classList.contains('active')
}); });
} }
} }
}, },
retrieveLogo() { retrieveLogo() {
const ncLogo = document.querySelector('#nextcloud .logo') const ncLogo = document.querySelector('#nextcloud .logo')
if (ncLogo) { if (ncLogo) {
const url = window.getComputedStyle(ncLogo, null) const url = window.getComputedStyle(ncLogo, null)
.getPropertyValue('background-image') .getPropertyValue('background-image')
.replace('url("', '') .replace('url("', '')
.replace('")', '') .replace('")', '')
if (url && url !== 'none') { if (url && url !== 'none') {
this.logo = url this.logo = url
} }
} }
}, },
}, },
created() { created() {
@@ -83,9 +86,12 @@ export default {
this.retrieveLogo(); this.retrieveLogo();
const menu = document.querySelector('#appmenu') const menu = document.querySelector('#appmenu')
const config = {attributes: true, childList: true, subtree: true};
const observer = new MutationObserver(this.retrieveApps); if (menu) {
observer.observe(menu, config); const config = {attributes: true, childList: true, subtree: true};
const observer = new MutationObserver(this.retrieveApps);
observer.observe(menu, config);
}
} }
} }
</script> </script>
+6
View File
@@ -17,10 +17,16 @@
const elements = [ const elements = [
'side-menu-background-color', 'side-menu-background-color',
'side-menu-background-color-to',
'side-menu-current-app-background-color', 'side-menu-current-app-background-color',
'side-menu-text-color', 'side-menu-text-color',
'side-menu-opener', 'side-menu-opener',
'side-menu-opener-position',
'side-menu-opener-hover',
'side-menu-opener-only',
'side-menu-display-logo', 'side-menu-display-logo',
'side-menu-size-icon',
'side-menu-size-text',
'side-menu-cache', 'side-menu-cache',
]; ];
-30
View File
@@ -1,30 +0,0 @@
/**
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
const sideMenuContainer = $('<div id="side-menu-container">')
const sideMenuOpener = $('<button class="side-menu-opener"></button>')
const sideMenu = $('<div id="side-menu">')
sideMenuContainer.append(sideMenu);
$('body').append(sideMenuContainer);
sideMenuOpener.insertBefore('#nextcloud');
$('body').on('click', '.side-menu-opener', () => {
$('#side-menu').toggleClass('open');
})
+82 -14
View File
@@ -1,24 +1,92 @@
:root { :root {
<?php foreach ($_['vars'] as $key => $value): ?> <?php foreach ($_['vars'] as $key => $value): ?>
<?php if ($key === 'opener'): ?> <?php if ($key === 'opener'): ?>
--side-menu-<?php echo $key ?>: url('<?php echo $_['assetsRoot'] ?>/img/<?php echo $value ?>.svg'); --side-menu-<?php echo $key ?>: url('<?php print_unescaped(image_path('side_menu', $value.'.svg')); ?>');
<?php else: ?> <?php else: ?>
--side-menu-<?php echo $key ?>: <?php echo $value ?>; --side-menu-<?php echo $key ?>: <?php echo $value ?>;
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
} }
<?php if ($_['display-logo'] === false): ?> <?php if ($_['opener-only'] === true): ?>
.side-menu-logo { #nextcloud {
display: none; display: none;
} }
<?php endif; ?>
.side-menu-header {
height: 50px; <?php if ($_['display-logo'] === false): ?>
} .side-menu-logo {
display: none;
.side-menu-apps-list { }
height: calc(100vh - 60px);
top: 60px; .side-menu-header {
} height: 50px;
}
.side-menu-apps-list {
height: calc(100vh - 60px);
top: 60px;
}
#side-menu.hide-opener .side-menu-header {
display: none;
}
#side-menu.hide-opener .side-menu-apps-list {
height: calc(100vh);
top: 0;
}
<?php if ($_['size-text'] === 'hidden'): ?>
#side-menu, .side-menu-apps-list {
<?php if ($_['size-icon'] === 'big'): ?>
width: 55px;
<?php else: ?>
width: 52px;
<?php endif; ?>
}
#side-menu .side-menu-opener {
<?php if ($_['size-icon'] === 'big'): ?>
margin-left: 6px;
<?php else: ?>
margin-left: 4px;
<?php endif; ?>
}
<?php endif; ?>
<?php endif; ?>
<?php if ($_['size-icon'] === 'hidden'): ?>
.side-menu-app-icon {
display: none;
}
<?php elseif ($_['size-icon'] === 'small'): ?>
.side-menu-app-icon svg {
width: 15px;
height: 15px;
}
<?php elseif ($_['size-icon'] === 'normal'): ?>
.side-menu-app-icon svg {
width: 20px;
height: 20px;
}
<?php elseif ($_['size-icon'] === 'big'): ?>
.side-menu-app-icon svg {
width: 23px;
height: 23px;
}
<?php endif; ?>
<?php if ($_['size-text'] === 'hidden'): ?>
.side-menu-app-text {
display: none;
}
<?php elseif ($_['size-text'] === 'small'): ?>
.side-menu-app-text {
font-size: 12px;
}
<?php elseif ($_['size-text'] === 'big'): ?>
.side-menu-app-text {
font-size: 16px;
}
<?php endif; ?> <?php endif; ?>
+57
View File
@@ -0,0 +1,57 @@
(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')
body.append(sideMenuContainer)
sideMenuContainer.append(sideMenu)
<?php if ($_['opener-position'] === 'before'): ?>
sideMenuOpener.insertBefore('#nextcloud')
<?php else: ?>
sideMenuOpener.insertAfter('#nextcloud')
<?php endif; ?>
var isTouchDevice = window.matchMedia("(pointer: coarse)").matches
body.on('side-menu.ready', function() {
sideMenu = $('#side-menu')
var headerMenuOpener = $('#header .side-menu-opener')
var sideMenuOpener = $('#side-menu .side-menu-opener')
<?php if ($_['opener-hover']): ?>
var sideMenuMouseLeave = function() {
sideMenu
.removeClass('open')
.off('mouseleave', sideMenuMouseLeave)
}
var sideMenuMouseEnter = function() {
sideMenu.on('mouseleave', sideMenuMouseLeave)
}
var sideMenuOpenerMouseEnter = function() {
sideMenu
.addClass('open')
.on('mouseenter', sideMenuMouseEnter)
}
if (!isTouchDevice) {
headerMenuOpener.on('mouseenter', sideMenuOpenerMouseEnter)
sideMenu.addClass('hide-opener')
}
<?php endif; ?>
headerMenuOpener.on('click', function() {
sideMenu.addClass('open');
})
sideMenuOpener.on('click', function() {
sideMenu.removeClass('open');
})
})
})();
+207 -85
View File
@@ -18,100 +18,222 @@
script('side_menu', 'admin'); script('side_menu', 'admin');
style('side_menu', 'admin'); style('side_menu', 'admin');
style('side_menu', 'support');
$choicesYesNo = [
'No' => '0',
'Yes' => '1',
];
$choicesSizes = [
'Hidden' => 'hidden',
'Small' => 'small',
'Normal' => 'normal',
'Big' => 'big',
];
?> ?>
<div id="side-menu-section" class="section"> <div id="side-menu-section">
<h2 class="inlineblock"><?php p($l->t('Side menu settings')); ?></h2> <div class="section">
<h2>
<?php p($l->t('Colors')); ?>
</h2>
<div> <div>
<label for="side-menu-background-color" class="settings-hint"> <label for="side-menu-background-color" class="settings-hint">
<?php p($l->t('Background color')); ?> <?php p($l->t('Background color')); ?>
</label> </label>
</div> </div>
<div> <div>
<input <input
id="side-menu-background-color" id="side-menu-background-color"
name="background-color" name="background-color"
type="color" type="color"
value="<?php print_unescaped($_['background-color']); ?>"> value="<?php print_unescaped($_['background-color']); ?>">
<input
id="side-menu-background-color-to"
name="background-color-to"
type="color"
value="<?php print_unescaped($_['background-color-to']); ?>">
</div>
<div>
<label for="side-menu-current-app-background-color" class="settings-hint">
<?php p($l->t('Background color of current app')); ?>
</label>
</div>
<div>
<input
id="side-menu-current-app-background-color"
name="current-app-background-color"
type="color"
value="<?php print_unescaped($_['current-app-background-color']); ?>">
</div>
<div>
<label for="side-menu-text-color" class="settings-hint">
<?php p($l->t('Text color')); ?>
</label>
</div>
<div>
<input
id="side-menu-text-color"
name="text-color"
type="color"
value="<?php print_unescaped($_['text-color']); ?>">
</div>
</div> </div>
<div> <div class="section">
<label for="side-menu-current-app-background-color" class="settings-hint"> <h2>
<?php p($l->t('Background color of current app')); ?> <?php p($l->t('Opener')); ?>
</label> </h2>
</div>
<div> <?php
<input $choices = [
id="side-menu-current-app-background-color" 'Default' => 'side-menu-opener',
name="current-app-background-color" 'Hamburger' => 'side-menu-opener-hamburger',
type="color" 'Hamburger 2' => 'side-menu-opener-hamburger-2',
value="<?php print_unescaped($_['current-app-background-color']); ?>"> ];
?>
<div>
<label for="side-menu-opener" class="settings-hint">
<?php p($l->t('Icon')); ?>
</label>
</div>
<div>
<select id="side-menu-opener" name="opener">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php
$choices = [
'Before the logo' => 'before',
'After the logo' => 'after',
];
?>
<div>
<label for="side-menu-opener-position" class="settings-hint">
<?php p($l->t('Position')); ?>
</label>
</div>
<div>
<select id="side-menu-opener-position" name="opener-position">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-position']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-opener-only" class="settings-hint">
<?php p($l->t('Show only the opener (hidden logo)')); ?>
</label>
</div>
<div>
<select id="side-menu-opener-only" name="opener-only">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-only']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div> </div>
<div> <div class="section">
<label for="side-menu-text-color" class="settings-hint"> <h2>
<?php p($l->t('Text color')); ?> <?php p($l->t('Panel')); ?>
</label> </h2>
</div>
<div> <div>
<input <label for="side-menu-opener" class="settings-hint">
id="side-menu-text-color" <?php p($l->t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?>
name="text-color" </label>
type="color" </div>
value="<?php print_unescaped($_['text-color']); ?>">
<div>
<select id="side-menu-opener-hover" name="opener-hover">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener-hover']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-opener" class="settings-hint">
<?php p($l->t('Display the logo')); ?>
</label>
</div>
<div>
<select id="side-menu-display-logo" name="display-logo">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['display-logo']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="settings-hint">
<?php p($l->t('Icons and texts')); ?>
</label>
</div>
<div>
<select id="side-menu-size-icon" name="size-icon">
<?php foreach ($choicesSizes as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['size-icon']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> icon
</option>
<?php endforeach; ?>
</select>
<select id="side-menu-size-text" name="size-text">
<?php foreach ($choicesSizes as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['size-text']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> text
</option>
<?php endforeach; ?>
</select>
</div>
</div> </div>
<div> <div class="section">
<label for="side-menu-opener" class="settings-hint"> <input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>">
<?php p($l->t('Opener icon')); ?>
</label> <button id="side-menu-save" class="btn btn-primary"><?php p($l->t('Save')); ?></button>
<span id="side-menu-message" class="msg"></span>
<div style="height: 30px"></div>
<div>
<span for="side-menu-opener" class="settings-hint">
<?php p($l->t('You like this app and you want to support me?')); ?>
<a style="margin-left: 10px" target="_blank" href="https://www.buymeacoffee.com/deblan">
<button>
<?php p($l->t('Buy me a coffe ☕')); ?>
</button>
</a>
</span>
</div>
</div> </div>
<?php
$choices = [
'Default' => 'side-menu-opener',
'Hamburger' => 'side-menu-opener-hamburger',
];
?>
<div>
<select id="side-menu-opener" name="opener">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['opener']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-opener" class="settings-hint">
<?php p($l->t('Display the logo')); ?>
</label>
</div>
<?php
$choices = [
'Yes' => '1',
'No' => '0',
];
?>
<div>
<select id="side-menu-display-logo" name="display-logo">
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['display-logo']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>">
<button id="side-menu-save" class="btn btn-primary"><?php p($l->t('Save')); ?></button>
<span id="side-menu-message" class="msg"></span>
</div> </div>
-1
View File
@@ -4,7 +4,6 @@ const StyleLintPlugin = require('stylelint-webpack-plugin')
module.exports = { module.exports = {
entry: { entry: {
'main': path.join(__dirname, 'src', 'main.js'),
'admin': path.join(__dirname, 'src', 'admin.js'), 'admin': path.join(__dirname, 'src', 'admin.js'),
'sideMenu': path.join(__dirname, 'src', 'SideMenu.js'), 'sideMenu': path.join(__dirname, 'src', 'SideMenu.js'),
}, },