Skip to main content

useShareToCircle

Location: src/hooks/useShareToCircle.js

Overview

Manages the full workflow for sharing a post to a circle. Handles modal open/close state, circle selection, share notes (max 280 characters), validation (sharing allowed, one-hop limit, no self-sharing), and the actual share RPC call. Also integrates W.E.L. (Wisdom, Encouragement, Learning) cultural prompts that may appear after a successful share.

Signature

function useShareToCircle(): {
// State
isModalOpen: boolean,
selectedPost: Post | null,
selectedCircle: Circle | null,
shareNote: string,
isSharing: boolean,
error: string | null,
shareableCircles: Circle[],
loadingCircles: boolean,
// W.E.L.
welPrompt: object | null,
dismissWelPrompt: () => void,
// Actions
openShareModal: (post: Post) => void,
closeShareModal: () => void,
setCircle: (circle: Circle) => void,
setNote: (note: string) => void,
// Validation
canSharePost: (post: Post) => Promise<boolean>,
canSharePostSync: (post: Post, currentUserId: string) => boolean,
// Data fetching
getShareableCircles: (post: Post) => Promise<Circle[]>,
getShareCount: (postId: string) => Promise<number>,
hasUserSharedPost: (postId: string) => Promise<boolean>,
// Main action
shareToCircle: () => Promise<{ success: boolean, shareId?: string, error?: string }>,
// Constants
MAX_NOTE_LENGTH: number
}

Parameters

This hook takes no parameters. It manages its own internal state.

Return Value

PropertyTypeDescription
isModalOpenbooleanWhether the share modal is open
selectedPostPost | nullThe post being shared
selectedCircleCircle | nullThe target circle
shareNotestringOptional note to accompany the share (max 280 chars)
isSharingbooleanWhether the share is being submitted
errorstring | nullError message if sharing failed
shareableCirclesCircle[]Circles the user can share to (includes already-shared circles marked with alreadyShared: true)
loadingCirclesbooleanWhether circles are being loaded
welPromptobject | nullW.E.L. cultural prompt to display (10% chance after successful share)
dismissWelPrompt() => voidDismiss the W.E.L. prompt
openShareModal(post) => voidOpen the share modal for a specific post
closeShareModal() => voidClose the modal and reset all state
setCircle(circle) => voidSelect a target circle
setNote(note) => voidSet the share note (enforces max length)
canSharePost(post) => Promise<boolean>Async check if a post can be shared
canSharePostSync(post, userId) => booleanSynchronous shareability check for quick UI decisions
getShareableCircles(post) => Promise<Circle[]>Fetch circles available for sharing this post
getShareCount(postId) => Promise<number>Get the number of times a post has been shared
hasUserSharedPost(postId) => Promise<boolean>Check if the current user has already shared this post
shareToCircle() => Promise<Result>Execute the share using current selected post and circle
MAX_NOTE_LENGTHnumberMaximum share note length (280)

Usage

import { useShareToCircle } from '../hooks/useShareToCircle';

function PostActions({ post }) {
const {
openShareModal,
isModalOpen,
shareableCircles,
getShareableCircles,
setCircle,
shareToCircle,
closeShareModal,
canSharePostSync
} = useShareToCircle();

if (!canSharePostSync(post, currentUserId)) return null;

return (
<>
<button onClick={() => {
openShareModal(post);
getShareableCircles(post);
}}>
Share to Circle
</button>
{isModalOpen && (
<ShareModal
circles={shareableCircles}
onSelect={setCircle}
onShare={shareToCircle}
onClose={closeShareModal}
/>
)}
</>
);
}

Notes

  • Sharing rules: posts with sharing_allowed === false cannot be shared; re-shares (is_share === true) cannot be re-shared (one-hop limit); users cannot share their own posts.
  • The share is executed via the share_post_to_circle RPC function which performs full server-side validation.
  • Already-shared circles are included in shareableCircles but marked with alreadyShared: true for display purposes.

Last updated: 2026-02-07