Compare commits

..

36 Commits

Author SHA1 Message Date
Simon Vieille cc0fac6486 release v1.16.0 2020-09-24 14:29:12 +02:00
Simon Vieille 4d1ec41a9b release v1.16.0 2020-09-24 14:27:35 +02:00
Simon Vieille 034b24369a Merge branch 'feature/issue38' into develop 2020-09-24 14:26:46 +02:00
Simon Vieille b5874792f1 update screenshots 2020-09-24 14:26:43 +02:00
Simon Vieille c7f9fd1b8b add an option to force settings to users 2020-09-24 14:26:25 +02:00
Simon Vieille 4b6a1f2989 release v1.15.0 2020-09-23 14:34:59 +02:00
Simon Vieille 87dc460ed0 Merge branch 'feature/issue35' into develop 2020-09-23 14:34:17 +02:00
Simon Vieille 508d9f71d1 fix #36: always displayed is not expanding 2020-09-23 14:32:25 +02:00
Simon Vieille fcb2d2a385 update translations 2020-09-23 13:21:22 +02:00
Simon Vieille c9645a4f85 change 'Side menu' with 'Custom menu' 2020-09-23 13:17:13 +02:00
Simon Vieille a6397d2f24 update app icon 2020-09-23 13:16:58 +02:00
Simon Vieille b0b2ae44f5 update template for issue 2020-09-23 12:57:45 +02:00
Simon Vieille 9d2eab42d8 fix args type 2020-09-23 12:51:55 +02:00
Simon Vieille 12c115d6d6 fix #37: update template for issue 2020-09-23 12:51:32 +02:00
Simon Vieille 30ed6c1b54 release v1.14.0 2020-09-22 15:04:05 +02:00
Simon Vieille bd7cefa6b6 release v1.14.0 2020-09-22 14:59:33 +02:00
Simon Vieille 240a6b1aa4 PSR 2 compliance 2020-09-22 14:35:09 +02:00
Simon Vieille 40e883841e add config proxy 2020-09-22 14:24:53 +02:00
Simon Vieille 7b5e92f83e add config proxy 2020-09-22 14:24:48 +02:00
Simon Vieille 9a67c165bd add constante for the app id and the app name 2020-09-21 11:28:55 +02:00
Simon Vieille 78c95c58ff fix regression with the logo and the avatar display 2020-09-21 09:49:09 +02:00
Simon Vieille 98f74bfe33 remove useless attributes 2020-09-21 09:45:51 +02:00
Simon Vieille a9b4283e76 Merge branch 'feature/conf' into develop 2020-09-20 20:57:02 +02:00
Simon Vieille 85c15a1967 add PHP doc 2020-09-20 20:56:59 +02:00
Simon Vieille 45abf1f09d SideMenu and SideMenuBig use the new controller to get configuration 2020-09-20 20:56:36 +02:00
Simon Vieille 5153bee7c6 - add specific methods to get the config
- add a controller to retrieve most of the configuration
2020-09-20 20:53:03 +02:00
Simon Vieille cd294273cb update description 2020-09-19 15:51:56 +02:00
Simon Vieille be17c0e232 update translations 2020-09-18 13:02:23 +02:00
Simon Vieille 41ca035299 release v1.13.0 2020-09-18 11:12:47 +02:00
Simon Vieille 110ac5b130 update screenshots 2020-09-18 11:12:19 +02:00
Simon Vieille 266ba1453e Merge branch 'feature/issue34' into develop 2020-09-18 11:10:22 +02:00
Simon Vieille ba6d6fdd8f PSR 2 compliance 2020-09-18 11:09:14 +02:00
Simon Vieille e5dd893774 add option to show the avatar instead of the logo 2020-09-18 11:09:01 +02:00
Simon Vieille 85c25f0fc7 update description 2020-09-18 09:14:05 +02:00
Simon Vieille ae130388a5 release v1.12.3 2020-09-18 09:05:06 +02:00
Simon Vieille e653214b91 add a delay before moving elements (fix #33) 2020-09-17 15:19:42 +02:00
25 changed files with 601 additions and 290 deletions
+2
View File
@@ -15,8 +15,10 @@
### Environment ### Environment
* Side menu version: ... * Side menu version: ...
* Nextcloud version: ...
* PHP version: ... * PHP version: ...
* Web server (Nginx, Apache2): ... * Web server (Nginx, Apache2): ...
* Web browser and version (Firefox 80, Google Chrome 74, etc): ...
### Steps to reproduce ### Steps to reproduce
+3 -3
View File
@@ -1,7 +1,7 @@
🤙 Nextcloud app / Side menu 🎨 🤙 Nextcloud app / Custom menu 🎨
=============================== ===============================
Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface or with a big menu on the top. Allows you to modify the position of the main menu by creating a panel on the left of the interface or with a big menu on the top.
You can also define apps that must be displayed in the top menu. Fully customisable. You can also define apps that must be displayed in the top menu. Fully customisable.
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.
@@ -17,7 +17,7 @@ You like this app and you want to support me? [Buy me a coffee](https://www.buym
Installation and upgrade Installation and upgrade
------------------------ ------------------------
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`. Custom menu is available 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`.
``` ```
$ cd /path/to/nextcloud/apps $ cd /path/to/nextcloud/apps
+7 -3
View File
@@ -1,9 +1,9 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<info> <info>
<id>side_menu</id> <id>side_menu</id>
<name>Side menu</name> <name>Custom menu</name>
<summary>Modify the display of the menu.</summary> <summary>Modify the display of the menu.</summary>
<description><![CDATA[Side menu allows you to modify the position of the main menu by creating a panel on the left of the interface or with a big menu on the top. <description><![CDATA[Custom menu allows you to modify the position of the main menu by creating a panel on the left of the interface or with a big menu on the top.
You can also define apps that must be displayed in the top menu. Fully customisable. You can also define apps that must be displayed in the top menu. Fully customisable.
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.
@@ -14,10 +14,14 @@ 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.
If you like this application and want to support the development:
* ☕ [Buy me a coffee](https://www.buymeacoffee.com/deblan)
* 😃 [Leave a comment](https://apps.nextcloud.com/apps/side_menu#comments)
]]></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.12.2</version> <version>1.16.0</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>
+1
View File
@@ -21,6 +21,7 @@ return [
'routes' => [ 'routes' => [
['name' => 'Css#stylesheet', 'url' => '/css/stylesheet', 'verb' => 'GET'], ['name' => 'Css#stylesheet', 'url' => '/css/stylesheet', 'verb' => 'GET'],
['name' => 'Js#script', 'url' => '/js/script', 'verb' => 'GET'], ['name' => 'Js#script', 'url' => '/js/script', 'verb' => 'GET'],
['name' => 'Js#config', 'url' => '/js/config', 'verb' => 'GET'],
['name' => 'Nav#items', 'url' => '/nav/items', 'verb' => 'GET'], ['name' => 'Nav#items', 'url' => '/nav/items', 'verb' => 'GET'],
['name' => 'PersonalSetting#valueSet', 'url' => '/personalSetting/valueSet', 'verb' => 'POST'], ['name' => 'PersonalSetting#valueSet', 'url' => '/personalSetting/valueSet', 'verb' => 'POST'],
], ],
+113
View File
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="37.099998mm"
height="37.099998mm"
viewBox="0 0 37.099998 37.099998"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="icon.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="242.1839"
inkscape:cy="32.026866"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1918"
inkscape:window-height="1027"
inkscape:window-x="1920"
inkscape:window-y="21"
inkscape:window-maximized="0"
inkscape:snap-nodes="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-59.922223,-92.669069)">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1.46500015;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;enable-background:accumulate"
id="rect815-6-2-7"
width="34.535"
height="34.535"
x="61.204723"
y="93.951569"
rx="5.4806547"
ry="5.4806547" />
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.46500015;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;enable-background:accumulate"
id="rect815-6-7"
width="20.357224"
height="33.40107"
x="61.677193"
y="94.518532"
rx="0"
ry="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:3.16499996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 66.59458,111.16177 h 9.997359"
id="path873-5"
inkscape:connector-curvature="0" />
<g
id="g1018"
transform="translate(2.6458333)"
style="stroke:#333333;stroke-opacity:1">
<g
id="g1013"
style="stroke:#333333;stroke-opacity:1">
<path
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:3.16499996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 63.948747,103.80467 H 75.349244"
id="path873"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:3.16499996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 63.948747,118.51887 H 75.349244"
id="path873-5-3"
inkscape:connector-curvature="0" />
</g>
</g>
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#333333;stroke-width:2.56500006;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:fill markers stroke;enable-background:accumulate"
id="rect815-6-2"
width="34.535"
height="34.535"
x="61.204723"
y="93.951569"
rx="5.4806547"
ry="5.4806547" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

+16 -7
View File
@@ -6,6 +6,7 @@ use OC;
use OC\Security\CSP\ContentSecurityPolicyNonceManager; use OC\Security\CSP\ContentSecurityPolicyNonceManager;
use OC\User\User; use OC\User\User;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\App; use OCP\AppFramework\App;
use OCP\IUserSession; use OCP\IUserSession;
use OCP\Util; use OCP\Util;
@@ -18,6 +19,9 @@ use Psr\Container\ContainerInterface;
*/ */
class Application extends App class Application extends App
{ {
public const APP_ID = 'side_menu';
public const APP_NAME = 'Custom menu';
/** /**
* @var OC\AllConfig * @var OC\AllConfig
*/ */
@@ -38,7 +42,7 @@ class Application extends App
*/ */
public function __construct(array $urlParams = []) public function __construct(array $urlParams = [])
{ {
parent::__construct('side_menu', $urlParams); parent::__construct(self::APP_ID, $urlParams);
$this->config = OC::$server->getConfig(); $this->config = OC::$server->getConfig();
$this->cspnm = OC::$server->getContentSecurityPolicyNonceManager(); $this->cspnm = OC::$server->getContentSecurityPolicyNonceManager();
@@ -51,9 +55,10 @@ class Application extends App
public function isEnabled(): bool public function isEnabled(): bool
{ {
$enabled = true; $enabled = true;
$isForced = (bool) $this->config->getAppValue(self::APP_ID, 'force', '0');
if (null !== $this->user) { if (null !== $this->user && !$isForced) {
$enabled = (bool) $this->config->getUserValue($this->user->getUid(), 'side_menu', 'enabled', '1'); $enabled = (bool) $this->config->getUserValue($this->user->getUid(), self::APP_ID, 'enabled', '1');
} }
return $enabled; return $enabled;
@@ -69,6 +74,10 @@ class Application extends App
$container->registerService('AppRepository', function (ContainerInterface $c) { $container->registerService('AppRepository', function (ContainerInterface $c) {
return new AppRepository(new OC_App()); return new AppRepository(new OC_App());
}); });
$container->registerService('ConfigProxy', function (ContainerInterface $c) {
return new ConfigProxy($this->config);
});
} }
/** /**
@@ -76,20 +85,20 @@ class Application extends App
*/ */
public function registerAssets() public function registerAssets()
{ {
Util::addScript('side_menu', 'sideMenu'); Util::addScript(self::APP_ID, 'sideMenu');
Util::addStyle('side_menu', 'sideMenu'); Util::addStyle(self::APP_ID, 'sideMenu');
$stylesheet = OC::$server->getURLGenerator()->linkToRoute( $stylesheet = OC::$server->getURLGenerator()->linkToRoute(
'side_menu.Css.stylesheet', 'side_menu.Css.stylesheet',
[ [
'v' => $this->config->getAppValue('side_menu', 'cache', '0'), 'v' => $this->config->getAppValue(self::APP_ID, 'cache', '0'),
] ]
); );
$script = OC::$server->getURLGenerator()->linkToRoute( $script = OC::$server->getURLGenerator()->linkToRoute(
'side_menu.Js.script', 'side_menu.Js.script',
[ [
'v' => $this->config->getAppValue('side_menu', 'cache', '0'), 'v' => $this->config->getAppValue(self::APP_ID, 'cache', '0'),
] ]
); );
+47 -40
View File
@@ -19,27 +19,32 @@
namespace OCA\SideMenu\Controller; namespace OCA\SideMenu\Controller;
use OC; use OC;
use OC\User\User;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
class CssController extends Controller class CssController extends Controller
{ {
/** /**
* @var \OCP\IConfig * @var ConfigProxy
*/ */
protected $config; protected $config;
/** /**
* @param string $appName * @var User
*/ */
public function __construct($appName, IRequest $request, IConfig $config) protected $user;
public function __construct(string $appName, IRequest $request, ConfigProxy $config)
{ {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->user = OC::$server[IUserSession::class]->getUser();
$this->config = $config; $this->config = $config;
} }
@@ -52,44 +57,46 @@ class CssController extends Controller
*/ */
public function stylesheet() public function stylesheet()
{ {
$backgroundColor = $this->config->getAppValue('side_menu', 'background-color', '#333333'); $response = new TemplateResponse(Application::APP_ID, 'css/stylesheet', $this->getConfig(), 'blank');
$backgroundColorTo = $this->config->getAppValue('side_menu', 'background-color-to', $backgroundColor);
$user = OC::$server[IUserSession::class]->getUser();
$topMenuApps = (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true);
if ($user) {
$userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true);
if (!empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps;
}
}
$parameters = [
'vars' => [
'background-color' => $backgroundColor,
'background-color-to' => $backgroundColorTo,
'current-app-background-color' => $this->config->getAppValue('side_menu', 'current-app-background-color', '#444444'),
'loader-color' => $this->config->getAppValue('side_menu', 'loader-color', '#0e75ac'),
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'),
'icon-invert-filter' => abs((int) $this->config->getAppValue('side_menu', 'icon-invert-filter', '0')).'%',
'icon-opacity' => abs((int) $this->config->getAppValue('side_menu', 'icon-opacity', '100') / 100),
],
'display-logo' => (bool) $this->config->getAppValue('side_menu', 'display-logo', 1),
'opener-only' => (bool) $this->config->getAppValue('side_menu', 'opener-only', 0),
'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,
];
$response = new TemplateResponse('side_menu', 'css/stylesheet', $parameters, 'blank');
$response->addHeader('Content-Type', 'text/css'); $response->addHeader('Content-Type', 'text/css');
return $response; return $response;
} }
protected function getConfig(): array
{
$backgroundColor = $this->config->getAppValue('background-color', '#333333');
$backgroundColorTo = $this->config->getAppValue('background-color-to', $backgroundColor);
$isForced = $this->config->getAppValueBool('force', '0');
$topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]');
if ($this->user) {
$userTopMenuApps = $this->config->getUserValueArray($this->user, 'top-menu-apps', '[]');
if (!empty($userTopMenuApps) && !$isForced) {
$topMenuApps = $userTopMenuApps;
}
}
return [
'vars' => [
'background-color' => $backgroundColor,
'background-color-to' => $backgroundColorTo,
'current-app-background-color' => $this->config->getAppValue('current-app-background-color', '#444444'),
'loader-color' => $this->config->getAppValue('loader-color', '#0e75ac'),
'text-color' => $this->config->getAppValue('text-color', '#FFFFFF'),
'opener' => $this->config->getAppValue('opener', 'side-menu-opener'),
'icon-invert-filter' => abs($this->config->getAppValueInt('icon-invert-filter', '0')).'%',
'icon-opacity' => abs($this->config->getAppValueInt('icon-opacity', '100') / 100),
],
'display-logo' => $this->config->getAppValueBool('display-logo', '1'),
'opener-only' => $this->config->getAppValueBool('opener-only', '0'),
'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', '0'),
'size-icon' => $this->config->getAppValue('size-icon', 'normal'),
'size-text' => $this->config->getAppValue('size-text', 'normal'),
'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'),
'big-menu' => $this->config->getAppValueBool('big-menu', '0'),
'top-menu-apps' => $topMenuApps,
];
}
} }
+81 -42
View File
@@ -19,27 +19,40 @@
namespace OCA\SideMenu\Controller; namespace OCA\SideMenu\Controller;
use OC; use OC;
use OC\User\User;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\ConfigProxy;
use OCA\Theming\ThemingDefaults;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
class JsController extends Controller class JsController extends Controller
{ {
/** /**
* @var \OCP\IConfig * @var ConfigProxy
*/ */
protected $config; protected $config;
/** /**
* @param string $appName * @var User
*/ */
public function __construct($appName, IRequest $request, IConfig $config) protected $user;
/**
* @var ThemingDefaults
*/
protected $themingDefaults;
public function __construct(string $appName, IRequest $request, ConfigProxy $config, ThemingDefaults $themingDefaults)
{ {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->themingDefaults = $themingDefaults;
$this->user = OC::$server[IUserSession::class]->getUser();
$this->config = $config; $this->config = $config;
} }
@@ -47,47 +60,73 @@ class JsController extends Controller
* @NoAdminRequired * @NoAdminRequired
* @NoCSRFRequired * @NoCSRFRequired
* @PublicPage * @PublicPage
*
* @return Response
*/ */
public function script() public function script(): TemplateResponse
{ {
$user = OC::$server[IUserSession::class]->getUser(); $response = new TemplateResponse(Application::APP_ID, 'js/script', $this->getConfig(), 'blank');
$topMenuApps = (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true);
$targetBlankApps = (array) json_decode($this->config->getAppValue('side_menu', 'target-blank-apps', '[]'), true);
if ($user) {
$userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true);
if (!empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps;
}
$userTargetBlankMode = (int) $this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-mode', '1');
$userTargetBlankApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-apps', '[]'), true);
if ($userTargetBlankMode === 2) {
$targetBlankApps = $userTargetBlankApps;
}
}
$parameters = [
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'),
'opener-hover' => (bool) $this->config->getAppValue('side_menu', 'opener-hover', '0'),
'external-sites-in-top-menu' => (bool) $this->config->getAppValue('side_menu', 'external-sites-in-top-menu', 0),
'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,
'target-blank-apps' => $targetBlankApps,
];
$response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank');
$response->addHeader('Content-Type', 'text/javascript'); $response->addHeader('Content-Type', 'text/javascript');
return $response; return $response;
} }
/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
*/
public function config(): JSONResponse
{
return new JSONResponse($this->getConfig());
}
protected function getConfig(): array
{
$topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]');
$targetBlankApps = $this->config->getAppValueArray('target-blank-apps', '[]');
$useAvatar = $this->config->getAppValueBool('use-avatar', '0');
$isForced = $this->config->getAppValueBool('force', '0');
$avatar = null;
if ($this->user) {
$userTopMenuApps = $this->config->getUserValueArray($this->user, 'top-menu-apps', '[]');
if (!empty($userTopMenuApps) && !$isForced) {
$topMenuApps = $userTopMenuApps;
}
$userTargetBlankMode = $this->config->getUserValueInt($this->user, 'target-blank-mode', '1');
$userTargetBlankApps = $this->config->getUserValueArray($this->user, 'target-blank-apps', '[]');
if (2 === $userTargetBlankMode && !$isForced) {
$targetBlankApps = $userTargetBlankApps;
}
$isAvatarSet = OC::$server->getAvatarManager()->getAvatar($this->user->getUid())->exists();
if ($useAvatar && $isAvatarSet) {
$avatar = OC::$server->getURLGenerator()->linkToRoute(
'core.avatar.getAvatar', [
'userId' => $this->user->getUid(),
'size' => 128,
'v' => $this->config->getUserValueInt($this->user, 'avatar', 'version', 0),
]
);
}
}
return [
'opener-position' => $this->config->getAppValue('opener-position', 'before'),
'opener-hover' => $this->config->getAppValueBool('opener-hover', '0'),
'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', '0'),
'force-light-icon' => $this->config->getAppValueBool('force-light-icon', '0'),
'hide-when-no-apps' => $this->config->getAppValueBool('hide-when-no-apps', '0'),
'loader-enabled' => $this->config->getAppValueBool('loader-enabled', '1'),
'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'),
'big-menu' => $this->config->getAppValueBool('big-menu', '0'),
'avatar' => $avatar,
'top-menu-apps' => $topMenuApps,
'target-blank-apps' => $targetBlankApps,
'logo' => $this->themingDefaults->getLogo(),
];
}
} }
+7 -10
View File
@@ -22,9 +22,9 @@ use OC;
use OC\App\AppStore\Fetcher\CategoryFetcher; use OC\App\AppStore\Fetcher\CategoryFetcher;
use OC\URLGenerator; use OC\URLGenerator;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
@@ -33,7 +33,7 @@ use OCP\L10N\IFactory;
class NavController extends Controller class NavController extends Controller
{ {
/** /**
* @var IConfig * @var ConfigProxy
*/ */
protected $config; protected $config;
@@ -57,13 +57,10 @@ class NavController extends Controller
*/ */
protected $router; protected $router;
/**
* @param string $appName
*/
public function __construct( public function __construct(
$appName, string $appName,
IRequest $request, IRequest $request,
IConfig $config, ConfigProxy $config,
AppRepository $appRepository, AppRepository $appRepository,
CategoryFetcher $categoryFetcher, CategoryFetcher $categoryFetcher,
URLGenerator $router, URLGenerator $router,
@@ -91,7 +88,7 @@ class NavController extends Controller
$apps = $this->appRepository->getVisibleApps(); $apps = $this->appRepository->getVisibleApps();
$currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2); $currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2);
$categoriesLabels = $this->categoryFetcher->get(); $categoriesLabels = $this->categoryFetcher->get();
$externalSitesInTopMenu = (bool) $this->config->getAppValue('side_menu', 'external-sites-in-top-menu', 0); $externalSitesInTopMenu = $this->config->getAppValueBool('external-sites-in-top-menu', '0');
$user = OC::$server[IUserSession::class]->getUser(); $user = OC::$server[IUserSession::class]->getUser();
$appsCategories = []; $appsCategories = [];
$categoriesAppsCount = []; $categoriesAppsCount = [];
@@ -103,8 +100,8 @@ class NavController extends Controller
]); ]);
} }
$topMenuApps = (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true); $topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]');
$userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true); $userTopMenuApps = $this->config->getUserValueArray($user, 'top-menu-apps', '[]');
if (!empty($userTopMenuApps)) { if (!empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps; $topMenuApps = $userTopMenuApps;
+9 -2
View File
@@ -23,6 +23,8 @@ use OCP\AppFramework\Http\Response;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\ConfigProxy;
class PersonalSettingController extends Controller class PersonalSettingController extends Controller
{ {
@@ -36,11 +38,12 @@ class PersonalSettingController extends Controller
*/ */
private $userSession; private $userSession;
public function __construct($appName, IRequest $request, IConfig $config, IUserSession $userSession) public function __construct($appName, IRequest $request, IConfig $config, ConfigProxy $configProxy, IUserSession $userSession)
{ {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->config = $config; $this->config = $config;
$this->configProxy = $configProxy;
$this->userSession = $userSession; $this->userSession = $userSession;
} }
@@ -103,8 +106,12 @@ class PersonalSettingController extends Controller
} }
} }
if ($this->configProxy->getAppValueBool('force', '0')) {
$doSave = false;
}
if ($doSave) { if ($doSave) {
$this->config->setUserValue($user->getUid(), 'side_menu', $name, $value); $this->config->setUserValue($user->getUid(), Application::APP_ID, $name, $value);
return [ return [
'name' => $name, 'name' => $name,
+65
View File
@@ -0,0 +1,65 @@
<?php
namespace OCA\SideMenu\Service;
use OC\User\User;
use OCA\SideMenu\AppInfo\Application;
use OCP\IConfig;
/**
* class Config.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class ConfigProxy
{
/**
* @var IConfig
*/
protected $config;
public function __construct(IConfig $config)
{
$this->config = $config;
}
public function getAppValue(string $name, string $default): string
{
return (string) $this->config->getAppValue(Application::APP_ID, $name, $default);
}
public function getUserValue(User $user, string $name, string $default): string
{
return (string) $this->config->getUserValue($user->getUid(), Application::APP_ID, $name, $default);
}
public function getAppValueBool(string $name, string $default): bool
{
return (bool) $this->getAppValue($name, $default);
}
public function getAppValueArray(string $name, string $default): array
{
return (array) json_decode($this->getAppValue($name, $default), true);
}
public function getAppValueInt(string $name, string $default): int
{
return (int) $this->getAppValue($name, $default);
}
public function getUserValueBool(User $user, string $name, string $default): bool
{
return (bool) $this->getUserValue($user, $name, $default);
}
public function getUserValueArray(User $user, string $name, string $default): array
{
return (array) json_decode($this->getUserValue($user, $name, $default), true);
}
public function getUserValueInt(User $user, string $name, string $default): int
{
return (int) $this->getUserValue($user, $name, $default);
}
}
+29 -26
View File
@@ -18,9 +18,10 @@
namespace OCA\SideMenu\Settings; namespace OCA\SideMenu\Settings;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\ILogger; use OCP\ILogger;
use OCP\Settings\ISettings; use OCP\Settings\ISettings;
@@ -38,7 +39,7 @@ class Admin implements ISettings
private $logger; private $logger;
/** /**
* @var IConfig * @var ConfigProxy
*/ */
private $config; private $config;
@@ -47,7 +48,7 @@ class Admin implements ISettings
*/ */
private $appRepository; private $appRepository;
public function __construct(IL10N $l, ILogger $logger, IConfig $config, AppRepository $appRepository) public function __construct(IL10N $l, ILogger $logger, ConfigProxy $config, AppRepository $appRepository)
{ {
$this->l = $l; $this->l = $l;
$this->logger = $logger; $this->logger = $logger;
@@ -60,35 +61,37 @@ class Admin implements ISettings
*/ */
public function getForm() public function getForm()
{ {
$backgroundColor = $this->config->getAppValue('side_menu', 'background-color', '#333333'); $backgroundColor = $this->config->getAppValue('background-color', '#333333');
$backgroundColorTo = $this->config->getAppValue('side_menu', 'background-color-to', $backgroundColor); $backgroundColorTo = $this->config->getAppValue('background-color-to', $backgroundColor);
$parameters = [ $parameters = [
'background-color' => $backgroundColor, 'background-color' => $backgroundColor,
'background-color-to' => $backgroundColorTo, '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('current-app-background-color', '#444444'),
'loader-color' => $this->config->getAppValue('side_menu', 'loader-color', '#0e75ac'), 'loader-color' => $this->config->getAppValue('loader-color', '#0e75ac'),
'icon-invert-filter' => (int) $this->config->getAppValue('side_menu', 'icon-invert-filter', '0'), 'icon-invert-filter' => $this->config->getAppValueInt('icon-invert-filter', '0'),
'icon-opacity' => (int) $this->config->getAppValue('side_menu', 'icon-opacity', '100'), 'icon-opacity' => $this->config->getAppValueInt('icon-opacity', '100'),
'loader-enabled' => $this->config->getAppValue('side_menu', 'loader-enabled', '1'), 'loader-enabled' => $this->config->getAppValue('loader-enabled', '1'),
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'), 'text-color' => $this->config->getAppValue('text-color', '#FFFFFF'),
'cache' => $this->config->getAppValue('side_menu', 'cache', '0'), 'cache' => $this->config->getAppValue('cache', '0'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'), 'opener' => $this->config->getAppValue('opener', 'side-menu-opener'),
'always-displayed' => $this->config->getAppValue('side_menu', 'always-displayed', '0'), 'always-displayed' => $this->config->getAppValue('always-displayed', '0'),
'big-menu' => $this->config->getAppValue('side_menu', 'big-menu', '0'), 'big-menu' => $this->config->getAppValue('big-menu', '0'),
'display-logo' => $this->config->getAppValue('side_menu', 'display-logo', '1'), 'display-logo' => $this->config->getAppValue('display-logo', '1'),
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'), 'use-avatar' => $this->config->getAppValue('use-avatar', '0'),
'opener-hover' => $this->config->getAppValue('side_menu', 'opener-hover', '0'), 'opener-position' => $this->config->getAppValue('opener-position', 'before'),
'opener-only' => $this->config->getAppValue('side_menu', 'opener-only', '0'), 'opener-hover' => $this->config->getAppValue('opener-hover', '0'),
'hide-when-no-apps' => $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'), 'opener-only' => $this->config->getAppValue('opener-only', '0'),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'), 'hide-when-no-apps' => $this->config->getAppValue('hide-when-no-apps', '0'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'), 'size-icon' => $this->config->getAppValue('size-icon', 'normal'),
'target-blank-apps' => (array) json_decode($this->config->getAppValue('side_menu', 'target-blank-apps', '[]'), true), 'size-text' => $this->config->getAppValue('size-text', 'normal'),
'top-menu-apps' => (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true), 'force' => $this->config->getAppValue('force', '0'),
'target-blank-apps' => $this->config->getAppValueArray('target-blank-apps', '[]'),
'top-menu-apps' => $this->config->getAppValueArray('top-menu-apps', '[]'),
'apps' => $this->appRepository->getVisibleApps(), 'apps' => $this->appRepository->getVisibleApps(),
]; ];
return new TemplateResponse('side_menu', 'settings/admin-form', $parameters, ''); return new TemplateResponse(Application::APP_ID, 'settings/admin-form', $parameters, '');
} }
/** /**
@@ -96,7 +99,7 @@ class Admin implements ISettings
*/ */
public function getSection() public function getSection()
{ {
return 'side_menu'; return Application::APP_ID;
} }
/** /**
+4 -3
View File
@@ -21,6 +21,7 @@ namespace OCA\SideMenu\Settings;
use OCP\IL10N; use OCP\IL10N;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\Settings\IIconSection; use OCP\Settings\IIconSection;
use OCA\SideMenu\AppInfo\Application;
class AdminSection implements IIconSection class AdminSection implements IIconSection
{ {
@@ -52,7 +53,7 @@ class AdminSection implements IIconSection
*/ */
public function getID() public function getID()
{ {
return 'side_menu'; return Application::APP_ID;
} }
/** /**
@@ -63,7 +64,7 @@ class AdminSection implements IIconSection
*/ */
public function getName() public function getName()
{ {
return $this->l->t('Side menu'); return $this->l->t(Application::APP_NAME);
} }
/** /**
@@ -83,6 +84,6 @@ class AdminSection implements IIconSection
*/ */
public function getIcon() public function getIcon()
{ {
return $this->url->imagePath('theming', 'app-dark.svg'); return $this->url->imagePath(Application::APP_ID, 'icon.svg');
} }
} }
+15 -13
View File
@@ -18,13 +18,14 @@
namespace OCA\SideMenu\Settings; namespace OCA\SideMenu\Settings;
use OCA\SideMenu\AppInfo\Application;
use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\Service\ConfigProxy;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
use OCP\IL10N; use OCP\IL10N;
use OCP\ILogger; use OCP\ILogger;
use OCP\Settings\ISettings;
use OCP\IConfig;
use OCP\IUserSession; use OCP\IUserSession;
use OCA\SideMenu\Service\AppRepository; use OCP\Settings\ISettings;
class Personal implements ISettings class Personal implements ISettings
{ {
@@ -39,7 +40,7 @@ class Personal implements ISettings
private $logger; private $logger;
/** /**
* @var IConfig * @var ConfigProxy
*/ */
private $config; private $config;
@@ -53,7 +54,7 @@ class Personal implements ISettings
*/ */
private $appRepository; private $appRepository;
public function __construct(IL10N $l, ILogger $logger, IConfig $config, IUserSession $userSession, AppRepository $appRepository) public function __construct(IL10N $l, ILogger $logger, ConfigProxy $config, IUserSession $userSession, AppRepository $appRepository)
{ {
$this->l = $l; $this->l = $l;
$this->logger = $logger; $this->logger = $logger;
@@ -70,14 +71,15 @@ class Personal implements ISettings
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
$parameters = [ $parameters = [
'enabled' => $this->config->getUserValue($user->getUid(), 'side_menu', 'enabled', '1'), 'force' => $this->config->getAppValueBool('force', '0'),
'top-menu-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true), 'enabled' => $this->config->getUserValue($user, 'enabled', '1'),
'target-blank-mode' => $this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-mode', '1'), 'top-menu-apps' => $this->config->getUserValueArray($user, 'top-menu-apps', '[]'),
'target-blank-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank-apps', '[]'), true), 'target-blank-mode' => $this->config->getUserValue($user, 'target-blank-mode', '1'),
'target-blank-apps' => $this->config->getUserValueArray($user, 'target-blank-apps', '[]'),
'apps' => $this->appRepository->getVisibleApps(), 'apps' => $this->appRepository->getVisibleApps(),
]; ];
return new TemplateResponse('side_menu', 'settings/personal-form', $parameters, ''); return new TemplateResponse(Application::APP_ID, 'settings/personal-form', $parameters, '');
} }
/** /**
@@ -85,13 +87,13 @@ class Personal implements ISettings
*/ */
public function getSection() public function getSection()
{ {
return 'side_menu'; return Application::APP_ID;
} }
/** /**
* @return int whether the form should be rather on the top or bottom of * @return int whether the form should be rather on the top or bottom of
* the admin section. The forms are arranged in ascending order of the * the admin section. The forms are arranged in ascending order of the
* priority values. It is required to return a value between 0 and 100. * priority values. It is required to return a value between 0 and 100.
* *
* E.g.: 70 * E.g.: 70
*/ */
+4 -3
View File
@@ -21,6 +21,7 @@ namespace OCA\SideMenu\Settings;
use OCP\IL10N; use OCP\IL10N;
use OCP\IURLGenerator; use OCP\IURLGenerator;
use OCP\Settings\IIconSection; use OCP\Settings\IIconSection;
use OCA\SideMenu\AppInfo\Application;
class PersonalSection implements IIconSection class PersonalSection implements IIconSection
{ {
@@ -52,7 +53,7 @@ class PersonalSection implements IIconSection
*/ */
public function getID() public function getID()
{ {
return 'side_menu'; return Application::APP_ID;
} }
/** /**
@@ -63,7 +64,7 @@ class PersonalSection implements IIconSection
*/ */
public function getName() public function getName()
{ {
return $this->l->t('Side menu'); return $this->l->t(Application::APP_NAME);
} }
/** /**
@@ -83,6 +84,6 @@ class PersonalSection implements IIconSection
*/ */
public function getIcon() public function getIcon()
{ {
return $this->url->imagePath('theming', 'app-dark.svg'); return $this->url->imagePath(Application::APP_ID, 'icon.svg');
} }
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 57 KiB

+21 -17
View File
@@ -19,9 +19,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="side-menu-header"> <div class="side-menu-header">
<button class="side-menu-opener"></button> <button class="side-menu-opener"></button>
<div v-if="logo" class="side-menu-logo"> <div v-if="!avatar && logo" v-bind:class="{'side-menu-logo': true, 'avatardiv': false}">
<img v-bind:src="logo"> <img v-bind:src="logo">
</div> </div>
<div v-if="avatar" v-bind:class="{'side-menu-logo': true, 'avatardiv': true}">
<img v-bind:src="avatar">
</div>
</div> </div>
<ul class="side-menu-apps-list"> <ul class="side-menu-apps-list">
@@ -37,6 +40,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<script> <script>
import trim from 'trim' import trim from 'trim'
import axios from 'axios'
export default { export default {
name: 'SideMenu', name: 'SideMenu',
@@ -44,8 +48,9 @@ export default {
return { return {
apps: [], apps: [],
logo: null, logo: null,
avatar: null,
forceLightIcon: false, forceLightIcon: false,
targetBlank: false, targetBlankApps: [],
} }
}, },
methods: { methods: {
@@ -87,7 +92,7 @@ export default {
} }
this.apps.push({ this.apps.push({
id: dataId, id: dataId,
href: href, href: href,
name: trim(element.querySelector('span').innerHTML), name: trim(element.querySelector('span').innerHTML),
icon: svg, icon: svg,
@@ -102,26 +107,25 @@ export default {
}, 1000) }, 1000)
})(this.apps) })(this.apps)
}, },
retrieveLogo() {
const ncLogo = document.querySelector('#nextcloud .logo')
if (ncLogo) { retrieveConfig() {
const url = window.getComputedStyle(ncLogo, null) let that = this
.getPropertyValue('background-image')
.replace('url("', '')
.replace('")', '')
if (url && url !== 'none') { axios
this.logo = url .get(OC.generateUrl('/apps/side_menu/js/config'))
} .then(function(response) {
} const config = response.data
that.targetBlankApps = config['target-blank-apps']
that.forceLightIcon = config['force-light-icon']
that.avatar = config['avatar']
that.logo = config['logo']
});
}, },
}, },
mounted() { mounted() {
this.retrieveConfig()
this.retrieveApps() this.retrieveApps()
this.retrieveLogo()
this.forceLightIcon = document.querySelector('#side-menu-container').getAttribute('data-forcelighticon') == 1;
this.targetBlankApps = document.querySelector('#side-menu-container').getAttribute('data-targetblankapps').split(',');
const menu = document.querySelector('#appmenu') const menu = document.querySelector('#appmenu')
+17 -4
View File
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div id="side-menu" class="side-menu-big"> <div id="side-menu" class="side-menu-big">
<div class="side-menu-header"> <div class="side-menu-header">
<button class="side-menu-opener side-menu-closer"></button> <button class="side-menu-opener side-menu-closer"></button>
<button class="side-menu-opener"></button> <button class="side-menu-opener"></button>
</div> </div>
<div class="side-menu-categories-wrapper"> <div class="side-menu-categories-wrapper">
@@ -50,7 +50,8 @@ export default {
return { return {
items: [], items: [],
activeApp: null, activeApp: null,
targetBlank: false, targetBlank: false,
targetBlankApps: [],
} }
}, },
methods: { methods: {
@@ -74,14 +75,26 @@ export default {
jQuery('body').trigger('side-menu.apps', [apps]) jQuery('body').trigger('side-menu.apps', [apps])
}); });
}, },
retrieveActiveApp() { retrieveActiveApp() {
let activeAppLink = document.querySelector('#appmenu a.active') let activeAppLink = document.querySelector('#appmenu a.active')
this.activeApp = activeAppLink ? activeAppLink.parentNode.getAttribute('data-id') : null this.activeApp = activeAppLink ? activeAppLink.parentNode.getAttribute('data-id') : null
}, },
retrieveConfig() {
let that = this
axios
.get(OC.generateUrl('/apps/side_menu/js/config'))
.then(function(response) {
const config = response.data
that.targetBlankApps = config['target-blank-apps']
});
},
}, },
mounted() { mounted() {
this.targetBlankApps = document.querySelector('#side-menu-container').getAttribute('data-targetblankapps').split(','); this.retrieveConfig()
this.retrieveApps() this.retrieveApps()
this.retrieveActiveApp() this.retrieveActiveApp()
} }
+5 -2
View File
@@ -1,5 +1,5 @@
"Side menu": "Seitenmenü" "Custom menu": "Benutzerdefiniertes Menü"
"Enable the side menu": "Aktiviere das Seitenmenü" "Enable the custom menu": "Aktiviere das Benutzerdefiniertes Menü"
"No": "Nein" "No": "Nein"
"Yes": "Ja" "Yes": "Ja"
"Menu": "Menü" "Menu": "Menü"
@@ -56,3 +56,6 @@
"Use the global setting": "Verwende die globale Einstellung" "Use the global setting": "Verwende die globale Einstellung"
"Use my selection": "Verwende meine Auswahl" "Use my selection": "Verwende meine Auswahl"
"Show and hide the list of applications": "Ein- und Ausblenden der Anwendungsliste" "Show and hide the list of applications": "Ein- und Ausblenden der Anwendungsliste"
"Use the avatar instead of the logo": "Verwenden Sie den Avatar anstelle des Logos"
"You do not have permission to change the settings.": "Sie haben keine Berechtigung zum Ändern der Einstellungen."
"Force this configuration to users": "Erzwingen Sie diese Konfiguration für Benutzer"
+5 -2
View File
@@ -1,5 +1,5 @@
"Side menu": "Menu latéral" "Custom menu": "Menu personnalisé"
"Enable the side menu": "Activer le menu latéral" "Enable the custom menu": "Activer le menu personnalisé"
"No": "Non" "No": "Non"
"Yes": "Oui" "Yes": "Oui"
"Menu": "Menu" "Menu": "Menu"
@@ -56,3 +56,6 @@
"Use the global setting": "Utiliser la configuration globale" "Use the global setting": "Utiliser la configuration globale"
"Use my selection": "Utiliser ma sélection" "Use my selection": "Utiliser ma sélection"
"Show and hide the list of applications": "Afficher et masquer la liste des applications" "Show and hide the list of applications": "Afficher et masquer la liste des applications"
"Use the avatar instead of the logo": "Utiliser l'avatar à la place du logo"
"You do not have permission to change the settings.": "Vous n'avez pas la permission de changer les paramètres."
"Force this configuration to users": "Forcer cette configuration aux utilisateurs"
+1 -1
View File
@@ -41,4 +41,4 @@ var alwaysDisplayed = function() {
} }
} }
alwaysDisplayed() window.setTimeout(alwaysDisplayed, 200)
+3 -9
View File
@@ -10,12 +10,6 @@
sideMenu.attr('data-bigmenu', '1') sideMenu.attr('data-bigmenu', '1')
<?php endif; ?> <?php endif; ?>
<?php if ($_['force-light-icon']): ?>
sideMenuContainer.attr('data-forcelighticon', '1')
<?php endif; ?>
sideMenuContainer.attr('data-targetblankapps', '<?php p(implode(',', $_['target-blank-apps'])) ?>')
var targetBlankApps = <?php echo json_encode($_['target-blank-apps']) ?>; var targetBlankApps = <?php echo json_encode($_['target-blank-apps']) ?>;
body.on('side-menu.apps', function(e, apps) { body.on('side-menu.apps', function(e, apps) {
@@ -91,10 +85,10 @@
headerMenuOpener.on('mouseenter', sideMenuOpenerMouseEnter) headerMenuOpener.on('mouseenter', sideMenuOpenerMouseEnter)
sideMenu.addClass('hide-opener') sideMenu.addClass('hide-opener')
<?php else: ?>
sideMenu.on('mouseleave', sideMenuMouseLeave)
sideMenu.on('mouseenter', sideMenuOpenerMouseEnter)
<?php endif ?> <?php endif ?>
sideMenu.on('mouseleave', sideMenuMouseLeave)
sideMenu.on('mouseenter', sideMenuOpenerMouseEnter)
} }
<?php endif; ?> <?php endif; ?>
+26
View File
@@ -342,6 +342,18 @@ $choicesSizes = [
</select> </select>
</div> </div>
<p><em><?php p($l->t('Use the avatar instead of the logo')); ?></em></p>
<div>
<select id="side-menu-use-avatar" name="use-avatar" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['use-avatar']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div> <div>
<label> <label>
<?php p($l->t('Icons and texts')); ?> <?php p($l->t('Icons and texts')); ?>
@@ -461,6 +473,20 @@ $choicesSizes = [
</div> </div>
<div class="section"> <div class="section">
<div>
<label for="side-menu-opener-only">
<?php p($l->t('Force this configuration to users')); ?>
</label>
<select id="side-menu-force" name="force" class="side-menu-setting">
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['force']): ?>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']); ?>" class="side-menu-setting"> <input type="hidden" id="side-menu-cache" name="cache" value="<?php print_unescaped($_['cache']); ?>" class="side-menu-setting">
<button id="side-menu-save" class="btn btn-primary"><?php p($l->t('Save')); ?></button> <button id="side-menu-save" class="btn btn-primary"><?php p($l->t('Save')); ?></button>
+120 -103
View File
@@ -27,125 +27,142 @@ $choicesYesNo = [
?> ?>
<div id="side-menu-section"> <div id="side-menu-section">
<div class="section"> <?php if ($_['force']): ?>
<h2> <div class="section">
<?php p($l->t('Menu')); ?> <h2>
</h2> <?php p($l->t('Menu')); ?>
</h2>
<div> <p>
<label for="side-menu-enabled"> <em><?php echo $l->t('You do not have permission to change the settings.'); ?></em>
<?php p($l->t('Enable the side menu')); ?> </p>
</label>
</div> </div>
<?php else: ?>
<div class="section">
<h2>
<?php p($l->t('Menu')); ?>
</h2>
<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>
<div>
<select id="side-menu-enabled" name="enabled" class="side-menu-setting" data-personal> <div>
<?php foreach ($choicesYesNo as $label => $value): ?> <label for="side-menu-enabled">
<option value="<?php echo $value ?>" <?php if ($value === $_['enabled']): ?>selected<?php endif; ?>> <?php p($l->t('Enable the custom menu')); ?>
<?php echo $l->t($label); ?> </label>
</option> </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>
<div>
<select id="side-menu-enabled" name="enabled" class="side-menu-setting" data-personal>
<?php foreach ($choicesYesNo as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['enabled']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="side-menu-target-blank">
<?php p($l->t('Open apps in new tab')); ?>
</label>
</div>
<div>
<?php $choices = [
'Use the global setting' => '1',
'Use my selection' => '2',
]; ?>
<select id="side-menu-loader-enabled" name="target-blank-mode" class="side-menu-setting" data-personal>
<?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['target-blank-mode']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<p>
<a class="side-menu-toggler" data-target="#target-blank-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="target-blank-apps" id="target-blank-apps" data-personal data-checkbox style="display: none">
<?php foreach ($_['apps'] as $app): ?>
<div>
<input
type="checkbox"
name="target-blank-apps[]"
value="<?php echo $app['id'] ?>"
id="target-blank-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['target-blank-apps'])): ?>checked<?php endif; ?>
/>
<label for="target-blank-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</div>
<?php endforeach; ?> <?php endforeach; ?>
</select> </div>
</div> </div>
<div> <div class="section">
<label for="side-menu-target-blank"> <h2>
<?php p($l->t('Open apps in new tab')); ?> <?php p($l->t('Top menu')); ?>
</label> </h2>
</div> <div>
<label for="side-menu-top-menu-apps">
<?php p($l->t('Apps that not must be moved in the side menu')); ?>
</label>
</div>
<div> <p>
<?php $choices = [ <em>
'Use the global setting' => '1', <?php p($l->t('If there is no selection then the global configuration is applied.')); ?>
'Use my selection' => '2', </em>
]; ?> </p>
<select id="side-menu-loader-enabled" name="target-blank-mode" class="side-menu-setting" data-personal> <p>
<?php foreach ($choices as $label => $value): ?> <a class="side-menu-toggler" data-target="#top-menu-apps" href="#_">
<option value="<?php echo $value ?>" <?php if ($value === $_['target-blank-mode']): ?>selected<?php endif; ?>> 🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
<?php echo $l->t($label); ?> </a>
</option> </p>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox data-personal id="top-menu-apps" style="display: none">
<?php foreach ($_['apps'] as $app): ?>
<div>
<input
type="checkbox"
name="top-menu-apps[]"
value="<?php echo $app['id'] ?>"
id="top-menu-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['top-menu-apps'])): ?>checked<?php endif; ?>
/>
<label for="top-menu-app-<?php echo $app['id'] ?>">
<?php echo $app['name'] ?>
</label>
</div>
<?php endforeach; ?> <?php endforeach; ?>
</select> </div>
</div> </div>
<?php endif ?>
<p>
<a class="side-menu-toggler" data-target="#target-blank-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="target-blank-apps" id="target-blank-apps" data-personal data-checkbox style="display: none">
<?php foreach ($_['apps'] as $app): ?>
<div>
<input
type="checkbox"
name="target-blank-apps[]"
value="<?php echo $app['id'] ?>"
id="target-blank-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['target-blank-apps'])): ?>checked<?php endif; ?>
/>
<label for="target-blank-app-<?php echo $app['id'] ?>">
<?php echo p($l->t($app['name'])); ?>
</label>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="section"> <div class="section">
<h2> <?php if (!$_['force']): ?>
<?php p($l->t('Top menu')); ?> <button id="side-menu-save" class="btn btn-primary"><?php p($l->t('Save')); ?></button>
</h2>
<div>
<label for="side-menu-top-menu-apps">
<?php p($l->t('Apps that not must be moved in the side menu')); ?>
</label>
</div>
<p> <span id="side-menu-message" class="msg"></span>
<em>
<?php p($l->t('If there is no selection then the global configuration is applied.')); ?>
</em>
</p>
<p> <div style="height: 30px"></div>
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_"> <?php endif ?>
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox data-personal id="top-menu-apps" style="display: none">
<?php foreach ($_['apps'] as $app): ?>
<div>
<input
type="checkbox"
name="top-menu-apps[]"
value="<?php echo $app['id'] ?>"
id="top-menu-app-<?php echo $app['id'] ?>"
<?php if (in_array($app['id'], $_['top-menu-apps'])): ?>checked<?php endif; ?>
/>
<label for="top-menu-app-<?php echo $app['id'] ?>">
<?php echo $app['name'] ?>
</label>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="section">
<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> <div>
<span for="side-menu-opener"> <span for="side-menu-opener">