import { Fragment, useMemo, useState } from "react"; import { UseDiscloseReturn, useDisclose } from "~/hooks/useDisclose"; import { FiChevronRight, FiFilePlus, FiFolderPlus, FiMoreVertical, } from "react-icons/fi"; import { FaCheck, FaThumbtack } from "react-icons/fa"; import trpc from "~/lib/trpc"; import type { FileSchema } from "~/server/db/schema/file"; import CreateFileDialog, { CreateFileSchema } from "./createfile-dialog"; import ActionButton from "../../../../components/ui/action-button"; import { useEditorContext } from "../context/editor"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator, } from "~/components/ui/dropdown-menu"; import { cn, getPreviewUrl, getUrl, copy } from "~/lib/utils"; import FileIcon from "~/components/ui/file-icon"; import { useData } from "~/renderer/hooks"; import Spinner from "~/components/ui/spinner"; import { Data } from "../+data"; import { settingsDialog } from "../stores/dialogs"; const FileListing = () => { const { project, files: initialFiles } = useData(); const { onOpenFile, onFileChanged } = useEditorContext(); const createFileDlg = useDisclose(); const files = trpc.file.getAll.useQuery( { projectId: project.id }, { initialData: initialFiles } ); const fileList = useMemo(() => groupFiles(files.data, null), [files.data]); return (

{project.title}

createFileDlg.onOpen()} /> createFileDlg.onOpen({ isDirectory: true, filename: "" }) } /> {/* Upload File */} {/* */} settingsDialog.setState(true)}> Project Settings {/* Download Project */}
{files.isLoading ? (
) : (
{fileList.map((file) => ( ))}
)} { files.refetch(); if (type === "create" && !file.isDirectory && !file.isFile) { onOpenFile && onOpenFile(file.id); } if (onFileChanged) { onFileChanged(file); } }} />
); }; type TFile = Omit & { children: TFile[] }; type FileItemProps = { file: TFile; createFileDlg: UseDiscloseReturn; }; const FileItem = ({ file, createFileDlg }: FileItemProps) => { const { project } = useData(); const { onOpenFile, onDeleteFile } = useEditorContext(); const [isCollapsed, setCollapsed] = useState(false); const trpcUtils = trpc.useUtils(); const updateFile = trpc.file.update.useMutation({ onSuccess() { trpcUtils.file.getAll.invalidate(); }, }); return (
{file.isDirectory ? ( <> createFileDlg.onOpen({ parentId: file.id, filename: "" }) } /> createFileDlg.onOpen({ parentId: file.id, isDirectory: true, filename: "", }) } /> ) : null} createFileDlg.onOpen(file)}> Rename {/* Duplicate */} onDeleteFile(file.id)}> Delete copy(file.filename)}> Copy Name copy(file.path)}> Copy Path copy(getPreviewUrl(project, file, { raw: true })) } > Copy URL window.open( getPreviewUrl(project, file, { raw: true }), "_blank" ) } > Open in new tab copy(getUrl(project.slug + `?files=${file.path}`)) } > Share { return updateFile.mutate({ projectId: file.projectId, id: file.id, isPinned: !file.isPinned, }); }} > Pinned {file.isPinned ? : null}
{isCollapsed && file.children?.length > 0 ? (
{file.children.map((file) => ( ))}
) : null}
); }; function groupFiles(files?: any[] | null, parentId?: number | null) { if (!files) { return []; } const groupedFiles: TFile[] = []; files.forEach((file) => { if (file.parentId !== parentId) { return; } groupedFiles.push(file); if (file.isDirectory) { file.children = groupFiles(files, file.id); } }); return groupedFiles; } export default FileListing;