@replyke/core
Version:
Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.
111 lines • 4.54 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const useAxiosPrivate_1 = __importDefault(require("../../config/useAxiosPrivate"));
const useProject_1 = __importDefault(require("../projects/useProject"));
// Type guard to detect browser File vs React Native file object
function isBrowserFile(file) {
return typeof File !== "undefined" && file instanceof File;
}
function useUploadImage() {
const axios = (0, useAxiosPrivate_1.default)();
const { projectId } = (0, useProject_1.default)();
const [uploading, setUploading] = (0, react_1.useState)(false);
const [progress, setProgress] = (0, react_1.useState)(0);
const uploadImage = (0, react_1.useCallback)(async (file, options) => {
// Validate required inputs
if (!projectId) {
throw new Error("No projectId available.");
}
if (!file) {
throw new Error("No file provided.");
}
setUploading(true);
setProgress(0);
try {
const formData = new FormData();
// Append file (handle both browser and React Native)
if (isBrowserFile(file)) {
formData.append("file", file, file.name);
}
else {
formData.append("file", {
uri: file.uri,
type: file.type || "image/jpeg",
name: file.name,
});
}
// Append mode (required)
formData.append("mode", options.mode);
// Append mode-specific fields
if (options.mode === "exact-dimensions") {
formData.append("dimensions", JSON.stringify(options.dimensions));
}
else if (options.mode === "aspect-ratio-width-based") {
formData.append("aspectRatio", JSON.stringify(options.aspectRatio));
formData.append("widths", JSON.stringify(options.widths));
}
else if (options.mode === "aspect-ratio-height-based") {
formData.append("aspectRatio", JSON.stringify(options.aspectRatio));
formData.append("heights", JSON.stringify(options.heights));
}
else if (options.mode === "original-aspect") {
formData.append("sizes", JSON.stringify(options.sizes));
}
// Append common optional fields
if (options.pathParts) {
formData.append("pathParts", JSON.stringify(options.pathParts));
}
if (options.quality !== undefined) {
formData.append("quality", options.quality.toString());
}
if (options.format) {
formData.append("format", options.format);
}
if (options.stripExif !== undefined) {
formData.append("stripExif", options.stripExif.toString());
}
if (options.fit) {
formData.append("fit", options.fit);
}
// Append optional associations
if (options.entityId) {
formData.append("entityId", options.entityId);
}
if (options.commentId) {
formData.append("commentId", options.commentId);
}
if (options.spaceId) {
formData.append("spaceId", options.spaceId);
}
// Make request with progress tracking
const response = await axios.post(`/${projectId}/storage/images`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
setProgress(percentCompleted);
options.onProgress?.(percentCompleted);
}
},
});
return response.data;
}
finally {
setUploading(false);
setProgress(0);
}
}, [projectId, axios]);
return {
uploadImage,
uploading,
progress,
};
}
exports.default = useUploadImage;
//# sourceMappingURL=useUploadImage.js.map