feat: chat — ⋮ room menu, typing indicator, online presence, read receipts
- RoomRow: ⋮ button (hover) for pin/unpin context menu - MessageBubble: right-click context menu with emoji reactions + edit/delete - Typing indicator: debounced setTyping, animated TypingDots, polling getTyping every 2s - Online presence: heartbeat setPresence every 30s, green dot on avatars/header - Read receipts: ✓/✓✓ for own messages in direct rooms via otherUserLastRead - Migration 075: chat_presence + chat_typing tables - Context menus clamped to viewport bounds Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
17
backend/migrations/075_chat_presence.sql
Normal file
17
backend/migrations/075_chat_presence.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
-- Online presence
|
||||
CREATE TABLE IF NOT EXISTS chat_presence (
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
hotel_id UUID NOT NULL REFERENCES hotels(id) ON DELETE CASCADE,
|
||||
last_seen TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (user_id, hotel_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_chat_presence_hotel ON chat_presence(hotel_id, last_seen);
|
||||
|
||||
-- Typing indicator (expires after 5s — queried with WHERE typing_at > NOW() - interval '5s')
|
||||
CREATE TABLE IF NOT EXISTS chat_typing (
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
room_id UUID NOT NULL REFERENCES chat_rooms(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
typing_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (user_id, room_id)
|
||||
);
|
||||
Reference in New Issue
Block a user