feat(phase7): per-channel notification settings and read receipts
Phase 7.1 — Per-channel notification settings
- New notification_settings table (user_id, channel_id, level)
- GET/PUT/DELETE handlers under /channels/{channelID}/notifications
- Push dispatch and @mention loops filtered by notification level
- Frontend: bell icon per channel cycling all/mentions/none
Phase 7.4 — Read receipts
- New read_states table (user_id, channel_id, last_read_message_id)
- PUT /channels/{channelID}/read and GET /users/me/read-states
- Auto-mark-read when messages load in ChatArea
- Unread dot for channels never opened
Also: favicon/icon refresh in index.html
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { create } from 'zustand';
|
||||
import { api } from '../lib/api';
|
||||
|
||||
type NotificationLevel = 'all' | 'mentions' | 'none';
|
||||
|
||||
interface NotificationSettingsState {
|
||||
settings: Record<string, NotificationLevel>;
|
||||
initialized: boolean;
|
||||
loaded: boolean;
|
||||
fetchSettings: () => Promise<void>;
|
||||
setLevel: (channelId: string, level: NotificationLevel) => Promise<void>;
|
||||
}
|
||||
|
||||
export const useNotificationSettingsStore = create<NotificationSettingsState>()((set) => ({
|
||||
settings: {},
|
||||
initialized: false,
|
||||
loaded: false,
|
||||
|
||||
fetchSettings: async () => {
|
||||
try {
|
||||
const settings = await api.get<Record<string, NotificationLevel>>('/channels/me/notifications');
|
||||
set({ settings, loaded: true, initialized: true });
|
||||
} catch {
|
||||
set({ loaded: true, initialized: true });
|
||||
}
|
||||
},
|
||||
|
||||
setLevel: async (channelId: string, level: NotificationLevel) => {
|
||||
await api.put(`/channels/${channelId}/notifications`, { level });
|
||||
set((state) => ({
|
||||
settings: { ...state.settings, [channelId]: level },
|
||||
}));
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user