Validate upload size against the node limit before uploading

Expose the node's upload_size on the client server resource and reject
files over it in the file manager before any bytes are sent.
This commit is contained in:
dualfroz committed 2026-10-14 18:16:57 +02:00
1 parent 56e5db2059
commit 2e78dfef1e
12 files changed
+144 -2

No files matched your search

@@ -1,16 +1,19 @@
import { useCallback, useEffect, useRef } from 'react';
import { toast } from 'sonner';
import { useCurrentServerUuid } from '@/api/server/queries';
import { useCurrentServer, useCurrentServerUuid, type Server } from '@/api/server/queries';
import { useUploadFiles } from '@/api/server/files/queries';
import { useFileUploadActions, useServerDirectory } from '@/state/server';
const UPLOADED_DISPLAY_MS = 500;
const selectUploadSize = (server: Server) => server.attributes.upload_size;
/** Uploads into the current directory; rejects when any file failed, after its error toast. */
export default function useFileUploader(): (files: readonly File[]) => Promise<void> {
const removals = useRef(new Map<string, ReturnType<typeof setTimeout>>());
const { mutateAsync } = useUploadFiles();
const uuid = useCurrentServerUuid()!;
const uploadSize = useCurrentServer(selectUploadSize)!;
const directory = useServerDirectory();
const { removeFileUpload, pushFileUpload, setUploadProgress } = useFileUploadActions();
@@ -34,6 +37,18 @@ export default function useFileUploader(): (files: readonly File[]) => Promise<v
throw new Error('Folder uploads are not supported.');
}
const oversized = files.filter((file) => file.size > uploadSize * 1024 * 1024);
if (oversized.length > 0) {
const message =
oversized.length === 1
? `${oversized[0].name} is larger than the ${uploadSize} MiB upload limit.`
: `${oversized.length} files are larger than the ${uploadSize} MiB upload limit.`;
toast.error(message);
throw new Error(message);
}
const { failed } = await mutateAsync({
uuid,
directory,
@@ -68,6 +83,6 @@ export default function useFileUploader(): (files: readonly File[]) => Promise<v
);
}
},
[mutateAsync, uuid, directory, removeFileUpload, pushFileUpload, setUploadProgress]
[mutateAsync, uuid, uploadSize, directory, removeFileUpload, pushFileUpload, setUploadProgress]
);
}