20260629154839

This commit is contained in:
oneao committed 2026-06-29 15:48:39 +08:00
1 parent e687846eb4
commit bb596f3245
41 files changed
+5735 -86

No files matched your search

+22 -2
View File
@@ -1,4 +1,5 @@
import { createContext, ReactNode, useCallback, useContext, useEffect, useRef } from "react";
import { usePathname } from "expo-router";
import { toast } from "sonner-native";
import { useUserStore, useFamilyStore } from "@/store";
import { useChatStore } from "@/store/chat";
@@ -24,7 +25,9 @@ const ChatWebSocketContext = createContext<ChatWebSocketValue | null>(null);
function useChatWebSocketConnection(): ChatWebSocketValue {
const token = useUserStore((s) => s.userInfo?.token);
const userId = useUserStore((s) => s.userInfo?.id);
const familyId = useFamilyStore((s) => s.currentFamily?.family_id);
const pathname = usePathname();
const messages = useChatStore((s) => s.messages);
const onlineUsers = useChatStore((s) => s.onlineUsers);
const isConnected = useChatStore((s) => s.isConnected);
@@ -38,6 +41,8 @@ function useChatWebSocketConnection(): ChatWebSocketValue {
const mounted = useRef(true);
const wasConnected = useRef(false);
const shouldReconnect = useRef(false);
const pathnameRef = useRef(pathname);
const userIdRef = useRef(userId);
const buildWsUrl = useCallback(() => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL || "";
@@ -103,10 +108,17 @@ function useChatWebSocketConnection(): ChatWebSocketValue {
const handleMessage = useCallback((msg: any) => {
switch (msg.type) {
case "message": {
const data = msg.data as ChatMessage;
const data = normalizeChatMessage(msg.data as ChatMessage);
if (data.id <= lastReceivedId.current) return;
lastReceivedId.current = data.id;
useChatStore.getState().addMessage(normalizeChatMessage(data));
useChatStore.getState().addMessage(data);
const inChatPage =
pathnameRef.current === "/chat" || pathnameRef.current.startsWith("/chat/");
const fromCurrentUser = String(data.user_id) === String(userIdRef.current);
if (!inChatPage && !fromCurrentUser) {
toast(`${data.nickname || "有人"}发送了一条信息`);
}
break;
}
case "message_recalled": {
@@ -143,6 +155,14 @@ function useChatWebSocketConnection(): ChatWebSocketValue {
wsRef.current.send(JSON.stringify({ type: "delete", message_id: messageId }));
}, []);
useEffect(() => {
pathnameRef.current = pathname;
}, [pathname]);
useEffect(() => {
userIdRef.current = userId;
}, [userId]);
useEffect(() => {
mounted.current = true;
shouldReconnect.current = !!token && !!familyId;
@@ -0,0 +1,35 @@
import { useCallback } from "react";
import { useChatWebSocket } from "@/hooks/useChatWebSocket";
import { ChatMsgType } from "@/types/chat";
interface ModuleOperationNotifyPayload {
module: string;
action: string;
target?: string;
detail?: string;
sourceTable?: string;
sourceId?: number;
}
export function useModuleChatNotifier() {
const chat = useChatWebSocket();
return useCallback(
({ module, action, target, detail, sourceTable, sourceId }: ModuleOperationNotifyPayload) => {
const content = [
`【${module}】${action}`,
target ? `:${target}` : "",
detail ? `(${detail})` : "",
].join("");
chat.send({
type: "send",
msg_type: ChatMsgType.System,
content,
source_table: sourceTable,
source_id: sourceId,
});
},
[chat],
);
}