chat
This commit is contained in:
@@ -269,76 +269,83 @@ function TicketChat({ params }: ITicketChatProps) {
|
||||
const isFileUpload = fileForUpload && fileType !== "location";
|
||||
|
||||
try {
|
||||
let response: ChatMessage | { data: ChatMessage };
|
||||
if (!socketRef.current) {
|
||||
throw new Error("Socket not connected");
|
||||
}
|
||||
|
||||
let messagePayload: Record<string, unknown> = {
|
||||
content: textContent,
|
||||
receiverId: targetReceiverId,
|
||||
senderId: currentUserId,
|
||||
tempId: tempId,
|
||||
};
|
||||
|
||||
if (replySource?._id && !replySource._id.startsWith("temp")) {
|
||||
messagePayload.replyToId = replySource._id;
|
||||
}
|
||||
if (selfDestructSeconds) {
|
||||
messagePayload.selfDestructSeconds = selfDestructSeconds;
|
||||
}
|
||||
if (fileType) {
|
||||
messagePayload.fileType = fileType;
|
||||
}
|
||||
if (applyViewOnce) {
|
||||
messagePayload.viewOnce = true;
|
||||
}
|
||||
|
||||
if (isFileUpload) {
|
||||
const formData = new FormData();
|
||||
formData.append("content", textContent);
|
||||
formData.append("receiverId", targetReceiverId);
|
||||
formData.append("senderId", currentUserId);
|
||||
if (replySource?._id && !replySource._id.startsWith("temp")) {
|
||||
formData.append("replyToId", replySource._id);
|
||||
for (const key in messagePayload) {
|
||||
formData.append(key, String(messagePayload[key]));
|
||||
}
|
||||
formData.append("file", fileForUpload);
|
||||
if (fileType) formData.append("fileType", fileType);
|
||||
if (selfDestructSeconds) {
|
||||
formData.append("selfDestructSeconds", String(selfDestructSeconds));
|
||||
}
|
||||
if (applyViewOnce) {
|
||||
formData.append("viewOnce", "true");
|
||||
}
|
||||
|
||||
response = await request<ChatMessage | { data: ChatMessage }>(
|
||||
// ارسال فایل از طریق HTTP (معمولاً فایلها از طریق HTTP ارسال میشوند و اطلاعات از طریق Socket.IO)
|
||||
const response = await request<ChatMessage | { data: ChatMessage }>(
|
||||
"post",
|
||||
"/chat/file",
|
||||
formData
|
||||
);
|
||||
const serverMsg = normalizeMessage(response as ChatMessage);
|
||||
socketRef.current.emit("sendMessage", { ...serverMsg, tempId });
|
||||
} else {
|
||||
const payload: Record<string, unknown> = {
|
||||
content: textContent,
|
||||
receiverId: targetReceiverId,
|
||||
senderId: currentUserId,
|
||||
};
|
||||
if (replySource?._id && !replySource._id.startsWith("temp")) {
|
||||
payload.replyToId = replySource._id;
|
||||
}
|
||||
if (selfDestructSeconds) {
|
||||
payload.selfDestructSeconds = selfDestructSeconds;
|
||||
}
|
||||
|
||||
response = await request<ChatMessage | { data: ChatMessage }>(
|
||||
"post",
|
||||
"/chat",
|
||||
payload
|
||||
);
|
||||
socketRef.current.emit("sendMessage", messagePayload);
|
||||
}
|
||||
|
||||
const serverMsg = normalizeMessage(response as ChatMessage);
|
||||
const sentMsg: ChatMessage = {
|
||||
...serverMsg,
|
||||
status: "sent",
|
||||
replyTo: serverMsg.replyTo ?? replyPayload,
|
||||
};
|
||||
// اپتیمیستیک آپدیت (این بخش باید توسط رویداد Socket.IO سرور تایید شود)
|
||||
// const serverMsg = normalizeMessage(response as ChatMessage);
|
||||
// const sentMsg: ChatMessage = {
|
||||
// ...serverMsg,
|
||||
// status: "sent",
|
||||
// replyTo: serverMsg.replyTo ?? replyPayload,
|
||||
// };
|
||||
|
||||
if (currentUserId && targetReceiverId) {
|
||||
linkIds(tempId, sentMsg._id);
|
||||
queryClient.setQueryData(
|
||||
chatThreadQueryKey(currentUserId, targetReceiverId),
|
||||
(oldData) => appendMessageToThreadCache(oldData, sentMsg)
|
||||
);
|
||||
}
|
||||
// if (currentUserId && targetReceiverId) {
|
||||
// linkIds(tempId, sentMsg._id);
|
||||
// queryClient.setQueryData(
|
||||
// chatThreadQueryKey(currentUserId, targetReceiverId),
|
||||
// (oldData) => appendMessageToThreadCache(oldData, sentMsg)
|
||||
// );
|
||||
// }
|
||||
|
||||
setPendingMessages((prev) => prev.filter((m) => m._id !== tempId));
|
||||
// setPendingMessages((prev) => prev.filter((m) => m._id !== tempId));
|
||||
|
||||
setReplyingTo(null);
|
||||
activeReplyRef.current = null;
|
||||
setSelfDestructSeconds(null);
|
||||
if (applyViewOnce) setViewOnceMedia(false);
|
||||
// این موارد پس از دریافت تاییدیه از Socket.IO باید انجام شوند
|
||||
// setReplyingTo(null);
|
||||
// activeReplyRef.current = null;
|
||||
// setSelfDestructSeconds(null);
|
||||
// if (applyViewOnce) setViewOnceMedia(false);
|
||||
} catch (error) {
|
||||
console.error("Error sending message:", error);
|
||||
setPendingMessages((prev) => prev.filter((m) => m._id !== tempId));
|
||||
toast.error("ارسال پیام ناموفق بود.");
|
||||
}
|
||||
|
||||
// پاک کردن وضعیت پیام پس از ارسال
|
||||
setReplyingTo(null);
|
||||
activeReplyRef.current = null;
|
||||
setSelfDestructSeconds(null);
|
||||
if (applyViewOnce) setViewOnceMedia(false);
|
||||
};
|
||||
|
||||
const handleExpirePending = useCallback((ids: string[]) => {
|
||||
|
||||
@@ -38,10 +38,10 @@ export default function ExploreAuthor({
|
||||
<ProfileAvatar
|
||||
src={avatarSrc}
|
||||
alt={userName || displayName}
|
||||
size="xxs"
|
||||
size="xs"
|
||||
rounded="full"
|
||||
/>
|
||||
<span className="truncate text-[10px] font-medium text-neutral-600 dark:text-neutral-300">
|
||||
<span className="truncate text-xs font-medium text-neutral-600 dark:text-neutral-300">
|
||||
{userName ? `@${userName}` : displayName}
|
||||
</span>
|
||||
</>
|
||||
|
||||
@@ -220,17 +220,23 @@ export default function ExploreGrid({
|
||||
? fetchAcademyExplore(page, 15, token)
|
||||
: Promise.resolve({ items: [], hasNextPage: false });
|
||||
|
||||
const [postsResult, academyResult] = await Promise.all([
|
||||
const [postsResult, academyResult] = await Promise.allSettled([
|
||||
postsPromise,
|
||||
academyPromise,
|
||||
]);
|
||||
|
||||
const resolvedPosts = postsResult.status === "fulfilled" ? postsResult.value.posts ?? [] : [];
|
||||
const resolvedPostsHasMore = postsResult.status === "fulfilled" ? (postsResult.value.posts?.length ?? 0) > 0 : false;
|
||||
|
||||
const resolvedAcademyItems = academyResult.status === "fulfilled" ? academyResult.value.items : [];
|
||||
const resolvedAcademyHasMore = academyResult.status === "fulfilled" ? academyResult.value.hasNextPage : false;
|
||||
|
||||
return {
|
||||
page,
|
||||
posts: postsResult.posts ?? [],
|
||||
postsHasMore: (postsResult.posts?.length ?? 0) > 0,
|
||||
academyItems: academyResult.items,
|
||||
academyHasMore: academyResult.hasNextPage,
|
||||
posts: resolvedPosts,
|
||||
postsHasMore: resolvedPostsHasMore,
|
||||
academyItems: resolvedAcademyItems,
|
||||
academyHasMore: resolvedAcademyHasMore,
|
||||
};
|
||||
},
|
||||
getNextPageParam: (lastPage, allPages) => {
|
||||
|
||||
Reference in New Issue
Block a user