Real-time unread message counter and read receipt tracker for Convex with watermark-based read positions and React hooks.
npm install convex-unread-tracking**Full-featured read tracking for chat and messaging apps.**
Drop-in unread state management using a watermark system with explicit per-message overrides.
- Per-user, per-channel read positions
- Message accounting & subscription management
- Muted senders, channel archival & group ops
- Automatic cleanup via built-in crons
Includes React hooks with optimistic mark-as-read and localStorage offline support.
Use convex-unread-tracking to register messages with insertMessage() when sent, then call getUnreadCount() to get real-time unread counts per channel. The component tracks read positions using watermarks and provides automatic cleanup via crons.
The component provides markReadUpTo() for watermark-based read tracking and getLastRead() for scroll anchoring. It supports explicit range overrides with markReadRange() and single message unread marking with markOneUnread().
Use group operations like addToGroup() and subscribeAll() to manage team-wide channel subscriptions. The component supports muting senders with muteSender() and archiving entire channels with archive().
The useMarkAsRead and useOptimisticUnreadCount hooks provide immediate UI feedback when marking messages as read, with localStorage fallback for offline scenarios. Call markRead() optimistically, then confirmRead() after server sync.
The convex-unread-tracking component uses timestamps as watermarks to mark everything up to a specific time as read via markReadUpTo(). You can override this with explicit ranges using markReadRange() or mark individual messages unread with markOneUnread().
Yes, convex-unread-tracking provides getTotalUnreadCount() for aggregate counts across all user subscriptions and getSingleUnreads() for batch fetching per-channel counts. Both methods work with the subscription management system.
Use the group operations in convex-unread-tracking: addToGroup() to add users to a group, then subscribeAll() or unsubscribeAll() to manage entire team subscriptions to channels in bulk operations.
Yes, convex-unread-tracking includes a cleanup mutation designed for Convex cron jobs. Set up a daily cron to automatically garbage collect old tracking data and maintain database performance.
The convex-unread-tracking React hooks use localStorage to persist optimistic state when offline. Call markRead() for immediate UI updates, then confirmRead() once the server mutation succeeds to sync the optimistic state.