68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import {
|
|
createContext,
|
|
useContext,
|
|
useEffect,
|
|
useRef,
|
|
useState,
|
|
type ReactNode,
|
|
} from "react";
|
|
import { PusherClient, type ConnectionState } from "./pusher-client";
|
|
import { useSessionStore } from "@/stores/session-store";
|
|
import { appConfig } from "@/config/env";
|
|
|
|
const PusherContext = createContext<PusherClient | null>(null);
|
|
const PusherStateContext = createContext<ConnectionState>("disconnected");
|
|
|
|
export function PusherProvider({ children }: { children: ReactNode }) {
|
|
const token = useSessionStore((s) => s.token);
|
|
const clientRef = useRef<PusherClient | null>(null);
|
|
const [connectionState, setConnectionState] =
|
|
useState<ConnectionState>("disconnected");
|
|
|
|
useEffect(() => {
|
|
if (!token) {
|
|
if (clientRef.current) {
|
|
clientRef.current.disconnect();
|
|
clientRef.current = null;
|
|
setConnectionState("disconnected");
|
|
}
|
|
return;
|
|
}
|
|
|
|
const client = new PusherClient({
|
|
url: appConfig.pusherUrl,
|
|
getToken: () => useSessionStore.getState().token,
|
|
});
|
|
|
|
clientRef.current = client;
|
|
|
|
const unsubscribeState = client.onStateChange((state) => {
|
|
setConnectionState(state);
|
|
});
|
|
|
|
client.connect();
|
|
|
|
return () => {
|
|
unsubscribeState();
|
|
client.disconnect();
|
|
clientRef.current = null;
|
|
};
|
|
}, [token]);
|
|
|
|
return (
|
|
<PusherContext.Provider value={clientRef.current}>
|
|
<PusherStateContext.Provider value={connectionState}>
|
|
{children}
|
|
</PusherStateContext.Provider>
|
|
</PusherContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function usePusherClient(): PusherClient | null {
|
|
return useContext(PusherContext);
|
|
}
|
|
|
|
export function usePusherConnectionState(): ConnectionState {
|
|
return useContext(PusherStateContext);
|
|
}
|