feat(ui): useUploadJar uses XHR and exposes onProgress

This commit is contained in:
hsiegeln
2026-04-23 15:44:50 +02:00
parent 13f218d522
commit a208f2eec7

View File

@@ -140,21 +140,47 @@ export function useAppVersions(envSlug: string | undefined, appSlug: string | un
export function useUploadJar() {
const qc = useQueryClient();
return useMutation({
mutationFn: async ({ envSlug, appSlug, file }: { envSlug: string; appSlug: string; file: File }) => {
mutationFn: ({ envSlug, appSlug, file, onProgress }: {
envSlug: string;
appSlug: string;
file: File;
onProgress?: (pct: number) => void;
}) => {
const token = useAuthStore.getState().accessToken;
const form = new FormData();
form.append('file', file);
const res = await fetch(
`${config.apiBaseUrl}${envBase(envSlug)}/${encodeURIComponent(appSlug)}/versions`, {
method: 'POST',
headers: {
...(token ? { Authorization: `Bearer ${token}` } : {}),
'X-Cameleer-Protocol-Version': '1',
},
body: form,
return new Promise<AppVersion>((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(
'POST',
`${config.apiBaseUrl}${envBase(envSlug)}/${encodeURIComponent(appSlug)}/versions`,
);
if (token) xhr.setRequestHeader('Authorization', `Bearer ${token}`);
xhr.setRequestHeader('X-Cameleer-Protocol-Version', '1');
xhr.upload.onprogress = (e) => {
if (!onProgress || !e.lengthComputable) return;
onProgress(Math.round((e.loaded / e.total) * 100));
};
xhr.onload = () => {
if (xhr.status < 200 || xhr.status >= 300) {
reject(new Error(`Upload failed: ${xhr.status}`));
return;
}
try {
resolve(JSON.parse(xhr.responseText) as AppVersion);
} catch (err) {
reject(err instanceof Error ? err : new Error('Invalid response'));
}
};
xhr.onerror = () => reject(new Error('Upload network error'));
xhr.onabort = () => reject(new Error('Upload aborted'));
xhr.send(form);
});
if (!res.ok) throw new Error(`Upload failed: ${res.status}`);
return res.json() as Promise<AppVersion>;
},
onSuccess: (_data, { envSlug, appSlug }) =>
qc.invalidateQueries({ queryKey: ['apps', envSlug, appSlug, 'versions'] }),