import { createContext, useContext, useEffect, useMemo } from "react" import { useRouter } from "next/router" import type { NextPage } from "../hooks/usePagination" import { usePagination } from "../hooks/usePagination" import { useAuthentication } from "../tools/authentication" import type { Channel, ChannelWithDefaultChannelId } from "../models/Channel" import type { GuildsChannelsPath } from "../components/Application" import type { SocketData } from "../tools/handleSocketData" import { handleSocketData } from "../tools/handleSocketData" import type { CacheKey } from "../tools/cache" import { CHANNELS_CACHE_KEY } from "../tools/cache" export interface Channels { channels: Channel[] hasMore: boolean nextPage: NextPage } const defaultChannelsContext = {} as any const ChannelsContext = createContext(defaultChannelsContext) export interface ChannelsProviderProps { path: GuildsChannelsPath } export const ChannelsProvider: React.FC< React.PropsWithChildren > = (props) => { const { path, children } = props const router = useRouter() const { authentication } = useAuthentication() const cacheKey = useMemo(() => { return `${path.guildId}-${CHANNELS_CACHE_KEY}` }, [path.guildId]) const { items: channels, hasMore, nextPage, resetPagination, setItems, } = usePagination({ api: authentication.api, url: `/guilds/${path.guildId}/channels`, cacheKey, }) useEffect(() => { authentication?.socket?.on( "channels", async (data: SocketData) => { handleSocketData({ data, setItems, cacheKey }) if (data.action === "delete") { await router.push( `/application/${path.guildId}/${data.item.defaultChannelId}`, ) } }, ) return () => { authentication?.socket?.off("channels") } }, [authentication.socket, path.guildId, router, setItems, cacheKey]) useEffect(() => { resetPagination() nextPage() }, [nextPage, resetPagination]) return ( {children} ) } export const useChannels = (): Channels => { const channels = useContext(ChannelsContext) if (channels === defaultChannelsContext) { throw new Error("`useChannels` must be used within `ChannelsProvider`") } return channels }