webapp/src/context/inbox.tsx

93 lines
2.8 KiB
TypeScript
Raw Normal View History

2023-02-10 01:19:20 +00:00
import type { Accessor, JSX } from 'solid-js'
import { createContext, createSignal, useContext, createMemo } from 'solid-js'
2023-02-23 14:07:25 +00:00
import { createSubClient } from '../graphql/privateGraphQLClient'
2022-12-17 03:27:00 +00:00
import type { Chat, Message, MutationCreateMessageArgs } from '../graphql/types.gen'
2022-11-24 15:39:31 +00:00
import { apiClient } from '../utils/apiClient'
2023-01-31 17:31:13 +00:00
import newMessage from '../graphql/subs/new-message'
import type { Client } from '@urql/core'
2022-12-17 03:27:00 +00:00
import { pipe, subscribe } from 'wonka'
import { loadMessages } from '../stores/inbox'
2022-11-24 15:39:31 +00:00
type InboxContextType = {
2022-12-17 03:27:00 +00:00
chats: Accessor<Chat[]>
messages?: Accessor<Message[]>
2022-11-24 15:39:31 +00:00
actions: {
2022-12-17 03:27:00 +00:00
createChat: (members: number[], title: string) => Promise<{ chat: Chat }>
loadChats: () => Promise<void>
getMessages?: (chatId: string) => Promise<void>
sendMessage?: (args: MutationCreateMessageArgs) => void
// unsubscribe: () => void
2022-11-24 15:39:31 +00:00
}
}
const InboxContext = createContext<InboxContextType>()
export function useInbox() {
return useContext(InboxContext)
}
export const InboxProvider = (props: { children: JSX.Element }) => {
2022-12-17 03:27:00 +00:00
const [chats, setChats] = createSignal<Chat[]>([])
const [messages, setMessages] = createSignal<Message[]>([])
2023-02-23 14:07:25 +00:00
const subclient = createMemo<Client>(() => createSubClient())
2022-12-17 03:27:00 +00:00
const loadChats = async () => {
try {
const newChats = await apiClient.getChats({ limit: 50, offset: 0 })
setChats(newChats)
} catch (error) {
console.log(error)
}
}
const getMessages = async (chatId: string) => {
if (!chatId) return
try {
const response = await loadMessages({ chat: chatId })
setMessages(response as unknown as Message[])
} catch (error) {
console.error('[loadMessages]', error)
}
}
const sendMessage = async (args) => {
try {
const message = await apiClient.createMessage(args)
setMessages((prev) => [...prev, message])
const currentChat = chats().find((chat) => chat.id === args.chat)
setChats((prev) => [
...prev.filter((c) => c.id !== currentChat.id),
{ ...currentChat, updatedAt: message.createdAt }
])
} catch (error) {
console.error('[post message error]:', error)
}
}
2022-11-24 15:39:31 +00:00
2022-12-02 11:11:45 +00:00
const createChat = async (members: number[], title: string) => {
2022-11-27 05:49:48 +00:00
const chat = await apiClient.createChat({ members, title })
2022-12-17 03:27:00 +00:00
setChats((prevChats) => {
return [chat, ...prevChats]
2022-11-25 07:36:45 +00:00
})
2022-11-25 23:34:46 +00:00
return chat
2022-11-24 15:39:31 +00:00
}
2023-02-23 14:07:25 +00:00
pipe(
subclient().subscription(newMessage, {}),
2022-12-17 03:27:00 +00:00
subscribe((result) => {
console.info('[subscription]')
console.debug(result)
// TODO: handle data result
})
)
2022-11-24 15:39:31 +00:00
const actions = {
2022-12-17 03:27:00 +00:00
createChat,
loadChats,
getMessages,
2023-02-23 14:07:25 +00:00
sendMessage
// unsubscribe // TODO: call unsubscribe some time!
2022-11-24 15:39:31 +00:00
}
2022-11-27 05:49:48 +00:00
2022-12-17 03:27:00 +00:00
const value: InboxContextType = { chats, messages, actions }
2022-11-24 15:39:31 +00:00
return <InboxContext.Provider value={value}>{props.children}</InboxContext.Provider>
}