From 5e913dd9d5a4e2d83344ef8f25dbc78be79dbe42 Mon Sep 17 00:00:00 2001 From: Tilman Date: Wed, 1 Oct 2025 20:56:19 +0200 Subject: [PATCH] Add directory download as zip feature Implements the ability for users to download directories as zip files if enabled in config. Adds a new API route for directory zipping, updates UI components to show a download button for directories, and introduces related config and type changes. Also includes a new download icon. --- bewcloud.config.sample.ts | 1 + components/files/ListFiles.tsx | 25 ++- components/files/MainFiles.tsx | 17 ++ fresh.gen.ts | 2 + islands/files/FilesWrapper.tsx | 3 + lib/config.ts | 7 + lib/types.ts | 2 + routes/api/files/download-directory.tsx | 246 ++++++++++++++++++++++++ routes/file-share/[fileShareId].tsx | 1 + routes/files.tsx | 4 + static/images/download.svg | 13 ++ 11 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 routes/api/files/download-directory.tsx create mode 100644 static/images/download.svg diff --git a/bewcloud.config.sample.ts b/bewcloud.config.sample.ts index 84ffba8..dfbe56b 100644 --- a/bewcloud.config.sample.ts +++ b/bewcloud.config.sample.ts @@ -18,6 +18,7 @@ const config: PartialDeep = { // files: { // rootPath: 'data-files', // allowPublicSharing: false, // If true, public file sharing will be allowed (still requires a user to enable sharing for a given file or directory) + // allowDirectoryDownloads: true, // If true, directories can be downloaded as zip files // }, // core: { // enabledApps: ['news', 'notes', 'photos', 'expenses', 'contacts', 'calendar'], // dashboard and files cannot be disabled diff --git a/components/files/ListFiles.tsx b/components/files/ListFiles.tsx index 371e526..b4077a9 100644 --- a/components/files/ListFiles.tsx +++ b/components/files/ListFiles.tsx @@ -18,6 +18,7 @@ interface ListFilesProps { onClickDeleteFile?: (parentPath: string, name: string) => Promise; onClickCreateShare?: (filePath: string) => void; onClickOpenManageShare?: (fileShareId: string) => void; + onClickDownloadDirectory?: (parentPath: string, name: string) => void; isShowingNotes?: boolean; isShowingPhotos?: boolean; fileShareId?: string; @@ -39,6 +40,7 @@ export default function ListFiles( onClickDeleteFile, onClickCreateShare, onClickOpenManageShare, + onClickDownloadDirectory, isShowingNotes, isShowingPhotos, fileShareId, @@ -165,10 +167,26 @@ export default function ListFiles( typeof onClickOpenMoveDirectory === 'undefined') ? null : ( -
+
+ {typeof onClickDownloadDirectory === 'undefined' ? null : ( + + )}