import { TDraftEvent } from '@/types' import { tagNameEquals } from '@/lib/tag' import client from '@/services/client.service' import dayjs from 'dayjs' import { Event, kinds } from 'nostr-tools' import { createContext, useContext, useEffect, useMemo, useState } from 'react' import { useNostr } from './NostrProvider' type TFollowListContext = { followListEvent: Event | undefined followings: string[] isReady: boolean follow: (pubkey: string) => Promise unfollow: (pubkey: string) => Promise } const FollowListContext = createContext(undefined) export const useFollowList = () => { const context = useContext(FollowListContext) if (!context) { throw new Error('useFollowList must be used within a FollowListProvider') } return context } export function FollowListProvider({ children }: { children: React.ReactNode }) { const { pubkey: accountPubkey, publish } = useNostr() const [followListEvent, setFollowListEvent] = useState(undefined) const [isReady, setIsReady] = useState(false) const followings = useMemo( () => followListEvent?.tags .filter(tagNameEquals('p')) .map(([, pubkey]) => pubkey) .filter(Boolean) .reverse() ?? [], [followListEvent] ) useEffect(() => { if (!accountPubkey) return const init = async () => { setIsReady(false) setFollowListEvent(undefined) const event = await client.fetchFollowListEvent(accountPubkey) setFollowListEvent(event) setIsReady(true) } init() }, [accountPubkey]) const follow = async (pubkey: string) => { if (!isReady || !accountPubkey) return const newFollowListDraftEvent: TDraftEvent = { kind: kinds.Contacts, content: followListEvent?.content ?? '', created_at: dayjs().unix(), tags: (followListEvent?.tags ?? []).concat([['p', pubkey]]) } const newFollowListEvent = await publish(newFollowListDraftEvent) client.updateFollowListCache(accountPubkey, newFollowListEvent) setFollowListEvent(newFollowListEvent) } const unfollow = async (pubkey: string) => { if (!isReady || !accountPubkey || !followListEvent) return const newFollowListDraftEvent: TDraftEvent = { kind: kinds.Contacts, content: followListEvent.content ?? '', created_at: dayjs().unix(), tags: followListEvent.tags.filter( ([tagName, tagValue]) => tagName !== 'p' || tagValue !== pubkey ) } const newFollowListEvent = await publish(newFollowListDraftEvent) client.updateFollowListCache(accountPubkey, newFollowListEvent) setFollowListEvent(newFollowListEvent) } return ( {children} ) }