"use client"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { FileReadResponse } from "@/lib/shared/contracts/files"; import { queryKeys } from "@/lib/shared/query-keys"; import { createFile, createFolder, fetchDirectory, fetchFileContent, fetchRoot, fetchStarredFiles, getFileInfo, getParentPath, pasteFile, renameFile, searchFilesRequest, saveFileContent, toFilePath, toggleStar, unzipFile, uploadFilesToPath, } from "@/modules/files/hooks/files-api"; export { buildAssetUrl, buildDownloadUrl, buildZipUrl, toFilePath } from "@/modules/files/hooks/files-api"; export type { FilePasteCollision } from "@/modules/files/hooks/files-api"; export function useFilesRoot() { return useQuery({ queryKey: queryKeys.filesRoot, queryFn: fetchRoot, staleTime: 5_000, }); } export function useFilesDirectory( pathSegments: string[], includeHidden = false, options: { enabled?: boolean } = {}, ) { const filePath = toFilePath(pathSegments); return useQuery({ queryKey: queryKeys.filesList(filePath, includeHidden), queryFn: () => fetchDirectory(filePath, includeHidden), staleTime: 3_000, enabled: options.enabled !== false, }); } export function useFileContent(filePath: string | null) { return useQuery({ queryKey: queryKeys.fileContent(filePath ?? ""), queryFn: () => fetchFileContent(filePath ?? ""), enabled: Boolean(filePath), staleTime: 0, }); } export function useSaveFileContent() { const queryClient = useQueryClient(); return useMutation({ mutationFn: saveFileContent, onSuccess: (data, variables) => { void queryClient.invalidateQueries({ queryKey: queryKeys.fileContent(variables.path), }); void queryClient.invalidateQueries({ queryKey: ["files", "list", getParentPath(variables.path)], }); queryClient.setQueryData(queryKeys.fileContent(variables.path), ( prev: { data: FileReadResponse } | FileReadResponse | undefined, ) => { const previous = prev && "data" in prev ? prev.data : (prev as FileReadResponse | undefined); if (!previous || previous.mode !== "text") return previous; return { ...previous, content: variables.content, mtimeMs: data.mtimeMs, modifiedAt: data.modifiedAt, sizeBytes: data.sizeBytes, } satisfies FileReadResponse; }); }, }); } function invalidateFileListPath(queryClient: ReturnType, filePath: string) { void queryClient.invalidateQueries({ queryKey: ["files", "list", filePath], }); } export function useCreateFolder() { const queryClient = useQueryClient(); return useMutation({ mutationFn: createFolder, onSuccess: (_, variables) => { invalidateFileListPath(queryClient, variables.parentPath); }, }); } export function useCreateFile() { const queryClient = useQueryClient(); return useMutation({ mutationFn: createFile, onSuccess: (_, variables) => { invalidateFileListPath(queryClient, variables.parentPath); }, }); } export function usePasteFileEntry() { const queryClient = useQueryClient(); return useMutation({ mutationFn: pasteFile, onSuccess: (_, variables) => { invalidateFileListPath(queryClient, variables.destinationPath); invalidateFileListPath(queryClient, getParentPath(variables.sourcePath)); if (variables.operation === "move") { void queryClient.invalidateQueries({ queryKey: queryKeys.fileContent(variables.sourcePath), }); } }, }); } export function useRenameFileEntry() { const queryClient = useQueryClient(); return useMutation({ mutationFn: renameFile, onSuccess: (data, variables) => { invalidateFileListPath(queryClient, getParentPath(variables.path)); if (getParentPath(variables.path) !== getParentPath(data.path)) { invalidateFileListPath(queryClient, getParentPath(data.path)); } void queryClient.invalidateQueries({ queryKey: queryKeys.fileContent(variables.path), }); void queryClient.invalidateQueries({ queryKey: queryKeys.fileContent(data.path), }); }, }); } export function useFileEntryInfo() { return useMutation({ mutationFn: getFileInfo, }); } export function useToggleFileStar() { const queryClient = useQueryClient(); return useMutation({ mutationFn: toggleStar, onSuccess: (_data, pathValue) => { invalidateFileListPath(queryClient, getParentPath(pathValue)); void queryClient.invalidateQueries({ queryKey: queryKeys.filesStarred }); }, }); } export function useStarredFiles() { return useQuery({ queryKey: queryKeys.filesStarred, queryFn: fetchStarredFiles, staleTime: 5_000, }); } export function useSearchFiles(params: { query: string; basePath?: string; includeHidden?: boolean; enabled?: boolean; }) { return useQuery({ queryKey: queryKeys.filesSearch( params.query, params.basePath ?? "", params.includeHidden ?? false, ), queryFn: () => searchFilesRequest({ query: params.query, basePath: params.basePath, includeHidden: params.includeHidden, }), enabled: Boolean(params.enabled) && params.query.trim().length >= 2, staleTime: 10_000, }); } export function useUploadFiles() { const queryClient = useQueryClient(); return useMutation({ mutationFn: uploadFilesToPath, onSuccess: (_data, variables) => { invalidateFileListPath(queryClient, variables.destinationPath); }, }); } export function useUnzipFile() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (pathValue: string) => unzipFile(pathValue), onSuccess: (data) => { invalidateFileListPath(queryClient, data.destinationPath); }, }); }