diff --git a/app/components/header/HeaderActionButtons.client.tsx b/app/components/header/HeaderActionButtons.client.tsx index 6f8e843..302f7e7 100644 --- a/app/components/header/HeaderActionButtons.client.tsx +++ b/app/components/header/HeaderActionButtons.client.tsx @@ -1,18 +1,59 @@ -import { useStore } from '@nanostores/react'; +import JSZip from 'jszip'; import { chatStore } from '~/lib/stores/chat'; import { workbenchStore } from '~/lib/stores/workbench'; import { classNames } from '~/utils/classNames'; +import { useStore } from '@nanostores/react'; +import type { FileMap } from '~/lib/stores/files'; +import { saveAs } from 'file-saver'; interface HeaderActionButtonsProps {} export function HeaderActionButtons({}: HeaderActionButtonsProps) { const showWorkbench = useStore(workbenchStore.showWorkbench); const { showChat } = useStore(chatStore); + const files = useStore(workbenchStore.files) as FileMap; const canHideChat = showWorkbench || !showChat; + const downloadZip = async () => { + const zip = new JSZip(); + + for (const [filePath, dirent] of Object.entries(files)) { + if (dirent?.type === 'file' && !dirent.isBinary) { + // remove '/home/project/' from the beginning of the path + const relativePath = filePath.replace(/^\/home\/project\//, ''); + + // split the path into segments + const pathSegments = relativePath.split('/'); + + // if there's more than one segment, we need to create folders + if (pathSegments.length > 1) { + let currentFolder = zip; + + for (let i = 0; i < pathSegments.length - 1; i++) { + currentFolder = currentFolder.folder(pathSegments[i])!; + } + currentFolder.file(pathSegments[pathSegments.length - 1], dirent.content); + } else { + // if there's only one segment, it's a file in the root + zip.file(relativePath, dirent.content); + } + } + } + + const content = await zip.generateAsync({ type: 'blob' }); + saveAs(content, 'project.zip'); + }; + return ( -
+
+