import { InputField } from 'components/Inputs' import { ProfileQRButtonWithPopUp } from 'components/ProfileSection' import { useAppDispatch, useAppSelector } from 'hooks' import { kinds, nip19, UnsignedEvent, Event } from 'nostr-tools' import { useEffect, useState } from 'react' import { Link } from 'react-router-dom' import { toast } from 'react-toastify' import { appRoutes, getProfilePageRoute } from 'routes' import { copyTextToClipboard, log, LogType, now, npubToHex } from 'utils' import 'styles/profile.css' import { NDKEvent, NDKUserProfile, profileFromEvent, serializeProfile } from '@nostr-dev-kit/ndk' import { RelayController } from 'controllers' import { LoadingSpinner } from 'components/LoadingSpinner' import { setUser } from 'store/reducers/user' type FormState = { name: string displayName: string bio: string picture: string banner: string nip05: string lud16: string } const defaultFormState: FormState = { name: '', displayName: '', bio: '', picture: '', banner: '', nip05: '', lud16: '' } export const ProfileSettings = () => { const dispatch = useAppDispatch() const userState = useAppSelector((state) => state.user) const [isPublishing, setIsPublishing] = useState(false) const [formState, setFormState] = useState(defaultFormState) useEffect(() => { if (userState.auth && userState.user) { const { name, displayName, about, bio, image, picture, banner, nip05, lud16 } = userState.user setFormState({ name: name || '', displayName: displayName || '', bio: bio || about || '', picture: typeof picture === 'string' ? picture : image || '', banner: banner || '', nip05: nip05 || '', lud16: lud16 || '' }) } else { setFormState(defaultFormState) } }, [userState]) const handleInputChange = (field: string, value: string) => { setFormState((prev) => ({ ...prev, [field]: value })) } const banner = formState.banner || '/assets/img/DEGMods%20Placeholder%20Img.png' const picture = formState.picture || '/assets/img/DEG%20Mods%20Default%20PP.png' const name = formState.displayName || formState.name || 'User name' const nip05 = formState.nip05 || 'nip5handle@domain.com' const npub = (userState.user?.npub as string) || 'npub1address' const bio = formState.bio || 'user bio, this is a long string of temporary text that would be replaced with the user bio from their metadata address' // In case user is not logged in clicking on profile link will navigate to homepage let profileRoute = appRoutes.home if (userState.auth && userState.user) { const hexPubkey = npubToHex(userState.user.npub as string) if (hexPubkey) { profileRoute = getProfilePageRoute( nip19.nprofileEncode({ pubkey: hexPubkey }) ) } } const handleCopy = async () => { copyTextToClipboard(npub).then((isCopied) => { if (isCopied) { toast.success('Npub copied to clipboard!') } else { toast.error( 'Failed to copy, look into console for more details on error!' ) } }) } const handlePublish = async () => { if (!userState.auth && !userState.user?.pubkey) return setIsPublishing(true) const prevProfile = userState.user as NDKUserProfile const updatedProfile = { ...prevProfile, name: formState.name, displayName: formState.displayName, bio: formState.bio, picture: formState.picture, banner: formState.banner, nip05: formState.nip05, lud16: formState.lud16 } const serializedProfile = serializeProfile(updatedProfile) const unsignedEvent: UnsignedEvent = { kind: kinds.Metadata, tags: [], content: serializedProfile, created_at: now(), pubkey: userState.user?.pubkey as string } 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) { setIsPublishing(false) return } const publishedOnRelays = await RelayController.getInstance().publish( signedEvent as Event ) // Handle cases where publishing failed or succeeded if (publishedOnRelays.length === 0) { toast.error('Failed to publish event on any relay') } else { toast.success( `Event published successfully to the following relays\n\n${publishedOnRelays.join( '\n' )}` ) const ndkEvent = new NDKEvent(undefined, signedEvent) const userProfile = profileFromEvent(ndkEvent) dispatch(setUser(userProfile)) } setIsPublishing(false) } return ( <> {isPublishing && }

{name}

{nip05}

{npub}

{typeof userState.user?.pubkey === 'string' && ( )}

{bio}

) }