From 6aa15c04c4973ad355525fb7e9651001ae0e367a Mon Sep 17 00:00:00 2001 From: highperfocused Date: Wed, 7 May 2025 17:08:58 +0200 Subject: [PATCH] fix: streamline follow state management and preserve tag structure --- components/FollowButton.tsx | 63 +++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/components/FollowButton.tsx b/components/FollowButton.tsx index 2fc8c05..aaa3fa3 100644 --- a/components/FollowButton.tsx +++ b/components/FollowButton.tsx @@ -34,24 +34,18 @@ const FollowButton: React.FC = ({ pubkey, userPubkey }) => { return [...events].sort((a, b) => (b.created_at || 0) - (a.created_at || 0))[0] }, [events]) - // Extract the list of pubkeys the user is following - const followingPubkeys = useMemo(() => { - if (!latestFollowList) return [] - return latestFollowList.tags - .filter(tag => tag[0] === "p") - .map(tag => tag[1]) - }, [latestFollowList]) - - // Determine if the user is following the profile + // Check if the user is following the profile useEffect(() => { - if (!isPending) { - const following = followingPubkeys.includes(pubkey) + if (!isPending && latestFollowList) { + const following = latestFollowList.tags + .filter(tag => tag[0] === "p") + .some(tag => tag[1] === pubkey) setIsFollowing(following) } - }, [followingPubkeys, pubkey, isPending]) + }, [latestFollowList, pubkey, isPending]) const handleFollow = useCallback(async () => { - if (!userPubkey || isPending || isLoading) return + if (!userPubkey || isPending || isLoading || !latestFollowList) return setIsPending(true) // Optimistically update UI @@ -59,34 +53,35 @@ const FollowButton: React.FC = ({ pubkey, userPubkey }) => { setIsFollowing(newFollowingState) try { - // Create a new follow list based on current follows - let newFollowList = [...followingPubkeys] + // Create a new tags array that maintains the original structure + let newTags = [...latestFollowList.tags] if (newFollowingState) { // Add to follow list if not already there - if (!newFollowList.includes(pubkey)) { - newFollowList.push(pubkey) + if (!newTags.some(tag => tag[0] === "p" && tag[1] === pubkey)) { + // // Find the last 'p' tag to preserve ordering + // const lastPTagIndex = [...newTags].reverse().findIndex(tag => tag[0] === "p") + + // if (lastPTagIndex >= 0) { + // // Insert after the last 'p' tag (accounting for reverse indexing) + // const insertPosition = newTags.length - lastPTagIndex + // newTags.splice(insertPosition, 0, ["p", pubkey]) + // } else { + // No existing 'p' tags, add to the end + newTags.push(["p", pubkey]) + // } } } else { - // Remove from follow list - newFollowList = newFollowList.filter(pk => pk !== pubkey) + // Remove from follow list while preserving order + newTags = newTags.filter(tag => !(tag[0] === "p" && tag[1] === pubkey)) } - // Get all non-'p' tags from the original event to preserve them - const nonPTags = latestFollowList - ? latestFollowList.tags.filter(tag => tag[0] !== "p") - : [] - - // Convert to properly formatted p tags and combine with non-p tags - const pTags = newFollowList.map(pk => ["p", pk]) - const allTags = [...nonPTags, ...pTags] - - // Create the follow list event (NIP-02) + // Create the follow list event (NIP-02) with preserved tag structure const followEvent: NostrEvent = { kind: 3, created_at: Math.floor(Date.now() / 1000), - tags: allTags, - content: "", + tags: newTags, + content: latestFollowList.content || "", // Preserve original content pubkey: "", // Placeholder, will be set by signEvent id: "", // Placeholder, will be set by signEvent sig: "", // Placeholder, will be set by signEvent @@ -97,7 +92,7 @@ const FollowButton: React.FC = ({ pubkey, userPubkey }) => { if (signedEvent) { publish(signedEvent) - // Don't need to update local state since the useEffect will catch the new event + // The useEffect will catch the new event } else { // Revert the optimistic update if signing fails setIsFollowing(!newFollowingState) @@ -114,7 +109,7 @@ const FollowButton: React.FC = ({ pubkey, userPubkey }) => { setIsPending(false) }, 1500) } - }, [userPubkey, isPending, isLoading, isFollowing, followingPubkeys, pubkey, loginType, publish]) + }, [userPubkey, isPending, isLoading, isFollowing, latestFollowList, pubkey, loginType, publish]) // Determine the button text based on current state const buttonText = useMemo(() => { @@ -127,7 +122,7 @@ const FollowButton: React.FC = ({ pubkey, userPubkey }) => {