2025-11-13 08:38:25 +00:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { createContext, useEffect, useState } from "react";
|
|
|
|
|
import { useCurrentUser } from "@/hooks/auth";
|
|
|
|
|
import { NimLoginProvider } from "./NimLoginContext";
|
|
|
|
|
import { useGetIMAccount, useIMAccount } from "@/hooks/useIm";
|
|
|
|
|
import { ConversationProvider } from "./ConversationContext";
|
|
|
|
|
import { NimMsgProvider } from "./NimMsgContext";
|
|
|
|
|
import { NimUserProvider } from "./NimUserContext";
|
|
|
|
|
|
2025-11-24 03:47:20 +00:00
|
|
|
// 动态导入类型
|
|
|
|
|
type V2NIM = any;
|
|
|
|
|
type V2NIMLoginStatus = any;
|
|
|
|
|
|
|
|
|
|
// 延迟加载的 NIM 实例
|
|
|
|
|
let nimInstance: V2NIM | null = null;
|
|
|
|
|
|
|
|
|
|
// 初始化 NIM 实例(仅在客户端)
|
|
|
|
|
const getNimInstance = () => {
|
|
|
|
|
if (typeof window === 'undefined') {
|
|
|
|
|
return null;
|
2025-11-13 08:38:25 +00:00
|
|
|
}
|
2025-11-24 03:47:20 +00:00
|
|
|
|
|
|
|
|
if (!nimInstance) {
|
|
|
|
|
// 动态导入 SDK
|
|
|
|
|
const V2NIM = require("nim-web-sdk-ng").default;
|
|
|
|
|
nimInstance = V2NIM.getInstance({
|
|
|
|
|
appkey: process.env.NEXT_PUBLIC_NIM_APP_KEY || "2d6abc076f434fc52320c7118de5fead",
|
|
|
|
|
debugLevel: 'error', // 设置日志 level
|
|
|
|
|
apiVersion: 'v2',
|
|
|
|
|
enableV2CloudConversation: true,
|
|
|
|
|
}, {
|
|
|
|
|
V2NIMLoginServiceConfig: {
|
|
|
|
|
lbsUrls: [
|
|
|
|
|
"https://lbs.netease.im/lbs/webconf"
|
|
|
|
|
],
|
|
|
|
|
linkUrl: "weblink01-sg.netease.im:443"
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nimInstance;
|
|
|
|
|
}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
const NimChatContext = createContext<{
|
2025-11-24 03:47:20 +00:00
|
|
|
nim: V2NIM | null;
|
2025-11-13 08:38:25 +00:00
|
|
|
isNimLoggedIn: boolean;
|
|
|
|
|
nimLoginStatus: V2NIMLoginStatus | null;
|
|
|
|
|
}>({
|
2025-11-24 03:47:20 +00:00
|
|
|
nim: null,
|
2025-11-13 08:38:25 +00:00
|
|
|
isNimLoggedIn: false,
|
|
|
|
|
nimLoginStatus: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const NimChatProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
|
|
const [isNimLoggedIn, setIsNimLoggedIn] = useState(false);
|
|
|
|
|
const [nimLoginStatus, setNimLoginStatus] = useState<V2NIMLoginStatus | null>(null);
|
|
|
|
|
const [hasInitialized, setHasInitialized] = useState(false);
|
2025-11-24 03:47:20 +00:00
|
|
|
const [nim, setNim] = useState<V2NIM | null>(null);
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
const { data: imAccount } = useGetIMAccount();
|
|
|
|
|
const { data: user } = useCurrentUser();
|
|
|
|
|
|
2025-11-24 03:47:20 +00:00
|
|
|
// 初始化 NIM 实例(仅在客户端)
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const instance = getNimInstance();
|
|
|
|
|
setNim(instance);
|
|
|
|
|
}, []);
|
|
|
|
|
|
2025-11-13 08:38:25 +00:00
|
|
|
// 初始化和检查登录状态
|
|
|
|
|
useEffect(() => {
|
2025-11-24 03:47:20 +00:00
|
|
|
if (!nim || hasInitialized || !user || !imAccount) return;
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
const init = async () => {
|
|
|
|
|
// 只有在未登录状态下才执行登录
|
|
|
|
|
console.log('NIM 开始登录...');
|
|
|
|
|
await nim.V2NIMLoginService.login(imAccount.accountId, imAccount.token, {
|
|
|
|
|
retryCount: 5,
|
|
|
|
|
})
|
|
|
|
|
setIsNimLoggedIn(true);
|
|
|
|
|
setHasInitialized(true);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查当前登录状态
|
|
|
|
|
const currentStatus = nim.V2NIMLoginService.getLoginStatus();
|
|
|
|
|
console.log('NIM 当前登录状态:', currentStatus);
|
|
|
|
|
setNimLoginStatus(currentStatus);
|
|
|
|
|
|
|
|
|
|
// 如果已经登录,更新状态
|
|
|
|
|
if (currentStatus === 1) {
|
|
|
|
|
console.log('NIM 已经登录,跳过重新登录');
|
|
|
|
|
setIsNimLoggedIn(true);
|
|
|
|
|
setHasInitialized(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init();
|
2025-11-24 03:47:20 +00:00
|
|
|
}, [nim, hasInitialized, user, imAccount])
|
|
|
|
|
|
|
|
|
|
// 在 nim 初始化之前不渲染子组件
|
|
|
|
|
if (!nim) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<NimUserProvider nim={nim}>
|
|
|
|
|
<ConversationProvider nim={nim}>
|
|
|
|
|
<NimMsgProvider nim={nim}>
|
|
|
|
|
<NimLoginProvider nim={nim}>
|
|
|
|
|
<NimChatContext.Provider value={{
|
|
|
|
|
nim,
|
|
|
|
|
isNimLoggedIn,
|
|
|
|
|
nimLoginStatus
|
|
|
|
|
}}>
|
|
|
|
|
{children}
|
|
|
|
|
</NimChatContext.Provider>
|
|
|
|
|
</NimLoginProvider>
|
|
|
|
|
</NimMsgProvider>
|
|
|
|
|
</ConversationProvider>
|
|
|
|
|
</NimUserProvider>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default NimChatContext;
|