EmojiPackProvider.tsx raw
1 import { buildATag, createUserEmojiListDraftEvent } from '@/lib/draft-event'
2 import { getReplaceableCoordinateFromEvent } from '@/lib/event'
3 import client from '@/services/client.service'
4 import { Event, kinds } from 'nostr-tools'
5 import { createContext, useContext, useMemo } from 'react'
6 import { useNostr } from './NostrProvider'
7
8 type TEmojiPackContext = {
9 emojiPackCoordinateSet: Set<string>
10 addEmojiPack: (event: Event) => Promise<void>
11 removeEmojiPack: (event: Event) => Promise<void>
12 }
13
14 const EmojiPackContext = createContext<TEmojiPackContext | undefined>(undefined)
15
16 export const useEmojiPack = () => {
17 const context = useContext(EmojiPackContext)
18 if (!context) {
19 throw new Error('useEmojiPack must be used within a EmojiPackProvider')
20 }
21 return context
22 }
23
24 export function EmojiPackProvider({ children }: { children: React.ReactNode }) {
25 const {
26 pubkey: accountPubkey,
27 userEmojiListEvent,
28 publish,
29 updateUserEmojiListEvent
30 } = useNostr()
31 const emojiPackCoordinateSet = useMemo(() => {
32 const set = new Set<string>()
33 userEmojiListEvent?.tags.forEach((tag) => {
34 if (tag[0] === 'a') {
35 set.add(tag[1])
36 }
37 })
38 return set
39 }, [userEmojiListEvent])
40
41 const addEmojiPack = async (event: Event) => {
42 if (!accountPubkey || event.kind !== kinds.Emojisets) return
43
44 const userEmojiListEvent = await client.fetchUserEmojiListEvent(accountPubkey)
45 const currentTags = userEmojiListEvent?.tags || []
46 const coordinate = getReplaceableCoordinateFromEvent(event)
47
48 // Check if already exists
49 if (currentTags.some((tag) => tag[0] === 'a' && tag[1] === coordinate)) {
50 return
51 }
52
53 const newUserEmojiListDraftEvent = createUserEmojiListDraftEvent(
54 [...currentTags, buildATag(event)],
55 userEmojiListEvent?.content
56 )
57 const newUserEmojiListEvent = await publish(newUserEmojiListDraftEvent)
58 await updateUserEmojiListEvent(newUserEmojiListEvent)
59 }
60
61 const removeEmojiPack = async (event: Event) => {
62 if (!accountPubkey) return
63
64 const userEmojiListEvent = await client.fetchUserEmojiListEvent(accountPubkey)
65 if (!userEmojiListEvent) return
66
67 const coordinate = getReplaceableCoordinateFromEvent(event)
68 const newTags = userEmojiListEvent.tags.filter((tag) => tag[0] !== 'a' || tag[1] !== coordinate)
69 if (newTags.length === userEmojiListEvent.tags.length) return
70
71 const newUserEmojiListDraftEvent = createUserEmojiListDraftEvent(
72 newTags,
73 userEmojiListEvent.content
74 )
75 const newUserEmojiListEvent = await publish(newUserEmojiListDraftEvent)
76 await updateUserEmojiListEvent(newUserEmojiListEvent)
77 }
78
79 return (
80 <EmojiPackContext.Provider
81 value={{
82 emojiPackCoordinateSet,
83 addEmojiPack,
84 removeEmojiPack
85 }}
86 >
87 {children}
88 </EmojiPackContext.Provider>
89 )
90 }
91