UserTrustProvider.tsx raw

   1  import client from '@/services/client.service'
   2  import fayan from '@/services/fayan.service'
   3  import storage, { dispatchSettingsChanged } from '@/services/local-storage.service'
   4  import { createContext, useCallback, useContext, useEffect, useState } from 'react'
   5  import { useNostr } from './NostrProvider'
   6  
   7  type TUserTrustContext = {
   8    hideUntrustedInteractions: boolean
   9    hideUntrustedNotifications: boolean
  10    hideUntrustedNotes: boolean
  11    updateHideUntrustedInteractions: (hide: boolean) => void
  12    updateHideUntrustedNotifications: (hide: boolean) => void
  13    updateHideUntrustedNotes: (hide: boolean) => void
  14    isUserTrusted: (pubkey: string) => boolean
  15    isSpammer: (pubkey: string) => Promise<boolean>
  16  }
  17  
  18  const UserTrustContext = createContext<TUserTrustContext | undefined>(undefined)
  19  
  20  export const useUserTrust = () => {
  21    const context = useContext(UserTrustContext)
  22    if (!context) {
  23      throw new Error('useUserTrust must be used within a UserTrustProvider')
  24    }
  25    return context
  26  }
  27  
  28  const wotSet = new Set<string>()
  29  
  30  export function UserTrustProvider({ children }: { children: React.ReactNode }) {
  31    const { pubkey: currentPubkey } = useNostr()
  32    const [hideUntrustedInteractions, setHideUntrustedInteractions] = useState(() =>
  33      storage.getHideUntrustedInteractions()
  34    )
  35    const [hideUntrustedNotifications, setHideUntrustedNotifications] = useState(() =>
  36      storage.getHideUntrustedNotifications()
  37    )
  38    const [hideUntrustedNotes, setHideUntrustedNotes] = useState(() =>
  39      storage.getHideUntrustedNotes()
  40    )
  41  
  42    useEffect(() => {
  43      if (!currentPubkey) return
  44  
  45      const initWoT = async () => {
  46        const followings = await client.fetchFollowings(currentPubkey, false)
  47        followings.forEach((pubkey) => wotSet.add(pubkey))
  48  
  49        const batchSize = 20
  50        for (let i = 0; i < followings.length; i += batchSize) {
  51          const batch = followings.slice(i, i + batchSize)
  52          await Promise.allSettled(
  53            batch.map(async (pubkey) => {
  54              const _followings = await client.fetchFollowings(pubkey, false)
  55              _followings.forEach((following) => {
  56                wotSet.add(following)
  57              })
  58            })
  59          )
  60          await new Promise((resolve) => setTimeout(resolve, 200))
  61        }
  62      }
  63      initWoT()
  64    }, [currentPubkey])
  65  
  66    const isUserTrusted = useCallback(
  67      (pubkey: string) => {
  68        if (!currentPubkey || pubkey === currentPubkey) return true
  69        return wotSet.has(pubkey)
  70      },
  71      [currentPubkey]
  72    )
  73  
  74    const isSpammer = useCallback(
  75      async (pubkey: string) => {
  76        if (isUserTrusted(pubkey)) return false
  77        const percentile = await fayan.fetchUserPercentile(pubkey)
  78        if (percentile === null) return false
  79        return percentile < 60
  80      },
  81      [isUserTrusted]
  82    )
  83  
  84    const updateHideUntrustedInteractions = (hide: boolean) => {
  85      setHideUntrustedInteractions(hide)
  86      storage.setHideUntrustedInteractions(hide)
  87      dispatchSettingsChanged()
  88    }
  89  
  90    const updateHideUntrustedNotifications = (hide: boolean) => {
  91      setHideUntrustedNotifications(hide)
  92      storage.setHideUntrustedNotifications(hide)
  93      dispatchSettingsChanged()
  94    }
  95  
  96    const updateHideUntrustedNotes = (hide: boolean) => {
  97      setHideUntrustedNotes(hide)
  98      storage.setHideUntrustedNotes(hide)
  99      dispatchSettingsChanged()
 100    }
 101  
 102    return (
 103      <UserTrustContext.Provider
 104        value={{
 105          hideUntrustedInteractions,
 106          hideUntrustedNotifications,
 107          hideUntrustedNotes,
 108          updateHideUntrustedInteractions,
 109          updateHideUntrustedNotifications,
 110          updateHideUntrustedNotes,
 111          isUserTrusted,
 112          isSpammer
 113        }}
 114      >
 115        {children}
 116      </UserTrustContext.Provider>
 117    )
 118  }
 119