feat(pages): add /application/[guildId]/[channelId] (#4)

This commit is contained in:
Divlo
2022-01-01 20:42:25 +01:00
committed by GitHub
parent 91e246b759
commit fdc2a2d1de
118 changed files with 6040 additions and 2094 deletions

View File

@ -1,15 +1,54 @@
export interface ChannelType {
id: number
name: string
description: string
createdAt: string
updatedAt: string
import { createContext, useContext, useEffect } from 'react'
import { NextPage, usePagination } from 'hooks/usePagination'
import { useAuthentication } from 'tools/authentication'
import { Channel } from 'models/Channel'
import { GuildsChannelsPath } from 'components/Application'
export interface Channels {
channels: Channel[]
hasMore: boolean
nextPage: NextPage
}
export const channelExample: ChannelType = {
id: 4,
name: 'Channel 4',
description: '',
createdAt: '',
updatedAt: ''
const defaultChannelsContext = {} as any
const ChannelsContext = createContext<Channels>(defaultChannelsContext)
export interface ChannelsProviderProps {
path: GuildsChannelsPath
}
export const ChannelsProvider: React.FC<ChannelsProviderProps> = (props) => {
const { path, children } = props
const { authentication } = useAuthentication()
const {
items: channels,
hasMore,
nextPage,
resetPagination
} = usePagination<Channel>({
api: authentication.api,
url: `/guilds/${path.guildId}/channels`
})
useEffect(() => {
resetPagination()
nextPage()
}, [nextPage, resetPagination])
return (
<ChannelsContext.Provider value={{ channels, hasMore, nextPage }}>
{children}
</ChannelsContext.Provider>
)
}
export const useChannels = (): Channels => {
const channels = useContext(ChannelsContext)
if (channels === defaultChannelsContext) {
throw new Error('useChannels must be used within ChannelsProvider')
}
return channels
}

51
contexts/GuildMember.tsx Normal file
View File

@ -0,0 +1,51 @@
import { createContext, useContext, useEffect, useState } from 'react'
import { Guild } from 'models/Guild'
import { Member } from 'models/Member'
import { GuildsChannelsPath } from 'components/Application'
import { useAuthentication } from 'tools/authentication'
export interface GuildMember {
guild: Guild
member: Member
}
export interface GuildMemberProps {
guildMember: GuildMember
path: GuildsChannelsPath
}
const defaultGuildMemberContext = {} as any
const GuildMemberContext = createContext<GuildMember>(defaultGuildMemberContext)
export const GuildMemberProvider: React.FC<GuildMemberProps> = (props) => {
const [guildMember, setGuildMember] = useState(props.guildMember)
const { authentication } = useAuthentication()
useEffect(() => {
const fetchGuildMember = async (): Promise<void> => {
const { data } = await authentication.api.get(
`/guilds/${props.path.guildId}`
)
setGuildMember(data)
}
fetchGuildMember().catch((error) => {
console.error(error)
})
}, [props.path, authentication.api])
return (
<GuildMemberContext.Provider value={guildMember}>
{props.children}
</GuildMemberContext.Provider>
)
}
export const useGuildMember = (): GuildMember => {
const guildMember = useContext(GuildMemberContext)
if (guildMember === defaultGuildMemberContext) {
throw new Error('useGuildMember must be used within GuildMemberProvider')
}
return guildMember
}

49
contexts/Guilds.tsx Normal file
View File

@ -0,0 +1,49 @@
import { createContext, useContext, useEffect } from 'react'
import { NextPage, usePagination } from 'hooks/usePagination'
import { useAuthentication } from 'tools/authentication'
import { GuildWithDefaultChannelId } from 'models/Guild'
export interface Guilds {
guilds: GuildWithDefaultChannelId[]
hasMore: boolean
nextPage: NextPage
}
const defaultGuildsContext = {} as any
const GuildsContext = createContext<Guilds>(defaultGuildsContext)
export const GuildsProvider: React.FC = (props) => {
const { children } = props
const { authentication } = useAuthentication()
const {
items: guilds,
hasMore,
nextPage,
resetPagination
} = usePagination<GuildWithDefaultChannelId>({
api: authentication.api,
url: '/guilds'
})
useEffect(() => {
resetPagination()
nextPage()
}, [nextPage, resetPagination])
return (
<GuildsContext.Provider value={{ guilds, hasMore, nextPage }}>
{children}
</GuildsContext.Provider>
)
}
export const useGuilds = (): Guilds => {
const guilds = useContext(GuildsContext)
if (guilds === defaultGuildsContext) {
throw new Error('useGuilds must be used within GuildsProvider')
}
return guilds
}

54
contexts/Members.tsx Normal file
View File

@ -0,0 +1,54 @@
import { createContext, useContext, useEffect } from 'react'
import { NextPage, usePagination } from 'hooks/usePagination'
import { useAuthentication } from 'tools/authentication'
import { MemberWithPublicUser } from 'models/Member'
import { GuildsChannelsPath } from 'components/Application'
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
} = usePagination<MemberWithPublicUser>({
api: authentication.api,
url: `/guilds/${path.guildId}/members`
})
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
}

60
contexts/Messages.tsx Normal file
View File

@ -0,0 +1,60 @@
import { createContext, useContext, useEffect } from 'react'
import { NextPage, usePagination } from 'hooks/usePagination'
import { useAuthentication } from 'tools/authentication'
import { MessageWithMember } from 'models/Message'
import { GuildsChannelsPath } from 'components/Application'
export interface Messages {
messages: MessageWithMember[]
hasMore: boolean
nextPage: NextPage
}
const defaultMessagesContext = {} as any
const MessagesContext = createContext<Messages>(defaultMessagesContext)
export interface MessagesProviderProps {
path: GuildsChannelsPath
}
export const MessagesProvider: React.FC<MessagesProviderProps> = (props) => {
const { path, children } = props
const { authentication } = useAuthentication()
const {
items: messages,
hasMore,
nextPage,
resetPagination
} = usePagination<MessageWithMember>({
api: authentication.api,
url: `/channels/${path.channelId}/messages`,
inverse: true
})
useEffect(() => {
resetPagination()
nextPage(undefined, () => {
const messagesDiv = window.document.getElementById(
'messages'
) as HTMLDivElement
messagesDiv.scrollTo(0, messagesDiv.scrollHeight)
})
}, [nextPage, resetPagination])
return (
<MessagesContext.Provider value={{ messages, hasMore, nextPage }}>
{children}
</MessagesContext.Provider>
)
}
export const useMessages = (): Messages => {
const messages = useContext(MessagesContext)
if (messages === defaultMessagesContext) {
throw new Error('useMessages must be used within a MessagesProvider')
}
return messages
}