UNPKG

@replyke/core

Version:

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

103 lines 4.91 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 hooks_1 = require("../../../store/hooks"); const chatSlice_1 = require("../../../store/slices/chatSlice"); const userSlice_1 = require("../../../store/slices/userSlice"); const authSlice_1 = require("../../../store/slices/authSlice"); const useAxiosPrivate_1 = __importDefault(require("../../../config/useAxiosPrivate")); const useProject_1 = __importDefault(require("../../projects/useProject")); const handleError_1 = require("../../../utils/handleError"); function useSendMessage({ conversationId, }) { const dispatch = (0, hooks_1.useReplykeDispatch)(); const { projectId } = (0, useProject_1.default)(); const axios = (0, useAxiosPrivate_1.default)(); // Get current user for the optimistic message const user = (0, hooks_1.useReplykeSelector)(userSlice_1.selectUser); const authUser = (0, hooks_1.useReplykeSelector)(authSlice_1.selectUser); const currentUser = user || authUser; const send = (0, react_1.useCallback)(async ({ content, gif, mentions, metadata, quotedMessageId, parentMessageId, files, }) => { if (!projectId) throw new Error("No projectId available."); if (!conversationId) throw new Error("No conversationId provided."); const localId = crypto.randomUUID(); const now = new Date(); // Insert optimistic message immediately const optimisticMsg = { id: `temp-${localId}`, localId, projectId, conversationId, userId: currentUser?.id ?? null, content: content ?? null, gif: gif ?? null, mentions: mentions ?? [], metadata: metadata ?? {}, parentMessageId: parentMessageId ?? null, quotedMessageId: quotedMessageId ?? null, threadReplyCount: 0, reactionCounts: {}, userReactions: [], editedAt: null, userDeletedAt: null, moderationStatus: null, moderatedAt: null, moderatedById: null, moderatedByType: null, moderationReason: null, createdAt: now, updatedAt: now, user: currentUser ?? null, }; dispatch((0, chatSlice_1.addOptimisticMessage)(optimisticMsg)); try { let response; if (files && files.length > 0) { // Multipart upload when files are attached const formData = new FormData(); formData.append("localId", localId); if (content) formData.append("content", content); if (gif) formData.append("gif", JSON.stringify(gif)); if (mentions && mentions.length > 0) formData.append("mentions", JSON.stringify(mentions)); if (metadata && Object.keys(metadata).length > 0) formData.append("metadata", JSON.stringify(metadata)); if (quotedMessageId) formData.append("quotedMessageId", quotedMessageId); if (parentMessageId) formData.append("parentMessageId", parentMessageId); files.forEach((file) => formData.append("files", file)); response = await axios.post(`/${projectId}/chat/conversations/${conversationId}/messages`, formData, { headers: { "Content-Type": "multipart/form-data" } }); } else { // JSON body for text/gif-only messages response = await axios.post(`/${projectId}/chat/conversations/${conversationId}/messages`, { localId, ...(content !== undefined && { content }), ...(gif !== undefined && { gif }), ...(mentions !== undefined && { mentions }), ...(metadata !== undefined && { metadata }), ...(quotedMessageId !== undefined && { quotedMessageId }), ...(parentMessageId !== undefined && { parentMessageId }), }); } const confirmedMsg = response.data; dispatch((0, chatSlice_1.upsertMessage)(confirmedMsg)); return confirmedMsg; } catch (err) { dispatch((0, chatSlice_1.failOptimisticMessage)({ conversationId, localId })); (0, handleError_1.handleError)(err, "Failed to send message"); throw err; } }, [projectId, conversationId, currentUser, axios, dispatch]); return send; } exports.default = useSendMessage; //# sourceMappingURL=useSendMessage.js.map