diff --git a/src/components/ProfileReactionButton.tsx b/src/components/ProfileReactionButton.tsx deleted file mode 100644 index 5490b7d5..00000000 --- a/src/components/ProfileReactionButton.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { useState, useRef, useCallback } from 'react'; -import { SmilePlus } from 'lucide-react'; -import { useQueryClient } from '@tanstack/react-query'; - -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { QuickReactMenu } from '@/components/QuickReactMenu'; -import { Button } from '@/components/ui/button'; -import { useAppContext } from '@/hooks/useAppContext'; -import { useCurrentUser } from '@/hooks/useCurrentUser'; -import { useNostrPublish } from '@/hooks/useNostrPublish'; -import { useEmojiUsage } from '@/hooks/useEmojiUsage'; -import { useToast } from '@/hooks/useToast'; -import { impactLight } from '@/lib/haptics'; -import { invalidateEventStats } from '@/lib/invalidateEventStats'; -import type { NostrEvent } from '@nostrify/nostrify'; - -interface ProfileReactionButtonProps { - /** The kind 0 metadata event for the profile being reacted to. */ - profileEvent: NostrEvent; - /** Optional extra class names for the trigger button. */ - className?: string; -} - -/** - * Emoji reaction button for user profiles. - * Opens an emoji picker and publishes a kind 7 reaction targeting - * the user's kind 0 profile event with `a`, `e`, and `p` tags. - */ -export function ProfileReactionButton({ profileEvent, className }: ProfileReactionButtonProps) { - const { user } = useCurrentUser(); - const { mutate: publishEvent } = useNostrPublish(); - const { trackEmojiUsage } = useEmojiUsage(); - const { toast } = useToast(); - const queryClient = useQueryClient(); - const { config } = useAppContext(); - const statsPubkey = config.nip85StatsPubkey; - const [menuOpen, setMenuOpen] = useState(false); - const pickerExpandedRef = useRef(false); - const justClosedRef = useRef(false); - - const handleReact = useCallback((emoji: string, emojiTag?: string[]) => { - if (!user) return; - impactLight(); - - trackEmojiUsage(emoji); - - const tags: string[][] = [ - ['e', profileEvent.id], - ['p', profileEvent.pubkey], - ['a', `0:${profileEvent.pubkey}:`], - ['k', '0'], - ]; - if (emojiTag) tags.push(emojiTag); - - publishEvent( - { - kind: 7, - content: emoji, - created_at: Math.floor(Date.now() / 1000), - tags, - }, - { - onSuccess: () => { - toast({ title: 'Reaction sent!' }); - // Bump reaction count on the profile. Profile reactions target the - // kind 0 event by id, so useNip85EventStats refresh covers it. Also - // refresh the addressable `0::` key in case any consumer - // reads profile stats via useNip85AddrStats. - setTimeout(() => { - invalidateEventStats(queryClient, profileEvent, statsPubkey); - queryClient.invalidateQueries({ - queryKey: ['nip85-addr-stats', `0:${profileEvent.pubkey}:`, statsPubkey], - }); - queryClient.invalidateQueries({ - queryKey: ['nip85-addr-stats', `0:${profileEvent.pubkey}:`], - }); - }, 3000); - }, - }, - ); - }, [user, profileEvent, publishEvent, trackEmojiUsage, toast, queryClient, statsPubkey]); - - if (!user) return null; - - return ( - { - if (open && justClosedRef.current) return; - if (!open) pickerExpandedRef.current = false; - setMenuOpen(open); - }} - > - - - - e.stopPropagation()} - onOpenAutoFocus={(e) => e.preventDefault()} - > - { - pickerExpandedRef.current = expanded; - }} - onClose={() => { - pickerExpandedRef.current = false; - justClosedRef.current = true; - setMenuOpen(false); - setTimeout(() => { - justClosedRef.current = false; - }, 300); - }} - /> - - - ); -} diff --git a/src/components/profile/ProfileIdentityRail.tsx b/src/components/profile/ProfileIdentityRail.tsx index 7c7c76ef..29160231 100644 --- a/src/components/profile/ProfileIdentityRail.tsx +++ b/src/components/profile/ProfileIdentityRail.tsx @@ -28,7 +28,6 @@ import { EmojifiedText } from '@/components/CustomEmoji'; import { FollowToggleButton } from '@/components/FollowButton'; import { Nip05Badge } from '@/components/Nip05Badge'; import { PledgeCard } from '@/components/PledgeCard'; -import { ProfileReactionButton } from '@/components/ProfileReactionButton'; import { OrganizationsAllDialog } from '@/components/profile/OrganizationsAllDialog'; import { useCampaignModeration } from '@/hooks/useCampaignModeration'; import { useProfileOrganizations, type ProfileOrganization } from '@/hooks/useProfileOrganizations'; @@ -91,8 +90,6 @@ interface ProfileIdentityRailProps { onDonate: (campaign: ParsedCampaign) => void; /** Whether the viewer can take any action (logged in). Disables follow when null. */ canFollow: boolean; - /** Latest kind-0 event used by ProfileReactionButton; falls back to metadataEvent. */ - authorEvent: NostrEvent | undefined; } const RAIL_CAMPAIGN_LIMIT = 2; @@ -143,7 +140,6 @@ export function ProfileIdentityRail({ onTabChange, onDonate, canFollow, - authorEvent, }: ProfileIdentityRailProps) { if (isAuthorLoading) { return ( @@ -204,7 +200,6 @@ export function ProfileIdentityRail({ onFollowersOpen={onFollowersOpen} onFollowingOpen={onFollowingOpen} onTabChange={onTabChange} - authorEvent={authorEvent} /> void; onFollowingOpen: () => void; onTabChange: (tabId: string) => void; - authorEvent: NostrEvent | undefined; className?: string; /** * Suppress the internal action bar (Edit Profile / QR / more, or @@ -288,7 +282,6 @@ export function ProfileIdentityHeader({ onFollowersOpen, onFollowingOpen, onTabChange, - authorEvent, className, hideActionBar = false, }: ProfileIdentityHeaderProps) { @@ -346,7 +339,6 @@ export function ProfileIdentityHeader({ onToggleFollow={onToggleFollow} onMoreMenuOpen={onMoreMenuOpen} onFollowQROpen={onFollowQROpen} - authorEvent={authorEvent} onchainCampaigns={onchainCampaigns} onDonate={onDonate} /> @@ -526,7 +518,6 @@ export function ActionBar({ onToggleFollow, onMoreMenuOpen, onFollowQROpen, - authorEvent, onchainCampaigns, onDonate, align = 'start', @@ -538,7 +529,6 @@ export function ActionBar({ onToggleFollow: () => void; onMoreMenuOpen: () => void; onFollowQROpen: () => void; - authorEvent: NostrEvent | undefined; onchainCampaigns: ParsedCampaign[]; onDonate: (campaign: ParsedCampaign) => void; /** @@ -622,7 +612,6 @@ export function ActionBar({ ) : null} - {authorEvent && }