This repository has been archived on 2024-10-29. You can view files and clone it, but cannot push or open issues or pull requests.
website/contexts/GuildMember.tsx

97 lines
2.5 KiB
TypeScript

import { createContext, useContext, useEffect, useState } from "react"
import { useRouter } from "next/router"
import type { GuildWithDefaultChannelId } from "../models/Guild"
import type { Member } from "../models/Member"
import { useAuthentication } from "../tools/authentication"
import type { SocketData } from "../tools/handleSocketData"
export interface GuildMember {
guild: GuildWithDefaultChannelId
member: Member
}
export interface GuildMemberResult extends GuildMember {}
export interface GuildMemberProps {
guildMember: GuildMember
path: {
guildId: number
}
}
const defaultGuildMemberContext = {} as any
const GuildMemberContext = createContext<GuildMemberResult>(
defaultGuildMemberContext,
)
export const GuildMemberProvider: React.FC<
React.PropsWithChildren<GuildMemberProps>
> = (props) => {
const { path, children } = props
const router = useRouter()
const [guildMember, setGuildMember] = useState(props.guildMember)
const { authentication } = useAuthentication()
useEffect(() => {
const fetchGuildMember = async (): Promise<void> => {
const { data } = await authentication.api.get(`/guilds/${path.guildId}`)
setGuildMember(data)
}
fetchGuildMember().catch((error) => {
console.error(error)
})
}, [path, authentication.api])
useEffect(() => {
authentication?.socket?.on(
"guilds",
async (data: SocketData<GuildWithDefaultChannelId>) => {
if (data.item.id === path.guildId) {
switch (data.action) {
case "delete":
await router.push("/application")
break
case "update":
setGuildMember((oldGuildMember) => {
return {
...oldGuildMember,
guild: {
...oldGuildMember.guild,
...data.item,
},
}
})
break
}
}
},
)
return () => {
authentication?.socket?.off("guilds")
}
}, [authentication.socket, path.guildId, router])
return (
<GuildMemberContext.Provider
value={{
...guildMember,
}}
>
{children}
</GuildMemberContext.Provider>
)
}
export const useGuildMember = (): GuildMemberResult => {
const guildMember = useContext(GuildMemberContext)
if (guildMember === defaultGuildMemberContext) {
throw new Error(
"`useGuildMember` must be used within `GuildMemberProvider`",
)
}
return guildMember
}