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
| Property | Type | Description |
|---|---|---|
isModalOpen | boolean | Whether the share modal is open |
selectedPost | Post | null | The post being shared |
selectedCircle | Circle | null | The target circle |
shareNote | string | Optional note to accompany the share (max 280 chars) |
isSharing | boolean | Whether the share is being submitted |
error | string | null | Error message if sharing failed |
shareableCircles | Circle[] | Circles the user can share to (includes already-shared circles marked with alreadyShared: true) |
loadingCircles | boolean | Whether circles are being loaded |
welPrompt | object | null | W.E.L. cultural prompt to display (10% chance after successful share) |
dismissWelPrompt | () => void | Dismiss the W.E.L. prompt |
openShareModal | (post) => void | Open the share modal for a specific post |
closeShareModal | () => void | Close the modal and reset all state |
setCircle | (circle) => void | Select a target circle |
setNote | (note) => void | Set the share note (enforces max length) |
canSharePost | (post) => Promise<boolean> | Async check if a post can be shared |
canSharePostSync | (post, userId) => boolean | Synchronous 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_LENGTH | number | Maximum 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 === falsecannot 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_circleRPC function which performs full server-side validation. - Already-shared circles are included in
shareableCirclesbut marked withalreadyShared: truefor display purposes.
Last updated: 2026-02-07