Files
juwan-frontend/store/chat.ts
T
zetaloop 12284290cc refactor(store): adapt Zustand stores to backend-aligned types
- orders: remove name fields from creation, keep dispatchMode logic
- chat: remove readonly/senderName/senderAvatar references
- reviews: remove fromUserAvatar/toUserId, simplify participant check
- disputes: remove initiatorId/initiatorName from creation
- posts: remove authorRole/quotedPostId, keep linkedOrderId as number
- comments: remove postId from creation
- wallet: use string amounts
2026-04-23 21:15:11 +08:00

105 lines
2.7 KiB
TypeScript

import { generateId } from "@/lib/id"
import type { ChatMessage, ChatSession, Order } from "@/lib/types"
import { create } from "zustand"
interface ChatState {
sessions: ChatSession[]
messages: ChatMessage[]
ensureOrderSession: (order: Order) => ChatSession
sendTextMessage: (sessionId: string, actorId: string, content: string) => void
sendImageMessage: (sessionId: string, actorId: string, imageUrl: string) => void
}
function resolveAvatar(_userId: string) {
return ""
}
export const useChatStore = create<ChatState>((set, get) => ({
sessions: [],
messages: [],
ensureOrderSession: (order) => {
const existing = get().sessions.find(
(session) => session.type === "order" && session.orderId === order.id,
)
if (existing) {
return existing
}
const session: ChatSession = {
id: `chat-${order.id}`,
type: "order",
orderId: order.id,
participants: [
{
id: order.consumerId,
nickname: "",
avatar: resolveAvatar(order.consumerId),
},
{
id: order.playerId,
nickname: "",
avatar: resolveAvatar(order.playerId),
},
],
unreadCount: 0,
}
set((state) => ({
sessions: [session, ...state.sessions],
}))
return session
},
sendTextMessage: (sessionId, actorId, content) => {
const text = content.trim()
if (!text) return
const session = get().sessions.find((item) => item.id === sessionId)
if (!session) return
const sender = session.participants.find((participant) => participant.id === actorId)
if (!sender) return
const now = new Date().toISOString()
const message: ChatMessage = {
id: generateId("msg"),
sessionId,
senderId: actorId,
type: "text",
content: text,
createdAt: now,
}
set((state) => ({
messages: [...state.messages, message],
sessions: state.sessions.map((s) => (s.id === sessionId ? { ...s, lastMessage: text } : s)),
}))
},
sendImageMessage: (sessionId, actorId, imageUrl) => {
const content = imageUrl.trim()
if (!content) return
const session = get().sessions.find((item) => item.id === sessionId)
if (!session) return
const sender = session.participants.find((participant) => participant.id === actorId)
if (!sender) return
const now = new Date().toISOString()
const message: ChatMessage = {
id: generateId("msg"),
sessionId,
senderId: actorId,
type: "image",
content,
createdAt: now,
}
set((state) => ({
messages: [...state.messages, message],
sessions: state.sessions.map((item) =>
item.id === sessionId ? { ...item, lastMessage: "[图片]" } : item,
),
}))
},
}))