import { Button } from '@/components/ui/button' import { useToast } from '@/hooks/use-toast' import { createCommentDraftEvent, createShortTextNoteDraftEvent } from '@/lib/draft-event' import { useNostr } from '@/providers/NostrProvider' import postContentCache from '@/services/post-content-cache.service' import { ChevronDown, ImageUp, LoaderCircle } from 'lucide-react' import { Event, kinds } from 'nostr-tools' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import TextareaWithMentions from '../TextareaWithMentions' import Mentions from './Mentions' import PostOptions from './PostOptions' import Preview from './Preview' import SendOnlyToSwitch from './SendOnlyToSwitch' import Uploader from './Uploader' export default function NormalPostContent({ defaultContent = '', parentEvent, close }: { defaultContent?: string parentEvent?: Event close: () => void }) { const { t } = useTranslation() const { toast } = useToast() const { publish, checkLogin } = useNostr() const [content, setContent] = useState('') const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([]) const [posting, setPosting] = useState(false) const [showMoreOptions, setShowMoreOptions] = useState(false) const [addClientTag, setAddClientTag] = useState(false) const [specifiedRelayUrls, setSpecifiedRelayUrls] = useState(undefined) const [uploadingPicture, setUploadingPicture] = useState(false) const [mentions, setMentions] = useState([]) const [cursorOffset, setCursorOffset] = useState(0) const initializedRef = useRef(false) const canPost = !!content && !posting useEffect(() => { const cachedContent = postContentCache.getNormalPostCache({ defaultContent, parentEvent }) if (cachedContent) { setContent(cachedContent) } if (defaultContent) { setCursorOffset(defaultContent.length) } setTimeout(() => { initializedRef.current = true }, 100) }, [defaultContent, parentEvent]) useEffect(() => { if (!initializedRef.current) return postContentCache.setNormalPostCache({ defaultContent, parentEvent }, content) }, [content]) const post = async (e: React.MouseEvent) => { e.stopPropagation() checkLogin(async () => { if (!canPost) { close() return } setPosting(true) try { const draftEvent = parentEvent && parentEvent.kind !== kinds.ShortTextNote ? await createCommentDraftEvent(content, parentEvent, pictureInfos, mentions, { addClientTag, protectedEvent: !!specifiedRelayUrls }) : await createShortTextNoteDraftEvent(content, pictureInfos, mentions, { parentEvent, addClientTag, protectedEvent: !!specifiedRelayUrls }) await publish(draftEvent, { specifiedRelayUrls }) setContent('') close() } catch (error) { if (error instanceof AggregateError) { error.errors.forEach((e) => toast({ variant: 'destructive', title: t('Failed to post'), description: e.message }) ) } else if (error instanceof Error) { toast({ variant: 'destructive', title: t('Failed to post'), description: error.message }) } console.error(error) return } finally { setPosting(false) } toast({ title: t('Post successful'), description: t('Your post has been published') }) }) } return (
{content && }
{ setPictureInfos((prev) => [...prev, { url, tags }]) setContent((prev) => `${prev}\n${url}`) }} onUploadingChange={setUploadingPicture} accept="image/*,video/*,audio/*" >
) }