fix vine reactions and kind 16 repost for addressable events
- VineHeartButton: add optimistic cache updates and query invalidation on reaction so the heart fills and count increments immediately without a page refresh - RepostMenu: include NIP-18 'a' tag (kind:pubkey:d-tag) when reposting addressable events (30000–39999) so kind 16 events are properly linked back to the original vine
This commit is contained in:
@@ -58,6 +58,11 @@ export function RepostMenu({ event, children }: RepostMenuProps) {
|
||||
// Kind 16 generic reposts require a 'k' tag with the original event's kind
|
||||
if (repostKind === 16) {
|
||||
tags.push(['k', String(event.kind)]);
|
||||
// Addressable events (30000–39999) should include an 'a' tag per NIP-18
|
||||
if (event.kind >= 30000 && event.kind < 40000) {
|
||||
const dTag = event.tags.find(([name]) => name === 'd')?.[1] ?? '';
|
||||
tags.push(['a', `${event.kind}:${event.pubkey}:${dTag}`]);
|
||||
}
|
||||
}
|
||||
|
||||
publishEvent(
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useSeoMeta } from '@unhead/react';
|
||||
import {
|
||||
@@ -24,7 +25,7 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import { useStreamKind } from '@/hooks/useStreamKind';
|
||||
import { useAuthor } from '@/hooks/useAuthor';
|
||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||
import { useEventStats } from '@/hooks/useTrending';
|
||||
import { useEventStats, type EventStats } from '@/hooks/useTrending';
|
||||
import { useAppContext } from '@/hooks/useAppContext';
|
||||
import { useBlossomFallback } from '@/hooks/useBlossomFallback';
|
||||
import { useLayoutOptions } from '@/contexts/LayoutContext';
|
||||
@@ -128,12 +129,42 @@ export function VineHeartButton({ event, label, noBackground }: { event: NostrEv
|
||||
const { user } = useCurrentUser();
|
||||
const userReaction = useUserReaction(event.id);
|
||||
const { mutate: publishEvent } = useNostrPublish();
|
||||
const queryClient = useQueryClient();
|
||||
const hasReacted = !!userReaction;
|
||||
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if (!user || hasReacted) return;
|
||||
publishEvent({ kind: 7, content: '+', tags: [['e', event.id], ['p', event.pubkey], ['k', String(event.kind)]] });
|
||||
|
||||
// Optimistically update stats cache
|
||||
const prevStats = queryClient.getQueryData<EventStats>(['event-stats', event.id]);
|
||||
if (prevStats) {
|
||||
queryClient.setQueryData<EventStats>(['event-stats', event.id], {
|
||||
...prevStats,
|
||||
reactions: prevStats.reactions + 1,
|
||||
});
|
||||
}
|
||||
// Optimistically mark user as having reacted
|
||||
queryClient.setQueryData(['user-reaction', event.id], { content: '👍' });
|
||||
|
||||
publishEvent(
|
||||
{ kind: 7, content: '+', tags: [['e', event.id], ['p', event.pubkey], ['k', String(event.kind)]] },
|
||||
{
|
||||
onSuccess: () => {
|
||||
setTimeout(() => {
|
||||
queryClient.invalidateQueries({ queryKey: ['event-stats', event.id] });
|
||||
queryClient.invalidateQueries({ queryKey: ['event-interactions', event.id] });
|
||||
}, 3000);
|
||||
},
|
||||
onError: () => {
|
||||
// Revert optimistic updates
|
||||
if (prevStats) {
|
||||
queryClient.setQueryData<EventStats>(['event-stats', event.id], prevStats);
|
||||
}
|
||||
queryClient.removeQueries({ queryKey: ['user-reaction', event.id] });
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user