diff --git a/appinfo/routes.php b/appinfo/routes.php index e1c88f9a..6e4a55e6 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -1,5 +1,7 @@ 'Page#tags', 'url' => '/tags/{name}', 'verb' => 'GET'], 'name'), // Public folder share - ['name' => 'Public#showShare', 'url' => '/s/{token}', 'verb' => 'GET'], [ 'name' => 'Public#showAuthenticate', 'url' => '/s/{token}/authenticate/{redirect}', @@ -45,6 +46,7 @@ return [ 'url' => '/s/{token}/authenticate/{redirect}', 'verb' => 'POST', ], + w(['name' => 'Public#showShare', 'url' => '/s/{token}/{path}', 'verb' => 'GET'], 'path'), // Public album share ['name' => 'PublicAlbum#showShare', 'url' => '/a/{token}', 'verb' => 'GET'], diff --git a/lib/Controller/FoldersController.php b/lib/Controller/FoldersController.php index 1b943b85..716cc413 100644 --- a/lib/Controller/FoldersController.php +++ b/lib/Controller/FoldersController.php @@ -15,6 +15,8 @@ class FoldersController extends GenericApiController { /** * @NoAdminRequired + * + * @PublicPage */ public function sub(string $folder): Http\Response { @@ -24,14 +26,22 @@ class FoldersController extends GenericApiController throw Exceptions::BadRequest('Invalid parameter folder'); } + // Get the root folder (share root or user root) + $root = $this->fs->getShareNode() ?? Util::getUserFolder(); + if (!$root instanceof Folder) { + throw Exceptions::BadRequest('Root is not a folder'); + } + + // Get the inner folder try { - $node = Util::getUserFolder()->get($folder); + $node = $root->get($folder); } catch (\OCP\Files\NotFoundException) { throw Exceptions::NotFound("Folder not found: {$folder}"); } + // Make sure we have a folder if (!$node instanceof Folder) { - throw Exceptions::NotFound('Path is not a folder'); + throw Exceptions::BadRequest('Path is not a folder'); } // Ugly: get the view of the folder with reflection @@ -65,7 +75,6 @@ class FoldersController extends GenericApiController return [ 'fileid' => $node->getId(), 'name' => $node->getName(), - 'path' => $node->getPath(), 'previews' => $this->tq->getRootPreviews($root), ]; }, $folders); diff --git a/lib/Db/FsManager.php b/lib/Db/FsManager.php index 808d6590..91865397 100644 --- a/lib/Db/FsManager.php +++ b/lib/Db/FsManager.php @@ -84,7 +84,16 @@ class FsManager throw new \Exception('Share is not a folder'); } - $root->addFolder($share); + if ($path = $this->getRequestFolder()) { + try { + $node = $share->get(Util::sanitizePath($path)); + } catch (\OCP\Files\NotFoundException $e) { + throw new \Exception("Folder not found: {$e->getMessage()}"); + } + $root->addFolder($node); + } else { + $root->addFolder($share); + } return $root; } diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index 739b39a1..0828122c 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -580,7 +580,7 @@ export default defineComponent({ } // Folder - if (this.routeIsFolders) { + if (this.routeIsFolders || this.routeIsFolderShare) { const path = utils.getFolderRoutePath(this.config.folders_path); set(DaysFilterType.FOLDER, path); if (this.$route.query.recursive) { diff --git a/src/components/frame/Folder.vue b/src/components/frame/Folder.vue index e93463c5..a7d4b834 100644 --- a/src/components/frame/Folder.vue +++ b/src/components/frame/Folder.vue @@ -58,18 +58,17 @@ export default defineComponent({ computed: { /** Open folder */ target() { - const path = this.data.path - .split('/') - .filter((x) => x) - .slice(2) as string[]; - - // Remove base path if present - const basePath = this.config.folders_path.split('/').filter((x) => x); - if (path.length >= basePath.length && path.slice(0, basePath.length).every((x, i) => x === basePath[i])) { - path.splice(0, basePath.length); + let currentPath: string[] | string = this.$route.params.path || []; + if (typeof currentPath === 'string') { + currentPath = currentPath.split('/'); } - return { name: 'folders', params: { path } }; + return { + name: this.$route.name, + params: { + path: [...currentPath, this.data.name], + }, + }; }, }, @@ -89,12 +88,6 @@ export default defineComponent({ // Reset state this.error = false; - // Check if valid path present - if (!this.data.path) { - this.error = true; - return; - } - // Get preview infos const previews = this.data.previews; if (previews) { diff --git a/src/components/top-matter/DynamicTopMatter.vue b/src/components/top-matter/DynamicTopMatter.vue index bdd9428f..2a2a90e2 100644 --- a/src/components/top-matter/DynamicTopMatter.vue +++ b/src/components/top-matter/DynamicTopMatter.vue @@ -35,7 +35,7 @@ export default defineComponent({ }, currentmatter(): Component | null { - if (this.routeIsFolders) { + if (this.routeIsFolders || this.routeIsFolderShare) { return FolderDynamicTopMatter; } else if (this.routeIsPlaces) { return PlacesDynamicTopMatterVue; @@ -53,8 +53,8 @@ export default defineComponent({ return this.$route.params.name || ''; } - // Show share name for public shares - if (this.routeIsPublic) { + // Show share name for public shares, except for folder share, because the name is already present in the breadcrumbs + if (this.routeIsPublic && !this.routeIsFolderShare) { return PublicShareHeader.title; } diff --git a/src/components/top-matter/FolderTopMatter.vue b/src/components/top-matter/FolderTopMatter.vue index 70920cd3..d1895a40 100644 --- a/src/components/top-matter/FolderTopMatter.vue +++ b/src/components/top-matter/FolderTopMatter.vue @@ -1,16 +1,17 @@