Compare commits

...

37 Commits

Author SHA1 Message Date
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
Simon Vieille 9ca6a3a995 update screenshots 2020-09-14 14:56:09 +02:00
Simon Vieille 7303dbae41 release v1.12.2 2020-09-14 14:51:39 +02:00
Simon Vieille 511f5a0c45 fix issue #31 2020-09-14 14:40:14 +02:00
Simon Vieille 9ea5c1b59b release v1.12.1 2020-09-14 11:31:50 +02:00
Simon Vieille ade56062e3 fix typo 2020-09-14 11:31:03 +02:00
Simon Vieille 481a2d2606 Merge pull request 'src/l10n/fixtures/de.yaml ändern' (#32) from JuxLe/side_menu:juxle-patch-1 into develop
Reviewed-on: https://gitnet.fr/deblan/side_menu/pulls/32
2020-09-14 09:01:09 +02:00
JuxLe 3a809bb92e „src/l10n/fixtures/de.yaml“ ändern
some translation improvements
2020-09-13 03:18:09 +02:00
Simon Vieille cc2ab04035 release v1.12.0 2020-09-12 16:44:05 +02:00
Simon Vieille 17a57f3685 Merge branch 'feature/issue30-tab' into develop 2020-09-12 16:40:43 +02:00
Simon Vieille d41ecbbd9a add translations 2020-09-12 16:35:30 +02:00
Simon Vieille b6c6fc2486 add target _blank 2020-09-12 16:32:10 +02:00
Simon Vieille 918c55da3e add options to select apps that must be opend on new tab (UI) 2020-09-12 16:10:48 +02:00
Simon Vieille 385c27c691 add documentation 2020-09-11 13:46:48 +02:00
Simon Vieille 54d702ba9f add documentation 2020-09-11 13:46:25 +02:00
Simon Vieille c816c40c19 fix typo 2020-09-11 13:39:41 +02:00
27 changed files with 430 additions and 184 deletions
+2
View File
@@ -12,6 +12,8 @@ Comptatible with AppOrder.
* [How to contribute?](#how-to-contribute) * [How to contribute?](#how-to-contribute)
* [Screenshots](https://gitnet.fr/deblan/side_menu/src/branch/master/screenshots/) * [Screenshots](https://gitnet.fr/deblan/side_menu/src/branch/master/screenshots/)
You like this app and you want to support me? [Buy me a coffee](https://www.buymeacoffee.com/deblan) ☕
Installation and upgrade Installation and upgrade
------------------------ ------------------------
+5 -1
View File
@@ -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.
You like this app and you want to support me?
* ☕ [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.11.0</version> <version>1.14.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'],
], ],
+4
View File
@@ -64,3 +64,7 @@
font-size: 11px; font-size: 11px;
font-weight: normal; font-weight: normal;
} }
.side-menu-toggler {
cursor: pointer;
}
+2 -6
View File
@@ -217,15 +217,11 @@
.side-menu-always-displayed #side-menu.open, .side-menu-always-displayed #side-menu.open,
.side-menu-always-displayed #side-menu.open .side-menu-apps-list, .side-menu-always-displayed #side-menu.open .side-menu-apps-list,
.side-menu-always-displayed #side-menu.open .side-menu-header, .side-menu-always-displayed #side-menu.open .side-menu-header {
.side-menu-always-displayed #side-menu:hover,
.side-menu-always-displayed #side-menu:hover .side-menu-apps-list,
.side-menu-always-displayed #side-menu:hover .side-menu-header {
width: 100%; width: 100%;
} }
.side-menu-always-displayed #side-menu.open .side-menu-app-text, .side-menu-always-displayed #side-menu.open .side-menu-app-text {
.side-menu-always-displayed #side-menu:hover .side-menu-app-text {
display: inline; display: inline;
} }
+14 -6
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 = 'Side 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();
@@ -53,7 +57,7 @@ class Application extends App
$enabled = true; $enabled = true;
if (null !== $this->user) { if (null !== $this->user) {
$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 +73,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 +84,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'),
] ]
); );
+36 -29
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); $response->addHeader('Content-Type', 'text/css');
$user = OC::$server[IUserSession::class]->getUser(); return $response;
$topMenuApps = (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true); }
if ($user) { protected function getConfig(): array
$userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true); {
$backgroundColor = $this->config->getAppValue('background-color', '#333333');
$backgroundColorTo = $this->config->getAppValue('background-color-to', $backgroundColor);
$topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]');
if ($this->user) {
$userTopMenuApps = $this->config->getUserValueArray($this->user, 'top-menu-apps', '[]');
if (!empty($userTopMenuApps)) { if (!empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps; $topMenuApps = $userTopMenuApps;
} }
} }
$parameters = [ return [
'vars' => [ 'vars' => [
'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'),
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'), 'text-color' => $this->config->getAppValue('text-color', '#FFFFFF'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'), 'opener' => $this->config->getAppValue('opener', 'side-menu-opener'),
'icon-invert-filter' => abs((int) $this->config->getAppValue('side_menu', 'icon-invert-filter', '0')).'%', 'icon-invert-filter' => abs($this->config->getAppValueInt('icon-invert-filter', '0')).'%',
'icon-opacity' => abs((int) $this->config->getAppValue('side_menu', 'icon-opacity', '100') / 100), 'icon-opacity' => abs($this->config->getAppValueInt('icon-opacity', '100') / 100),
], ],
'display-logo' => (bool) $this->config->getAppValue('side_menu', 'display-logo', 1), 'display-logo' => $this->config->getAppValueBool('display-logo', 1),
'opener-only' => (bool) $this->config->getAppValue('side_menu', 'opener-only', 0), 'opener-only' => $this->config->getAppValueBool('opener-only', 0),
'external-sites-in-top-menu' => (bool) $this->config->getAppValue('side_menu', 'external-sites-in-top-menu', 0), 'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', 0),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'), 'size-icon' => $this->config->getAppValue('size-icon', 'normal'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'), 'size-text' => $this->config->getAppValue('size-text', 'normal'),
'always-displayed' => (bool) $this->config->getAppValue('side_menu', 'always-displayed', '0'), 'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'),
'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'), 'big-menu' => $this->config->getAppValueBool('big-menu', '0'),
'top-menu-apps' => $topMenuApps, 'top-menu-apps' => $topMenuApps,
]; ];
$response = new TemplateResponse('side_menu', 'css/stylesheet', $parameters, 'blank');
$response->addHeader('Content-Type', 'text/css');
return $response;
} }
} }
+71 -32
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,46 +60,72 @@ 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); $response->addHeader('Content-Type', 'text/javascript');
$targetBlank = (bool) $this->config->getAppValue('side_menu', 'target-blank', '0');
if ($user) { return $response;
$userTopMenuApps = (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true); }
/**
* @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');
$avatar = null;
if ($this->user) {
$userTopMenuApps = $this->config->getUserValueArray($this->user, 'top-menu-apps', '[]');
if (!empty($userTopMenuApps)) { if (!empty($userTopMenuApps)) {
$topMenuApps = $userTopMenuApps; $topMenuApps = $userTopMenuApps;
} }
$userTargetBlank = (int) $this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank', '-1'); $userTargetBlankMode = $this->config->getUserValueInt($this->user, 'target-blank-mode', '1');
$userTargetBlankApps = $this->config->getUserValueArray($this->user, 'target-blank-apps', '[]');
if ($userTargetBlank !== -1) { if (2 === $userTargetBlankMode) {
$targetBlank = (bool) $userTargetBlank; $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 [
$parameters = [ 'opener-position' => $this->config->getAppValue('opener-position', 'before'),
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'), 'opener-hover' => $this->config->getAppValueBool('opener-hover', '0'),
'opener-hover' => (bool) $this->config->getAppValue('side_menu', 'opener-hover', '0'), 'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', 0),
'external-sites-in-top-menu' => (bool) $this->config->getAppValue('side_menu', 'external-sites-in-top-menu', 0), 'force-light-icon' => $this->config->getAppValueBool('force-light-icon', '0'),
'force-light-icon' => (bool) $this->config->getAppValue('side_menu', 'force-light-icon', '0'), 'hide-when-no-apps' => $this->config->getAppValueBool('hide-when-no-apps', '0'),
'hide-when-no-apps' => (bool) $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'), 'loader-enabled' => $this->config->getAppValueBool('loader-enabled', '1'),
'loader-enabled' => (bool) $this->config->getAppValue('side_menu', 'loader-enabled', '1'), 'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'),
'always-displayed' => (bool) $this->config->getAppValue('side_menu', 'always-displayed', '0'), 'big-menu' => $this->config->getAppValueBool('big-menu', '0'),
'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'), 'avatar' => $avatar,
'top-menu-apps' => $topMenuApps, 'top-menu-apps' => $topMenuApps,
'target-blank' => $targetBlank, 'target-blank-apps' => $targetBlankApps,
'logo' => $this->themingDefaults->getLogo(),
]; ];
$response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank');
$response->addHeader('Content-Type', 'text/javascript');
return $response;
} }
} }
+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;
+20 -4
View File
@@ -23,6 +23,7 @@ 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;
class PersonalSettingController extends Controller class PersonalSettingController extends Controller
{ {
@@ -65,11 +66,26 @@ class PersonalSettingController extends Controller
} }
} }
if ('target-blank' === $name) { if ('target-blank-mode' === $name) {
$doSave = true; $doSave = true;
if (!in_array($value, ['-1', '0', '1'])) { if (!in_array($value, ['1', '2'])) {
$value = '-1'; $value = '1';
}
}
if ('target-blank-apps' === $name) {
$doSave = true;
$data = json_decode($value, true);
if (!is_array($data)) {
$doSave = false;
} else {
foreach ($data as $v) {
if (!is_string($v)) {
$doSave = false;
}
}
} }
} }
@@ -89,7 +105,7 @@ class PersonalSettingController extends Controller
} }
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);
}
}
+25 -23
View File
@@ -24,6 +24,7 @@ use OCP\IConfig;
use OCP\IL10N; use OCP\IL10N;
use OCP\ILogger; use OCP\ILogger;
use OCP\Settings\ISettings; use OCP\Settings\ISettings;
use OCA\SideMenu\AppInfo\Application;
class Admin implements ISettings class Admin implements ISettings
{ {
@@ -60,35 +61,36 @@ class Admin implements ISettings
*/ */
public function getForm() public function getForm()
{ {
$backgroundColor = $this->config->getAppValue('side_menu', 'background-color', '#333333'); $backgroundColor = $this->config->getAppValue(Application::APP_ID, 'background-color', '#333333');
$backgroundColorTo = $this->config->getAppValue('side_menu', 'background-color-to', $backgroundColor); $backgroundColorTo = $this->config->getAppValue(Application::APP_ID, '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(Application::APP_ID, 'current-app-background-color', '#444444'),
'loader-color' => $this->config->getAppValue('side_menu', 'loader-color', '#0e75ac'), 'loader-color' => $this->config->getAppValue(Application::APP_ID, 'loader-color', '#0e75ac'),
'icon-invert-filter' => (int) $this->config->getAppValue('side_menu', 'icon-invert-filter', '0'), 'icon-invert-filter' => (int) $this->config->getAppValue(Application::APP_ID, 'icon-invert-filter', '0'),
'icon-opacity' => (int) $this->config->getAppValue('side_menu', 'icon-opacity', '100'), 'icon-opacity' => (int) $this->config->getAppValue(Application::APP_ID, 'icon-opacity', '100'),
'loader-enabled' => $this->config->getAppValue('side_menu', 'loader-enabled', '1'), 'loader-enabled' => $this->config->getAppValue(Application::APP_ID, 'loader-enabled', '1'),
'text-color' => $this->config->getAppValue('side_menu', 'text-color', '#FFFFFF'), 'text-color' => $this->config->getAppValue(Application::APP_ID, 'text-color', '#FFFFFF'),
'cache' => $this->config->getAppValue('side_menu', 'cache', '0'), 'cache' => $this->config->getAppValue(Application::APP_ID, 'cache', '0'),
'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'), 'opener' => $this->config->getAppValue(Application::APP_ID, 'opener', 'side-menu-opener'),
'always-displayed' => $this->config->getAppValue('side_menu', 'always-displayed', '0'), 'always-displayed' => $this->config->getAppValue(Application::APP_ID, 'always-displayed', '0'),
'target-blank' => $this->config->getAppValue('side_menu', 'target-blank', '0'), 'big-menu' => $this->config->getAppValue(Application::APP_ID, 'big-menu', '0'),
'big-menu' => $this->config->getAppValue('side_menu', 'big-menu', '0'), 'display-logo' => $this->config->getAppValue(Application::APP_ID, 'display-logo', '1'),
'display-logo' => $this->config->getAppValue('side_menu', 'display-logo', '1'), 'use-avatar' => $this->config->getAppValue(Application::APP_ID, 'use-avatar', '0'),
'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'), 'opener-position' => $this->config->getAppValue(Application::APP_ID, 'opener-position', 'before'),
'opener-hover' => $this->config->getAppValue('side_menu', 'opener-hover', '0'), 'opener-hover' => $this->config->getAppValue(Application::APP_ID, 'opener-hover', '0'),
'opener-only' => $this->config->getAppValue('side_menu', 'opener-only', '0'), 'opener-only' => $this->config->getAppValue(Application::APP_ID, 'opener-only', '0'),
'hide-when-no-apps' => $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'), 'hide-when-no-apps' => $this->config->getAppValue(Application::APP_ID, 'hide-when-no-apps', '0'),
'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'), 'size-icon' => $this->config->getAppValue(Application::APP_ID, 'size-icon', 'normal'),
'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'), 'size-text' => $this->config->getAppValue(Application::APP_ID, 'size-text', 'normal'),
'top-menu-apps' => (array) json_decode($this->config->getAppValue('side_menu', 'top-menu-apps', '[]'), true), 'target-blank-apps' => (array) json_decode($this->config->getAppValue(Application::APP_ID, 'target-blank-apps', '[]'), true),
'top-menu-apps' => (array) json_decode($this->config->getAppValue(Application::APP_ID, 'top-menu-apps', '[]'), true),
'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 +98,7 @@ class Admin implements ISettings
*/ */
public function getSection() public function getSection()
{ {
return 'side_menu'; return Application::APP_ID;
} }
/** /**
+3 -2
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);
} }
/** /**
+7 -5
View File
@@ -25,6 +25,7 @@ use OCP\Settings\ISettings;
use OCP\IConfig; use OCP\IConfig;
use OCP\IUserSession; use OCP\IUserSession;
use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\AppRepository;
use OCA\SideMenu\AppInfo\Application;
class Personal implements ISettings class Personal implements ISettings
{ {
@@ -70,13 +71,14 @@ class Personal implements ISettings
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
$parameters = [ $parameters = [
'enabled' => $this->config->getUserValue($user->getUid(), 'side_menu', 'enabled', '1'), 'enabled' => $this->config->getUserValue($user->getUid(), Application::APP_ID, 'enabled', '1'),
'top-menu-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), 'side_menu', 'top-menu-apps', '[]'), true), 'top-menu-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), Application::APP_ID, 'top-menu-apps', '[]'), true),
'target-blank' => $this->config->getUserValue($user->getUid(), 'side_menu', 'target-blank', '-1'), 'target-blank-mode' => $this->config->getUserValue($user->getUid(), Application::APP_ID, 'target-blank-mode', '1'),
'target-blank-apps' => (array) json_decode($this->config->getUserValue($user->getUid(), Application::APP_ID, 'target-blank-apps', '[]'), true),
'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, '');
} }
/** /**
@@ -84,7 +86,7 @@ class Personal implements ISettings
*/ */
public function getSection() public function getSection()
{ {
return 'side_menu'; return Application::APP_ID;
} }
/** /**
+3 -2
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);
} }
/** /**
Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 58 KiB

+22 -17
View File
@@ -19,14 +19,17 @@ 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">
<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" :target="targetBlank ? '_blank' : undefined" v-bind:title="app.name"> <a v-bind:href="app.href" :target="targetBlankApps.indexOf(app.id) !== -1 ? '_blank' : undefined" 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>
@@ -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,6 +92,7 @@ export default {
} }
this.apps.push({ this.apps.push({
id: dataId,
href: href, href: href,
name: trim(element.querySelector('span').innerHTML), name: trim(element.querySelector('span').innerHTML),
icon: svg, icon: svg,
@@ -101,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.targetBlank = document.querySelector('#side-menu-container').getAttribute('data-targetblank') == 1;
const menu = document.querySelector('#appmenu') const menu = document.querySelector('#appmenu')
+18 -5
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">
@@ -28,7 +28,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-bind:class="{'side-menu-app': true, 'active': activeApp === appId}" v-for="(app, appId) in category.apps"> <li v-bind:class="{'side-menu-app': true, 'active': activeApp === appId}" v-for="(app, appId) in category.apps">
<a v-bind:href="app.href" :target="targetBlank ? '_blank' : undefined" v-bind:title="app.name"> <a v-bind:href="app.href" :target="targetBlankApps.indexOf(appId) !== -1 ? '_blank' : undefined" v-bind:title="app.name">
<img class="side-menu-app-icon" v-bind:src="app.icon"></span> <img class="side-menu-app-icon" v-bind:src="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>
@@ -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.targetBlank = document.querySelector('#side-menu-container').getAttribute('data-targetblank') == 1; this.retrieveConfig()
this.retrieveApps() this.retrieveApps()
this.retrieveActiveApp() this.retrieveActiveApp()
} }
+11
View File
@@ -81,6 +81,10 @@ const saveSettings = (key) => {
} }
} }
const elementToggler = (element) => {
jQuery(element).toggle()
}
jQuery(document).ready(() => { jQuery(document).ready(() => {
elements = jQuery('.side-menu-setting') elements = jQuery('.side-menu-setting')
@@ -118,4 +122,11 @@ jQuery(document).ready(() => {
document.documentElement.style.setProperty('--side-menu-' + name, value) document.documentElement.style.setProperty('--side-menu-' + name, value)
}) })
jQuery('.side-menu-toggler').on('click', (event) => {
var target = jQuery(event.target)
var element = target.attr('data-target')
elementToggler(element)
})
}); });
+16 -13
View File
@@ -1,16 +1,16 @@
"Side menu": "Seitenmenü" "Side menu": "Seitenmenü"
"Enable the side menu": "Aktivieren Sie das Seitenmenü" "Enable the side menu": "Aktiviere das Seitenmenü"
"No": "Nein" "No": "Nein"
"Yes": "Ja" "Yes": "Ja"
"Menu": "Speisekarte" "Menu": "Menü"
'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.': 'Verwenden Sie die Tastenkombination <span class="keyboard-key">Strg</span>+<span class="keyboard-key">o</span>, um das Seitenmenü zu öffnen und auszublenden. Verwenden Sie zum Navigieren die Registerkarte <span class="keyboard-key">tab</span>.' '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.': 'Verwende die Tastenkombination <span class="keyboard-key">Strg</span>+<span class="keyboard-key">o</span>, um das Seitenmenü ein- und auszublenden. Verwende <span class="keyboard-key">tab</span> zum Navigieren.'
"Top menu": "Hauptmenü" "Top menu": "Hauptmenü"
"Apps that not must be moved in the side menu": "Apps, die nicht im Seitenmenü verschoben werden müssen" "Apps that not must be moved in the side menu": "Apps, die nicht ins Seitenmenü verschoben werden müssen"
"If there is no selection then the global configuration is applied.": "Wenn keine Auswahl vorhanden ist, wird die globale Konfiguration angewendet." "If there is no selection then the global configuration is applied.": "Wenn keine Auswahl vorhanden ist, wird die globale Konfiguration angewendet."
"Experimental": "Experimental" "Experimental": "Experimentell"
"Save": "Sparen" "Save": "Speichern"
"You like this app and you want to support me?": "Du magst diese App und möchtest mich unterstützen?" "You like this app and you want to support me?": "Du magst diese App und möchtest mich unterstützen?"
"Buy me a coffe ☕": "Gib mir einen Kaffee ☕" "Buy me a coffee ☕": "Gib mir einen Kaffee ☕"
"Hidden": "Versteckt" "Hidden": "Versteckt"
"Small": "Klein" "Small": "Klein"
"Normal": "Normal" "Normal": "Normal"
@@ -36,13 +36,13 @@
"After the logo": "Nach dem Logo" "After the logo": "Nach dem Logo"
"Position": "Position" "Position": "Position"
"Show only the opener (hidden logo)": "Nur den Öffner anzeigen (verstecktes Logo)" "Show only the opener (hidden logo)": "Nur den Öffner anzeigen (verstecktes Logo)"
"Do not display the side menu and the opener if there is no application (eg: public pages).": "Zeigen Sie das Seitenmenü und den Öffner nicht an, wenn keine Anwendung vorhanden ist (z. B. öffentliche Seiten)." "Do not display the side menu and the opener if there is no application (eg: public pages).": "Zeige das Seitenmenü und den Öffner nicht an, wenn keine Anwendung vorhanden ist (z.B. bei öffentlichen Seiten)."
"Panel": "Panel" "Panel": "Panel"
"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Öffnen Sie das Menü, wenn Sie die Maus über den Öffner bewegen (auf Touchscreens automatisch deaktiviert)." "Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Öffne das Menü, wenn die Maus über den Öffner bewegt wird (auf Touchscreens automatisch deaktiviert)."
"Display the big menu": "Großes Menü anzeigen" "Display the big menu": "Großes Menü anzeigen"
"The big menu is not compatible with AppOrder.": "Das große Menü ist nicht mit AppOrder kompatibel." "The big menu is not compatible with AppOrder.": "Das große Menü ist nicht mit AppOrder kompatibel."
"Display the logo": "Logo anzeigen" "Display the logo": "Logo anzeigen"
"This feature is not compatible with the <code>big menu</code> display.": "Diese Funktion ist nicht mit der großen Menüanzeige kompatibel." "This feature is not compatible with the <code>big menu</code> display.": "Diese Funktion ist nicht mit <code>großes Menü</code> kompatibel."
"Icons and texts": "Symbole und Texte" "Icons and texts": "Symbole und Texte"
"Loader enabled": "Loader aktiviert" "Loader enabled": "Loader aktiviert"
"Tips": "Tipps" "Tips": "Tipps"
@@ -50,7 +50,10 @@
"The logo will be hidden when the menu is always displayed.": "Das Logo wird ausgeblendet, wenn das Menü immer angezeigt wird." "The logo will be hidden when the menu is always displayed.": "Das Logo wird ausgeblendet, wenn das Menü immer angezeigt wird."
"This is the automatic behavior when the menu is always displayed.": "Dies ist das automatische Verhalten, wenn das Menü immer angezeigt wird." "This is the automatic behavior when the menu is always displayed.": "Dies ist das automatische Verhalten, wenn das Menü immer angezeigt wird."
"Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens." "Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens."
"Big menu": "Große Speisekarte" "Big menu": "Großes Menü"
"Live preview": "Live Vorschau" "Live preview": "Live Vorschau"
"Open apps in new tab": "Öffnen Sie Apps in einem neuen Tab" "Open apps in new tab": "Öffne Apps in einem neuen Tab"
"Use the global setting": "Verwenden Sie die globale Einstellung" "Use the global setting": "Verwende die globale Einstellung"
"Use my selection": "Verwende meine Auswahl"
"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"
+4 -1
View File
@@ -10,7 +10,7 @@
"Experimental": "Expérimental" "Experimental": "Expérimental"
"Save": "Sauvegarder" "Save": "Sauvegarder"
"You like this app and you want to support me?": "Vous aimer cette application et vous souhaitez m'aider ?" "You like this app and you want to support me?": "Vous aimer cette application et vous souhaitez m'aider ?"
"Buy me a coffe ☕": "Offrez moi un café ☕" "Buy me a coffee ☕": "Offrez moi un café ☕"
"Hidden": "Caché" "Hidden": "Caché"
"Small": "Petit" "Small": "Petit"
"Normal": "Normal" "Normal": "Normal"
@@ -54,3 +54,6 @@
"Live preview": "Aperçu en direct" "Live preview": "Aperçu en direct"
"Open apps in new tab": "Ouvrir les applications dans un nouvel onglet" "Open apps in new tab": "Ouvrir les applications dans un nouvel onglet"
"Use the global setting": "Utiliser la configuration globale" "Use the global setting": "Utiliser la configuration globale"
"Use my selection": "Utiliser ma sélection"
"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"
+1 -1
View File
@@ -41,4 +41,4 @@ var alwaysDisplayed = function() {
} }
} }
alwaysDisplayed() window.setTimeout(alwaysDisplayed, 200)
+4
View File
@@ -38,6 +38,10 @@ var updateTopMenu = function() {
appShown.push(app) appShown.push(app)
navigationApps.append(app.outerHTML) navigationApps.append(app.outerHTML)
} }
if (targetBlankApps.indexOf(dataId) !== -1) {
jQuery(app).children('a').attr('target', '_blank');
}
}) })
var rightHeaderWidth = jQuery('.header-right').outerWidth() var rightHeaderWidth = jQuery('.header-right').outerWidth()
+9 -10
View File
@@ -10,13 +10,7 @@
sideMenu.attr('data-bigmenu', '1') sideMenu.attr('data-bigmenu', '1')
<?php endif; ?> <?php endif; ?>
<?php if ($_['force-light-icon']): ?> var targetBlankApps = <?php echo json_encode($_['target-blank-apps']) ?>;
sideMenuContainer.attr('data-forcelighticon', '1')
<?php endif; ?>
<?php if ($_['target-blank']): ?>
sideMenuContainer.attr('data-targetblank', '1')
<?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']): ?>
@@ -67,7 +61,7 @@
} }
} }
<?php if ($_['opener-hover']): ?> <?php if ($_['opener-hover'] || ($_['always-displayed'] && !$_['big-menu'])): ?>
var sideMenuMouseLeave = function() { var sideMenuMouseLeave = function() {
sideMenu sideMenu
.removeClass('open') .removeClass('open')
@@ -87,9 +81,14 @@
} }
if (!isTouchDevice) { if (!isTouchDevice) {
headerMenuOpener.on('mouseenter', sideMenuOpenerMouseEnter) <?php if ($_['opener-hover']): ?>
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; ?> <?php endif; ?>
+44 -10
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')); ?>
@@ -372,16 +384,32 @@ $choicesSizes = [
</label> </label>
</div> </div>
<div> <p>
<select id="side-menu-loader-enabled" name="target-blank" class="side-menu-setting"> <a class="side-menu-toggler" data-target="#target-blank-apps" href="#_">
<?php foreach ($choicesYesNo as $label => $value): ?> 🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['target-blank']): ?>selected<?php endif; ?>> </a>
<?php echo $l->t($label); ?> </p>
</option>
<?php endforeach; ?> <div class="side-menu-setting" data-name="target-blank-apps" id="target-blank-apps" data-checkbox style="display: none">
</select> <?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>
<br>
<div> <div>
<label for="side-menu-loader-enabled"> <label for="side-menu-loader-enabled">
<?php p($l->t('Loader enabled')); ?> <?php p($l->t('Loader enabled')); ?>
@@ -409,7 +437,13 @@ $choicesSizes = [
</label> </label>
</div> </div>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox> <p>
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_">
🖱️ <?php p($l->t('Show and hide the list of applications')); ?>
</a>
</p>
<div class="side-menu-setting" data-name="top-menu-apps" id="top-menu-apps" data-checkbox style="display: none">
<?php foreach ($_['apps'] as $app): ?> <?php foreach ($_['apps'] as $app): ?>
<div> <div>
<input <input
@@ -453,7 +487,7 @@ $choicesSizes = [
<a style="margin-left: 10px" target="_blank" href="https://www.buymeacoffee.com/deblan"> <a style="margin-left: 10px" target="_blank" href="https://www.buymeacoffee.com/deblan">
<button> <button>
<?php p($l->t('Buy me a coffe ☕')); ?> <?php p($l->t('Buy me a coffee ☕')); ?>
</button> </button>
</a> </a>
</span> </span>
+36 -7
View File
@@ -61,19 +61,42 @@ $choicesYesNo = [
<div> <div>
<?php $choices = [ <?php $choices = [
'Use global setting' => '-1', 'Use the global setting' => '1',
'No' => '0', 'Use my selection' => '2',
'Yes' => '1',
]; ?> ]; ?>
<select id="side-menu-loader-enabled" name="target-blank" class="side-menu-setting" data-personal> <select id="side-menu-loader-enabled" name="target-blank-mode" class="side-menu-setting" data-personal>
<?php foreach ($choices as $label => $value): ?> <?php foreach ($choices as $label => $value): ?>
<option value="<?php echo $value ?>" <?php if ($value === $_['target-blank']): ?>selected<?php endif; ?>> <option value="<?php echo $value ?>" <?php if ($value === $_['target-blank-mode']): ?>selected<?php endif; ?>>
<?php echo $l->t($label); ?> <?php echo $l->t($label); ?>
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </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; ?>
</div>
</div> </div>
<div class="section"> <div class="section">
@@ -92,7 +115,13 @@ $choicesYesNo = [
</em> </em>
</p> </p>
<div class="side-menu-setting" data-name="top-menu-apps" data-checkbox data-personal> <p>
<a class="side-menu-toggler" data-target="#top-menu-apps" href="#_">
🖱️ <?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): ?> <?php foreach ($_['apps'] as $app): ?>
<div> <div>
<input <input
@@ -124,7 +153,7 @@ $choicesYesNo = [
<a style="margin-left: 10px" target="_blank" href="https://www.buymeacoffee.com/deblan"> <a style="margin-left: 10px" target="_blank" href="https://www.buymeacoffee.com/deblan">
<button> <button>
<?php p($l->t('Buy me a coffe ☕')); ?> <?php p($l->t('Buy me a coffee ☕')); ?>
</button> </button>
</a> </a>
</span> </span>