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/Members.tsx

90 lines
2.3 KiB
TypeScript
Raw Permalink Normal View History

import { createContext, useContext, useEffect } from 'react'
2022-03-16 12:18:09 +01:00
import { NextPage, usePagination } from '../hooks/usePagination'
import { useAuthentication } from '../tools/authentication'
import { MemberWithPublicUser } from '../models/Member'
import { GuildsChannelsPath } from '../components/Application'
import { handleSocketData, SocketData } from '../tools/handleSocketData'
import { User } from '../models/User'
export interface Members {
members: MemberWithPublicUser[]
hasMore: boolean
nextPage: NextPage
}
const defaultMembersContext = {} as any
const MembersContext = createContext<Members>(defaultMembersContext)
export interface MembersProviderProps {
path: GuildsChannelsPath
}
export const MembersProviders: React.FC<MembersProviderProps> = (props) => {
const { children, path } = props
const { authentication } = useAuthentication()
const {
items: members,
hasMore,
nextPage,
resetPagination,
setItems
} = usePagination<MemberWithPublicUser>({
api: authentication.api,
url: `/guilds/${path.guildId}/members`
})
useEffect(() => {
authentication.socket.on(
'members',
(data: SocketData<MemberWithPublicUser>) => {
handleSocketData({ data, setItems })
}
)
authentication.socket.on('users', (data: SocketData<User>) => {
setItems((oldItems) => {
const newItems = [...oldItems]
switch (data.action) {
case 'update': {
for (const member of newItems) {
if (member.user.id === data.item.id) {
member.user = data.item
break
}
}
break
}
}
return newItems
})
})
return () => {
authentication.socket.off('members')
authentication.socket.off('users')
}
}, [authentication.socket, setItems])
useEffect(() => {
resetPagination()
nextPage()
}, [nextPage, resetPagination])
return (
<MembersContext.Provider value={{ members, hasMore, nextPage }}>
{children}
</MembersContext.Provider>
)
}
export const useMembers = (): Members => {
const members = useContext(MembersContext)
if (members === defaultMembersContext) {
throw new Error('useMembers must be used within MembersProvider')
}
return members
}