UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

111 lines 4.54 kB
"use strict"; 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