feat: Add Chat UX improvements with notifications and @mention support
- Add ActionBar component with expandable toolbar for mobile - Add @mention functionality with autocomplete dropdown - Add browser notification system (push, sound, vibration) - Add NotificationSettings modal for user preferences - Add mention badges on room list cards - Add ReportPreview with Markdown rendering and copy/download - Add message copy functionality with hover actions - Add backend mentions field to messages with Alembic migration - Add lots field to rooms, remove templates - Optimize WebSocket database session handling - Various UX polish (animations, accessibility) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
58
frontend/src/stores/mentionStore.ts
Normal file
58
frontend/src/stores/mentionStore.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Store for tracking unread @mentions across rooms
|
||||
* Uses localStorage for persistence
|
||||
*/
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
interface MentionState {
|
||||
// Map of roomId -> unread mention count
|
||||
unreadMentions: Record<string, number>
|
||||
|
||||
// Add a mention for a room
|
||||
addMention: (roomId: string) => void
|
||||
|
||||
// Clear mentions for a room (when user views the room)
|
||||
clearMentions: (roomId: string) => void
|
||||
|
||||
// Get mention count for a room
|
||||
getMentionCount: (roomId: string) => number
|
||||
|
||||
// Get total unread mentions across all rooms
|
||||
getTotalMentions: () => number
|
||||
}
|
||||
|
||||
export const useMentionStore = create<MentionState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
unreadMentions: {},
|
||||
|
||||
addMention: (roomId: string) => {
|
||||
set((state) => ({
|
||||
unreadMentions: {
|
||||
...state.unreadMentions,
|
||||
[roomId]: (state.unreadMentions[roomId] || 0) + 1,
|
||||
},
|
||||
}))
|
||||
},
|
||||
|
||||
clearMentions: (roomId: string) => {
|
||||
set((state) => {
|
||||
const { [roomId]: _, ...rest } = state.unreadMentions
|
||||
return { unreadMentions: rest }
|
||||
})
|
||||
},
|
||||
|
||||
getMentionCount: (roomId: string) => {
|
||||
return get().unreadMentions[roomId] || 0
|
||||
},
|
||||
|
||||
getTotalMentions: () => {
|
||||
return Object.values(get().unreadMentions).reduce((sum, count) => sum + count, 0)
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'task_reporter_mentions',
|
||||
}
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user