2025-12-11 11:31:56 +00:00
|
|
|
'use client';
|
|
|
|
|
import { Channel, StreamChat } from 'stream-chat';
|
|
|
|
|
import { create } from 'zustand';
|
|
|
|
|
|
|
|
|
|
interface StreamChatStore {
|
|
|
|
|
connect: (user: any) => Promise<void>;
|
|
|
|
|
channels: Channel[];
|
|
|
|
|
currentChannel: Channel | null;
|
|
|
|
|
switchToChannel: (id: string) => Promise<void>;
|
|
|
|
|
queryChannels: (filter: any) => Promise<void>;
|
|
|
|
|
deleteChannel: (id: string) => Promise<void>;
|
|
|
|
|
clearChannels: () => Promise<void>;
|
|
|
|
|
clearNotifications: () => Promise<void>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let client: StreamChat | null = null;
|
|
|
|
|
export const useStreamChatStore = create<StreamChatStore>((set, get) => ({
|
|
|
|
|
channels: [],
|
|
|
|
|
currentChannel: null,
|
|
|
|
|
async connect(user) {
|
2025-12-15 11:31:18 +00:00
|
|
|
if (client) return;
|
|
|
|
|
console.log('connecting stream chat', user);
|
2025-12-11 11:31:56 +00:00
|
|
|
const { data } = await getUserToken(user);
|
|
|
|
|
client = new StreamChat(process.env.NEXT_PUBLIC_STREAM_CHAT_API_KEY || '');
|
|
|
|
|
await client.connectUser(
|
|
|
|
|
{
|
|
|
|
|
id: user.userId,
|
|
|
|
|
name: user.userName,
|
|
|
|
|
},
|
|
|
|
|
data
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
async switchToChannel(id: string) {
|
|
|
|
|
const { channels } = get();
|
|
|
|
|
const channel = channels.find((ch) => ch.id === id);
|
|
|
|
|
if (channel) {
|
|
|
|
|
set({ currentChannel: channel });
|
|
|
|
|
// 可选:监听该频道的消息
|
|
|
|
|
await channel.watch();
|
|
|
|
|
} else {
|
|
|
|
|
console.warn(`Channel with id ${id} not found in channels list`);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async queryChannels(filter: any) {
|
|
|
|
|
if (!client) {
|
|
|
|
|
console.error('StreamChat client is not connected');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
const channels = await client.queryChannels(filter, {
|
|
|
|
|
last_message_at: -1,
|
|
|
|
|
});
|
|
|
|
|
set({ channels });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to query channels:', error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async deleteChannel(id: string) {
|
|
|
|
|
const { channels, currentChannel, queryChannels } = get();
|
|
|
|
|
const channel = channels.find((ch) => ch.id === id);
|
|
|
|
|
if (!channel) {
|
|
|
|
|
console.warn(`Channel with id ${id} not found`);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
await channel.delete();
|
|
|
|
|
await queryChannels({});
|
|
|
|
|
set({ currentChannel: null });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`Failed to delete channel ${id}:`, error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async clearChannels() {
|
|
|
|
|
const { channels } = get();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 停止监听所有频道
|
|
|
|
|
for (const channel of channels) {
|
|
|
|
|
try {
|
|
|
|
|
await channel.stopWatching();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.warn(`Failed to stop watching channel ${channel.id}:`, error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 清空频道列表和当前频道
|
|
|
|
|
set({
|
|
|
|
|
channels: [],
|
|
|
|
|
currentChannel: null,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Failed to clear channels:', error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async clearNotifications() {},
|
|
|
|
|
}));
|