UNPKG

bigblocks

Version:

Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React

161 lines (160 loc) 5.86 kB
// useLikePost Hook - Like/unlike posts with emoji reactions import { useMutation } from "@tanstack/react-query"; import { useBitcoinAuth } from "../../../hooks/useBitcoinAuth.js"; import { broadcastSocialTransaction } from "../../../lib/broadcast"; import { SocialActions } from "../../../lib/protocol.js"; export function useLikePost(options = {}) { const { app: _app = "bigblocks", onSuccess, onError } = options; const { user } = useBitcoinAuth(); const likeMutation = useMutation({ mutationFn: async ({ txid, emoji: _emoji = "❤" }) => { if (!user) { throw { code: "UNAUTHORIZED", message: "User must be authenticated to like posts", }; } if (!txid) { throw { code: "INVALID_CONTENT", message: "Transaction ID is required to like a post", }; } // Validate txid format (64 character hex string) if (!/^[a-fA-F0-9]{64}$/.test(txid)) { throw { code: "INVALID_CONTENT", message: "Invalid transaction ID format", }; } try { const signingKey = user.signingKey; if (!signingKey) { throw { code: "UNAUTHORIZED", message: "No signing key available", }; } // Build like transaction const signedTransaction = await SocialActions.like(txid, _emoji); // Broadcast to Bitcoin network const result = await broadcastSocialTransaction(signedTransaction); if (!result.success) { throw { code: "BROADCAST_FAILED", message: result.error || "Failed to broadcast like", }; } return { ...result, transaction: signedTransaction }; } catch (error) { if (error.code) { throw error; } throw { code: "TRANSACTION_FAILED", message: "Failed to create like transaction", details: error, }; } }, onSuccess: (data) => { onSuccess?.(data); }, onError: (error) => { console.error("Like post failed:", error); onError?.(error); }, }); return { mutate: likeMutation.mutate, mutateAsync: likeMutation.mutateAsync, isLoading: likeMutation.isPending, isError: likeMutation.isError, isSuccess: likeMutation.isSuccess, error: likeMutation.error, data: likeMutation.data, reset: likeMutation.reset, }; } // Unlike hook export function useUnlikePost(options = {}) { const { app: _app = "bigblocks", onSuccess, onError } = options; const { user } = useBitcoinAuth(); return useMutation({ mutationFn: async ({ txid, emoji: _emoji = "❤" }) => { if (!user) { throw { code: "UNAUTHORIZED", message: "User must be authenticated to unlike posts", }; } if (!txid) { throw { code: "INVALID_CONTENT", message: "Transaction ID is required to unlike a post", }; } if (!/^[a-fA-F0-9]{64}$/.test(txid)) { throw { code: "INVALID_CONTENT", message: "Invalid transaction ID format", }; } try { const signingKey = user.signingKey; if (!signingKey) { throw { code: "UNAUTHORIZED", message: "No signing key available", }; } // Build unlike transaction const signedTransaction = await SocialActions.unlike(txid); // Broadcast to Bitcoin network const result = await broadcastSocialTransaction(signedTransaction); if (!result.success) { throw { code: "BROADCAST_FAILED", message: result.error || "Failed to broadcast unlike", }; } return { ...result, transaction: signedTransaction }; } catch (error) { if (error.code) { throw error; } throw { code: "TRANSACTION_FAILED", message: "Failed to create unlike transaction", details: error, }; } }, onSuccess: (data) => { onSuccess?.(data); }, onError: (error) => { console.error("Unlike post failed:", error); onError?.(error); }, }); } // Combined hook for toggling likes export function useToggleLike(options = {}) { const likePost = useLikePost(options); const unlikePostMutation = useUnlikePost(options); return { like: likePost, unlike: unlikePostMutation, toggle: (txid, emoji, currentlyLiked) => { if (currentlyLiked) { return unlikePostMutation.mutate({ txid, emoji }); } return likePost.mutate({ txid, emoji }); }, isLoading: likePost.isLoading || unlikePostMutation.isPending, error: likePost.error || unlikePostMutation.error, }; }