Skip to main content

useFriends

Location: src/hooks/useFriends.js

Overview

This file exports four hooks that build on each other for working with the current user's friends list:

  • useFriends -- fetches all accepted friends
  • useFriendsWithSearch -- adds client-side search filtering
  • useFriendsExcluding -- filters out specific user IDs (for invite flows)
  • useFriendSelection -- manages selection state for friend picker UIs

Used across the app: messaging, circle invites, sharing, post audience selection, etc.


useFriends

Signature

function useFriends(): {
friends: FriendProfile[],
loading: boolean,
error: string | null,
refetch: () => Promise<void>
}

Parameters

None. Automatically resolves the current authenticated user.

Return Value

PropertyTypeDescription
friendsFriendProfile[]Array of friend profiles. Each item includes id, display_name, username, avatar_url, bio, friendshipId, and friendsSince. The "friend" is the other person in the friendship (not the current user).
loadingbooleantrue while the fetch is in progress.
errorstring | nullError message if the fetch failed.
refetch() => Promise<void>Re-fetch the friends list.

useFriendsWithSearch

Signature

function useFriendsWithSearch(): {
friends: FriendProfile[],
allFriends: FriendProfile[],
loading: boolean,
error: string | null,
searchQuery: string,
setSearchQuery: (query: string) => void,
clearSearch: () => void,
hasResults: boolean,
totalCount: number,
refetch: () => Promise<void>
}

Parameters

None. Internally uses useFriends.

Return Value

PropertyTypeDescription
friendsFriendProfile[]Filtered friends matching the search query. Returns all friends when the query is empty.
allFriendsFriendProfile[]The unfiltered friends list.
loadingbooleantrue while the fetch is in progress.
errorstring | nullError message if the fetch failed.
searchQuerystringThe current search query string.
setSearchQuery(query: string) => voidSet the search query. Filters by display_name and username (case-insensitive).
clearSearch() => voidClear the search query.
hasResultsbooleantrue if the filtered list has at least one result.
totalCountnumberTotal number of friends (before filtering).
refetch() => Promise<void>Re-fetch the friends list.

useFriendsExcluding

Signature

function useFriendsExcluding(
excludeIds?: string[]
): {
friends: FriendProfile[],
allFriends: FriendProfile[],
loading: boolean,
error: string | null,
searchQuery: string,
setSearchQuery: (query: string) => void,
clearSearch: () => void,
hasResults: boolean,
totalCount: number,
refetch: () => Promise<void>
}

Parameters

ParameterTypeRequiredDescription
excludeIdsstring[]NoArray of user IDs to exclude from results. Defaults to empty array.

Return Value

Same as useFriendsWithSearch, but friends and allFriends exclude the specified user IDs. Useful for "invite more friends" flows where some friends are already members.


useFriendSelection

Signature

function useFriendSelection(options?: {
multiSelect?: boolean,
maxSelections?: number | null,
initialSelection?: string[]
}): {
selectedIds: string[],
setSelectedIds: (ids: string[]) => void,
toggleSelection: (friendId: string) => void,
selectAll: (friendIds: string[]) => void,
clearSelection: () => void,
isSelected: (friendId: string) => boolean,
canSelectMore: boolean,
selectionCount: number
}

Parameters

All parameters are optional:

ParameterTypeDefaultDescription
multiSelectbooleanfalseWhether multiple friends can be selected.
maxSelectionsnumber | nullnullMaximum number of selections (only applies when multiSelect is true). null means unlimited.
initialSelectionstring[][]Array of initially selected friend IDs.

Return Value

PropertyTypeDescription
selectedIdsstring[]Array of currently selected friend IDs.
setSelectedIds(ids: string[]) => voidDirectly set the selection array.
toggleSelection(friendId: string) => voidToggle a friend's selection. In single-select mode, selecting a new friend deselects the previous one. In multi-select, respects maxSelections.
selectAll(friendIds: string[]) => voidSelect all provided IDs (multi-select only). Respects maxSelections.
clearSelection() => voidClear all selections.
isSelected(friendId: string) => booleanCheck if a specific friend is selected.
canSelectMorebooleantrue if more selections are allowed (respects maxSelections).
selectionCountnumberNumber of currently selected friends.

Usage

function FriendPicker({ onConfirm }) {
const { friends, loading, searchQuery, setSearchQuery } = useFriendsWithSearch();
const { selectedIds, toggleSelection, isSelected, clearSelection } = useFriendSelection({
multiSelect: true,
maxSelections: 5
});

if (loading) return <Skeleton />;

return (
<div>
<input
placeholder="Search friends..."
value={searchQuery}
onChange={e => setSearchQuery(e.target.value)}
/>
{friends.map(friend => (
<div
key={friend.id}
className={isSelected(friend.id) ? 'selected' : ''}
onClick={() => toggleSelection(friend.id)}
>
{friend.display_name}
</div>
))}
<button onClick={() => onConfirm(selectedIds)}>Confirm</button>
<button onClick={clearSelection}>Clear</button>
</div>
);
}

Last updated: 2026-02-07