Files
explore/lib/socket/context.tsx
T
tom goriunovandGitHub 36930767c9 OP Superchain Explorer: MVP (#2786)
* context for storing subchain config and tx view for subchain

* address page and block page for subchain

* address aggregated page: local txs tab

* connect MultichainSelect to context

* home page placeholder

* refactor subchain select state

* envs for demo

* fix ts

* clear value for l2 review

* subchain widgets on home page

* csp policies

* sockets, duck and goose

* fix socket on subchain address page

* link builder for subchain views

* update home widget

* fix time increment

* enable tx interpretator and metadata service

* generate multichain config based on every chain app config

* Fix the multichain config to work in Docker

* multichain socket test

* rename subchain-id to subchain-slug path param

* refactoring

* update chain icons on entities

* home page: latest local txs

* latest cross-chain txs

* minor improvements

* renaming, pt. 1

* rename chain routes

* enable blockchain interaction

* add loading state to icon shield

* fix build

* fix tests

* update types package
2025-07-03 15:07:00 +02:00

57 lines
1.4 KiB
TypeScript

// https://hexdocs.pm/phoenix/js/
import type { Channel, SocketConnectOption } from 'phoenix';
import { Socket } from 'phoenix';
import React, { useEffect, useState } from 'react';
type ChannelRegistry = Record<string, { channel: Channel; subscribers: number }>;
export const SocketContext = React.createContext<{
socket: Socket | null;
channelRegistry: React.MutableRefObject<ChannelRegistry>;
} | null>(null);
interface SocketProviderProps {
children: React.ReactNode;
url?: string;
options?: Partial<SocketConnectOption>;
}
export function SocketProvider({ children, options, url }: SocketProviderProps) {
const [ socket, setSocket ] = useState<Socket | null>(null);
const channelRegistry = React.useRef<ChannelRegistry>({});
useEffect(() => {
if (!url) {
return;
}
const socketInstance = new Socket(url, options);
socketInstance.connect();
setSocket(socketInstance);
return () => {
socketInstance.disconnect();
setSocket(null);
};
}, [ options, url ]);
const value = React.useMemo(() => ({
socket,
channelRegistry,
}), [ socket, channelRegistry ]);
return (
<SocketContext.Provider value={ value }>
{ children }
</SocketContext.Provider>
);
}
export function useSocket() {
const context = React.useContext(SocketContext);
if (context === undefined) {
throw new Error('useSocket must be used within a SocketProvider');
}
return context;
}