diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index fbe33fb54f..dfff7f6f46 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -39,24 +39,29 @@ $templateManager->registerTemplate('application/vnd.oasis.opendocument.presentat $templateManager->registerTemplate('application/vnd.oasis.opendocument.text', 'core/templates/filetemplates/template.odt'); $templateManager->registerTemplate('application/vnd.oasis.opendocument.spreadsheet', 'core/templates/filetemplates/template.ods'); -\OCA\Files\App::getNavigationManager()->add(function () use ($l) { - return [ - 'id' => 'files', - 'appname' => 'files', - 'script' => 'list.php', - 'order' => 0, - 'name' => $l->t('All files'), - ]; -}); +\OCA\Files\App::getNavigationManager()->add([ + 'id' => 'files', + 'appname' => 'files', + 'script' => 'list.php', + 'order' => 0, + 'name' => $l->t('All files') +]); -\OCA\Files\App::getNavigationManager()->add(function () use ($l) { - return [ - 'id' => 'recent', - 'appname' => 'files', - 'script' => 'recentlist.php', - 'order' => 2, - 'name' => $l->t('Recent'), - ]; -}); +\OCA\Files\App::getNavigationManager()->add([ + 'id' => 'recent', + 'appname' => 'files', + 'script' => 'recentlist.php', + 'order' => 2, + 'name' => $l->t('Recent') +]); + +\OCA\Files\App::getNavigationManager()->add([ + 'id' => 'favorites', + 'appname' => 'files', + 'script' => 'simplelist.php', + 'order' => 5, + 'name' => $l->t('Favorites'), + 'expandedState' => 'show_Quick_Access' +]); \OCP\Util::connectHook('\OCP\Config', 'js', '\OCA\Files\App', 'extendJsConfig'); diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php index a9d8ba0a1b..44663d185d 100644 --- a/apps/files/appinfo/routes.php +++ b/apps/files/appinfo/routes.php @@ -77,14 +77,9 @@ $application->registerRoutes( 'verb' => 'GET', ], [ - 'name' => 'API#showQuickAccess', - 'url' => '/api/v1/quickaccess/set/showList', - 'verb' => 'GET', - ], - [ - 'name' => 'API#getShowQuickAccess', - 'url' => '/api/v1/quickaccess/get/showList', - 'verb' => 'GET', + 'name' => 'API#toggleShowFolder', + 'url' => '/api/v1/toggleShowFolder/{key}', + 'verb' => 'POST' ], [ 'name' => 'API#getShowQuickaccessSettings', diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index 24ecbf399e..79dc2a26eb 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -93,7 +93,8 @@ background-image: url('../img/star.svg?v=1'); } .nav-icon-sharingin, -.nav-icon-sharingout { +.nav-icon-sharingout, +.nav-icon-shareoverview { background-image: url('../img/share.svg?v=1'); } .nav-icon-sharinglinks { diff --git a/apps/files/js/navigation.js b/apps/files/js/navigation.js index d4fa06cb45..8ce976a6f5 100644 --- a/apps/files/js/navigation.js +++ b/apps/files/js/navigation.js @@ -172,30 +172,18 @@ */ _onClickMenuButton: function (ev) { var $target = $(ev.target); + var $menu = $target.parent('li'); var itemId = $target.closest('button').attr('id'); var collapsibleToggles = []; var dotmenuToggles = []; - // The collapsibleToggles-Array consists of a list of Arrays. Every subarray must contain the Button to listen to at the 0th index, - // and the parent, which should be toggled at the first arrayindex. - collapsibleToggles.push(["#button-collapse-favorites", "#button-collapse-parent-favorites"]); - - // The dotmenuToggles-Array consists of a list of Arrays. Every subarray must contain the Button to listen to at the 0th index, - // and the parent, which should be toggled at the first arrayindex. - dotmenuToggles.push(["#dotmenu-button-favorites", "dotmenu-content-favorites"]); - - collapsibleToggles.forEach(function foundToggle (item) { - if (item[0] === ("#" + itemId)) { - $(item[1]).toggleClass('open'); - var show = 1; - if (!$(item[1]).hasClass('open')) { - show = 0; - } - $.get(OC.generateUrl("/apps/files/api/v1/quickaccess/set/showList"), {show: show}, function (data, status) { - }); - } - }); + if ($menu.hasClass('collapsible') && $menu.data('expandedstate')) { + $menu.toggleClass('open'); + var show = $menu.hasClass('open') ? 1 : 0; + var key = $menu.data('expandedstate'); + $.post(OC.generateUrl("/apps/files/api/v1/toggleShowFolder/" + key), {show: show}); + } dotmenuToggles.forEach(function foundToggle (item) { if (item[0] === ("#" + itemId)) { diff --git a/apps/files/js/tagsplugin.js b/apps/files/js/tagsplugin.js index bc1396b510..4ce6604384 100644 --- a/apps/files/js/tagsplugin.js +++ b/apps/files/js/tagsplugin.js @@ -68,29 +68,22 @@ * @param {String} appfolder folder to be removed */ function removeFavoriteFromList (appfolder) { - var quickAccessList = 'sublist-favorites'; - var collapsibleButtonId = 'button-collapse-favorites'; var listULElements = document.getElementById(quickAccessList); if (!listULElements) { return; } - var listLIElements = listULElements.getElementsByTagName('li'); var apppath=appfolder; if(appfolder.startsWith("//")){ apppath=appfolder.substring(1, appfolder.length); } - for (var i = 0; i <= listLIElements.length - 1; i++) { - if (listLIElements[i].getElementsByTagName('a')[0].href.endsWith("dir=" + apppath)) { - listLIElements[i].remove(); - } - } + $(listULElements).find('[data-dir="' + apppath + '"]').remove(); if (listULElements.childElementCount === 0) { - var collapsibleButton = document.getElementById("button-collapse-favorites"); - collapsibleButton.style.display = 'none'; + var collapsibleButton = $(listULElements).parent().find('button.collapse'); + collapsibleButton.hide(); $("#button-collapse-parent-favorites").removeClass('collapsible'); } } @@ -102,7 +95,6 @@ */ function addFavoriteToList (appfolder) { var quickAccessList = 'sublist-favorites'; - var collapsibleButtonId = 'button-collapse-favorites'; var listULElements = document.getElementById(quickAccessList); if (!listULElements) { return; @@ -110,13 +102,13 @@ var listLIElements = listULElements.getElementsByTagName('li'); var appName = appfolder.substring(appfolder.lastIndexOf("/") + 1, appfolder.length); - var apppath=appfolder; + var apppath = appfolder; if(appfolder.startsWith("//")){ - apppath=appfolder.substring(1, appfolder.length); + apppath = appfolder.substring(1, appfolder.length); } - var url=OC.generateUrl('/apps/files/?dir=')+apppath; - + var url = OC.generateUrl('/apps/files/?dir=' + apppath + '&view=files'); + var innerTagA = document.createElement('A'); innerTagA.setAttribute("href", url); @@ -125,7 +117,9 @@ var length = listLIElements.length + 1; var innerTagLI = document.createElement('li'); - innerTagLI.setAttribute("data-id", url); + innerTagLI.setAttribute("data-id", apppath.replace('/', '-')); + innerTagLI.setAttribute("data-dir", apppath); + innerTagLI.setAttribute("data-view", 'files'); innerTagLI.setAttribute("class", "nav-" + appName); innerTagLI.setAttribute("folderpos", length.toString()); innerTagLI.appendChild(innerTagA); @@ -134,10 +128,9 @@ if (data === "dir") { if (listULElements.childElementCount <= 0) { listULElements.appendChild(innerTagLI); - var collapsibleButton = document.getElementById(collapsibleButtonId); - collapsibleButton.style.display = ''; - - $("#button-collapse-parent-favorites").addClass('collapsible'); + var collapsibleButton = $(listULElements).parent().find('button.collapse'); + collapsibleButton.show(); + $(listULElements).parent().addClass('collapsible'); } else { listLIElements[listLIElements.length - 1].after(innerTagLI); } diff --git a/apps/files/lib/Controller/ApiController.php b/apps/files/lib/Controller/ApiController.php index aae1bec2e7..fd63d54515 100644 --- a/apps/files/lib/Controller/ApiController.php +++ b/apps/files/lib/Controller/ApiController.php @@ -291,29 +291,28 @@ class ApiController extends Controller { } /** - * Toggle default for showing/hiding QuickAccess folder + * Toggle default for showing/hiding xxx folder * * @NoAdminRequired * - * @param bool $show + * @param bool $show + * @param bool $key the key of the folder * * @return Response */ - public function showQuickAccess($show) { - $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'show_Quick_Access', (int)$show); - return new Response(); - } - - /** - * Toggle default for showing/hiding QuickAccess folder - * - * @NoAdminRequired - * - * @return String - */ - public function getShowQuickAccess() { - - return $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_Quick_Access', 0); + public function toggleShowFolder(int $show, string $key) { + // ensure the edited key exists + $navItems = \OCA\Files\App::getNavigationManager()->getAll(); + foreach ($navItems as $item) { + // check if data is valid + if (($show === 0 || $show === 1) && isset($item['expandedState']) && $key === $item['expandedState']) { + $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', $key, (int)$show); + return new Response(); + } + } + $response = new Response(); + $response->setStatus(Http::STATUS_FORBIDDEN); + return $response; } /** diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php index f240e04c72..0a13af3233 100644 --- a/apps/files/lib/Controller/ViewController.php +++ b/apps/files/lib/Controller/ViewController.php @@ -33,6 +33,8 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\App\IAppManager; +use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\IConfig; @@ -41,8 +43,6 @@ use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUserSession; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use OCP\Files\Folder; -use OCP\App\IAppManager; use Symfony\Component\EventDispatcher\GenericEvent; /** @@ -73,27 +73,27 @@ class ViewController extends Controller { protected $activityHelper; public function __construct(string $appName, - IRequest $request, - IURLGenerator $urlGenerator, - IL10N $l10n, - IConfig $config, - EventDispatcherInterface $eventDispatcherInterface, - IUserSession $userSession, - IAppManager $appManager, - IRootFolder $rootFolder, - Helper $activityHelper + IRequest $request, + IURLGenerator $urlGenerator, + IL10N $l10n, + IConfig $config, + EventDispatcherInterface $eventDispatcherInterface, + IUserSession $userSession, + IAppManager $appManager, + IRootFolder $rootFolder, + Helper $activityHelper ) { parent::__construct($appName, $request); - $this->appName = $appName; - $this->request = $request; - $this->urlGenerator = $urlGenerator; - $this->l10n = $l10n; - $this->config = $config; + $this->appName = $appName; + $this->request = $request; + $this->urlGenerator = $urlGenerator; + $this->l10n = $l10n; + $this->config = $config; $this->eventDispatcher = $eventDispatcherInterface; - $this->userSession = $userSession; - $this->appManager = $appManager; - $this->rootFolder = $rootFolder; - $this->activityHelper = $activityHelper; + $this->userSession = $userSession; + $this->appManager = $appManager; + $this->rootFolder = $rootFolder; + $this->activityHelper = $activityHelper; } /** @@ -102,8 +102,8 @@ class ViewController extends Controller { * @return string */ protected function renderScript($appName, $scriptName) { - $content = ''; - $appPath = \OC_App::getAppPath($appName); + $content = ''; + $appPath = \OC_App::getAppPath($appName); $scriptPath = $appPath . '/' . $scriptName; if (file_exists($scriptPath)) { // TODO: sanitize path / script name ? @@ -112,6 +112,7 @@ class ViewController extends Controller { $content = ob_get_contents(); @ob_end_clean(); } + return $content; } @@ -123,6 +124,7 @@ class ViewController extends Controller { */ protected function getStorageInfo() { $dirInfo = \OC\Files\Filesystem::getFileInfo('/', false); + return \OC_Helper::getStorageInfo('/', $dirInfo); } @@ -156,6 +158,7 @@ class ViewController extends Controller { $user = $this->userSession->getUser()->getUID(); + // Get all the user favorites to create a submenu try { $favElements = $this->activityHelper->getFavoriteFilePaths($this->userSession->getUser()->getUID()); } catch (\RuntimeException $e) { @@ -170,21 +173,21 @@ class ViewController extends Controller { $favoritesSublistArray = Array(); $navBarPositionPosition = 6; - $currentCount = 0; + $currentCount = 0; foreach ($favElements['folders'] as $dir) { - $id = substr($dir, strrpos($dir, '/') + 1, strlen($dir)); - $link = $this->urlGenerator->linkToRoute('files.view.index', ['dir' => $dir, 'view' => 'files']); + $id = substr($dir, strrpos($dir, '/') + 1, strlen($dir)); + $link = $this->urlGenerator->linkToRoute('files.view.index', ['dir' => $dir, 'view' => 'files']); $sortingValue = ++$currentCount; - $element = [ - 'id' => str_replace('/', '-', $dir), - 'view' => 'files', - 'href' => $link, - 'dir' => $dir, - 'order' => $navBarPositionPosition, - 'folderPosition' => $sortingValue, - 'name' => $id, - 'icon' => 'files', + $element = [ + 'id' => str_replace('/', '-', $dir), + 'view' => 'files', + 'href' => $link, + 'dir' => $dir, + 'order' => $navBarPositionPosition, + 'folderPosition' => $sortingValue, + 'name' => $id, + 'icon' => 'files', 'quickaccesselement' => 'true' ]; @@ -192,28 +195,18 @@ class ViewController extends Controller { $navBarPositionPosition++; } - - // show_Quick_Access stored as string - $defaultExpandedState = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_Quick_Access', '0') === '1'; - - \OCA\Files\App::getNavigationManager()->add( - [ - 'id' => 'favorites', - 'appname' => 'files', - 'script' => 'simplelist.php', - 'classes' => $collapseClasses, - 'order' => 5, - 'name' => $this->l10n->t('Favorites'), - 'sublist' => $favoritesSublistArray, - 'defaultExpandedState' => $defaultExpandedState, - 'enableMenuButton' => 0, - ] - ); - $navItems = \OCA\Files\App::getNavigationManager()->getAll(); - usort($navItems, function ($item1, $item2) { - return $item1['order'] - $item2['order']; - }); + + // add the favorites entry in menu + $navItems['favorites']['sublist'] = $favoritesSublistArray; + $navItems['favorites']['classes'] = $collapseClasses; + + // parse every menu and add the expandedState user value + foreach ($navItems as $key => $item) { + if (isset($item['expandedState'])) { + $navItems[$key]['defaultExpandedState'] = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', $item['expandedState'], '0') === '1'; + } + } $nav->assign('navigationItems', $navItems); @@ -235,29 +228,42 @@ class ViewController extends Controller { if (isset($item['script'])) { $content = $this->renderScript($item['appname'], $item['script']); } - $contentItem = []; - $contentItem['id'] = $item['id']; - $contentItem['content'] = $content; - $contentItems[] = $contentItem; + // parse submenus + if (isset($item['sublist'])) { + foreach ($item['sublist'] as $subitem) { + $subcontent = ''; + if (isset($subitem['script'])) { + $subcontent = $this->renderScript($subitem['appname'], $subitem['script']); + } + $contentItems[$subitem['id']] = [ + 'id' => $subitem['id'], + 'content' => $subcontent + ]; + } + } + $contentItems[$item['id']] = [ + 'id' => $item['id'], + 'content' => $content + ]; } $event = new GenericEvent(null, ['hiddenFields' => []]); $this->eventDispatcher->dispatch('OCA\Files::loadAdditionalScripts', $event); - $params = []; - $params['usedSpacePercent'] = (int)$storageInfo['relative']; - $params['owner'] = $storageInfo['owner']; - $params['ownerDisplayName'] = $storageInfo['ownerDisplayName']; - $params['isPublic'] = false; - $params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'); - $params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name'); + $params = []; + $params['usedSpacePercent'] = (int) $storageInfo['relative']; + $params['owner'] = $storageInfo['owner']; + $params['ownerDisplayName'] = $storageInfo['ownerDisplayName']; + $params['isPublic'] = false; + $params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'); + $params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name'); $params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc'); - $showHidden = (bool)$this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', false); - $params['showHiddenFiles'] = $showHidden ? 1 : 0; - $params['fileNotFound'] = $fileNotFound ? 1 : 0; - $params['appNavigation'] = $nav; - $params['appContents'] = $contentItems; - $params['hiddenFields'] = $event->getArgument('hiddenFields'); + $showHidden = (bool) $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', false); + $params['showHiddenFiles'] = $showHidden ? 1 : 0; + $params['fileNotFound'] = $fileNotFound ? 1 : 0; + $params['appNavigation'] = $nav; + $params['appContents'] = $contentItems; + $params['hiddenFields'] = $event->getArgument('hiddenFields'); $response = new TemplateResponse( $this->appName, @@ -268,7 +274,6 @@ class ViewController extends Controller { $policy->addAllowedFrameDomain('\'self\''); $response->setContentSecurityPolicy($policy); - return $response; } @@ -280,14 +285,14 @@ class ViewController extends Controller { * @throws \OCP\Files\NotFoundException */ private function showFile($fileId) { - $uid = $this->userSession->getUser()->getUID(); + $uid = $this->userSession->getUser()->getUID(); $baseFolder = $this->rootFolder->getUserFolder($uid); - $files = $baseFolder->getById($fileId); - $params = []; + $files = $baseFolder->getById($fileId); + $params = []; if (empty($files) && $this->appManager->isEnabledForUser('files_trashbin')) { - $baseFolder = $this->rootFolder->get($uid . '/files_trashbin/files/'); - $files = $baseFolder->getById($fileId); + $baseFolder = $this->rootFolder->get($uid . '/files_trashbin/files/'); + $files = $baseFolder->getById($fileId); $params['view'] = 'trashbin'; } @@ -302,6 +307,7 @@ class ViewController extends Controller { // and scroll to the entry $params['scrollto'] = $file->getName(); } + return new RedirectResponse($this->urlGenerator->linkToRoute('files.view.index', $params)); } throw new \OCP\Files\NotFoundException(); diff --git a/apps/files/templates/appnavigation.php b/apps/files/templates/appnavigation.php index 0b9ac66590..04bcc57700 100644 --- a/apps/files/templates/appnavigation.php +++ b/apps/files/templates/appnavigation.php @@ -66,21 +66,26 @@ function NavigationListElements($item, $l, $pinned) { strpos($item['classes'], 'pinned') !== false ? $pinned++ : ''; ?> -
  • id="button-collapse-parent-" - data-id="" data-dir="" data-view="" - class="nav- open" +
  • data-dir="" + data-view="" + data-expandedstate="" + class="nav- + + + open" folderposition="" > + class="nav-icon- svg"> - +