diff --git a/appinfo/routes.php b/appinfo/routes.php index dc82109..be3ae60 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -21,6 +21,7 @@ return [ 'routes' => [ ['name' => 'Css#stylesheet', 'url' => '/css/stylesheet', 'verb' => 'GET'], ['name' => 'Js#script', 'url' => '/js/script', 'verb' => 'GET'], + ['name' => 'Nav#items', 'url' => '/nav/items', 'verb' => 'GET'], ['name' => 'PersonalSetting#valueSet', 'url' => '/personalSetting/valueSet', 'verb' => 'POST'], ], ]; diff --git a/lib/Controller/CssController.php b/lib/Controller/CssController.php index b950115..6210dc0 100644 --- a/lib/Controller/CssController.php +++ b/lib/Controller/CssController.php @@ -70,6 +70,7 @@ class CssController extends Controller 'external-sites-in-top-menu' => (bool) $this->config->getAppValue('side_menu', 'external-sites-in-top-menu', 0), 'size-icon' => $this->config->getAppValue('side_menu', 'size-icon', 'normal'), 'size-text' => $this->config->getAppValue('side_menu', 'size-text', 'normal'), + 'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'), ]; $response = new TemplateResponse('side_menu', 'css/stylesheet', $parameters, 'blank'); diff --git a/lib/Controller/JsController.php b/lib/Controller/JsController.php index 49eee72..918e481 100644 --- a/lib/Controller/JsController.php +++ b/lib/Controller/JsController.php @@ -60,6 +60,7 @@ class JsController extends Controller 'force-light-icon' => (bool) $this->config->getAppValue('side_menu', 'force-light-icon', '0'), 'hide-when-no-apps' => (bool) $this->config->getAppValue('side_menu', 'hide-when-no-apps', '0'), 'loader-enabled' => (bool) $this->config->getAppValue('side_menu', 'loader-enabled', '1'), + 'big-menu' => (bool) $this->config->getAppValue('side_menu', 'big-menu', '0'), ]; $response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank'); diff --git a/lib/Controller/NavController.php b/lib/Controller/NavController.php new file mode 100644 index 0000000..ba8da4b --- /dev/null +++ b/lib/Controller/NavController.php @@ -0,0 +1,139 @@ +. + */ + +namespace OCA\SideMenu\Controller; + +use OCA\SideMenu\Service\AppRepository; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IRequest; +use OC\App\AppStore\Fetcher\CategoryFetcher; +use OCP\L10N\IFactory; + +class NavController extends Controller +{ + /** + * @var \OCP\IConfig + */ + protected $config; + + /** + * @var AppRepository + */ + protected $appRepository; + + /** + * @var IL10N + */ + protected $trans; + + /** + * @var IFactory + */ + protected $l10nFactory; + + /** + * @var CategoryFetcher + */ + protected $categoryFetcher; + + /** + * @param string $appName + */ + public function __construct( + $appName, + IRequest $request, + IConfig $config, + AppRepository $appRepository, + CategoryFetcher $categoryFetcher, + IFactory $l10nFactory, + IL10N $trans) + { + parent::__construct($appName, $request); + + $this->config = $config; + $this->appRepository = $appRepository; + $this->categoryFetcher = $categoryFetcher; + $this->l10nFactory = $l10nFactory; + $this->trans = $trans; + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @PublicPage + * + * @return JSONResponse + */ + public function items() + { + $apps = $this->appRepository->getVisibleApps(); + $currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2); + $categoriesLabels = $this->categoryFetcher->get(); + $items = []; + + foreach ($categoriesLabels as $k => $category) { + $categoriesLabels[$category['id']] = $category['translations'][$currentLanguage]['name'] ?? $category['translations']['en']['name']; + + unset($categoriesLabels[$k]); + } + + foreach ($apps as $app) { + $categories = $app['category']; + + foreach ($categories as $category) { + if (!isset($items[$category])) { + $items[$category] = [ + 'name' => $categoriesLabels[$category], + 'apps' => [], + ]; + } + + $items[$category]['apps'][$app['id']] = [ + 'name' => $app['name'], + 'href' => '#', + 'icon' => $app['previewAsIcon'] ? $app['preview'] : null, + ]; + } + } + + $items['other'] = [ + 'label' => $this->trans->t('Other'), + 'apps' => [], + ]; + + // foreach ($items as $category => $value) { + // if ($category !== 'other') { + // if (count($value['apps']) < 0) { + // $items['other']['apps'] = array_merge( + // $items['other']['apps'], + // $value['apps'] + // ); + // + // unset($items[$category]); + // } + // } + // } + + return new JSONResponse([ + 'items' => $items, + ]); + } +} diff --git a/lib/Controller/PersonalSettingController.php b/lib/Controller/PersonalSettingController.php index 2beba19..4ff135f 100644 --- a/lib/Controller/PersonalSettingController.php +++ b/lib/Controller/PersonalSettingController.php @@ -61,10 +61,16 @@ class PersonalSettingController extends Controller if (!in_array($value, ['0', '1'])) { $value = '1'; } + } elseif ($name === 'big-menu') { + $doSave = true; + + if (!in_array($value, ['0', '1'])) { + $value = '0'; + } } if ($doSave) { - $this->config->setUserValue($user->getUid(), 'side_menu', 'enabled', $value); + $this->config->setUserValue($user->getUid(), 'side_menu', $name, $value); } return []; diff --git a/lib/Service/AppRepository.php b/lib/Service/AppRepository.php new file mode 100644 index 0000000..bb202e3 --- /dev/null +++ b/lib/Service/AppRepository.php @@ -0,0 +1,48 @@ + + */ +class AppRepository +{ + /** + * @var OC_App + */ + protected $ocApp; + + /** + * @param OC_App $ocApp + */ + public function __construct(OC_App $ocApp) + { + $this->ocApp = $ocApp; + } + + /** + * Retrieves visibles apps. + * + * @return array + */ + public function getVisibleApps() + { + $navigation = $this->ocApp->getNavigation(); + $apps = $this->ocApp->listAllApps(); + $visibleApps = []; + + foreach ($apps as $app) { + $id = $app['id']; + + if (isset($navigation[$id])) { + $visibleApps[$id] = $app; + } + } + + return $visibleApps; + } +} diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index f368bfa..94a3c6c 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -66,6 +66,7 @@ class Admin implements ISettings 'force-light-icon' => $this->config->getAppValue('side_menu', 'force-light-icon', '0'), 'cache' => $this->config->getAppValue('side_menu', 'cache', '0'), 'opener' => $this->config->getAppValue('side_menu', 'opener', 'side-menu-opener'), + 'big-menu' => $this->config->getAppValue('side_menu', 'big-menu', '0'), 'display-logo' => $this->config->getAppValue('side_menu', 'display-logo', '1'), 'opener-position' => $this->config->getAppValue('side_menu', 'opener-position', 'before'), 'opener-hover' => $this->config->getAppValue('side_menu', 'opener-hover', '0'), diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index beef491..115647d 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -64,6 +64,7 @@ class Personal implements ISettings $parameters = [ 'enabled' => $this->config->getUserValue($user->getUid(), 'side_menu', 'enabled', '1'), + 'big-menu' => $this->config->getUserValue($user->getUid(), 'side_menu', 'big-menu', '0'), ]; return new TemplateResponse('side_menu', 'settings/personal-form', $parameters, ''); diff --git a/package.json b/package.json index 3837c1b..38edace 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "@nextcloud/axios": "^1.3.2", "@nextcloud/vue": "^1.4.0", + "axios": "^0.19.2", "trim": "0.0.1", "vue": "^2.6.11" }, diff --git a/src/SideMenu.js b/src/SideMenu.js index dd7d323..05d5e17 100644 --- a/src/SideMenu.js +++ b/src/SideMenu.js @@ -17,18 +17,28 @@ import Vue from 'vue' import SideMenu from './SideMenu.vue' +import SideMenuBig from './SideMenuBig.vue' // Vue.prototype.t = t -// Vue.prototype.OC = OC +Vue.prototype.OC = OC // Vue.prototype.OC = OCP -const View = Vue.extend(SideMenu) -const sideMenu = new View({}) const mountSideMenuComponent = () => { const sideMenuContainer = document.querySelector('#side-menu') if (sideMenuContainer) { + let component + + if (sideMenuContainer.getAttribute('data-bigmenu')) { + component = SideMenuBig + } else { + component = SideMenu + } + + const View = Vue.extend(component) + const sideMenu = new View({}) + sideMenu.$mount('#side-menu') $('body').trigger('side-menu.ready') diff --git a/src/SideMenuBig.vue b/src/SideMenuBig.vue new file mode 100644 index 0000000..c5023c7 --- /dev/null +++ b/src/SideMenuBig.vue @@ -0,0 +1,68 @@ + + + + diff --git a/templates/js/script.php b/templates/js/script.php index acc730d..a5297a5 100644 --- a/templates/js/script.php +++ b/templates/js/script.php @@ -5,6 +5,10 @@ var body = $('body') var isTouchDevice = window.matchMedia("(pointer: coarse)").matches + + sideMenu.attr('data-bigmenu', '1') + + sideMenuContainer.attr('data-forcelighticon', '1') diff --git a/templates/settings/admin-form.php b/templates/settings/admin-form.php index a5dc23a..84702be 100644 --- a/templates/settings/admin-form.php +++ b/templates/settings/admin-form.php @@ -217,6 +217,9 @@ $choicesSizes = [ +

Use the shortcut Ctrl+o + to open and to hide the side menu. Use tab to navigate.

+
-

Use the shortcut Ctrl+o - to open and to hide the side menu. Use tab to navigate.

+
+ +
+ +

The big menu is not compatible with AppOrder.

+ +
+ +
diff --git a/templates/settings/personal-form.php b/templates/settings/personal-form.php index 9f7cffe..b430cb8 100644 --- a/templates/settings/personal-form.php +++ b/templates/settings/personal-form.php @@ -49,6 +49,24 @@ $choicesYesNo = [ +
+ +
+ +
+ +
+ +

The big menu is not compatible with AppOrder.

+

Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.