feat: unread markers for channels and DMs
- Read states store: smarter hasUnread compares against latest message - ConversationList: orange dot + bold name for unread DMs - DMChat: auto-mark-read when viewing conversation - WS handler: mark DM read on new message while active+focused
This commit is contained in:
@@ -7,6 +7,7 @@ import { InviteModal } from './InviteModal.tsx';
|
||||
import { ChannelSettingsModal } from './ChannelSettingsModal.tsx';
|
||||
import { useNotificationSettingsStore } from '../stores/notificationSettings.ts';
|
||||
import { useReadStatesStore } from '../stores/readStates.ts';
|
||||
import { useMessageStore } from '../stores/message.ts';
|
||||
import { useContextMenu } from './ContextMenu.tsx';
|
||||
import { api } from '../lib/api.ts';
|
||||
|
||||
@@ -79,8 +80,9 @@ export function ChannelList() {
|
||||
const fetchNotifSettings = useNotificationSettingsStore((state) => state.fetchSettings);
|
||||
const setNotifLevel = useNotificationSettingsStore((state) => state.setLevel);
|
||||
|
||||
const readStates = useReadStatesStore((state) => state.states);
|
||||
const fetchReadStates = useReadStatesStore((state) => state.fetchStates);
|
||||
const hasUnread = useReadStatesStore((state) => state.hasUnread);
|
||||
const messagesByChannel = useMessageStore((state) => state.messagesByChannel);
|
||||
|
||||
const { showMenu, MenuPortal } = useContextMenu();
|
||||
|
||||
@@ -179,8 +181,9 @@ export function ChannelList() {
|
||||
return level === 'mentions' ? '🔔@' : '🔔';
|
||||
};
|
||||
|
||||
const hasUnread = (channelId: string): boolean => {
|
||||
return !(channelId in readStates);
|
||||
const getLatestMessageId = (channelId: string): string | undefined => {
|
||||
const msgs = messagesByChannel[channelId] || [];
|
||||
return msgs.length > 0 ? msgs[msgs.length - 1].id : undefined;
|
||||
};
|
||||
|
||||
// --- Channel context menu ---
|
||||
@@ -292,7 +295,7 @@ export function ChannelList() {
|
||||
{channel.type === 'forum' ? '■' : channel.type === 'calendar' ? '○' : channel.type === 'docs' ? '☰' : channel.type === 'list' ? '☑' : '#'}
|
||||
</span>
|
||||
<span className="truncate flex-1">{channel.name}</span>
|
||||
{hasUnread(channel.id) && (
|
||||
{hasUnread(channel.id, getLatestMessageId(channel.id)) && (
|
||||
<span className="text-gb-orange text-xs font-bold" title="Unread messages">●</span>
|
||||
)}
|
||||
<span className="flex items-center gap-1 text-xs pointer-events-none group-hover:pointer-events-auto">
|
||||
|
||||
Reference in New Issue
Block a user