65 lines
2.0 KiB
Markdown
65 lines
2.0 KiB
Markdown
---
|
|
id: task-7
|
|
title: Real-time presence cursors
|
|
status: Done
|
|
assignee: []
|
|
created_date: '2026-01-02 16:08'
|
|
updated_date: '2026-01-02 19:30'
|
|
labels:
|
|
- feature
|
|
- collaboration
|
|
- sync
|
|
dependencies: []
|
|
priority: medium
|
|
---
|
|
|
|
## Description
|
|
|
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
|
Show other users cursors and selections in real-time:
|
|
- Broadcast cursor position via WebSocket presence messages
|
|
- Display colored cursor with username label
|
|
- Show selection highlight when user has shape selected
|
|
- Fade out cursors after inactivity
|
|
- Different cursor colors per user
|
|
|
|
WebSocket already handles presence messages (see server/index.ts line 221-235), needs client-side rendering.
|
|
<!-- SECTION:DESCRIPTION:END -->
|
|
|
|
## Acceptance Criteria
|
|
<!-- AC:BEGIN -->
|
|
- [x] #1 Cursor position broadcasts on mousemove
|
|
- [x] #2 Other users cursors visible with name labels
|
|
- [x] #3 Selection state shared between users
|
|
- [x] #4 Cursors fade after 5s inactivity
|
|
<!-- AC:END -->
|
|
|
|
## Notes
|
|
|
|
### Implementation Complete
|
|
|
|
**PresenceManager class** (`lib/presence.ts`):
|
|
- Tracks remote users with cursor position, selection, username, color
|
|
- Renders SVG cursor pointer with username label
|
|
- 8 distinct colors assigned based on peer ID hash
|
|
- Selection highlight shows which shape each user has selected
|
|
- Auto-fade after 5 seconds of inactivity (opacity: 0.3)
|
|
- Auto-remove after 15 seconds of inactivity
|
|
- Helper function `generatePeerId()` creates unique peer IDs
|
|
|
|
**CommunitySync integration** (`lib/community-sync.ts`):
|
|
- Added `sendPresence()` method for broadcasting cursor/selection
|
|
- Presence messages relayed through server to all clients
|
|
|
|
**Canvas integration** (`website/canvas.html`):
|
|
- Mousemove handler sends throttled presence updates (50ms)
|
|
- Touch handler for mobile cursor position
|
|
- Presence event handler updates remote cursor display
|
|
- Username persisted in localStorage
|
|
|
|
**Technical details**:
|
|
- Cursor updates throttled to max 20/second
|
|
- Position relative to canvas, not window
|
|
- Peer IDs are 8-char UUIDs for uniqueness
|
|
- Selection highlight uses outline with peer color
|