import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk'
import { LoadingSpinner } from 'components/LoadingSpinner'
import { useAppDispatch, useAppSelector, useNDKContext } from 'hooks'
import { kinds, UnsignedEvent, Event } from 'nostr-tools'
import { useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { setSiteWotLevel, setUserWotLevel } from 'store/reducers/wot'
import { UserRelaysType } from 'types'
import { log, LogType, now, npubToHex } from 'utils'
// todo: use components from Input.tsx
export const PreferencesSetting = () => {
const { ndk, fetchEventFromUserRelays, publish } = useNDKContext()
const dispatch = useAppDispatch()
const user = useAppSelector((state) => state.user.user)
const { userWotLevel } = useAppSelector((state) => state.wot)
const [wotLevel, setWotLevel] = useState(userWotLevel)
const [isSaving, setIsSaving] = useState(false)
useEffect(() => {
if (user?.pubkey) {
const hexPubkey = user.pubkey as string
fetchEventFromUserRelays(
{
kinds: [NDKKind.AppSpecificData],
'#d': ['degmods'],
authors: [hexPubkey]
},
hexPubkey,
UserRelaysType.Both
).then((event) => {
if (event) {
const wot = event.tagValue('wot')
if (wot) setWotLevel(parseInt(wot))
}
})
}
}, [user, fetchEventFromUserRelays])
const handleSave = async () => {
setIsSaving(true)
let hexPubkey: string
if (user?.pubkey) {
hexPubkey = user.pubkey as string
} else {
hexPubkey = (await window.nostr?.getPublicKey()) as string
}
if (!hexPubkey) {
toast.error('Could not get pubkey')
setIsSaving(false)
return
}
const unsignedEvent: UnsignedEvent = {
kind: kinds.Application,
created_at: now(),
pubkey: hexPubkey,
content: '',
tags: [
['d', 'degmods'],
['wot', wotLevel.toString()]
]
}
const signedEvent = await window.nostr
?.signEvent(unsignedEvent)
.then((event) => event as Event)
.catch((err) => {
toast.error('Failed to sign the event!')
log(true, LogType.Error, 'Failed to sign the event!', err)
return null
})
if (!signedEvent) {
setIsSaving(false)
return
}
const ndkEvent = new NDKEvent(ndk, signedEvent)
await publish(ndkEvent)
.then((publishedOnRelays) => {
toast.success(
`Preferences published to following relays: \n\n${publishedOnRelays.join(
'\n'
)}`
)
dispatch(setUserWotLevel(wotLevel))
// If wot admin, update site wot level too
const SITE_WOT_NPUB = import.meta.env.VITE_SITE_WOT_NPUB
const siteWotPubkey = npubToHex(SITE_WOT_NPUB)
if (siteWotPubkey === hexPubkey) {
dispatch(setSiteWotLevel(wotLevel))
}
})
.catch((err) => {
console.error(err)
toast.error('Error: Failed to publish preferences!')
})
.finally(() => {
setIsSaving(false)
})
}
return (
<>
{isSaving &&
Notifications
Not Safe For Work (NSFW)
Web of Trust (WoT) level
This affects what posts you see, reactions, DMs, and notifications. Learn more: Link
{wotLevel}