You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

96 lines
3.2 KiB

import { replaceableEventService } from '@/services/client.service'
import { getPubkeysFromPTags } from '@/lib/tag'
import { kinds } from 'nostr-tools'
import storage from '@/services/local-storage.service'
import { UserTrustContext } from '@/contexts/user-trust-context'
import { type ReactNode, useCallback, useEffect, useState } from 'react'
import { useNostr } from './NostrProvider'
const wotSet = new Set<string>()
export function UserTrustProvider({ children }: { children: ReactNode }) {
const { pubkey: currentPubkey } = useNostr()
const [isTrustLoaded, setIsTrustLoaded] = useState(false)
const [hideUntrustedInteractions, setHideUntrustedInteractions] = useState(() =>
storage.getHideUntrustedInteractions()
)
const [hideUntrustedNotifications, setHideUntrustedNotifications] = useState(() =>
storage.getHideUntrustedNotifications()
)
const [hideUntrustedNotes, setHideUntrustedNotes] = useState(() =>
storage.getHideUntrustedNotes()
)
useEffect(() => {
if (!currentPubkey) {
setIsTrustLoaded(false)
return
}
// Clear wotSet when account changes to avoid cross-account contamination
wotSet.clear()
setIsTrustLoaded(false)
const initWoT = async () => {
const followListEvent = await replaceableEventService.fetchReplaceableEvent(currentPubkey, kinds.Contacts)
const followings = followListEvent ? getPubkeysFromPTags(followListEvent.tags) : []
followings.forEach((pubkey) => wotSet.add(pubkey.toLowerCase()))
const batchSize = 20
for (let i = 0; i < followings.length; i += batchSize) {
const batch = followings.slice(i, i + batchSize)
await Promise.allSettled(
batch.map(async (pubkey) => {
const followListEvent = await replaceableEventService.fetchReplaceableEvent(pubkey, kinds.Contacts)
const _followings = followListEvent ? getPubkeysFromPTags(followListEvent.tags) : []
_followings.forEach((following) => {
wotSet.add(following.toLowerCase())
})
})
)
await new Promise((resolve) => setTimeout(resolve, 200))
}
}
initWoT()
}, [currentPubkey])
const isUserTrusted = useCallback(
(pubkey: string) => {
if (!currentPubkey || pubkey.toLowerCase() === currentPubkey.toLowerCase()) return true
return wotSet.has(pubkey.toLowerCase())
},
[currentPubkey]
)
const updateHideUntrustedInteractions = (hide: boolean) => {
setHideUntrustedInteractions(hide)
storage.setHideUntrustedInteractions(hide)
}
const updateHideUntrustedNotifications = (hide: boolean) => {
setHideUntrustedNotifications(hide)
storage.setHideUntrustedNotifications(hide)
}
const updateHideUntrustedNotes = (hide: boolean) => {
setHideUntrustedNotes(hide)
storage.setHideUntrustedNotes(hide)
}
return (
<UserTrustContext.Provider
value={{
isTrustLoaded,
hideUntrustedInteractions,
hideUntrustedNotifications,
hideUntrustedNotes,
updateHideUntrustedInteractions,
updateHideUntrustedNotifications,
updateHideUntrustedNotes,
isUserTrusted
}}
>
{children}
</UserTrustContext.Provider>
)
}