Skip to main content

useSteppedAway

Location: src/hooks/useSteppedAway.js

Overview

Manages "stepped away" conversation detection. When a user leaves an open conversation for more than 5 minutes (the threshold), this hook fetches those conversations and provides actions to resume, dismiss, or clear the stepped-away status. This supports the platform's principle that absence is first-class and should be handled gracefully rather than creating urgency.

The hook queries conversation_participants for rows where stepped_away_at is set, step_away_prompted is false, and the conversation state is open. It then filters client-side to only include conversations where the user has been away longer than the 5-minute threshold.

Signature

function useSteppedAway(): {
steppedAwayConversations: Conversation[],
loading: boolean,
markSteppedAway: (conversationId: string) => Promise<void>,
clearSteppedAway: (conversationId: string) => Promise<void>,
dismissPrompt: (conversationId: string) => Promise<void>,
dismissAllPrompts: () => Promise<void>,
refetch: () => Promise<void>
}

Parameters

None. Automatically resolves the current authenticated user.

Return Value

PropertyTypeDescription
steppedAwayConversationsConversation[]Array of open conversations where the user has been away for more than 5 minutes and has not yet been prompted. Each item includes conversation details, participant profiles, and mySettings.stepped_away_at.
loadingbooleantrue while the initial fetch is in progress.
markSteppedAway(conversationId: string) => Promise<void>Record that the user has stepped away from a conversation. Sets stepped_away_at to now and resets step_away_prompted to false.
clearSteppedAway(conversationId: string) => Promise<void>Clear the stepped-away status (user has returned or taken action). Sets stepped_away_at to null. Removes the conversation from the local list.
dismissPrompt(conversationId: string) => Promise<void>Dismiss the stepped-away prompt without clearing the status. Sets step_away_prompted to true so the prompt does not reappear. Removes from local list.
dismissAllPrompts() => Promise<void>Dismiss all pending stepped-away prompts at once.
refetch() => Promise<void>Re-fetch the stepped-away conversations list.

Usage

function SteppedAwayBanner() {
const { steppedAwayConversations, loading, clearSteppedAway, dismissPrompt } = useSteppedAway();

if (loading || steppedAwayConversations.length === 0) return null;

return (
<div className="stepped-away-banner">
<p>You stepped away from {steppedAwayConversations.length} conversation(s).</p>
{steppedAwayConversations.map(conv => (
<div key={conv.id}>
<span>{conv.name || 'Conversation'}</span>
<button onClick={() => clearSteppedAway(conv.id)}>Return</button>
<button onClick={() => dismissPrompt(conv.id)}>Dismiss</button>
</div>
))}
</div>
);
}

Last updated: 2026-02-07