From 1b544b6a2f8acddc3ddbdc6ebde3c5caa883b6db Mon Sep 17 00:00:00 2001 From: Kenneth Date: Tue, 16 Dec 2025 01:45:36 +0000 Subject: [PATCH] fix: invalidte dir content when moving dir items --- apps/drive-web/src/files/use-file-drop.ts | 15 ++++-- apps/drive-web/src/vfs/api.ts | 58 +++++++++++++++++++++++ apps/drive-web/src/vfs/vfs.ts | 2 + 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/apps/drive-web/src/files/use-file-drop.ts b/apps/drive-web/src/files/use-file-drop.ts index d018643..0ffb08b 100644 --- a/apps/drive-web/src/files/use-file-drop.ts +++ b/apps/drive-web/src/files/use-file-drop.ts @@ -38,16 +38,21 @@ export function useFileDrop({ const setDragInfo = useSetAtom(dragInfoAtom) const store = useStore() + const moveDirectoryItemsMutation = useAtomValue( + moveDirectoryItemsMutationAtom, + ) + const { mutate: moveDroppedItems } = useMutation({ - ...useAtomValue(moveDirectoryItemsMutationAtom), - onSuccess: (result: MoveDirectoryItemsResult) => { - const conflictCount = result.conflicts.length + ...moveDirectoryItemsMutation, + onSuccess: (data: MoveDirectoryItemsResult, vars, result, ctx) => { + moveDirectoryItemsMutation.onSuccess?.(data, vars, result, ctx) + const conflictCount = data.errors.length if (conflictCount > 0) { toast.warning( - `${result.moved.length} items moved${conflictCount > 0 ? `, ${conflictCount} conflicts` : ""}`, + `${data.moved.length} items moved${conflictCount > 0 ? `, ${conflictCount} conflicts` : ""}`, ) } else { - toast.success(`${result.moved.length} items moved!`) + toast.success(`${data.moved.length} items moved!`) } }, }) diff --git a/apps/drive-web/src/vfs/api.ts b/apps/drive-web/src/vfs/api.ts index 67ae674..4d4bdd9 100644 --- a/apps/drive-web/src/vfs/api.ts +++ b/apps/drive-web/src/vfs/api.ts @@ -156,6 +156,64 @@ export const moveDirectoryItemsMutationAtom = atom((get) => ) return result }, + onMutate: ({ items }, { client }) => { + const movedItems = new Map>() + + for (const item of items) { + if (item.parentId) { + const s = movedItems.get(item.parentId) + if (!s) { + movedItems.set(item.parentId, new Set()) + } else { + s.add(item.id) + } + } + } + + const prevDirContentMap = new Map< + string, + DirectoryItem[] | undefined + >() + + movedItems.forEach((s, parentId) => { + const query = get(directoryContentQueryAtom(parentId)) + const prevDirContent = client.getQueryData(query.queryKey) + client.setQueryData( + query.queryKey, + (prev) => prev?.filter((it) => !s.has(it.id)) ?? prev, + ) + prevDirContentMap.set(parentId, prevDirContent) + }) + + return { prevDirContentMap } + }, + onSuccess: (_data, { targetDirectory, items }, _result, { client }) => { + const dirId = + typeof targetDirectory === "string" + ? targetDirectory + : targetDirectory.id + console.log(dirId) + client.invalidateQueries(get(directoryContentQueryAtom(dirId))) + for (const item of items) { + if (item.parentId) { + client.invalidateQueries( + get(directoryContentQueryAtom(item.parentId)), + ) + } + } + }, + onError: (_error, _vars, context, { client }) => { + if (context) { + context.prevDirContentMap.forEach( + (prevDirContent, parentId) => { + client.setQueryData( + get(directoryContentQueryAtom(parentId)).queryKey, + prevDirContent, + ) + }, + ) + } + }, }), ) diff --git a/apps/drive-web/src/vfs/vfs.ts b/apps/drive-web/src/vfs/vfs.ts index 778139d..31873a1 100644 --- a/apps/drive-web/src/vfs/vfs.ts +++ b/apps/drive-web/src/vfs/vfs.ts @@ -4,6 +4,7 @@ import { Path } from "@/lib/path" export const FileInfo = type({ kind: "'file'", id: "string", + "parentId?": "string", name: "string", size: "number", mimeType: "string", @@ -16,6 +17,7 @@ export type FileInfo = typeof FileInfo.infer export const DirectoryInfo = type({ kind: "'directory'", id: "string", + "parentId?": "string", name: "string", createdAt: "string.date.iso.parse", updatedAt: "string.date.iso.parse",