ospfcost/src/utilities/runtime-helpers.js
Gert-Jan Aalderink 607add2a7b Initial Entry
2025-07-09 21:33:13 +02:00

123 lines
3.8 KiB
JavaScript

import React from 'react';
function useHandleStreamResponse({
onChunk,
onFinish
}) {
const handleStreamResponse = React.useCallback(
async (response) => {
if (response.body) {
const reader = response.body.getReader();
if (reader) {
const decoder = new TextDecoder();
let content = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
onFinish(content);
break;
}
const chunk = decoder.decode(value, { stream: true });
content += chunk;
onChunk(content);
}
}
}
},
[onChunk, onFinish]
);
const handleStreamResponseRef = React.useRef(handleStreamResponse);
React.useEffect(() => {
handleStreamResponseRef.current = handleStreamResponse;
}, [handleStreamResponse]);
return React.useCallback((response) => handleStreamResponseRef.current(response), []);
}
function useUpload() {
const [loading, setLoading] = React.useState(false);
const upload = React.useCallback(async (input) => {
try {
setLoading(true);
let response;
if ('reactNativeAsset' in input && input.reactNativeAsset) {
if (input.reactNativeAsset.file) {
const formData = new FormData();
formData.append("file", input.reactNativeAsset.file);
response = await fetch("/_create/api/upload/", {
method: "POST",
body: formData
});
} else {
const response = await fetch("/_create/api/upload/presign/", {
method: 'POST',
})
const { secureSignature, secureExpire } = await response.json();
const result = await client.uploadFile(input.reactNativeAsset, {
fileName: input.reactNativeAsset.name ?? input.reactNativeAsset.uri.split("/").pop(),
contentType: input.reactNativeAsset.mimeType,
secureSignature,
secureExpire
});
return { url: `${process.env.EXPO_PUBLIC_BASE_CREATE_USER_CONTENT_URL}/${result.uuid}/`, mimeType: result.mimeType || null };
}
} else if ("file" in input && input.file) {
const formData = new FormData();
formData.append("file", input.file);
response = await fetch("/_create/api/upload/", {
method: "POST",
body: formData
});
} else if ("url" in input) {
response = await fetch("/_create/api/upload/", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ url: input.url })
});
} else if ("base64" in input) {
response = await fetch("/_create/api/upload/", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ base64: input.base64 })
});
} else {
response = await fetch("/_create/api/upload/", {
method: "POST",
headers: {
"Content-Type": "application/octet-stream"
},
body: input.buffer
});
}
if (!response.ok) {
if (response.status === 413) {
throw new Error("Upload failed: File too large.");
}
throw new Error("Upload failed");
}
const data = await response.json();
return { url: data.url, mimeType: data.mimeType || null };
} catch (uploadError) {
if (uploadError instanceof Error) {
return { error: uploadError.message };
}
if (typeof uploadError === "string") {
return { error: uploadError };
}
return { error: "Upload failed" };
} finally {
setLoading(false);
}
}, []);
return [upload, { loading }];
}
export {
useHandleStreamResponse,
useUpload,
}