import { Button } from '@/components/ui/button' import { useToast } from '@/hooks/use-toast' import { createPictureNoteDraftEvent } from '@/lib/draft-event' import { cn } from '@/lib/utils' import { useFeed } from '@/providers/FeedProvider.tsx' import { useNostr } from '@/providers/NostrProvider' import relayInfoService from '@/services/relay-info.service' import { ChevronDown, Loader, LoaderCircle, Plus, X } from 'lucide-react' import { Dispatch, SetStateAction, useState } from 'react' import { useTranslation } from 'react-i18next' import Image from '../Image' import TextareaWithMentions from '../TextareaWithMentions.tsx' import Mentions from './Mentions' import PostOptions from './PostOptions.tsx' import SendOnlyToSwitch from './SendOnlyToSwitch.tsx' import { TPostOptions } from './types.ts' import Uploader from './Uploader' export default function PicturePostContent({ close }: { close: () => void }) { const { t } = useTranslation() const { toast } = useToast() const { publish, checkLogin } = useNostr() const { relayUrls } = useFeed() const [content, setContent] = useState('') const [pictureInfos, setPictureInfos] = useState<{ url: string; tags: string[][] }[]>([]) const [posting, setPosting] = useState(false) const [showMoreOptions, setShowMoreOptions] = useState(false) const [postOptions, setPostOptions] = useState({}) const canPost = !!content && !posting && pictureInfos.length > 0 const post = async (e: React.MouseEvent) => { e.stopPropagation() checkLogin(async () => { if (!canPost) { close() return } setPosting(true) try { if (!pictureInfos.length) { throw new Error(t('Picture note requires images')) } let protectedEvent = false if (postOptions.sendOnlyToCurrentRelays) { const relayInfos = await relayInfoService.getRelayInfos(relayUrls) protectedEvent = relayInfos.every((info) => info?.supported_nips?.includes(70)) } const draftEvent = await createPictureNoteDraftEvent(content, pictureInfos, { addClientTag: postOptions.addClientTag, protectedEvent }) await publish(draftEvent, { specifiedRelayUrls: postOptions.sendOnlyToCurrentRelays ? relayUrls : undefined }) 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 (
{t('A special note for picture-first clients like Olas')}
) } function PictureUploader({ pictureInfos, setPictureInfos }: { pictureInfos: { url: string; tags: string[][] }[] setPictureInfos: Dispatch< SetStateAction< { url: string tags: string[][] }[] > > }) { const [uploading, setUploading] = useState(false) return (
{pictureInfos.map(({ url }, index) => (
))} { setPictureInfos((prev) => [...prev, { url, tags }]) }} onUploadingChange={setUploading} >
{uploading ? : }
) }