Overview
Presence features include:- Online/offline status with automatic detection
- Custom status messages with emoji
- Status expiration for temporary states
- Active channel tracking
- Do Not Disturb mode
- Real-time typing indicators
- Last seen timestamps
Real-Time Status
See who’s online and active in real-time across all channels
Typing Indicators
Know when someone is composing a reply in your channel
Custom Status
Set custom status messages with emoji and expiration
Heartbeat Detection
Reliable offline detection with automatic heartbeat monitoring
User Presence Status
Status Types
Users can have one of several status states:| Status | Indicator | Meaning |
|---|---|---|
| Online | 🟢 Green dot | User is actively using the app |
| Away | 🟡 Yellow dot | User is idle or away from keyboard |
| Do Not Disturb | 🔴 Red dot with line | User doesn’t want to be interrupted |
| Offline | ⚪ Gray dot | User is not connected |
Setting Your Status
Change your presence status:- Click your avatar in the sidebar
- Select a status:
- Online - I’m available
- Away - I’m away from keyboard
- Do Not Disturb - I don’t want to be disturbed
- Optionally add a custom message and emoji
- Optionally set an expiration time
Your status is synced across all devices. Setting “Online” on desktop will show you as online on mobile too.
Custom Status Messages
Add context to your status:- Click your avatar
- Click Set Status
- Choose an emoji (optional)
- Enter a status message
- Set expiration (optional):
- 30 minutes
- 1 hour
- 4 hours
- Today
- This week
- Custom date/time
- Click Save
Status Expiration
Status automatically clears when:- The expiration time is reached
- You manually clear your status
- You set a new status
- Custom message is cleared
- Emoji is removed
- Presence returns to automatic (online/away/offline)
Clearing Your Status
- Click your avatar
- Click Clear Status
- Your custom message and emoji are removed
Automatic Status Detection
Online Detection
You’re marked as online when:- The app is open and focused
- You’ve interacted with the app recently (within 5 minutes)
- Heartbeat requests are succeeding
Away Detection
You’re marked as away when:- No interaction for 5 minutes
- App is open but not focused
- Computer is locked or sleeping
Offline Detection
You’re marked as offline when:- No heartbeat received for 2 minutes
- Network connection lost
- App is closed
The system uses a heartbeat mechanism to reliably detect offline status. Heartbeats are sent every 30 seconds when the app is active.
Heartbeat System
Hazel Chat uses a lightweight heartbeat for reliable presence: How it works:- Client sends heartbeat every 30 seconds while active
- Heartbeat updates
lastSeenAttimestamp - Server-side cron job runs every minute
- Users with
lastSeenAtolder than 2 minutes are marked offline
Active Channel Tracking
The system tracks which channel you’re currently viewing:- Updates when you navigate to a channel
- Clears when you navigate away
- Used to show “viewing this channel” indicators
- Helps determine message read status
Do Not Disturb Mode
Enabling DND
- Click your avatar
- Select Do Not Disturb
- Optionally set when it should end
- Status shows 🔴 red dot
- Notifications are suppressed (see Notifications)
- Desktop/push notifications disabled
- Still receive and can send messages
- Other users see your DND status
DND with Expiration
Set temporary DND:Suppress Notifications Flag
ThesuppressNotifications flag controls notification behavior:
suppressNotifications is true, all notifications are suppressed regardless of channel settings.
Typing Indicators
See when others are typing in real-time.How Typing Indicators Work
- You start typing in a channel
- Client sends typing indicator event
- Other channel members see “[Name] is typing…”
- Indicator disappears when:
- You stop typing for 3 seconds
- You send the message
- You leave the channel
Privacy
Typing indicators:- Only visible to members of the same channel
- Automatically expire after 10 seconds
- Can be disabled in user preferences (coming soon)
Multiple Typers
When multiple users are typing:Technical Implementation
Start typing:(channelId, memberId) - if one already exists for that combination, it’s updated instead of creating a duplicate.
Last Seen Timestamp
Track when users were last active:- Updated with every heartbeat
- Shown on user profiles
- Used for offline detection
- Persists across sessions
Presence in UI
User List
Channel member lists show:- Online members first (green dot)
- Away members next (yellow dot)
- Offline members last (gray dot)
- Custom status message below name
- Status emoji next to name
Direct Messages
DM channels show presence:- Avatar has status indicator (colored dot)
- Last seen time if offline
- Custom status in channel header
Mentions and Profiles
User mentions and profile cards display:- Current status (online/away/dnd/offline)
- Custom status message and emoji
- Last seen timestamp if offline
Technical Details
Presence Data Model
Typing Indicator Data Model
RPC Operations
Update Presence:Real-Time Sync
Presence data syncs via Electric SQL:- Instant updates to all connected clients
- Optimistic updates for instant UI feedback
- Automatic conflict resolution
- Offline support with sync on reconnect
Offline Detection Cron
Server-side cron job:Typing Indicator Cleanup
Typing indicators auto-expire:- Client-side: Stop showing after 10 seconds with no update
- Server-side: Delete indicators older than 1 minute
Performance Considerations
Heartbeat frequency:- 30 seconds for active users
- Paused when app is backgrounded
- Batched with other status updates
- Maximum 1 update per second per channel
- Debounced on client side
- Automatic cleanup prevents stale data
Permissions
View Presence:- Organization members can see each other’s presence
- Public presence data (online/offline only) for DMs
- Any authenticated user
- Channel members only