diff --git a/src/components/PostEditor/Mentions.tsx b/src/components/PostEditor/Mentions.tsx index 7382d03b..e8b9af34 100644 --- a/src/components/PostEditor/Mentions.tsx +++ b/src/components/PostEditor/Mentions.tsx @@ -1,57 +1,138 @@ import { Button } from '@/components/ui/button' -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' import { extractMentions } from '@/lib/event' import { useNostr } from '@/providers/NostrProvider' import { Event } from 'nostr-tools' import { useEffect, useState } from 'react' -import UserAvatar from '../UserAvatar' -import Username from '../Username' import { useTranslation } from 'react-i18next' +import { SimpleUserAvatar } from '../UserAvatar' +import { SimpleUsername } from '../Username' export default function Mentions({ content, + mentions, + setMentions, parentEvent }: { content: string + mentions: string[] + setMentions: (mentions: string[]) => void parentEvent?: Event }) { const { t } = useTranslation() const { pubkey } = useNostr() const [pubkeys, setPubkeys] = useState([]) + const [relatedPubkeys, setRelatedPubkeys] = useState([]) + const [parentEventPubkey, setParentEventPubkey] = useState() + const [addedPubkeys, setAddedPubkeys] = useState([]) + const [removedPubkeys, setRemovedPubkeys] = useState([]) useEffect(() => { - extractMentions(content, parentEvent).then(({ pubkeys }) => + extractMentions(content, parentEvent).then(({ pubkeys, relatedPubkeys, parentEventPubkey }) => { setPubkeys(pubkeys.filter((p) => p !== pubkey)) - ) + setRelatedPubkeys(relatedPubkeys.filter((p) => p !== pubkey)) + setParentEventPubkey(parentEventPubkey !== pubkey ? parentEventPubkey : undefined) + const potentialMentions = [...pubkeys, ...relatedPubkeys] + setAddedPubkeys((pubkeys) => { + return pubkeys.filter((p) => potentialMentions.includes(p)) + }) + setRemovedPubkeys((pubkeys) => { + return pubkeys.filter((p) => potentialMentions.includes(p)) + }) + }) }, [content, parentEvent, pubkey]) + useEffect(() => { + const newMentions = [...pubkeys] + addedPubkeys.forEach((pubkey) => { + if (!newMentions.includes(pubkey) && pubkey !== parentEventPubkey) { + newMentions.push(pubkey) + } + }) + removedPubkeys.forEach((pubkey) => { + const index = newMentions.indexOf(pubkey) + if (index !== -1) { + newMentions.splice(index, 1) + } + }) + if (parentEventPubkey) { + newMentions.push(parentEventPubkey) + } + setMentions(newMentions) + }, [pubkeys, relatedPubkeys, parentEventPubkey, addedPubkeys, removedPubkeys]) + return ( - - + + - - + +
-
{t('Mentions')}:
- {pubkeys.map((pubkey, index) => ( -
- - {t('Mentions')}: + {parentEventPubkey && ( + + + + + )} + {(pubkeys.length > 0 || relatedPubkeys.length > 0) && } + {pubkeys.concat(relatedPubkeys).map((pubkey, index) => ( + { + if (checked) { + setAddedPubkeys((pubkeys) => [...pubkeys, pubkey]) + setRemovedPubkeys((pubkeys) => pubkeys.filter((p) => p !== pubkey)) + } else { + setRemovedPubkeys((pubkeys) => [...pubkeys, pubkey]) + setAddedPubkeys((pubkeys) => pubkeys.filter((p) => p !== pubkey)) + } + }} + > + + -
+ ))} + {(relatedPubkeys.length > 0 || pubkeys.length > 0) && ( + <> + + { + setAddedPubkeys([...relatedPubkeys]) + setRemovedPubkeys([]) + }} + > + {t('Select all')} + + + )}
-
-
+ + ) } diff --git a/src/components/PostEditor/NormalPostContent.tsx b/src/components/PostEditor/NormalPostContent.tsx index 793e96dd..0f2faae0 100644 --- a/src/components/PostEditor/NormalPostContent.tsx +++ b/src/components/PostEditor/NormalPostContent.tsx @@ -34,6 +34,7 @@ export default function NormalPostContent({ const [addClientTag, setAddClientTag] = useState(false) const [specifiedRelayUrls, setSpecifiedRelayUrls] = useState(undefined) const [uploadingPicture, setUploadingPicture] = useState(false) + const [mentions, setMentions] = useState([]) const canPost = !!content && !posting const post = async (e: React.MouseEvent) => { @@ -79,11 +80,11 @@ export default function NormalPostContent({ } const draftEvent = parentEvent && parentEvent.kind !== kinds.ShortTextNote - ? await createCommentDraftEvent(content, parentEvent, pictureInfos, { + ? await createCommentDraftEvent(content, parentEvent, pictureInfos, mentions, { addClientTag, protectedEvent: !!specifiedRelayUrls }) - : await createShortTextNoteDraftEvent(content, pictureInfos, { + : await createShortTextNoteDraftEvent(content, pictureInfos, mentions, { parentEvent, addClientTag, protectedEvent: !!specifiedRelayUrls @@ -162,7 +163,12 @@ export default function NormalPostContent({
- +
- +