import { ZapPopUp } from 'components/Zap' import { MetadataController, RelayController, UserRelaysType } from 'controllers' import { formatDate } from 'date-fns' import { useAppSelector, useDidMount, useReactions } from 'hooks' import { Event, kinds, nip19, Filter as NostrEventFilter, UnsignedEvent } from 'nostr-tools' import React, { useMemo } from 'react' import { Dispatch, SetStateAction, useState } from 'react' import { useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' import { getProfilePageRoute } from 'routes' import { ModDetails, UserProfile } from 'types' import { abbreviateNumber, hexToNpub, log, LogType, now } from 'utils' enum SortByEnum { Latest = 'Latest', Oldest = 'Oldest' } enum AuthorFilterEnum { All_Comments = 'All Comments', Creator_Comments = 'Creator Comments' } type FilterOptions = { sort: SortByEnum author: AuthorFilterEnum } type Props = { modDetails: ModDetails setCommentCount: Dispatch> } export const Comments = ({ modDetails, setCommentCount }: Props) => { const [commentEvents, setCommentEvents] = useState([]) const [filterOptions, setFilterOptions] = useState({ sort: SortByEnum.Latest, author: AuthorFilterEnum.All_Comments }) const userState = useAppSelector((state) => state.user) useDidMount(async () => { const metadataController = await MetadataController.getInstance() const authorReadRelays = await metadataController.findUserRelays( modDetails.author, UserRelaysType.Read ) const filter: NostrEventFilter = { kinds: [kinds.ShortTextNote], '#a': [modDetails.aTag] } RelayController.getInstance().subscribeForEvents( filter, authorReadRelays, (event) => { setCommentEvents((prev) => { if (prev.find((e) => e.id === event.id)) { return [...prev] } return [event, ...prev] }) } ) }) const handleSubmit = async (content: string): Promise => { if (content === '') return false let pubkey: string if (userState.auth && userState.user?.pubkey) { pubkey = userState.user.pubkey as string } else { pubkey = (await window.nostr?.getPublicKey()) as string } if (!pubkey) { toast.error('Could not get user pubkey') return false } const unsignedEvent: UnsignedEvent = { content: content, pubkey: pubkey, kind: kinds.ShortTextNote, created_at: now(), tags: [ ['e', modDetails.id], ['a', modDetails.aTag] ] } 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) return false setCommentEvents((prev) => [signedEvent, ...prev]) const publish = async () => { const metadataController = await MetadataController.getInstance() const modAuthorReadRelays = await metadataController.findUserRelays( modDetails.author, UserRelaysType.Read ) const commentatorWriteRelays = await metadataController.findUserRelays( pubkey, UserRelaysType.Write ) const combinedRelays = [ ...new Set(...modAuthorReadRelays, ...commentatorWriteRelays) ] RelayController.getInstance().publishOnRelays(signedEvent, combinedRelays) } publish() return true } setCommentCount(commentEvents.length) const comments = useMemo(() => { let filteredComments = commentEvents if (filterOptions.author === AuthorFilterEnum.Creator_Comments) { filteredComments = filteredComments.filter( (comment) => comment.pubkey === modDetails.author ) } if (filterOptions.sort === SortByEnum.Latest) { filteredComments.sort((a, b) => b.created_at - a.created_at) } else if (filterOptions.sort === SortByEnum.Oldest) { filteredComments.sort((a, b) => a.created_at - b.created_at) } return filteredComments }, [commentEvents, filterOptions, modDetails.author]) return (

Comments

{comments.map((event) => ( ))}
) } type CommentFormProps = { handleSubmit: (content: string) => Promise } const CommentForm = ({ handleSubmit }: CommentFormProps) => { const [isSubmitting, setIsSubmitting] = useState(false) const [commentText, setCommentText] = useState('') const handleComment = async () => { setIsSubmitting(true) const submitted = await handleSubmit(commentText) if (submitted) setCommentText('') setIsSubmitting(false) } return (