This commit is contained in:
payacom
2026-07-16 21:31:59 +03:30
parent 58314d0ab5
commit 17f334d0f1
14 changed files with 467 additions and 192 deletions

View File

@@ -9,6 +9,13 @@ function matchesPendingServer(server: ChatMessage, pending: ChatMessage): boolea
return Boolean(pending.fileType && server.fileType === pending.fileType);
}
export function findPendingMatchForServer(
server: ChatMessage,
pending: ChatMessage[]
): ChatMessage | undefined {
return pending.find((p) => matchesPendingServer(server, p));
}
export function filterResolvedPendingMessages(
server: ChatMessage[],
pending: ChatMessage[]

View File

@@ -0,0 +1,53 @@
import { io, Socket } from "socket.io-client";
import { SOCKET_URL } from "@/components/main/BaseUrl";
let sharedSocket: Socket | null = null;
let refCount = 0;
export function acquireChatSocket(): Socket {
if (!sharedSocket) {
sharedSocket = io(SOCKET_URL, {
transports: ["websocket", "polling"],
reconnection: true,
reconnectionAttempts: Infinity,
reconnectionDelay: 800,
reconnectionDelayMax: 5000,
timeout: 20000,
withCredentials: true,
autoConnect: true,
});
}
refCount += 1;
return sharedSocket;
}
/** Use after acquire — does not change ref count */
export function getChatSocket(): Socket | null {
return sharedSocket;
}
export function releaseChatSocket(): void {
refCount = Math.max(0, refCount - 1);
if (refCount === 0 && sharedSocket) {
sharedSocket.removeAllListeners();
sharedSocket.disconnect();
sharedSocket = null;
}
}
export function joinUserRoom(userId: string): void {
const id = String(userId).trim();
if (!id || !sharedSocket) return;
sharedSocket.emit("joinUser", { userId: id });
}
export function joinChatRoom(userId: string, receiverId: string): void {
const uid = String(userId).trim();
const rid = String(receiverId).trim();
if (!uid || !rid || !sharedSocket) return;
sharedSocket.emit("joinChat", { userId: uid, receiverId: rid });
}
export function isChatSocketConnected(): boolean {
return Boolean(sharedSocket?.connected);
}

View File

@@ -34,3 +34,33 @@ export function appendMessageToThreadCache(
return { ...oldData, pages: newPages };
}
/** Add or update — avoids duplicate / flicker when optimistic + socket + HTTP overlap */
export function upsertMessageInThreadCache(
oldData: ChatThreadData | undefined,
message: ChatMessage
): ChatThreadData {
if (!oldData?.pages?.length) {
return appendMessageToThreadCache(oldData, message);
}
const messageId = String(message._id);
let found = false;
const newPages = oldData.pages.map((page) => ({
...page,
messages: page.messages.map((m) => {
if (String(m._id) === messageId) {
found = true;
return { ...m, ...message };
}
return m;
}),
}));
if (found) {
return { ...oldData, pages: newPages };
}
return appendMessageToThreadCache(oldData, message);
}