Add 'read up to here' marker line in chat messages

This commit is contained in:
DGSoft 2025-12-12 12:45:03 +01:00
parent f52fb50a39
commit df394b3b7d
2 changed files with 43 additions and 0 deletions

View File

@ -5,6 +5,7 @@ import CodeBlock from '../common/CodeBlock';
import { useAuth } from '../../contexts/AuthContext';
import { useToast } from '../../contexts/ToastContext';
import { useUserStatus } from '../../contexts/UserStatusContext';
import { useUnreadMessages } from '../../contexts/UnreadMessagesContext';
import UserStatusIndicator from '../common/UserStatusIndicator';
interface MessageListProps {
@ -16,6 +17,7 @@ const MessageList: React.FC<MessageListProps> = ({ channelId, onReply }) => {
const { user } = useAuth();
const { addToast } = useToast();
const { getUserStatus } = useUserStatus();
const { getLastReadTimestamp } = useUnreadMessages();
const [messages, setMessages] = useState<Message[]>([]);
const [loading, setLoading] = useState(true);
const [hasMore, setHasMore] = useState(true);
@ -272,6 +274,23 @@ const MessageList: React.FC<MessageListProps> = ({ channelId, onReply }) => {
<span className="text-xs text-gray-500 dark:text-gray-400">Lade ältere Nachrichten...</span>
</div>
)}
{(() => {
const lastReadTimestamp = getLastReadTimestamp('channel', channelId);
const hasUnreadMessages = messages.some(msg => {
const messageDate = new Date(msg.created_at);
return lastReadTimestamp && messageDate > lastReadTimestamp;
});
return hasUnreadMessages ? (
<div className="flex items-center my-4">
<div className="flex-1 border-t border-gray-300 dark:border-gray-600"></div>
<div className="px-3 py-1 bg-gray-100 dark:bg-gray-700 rounded-full text-xs text-gray-600 dark:text-gray-300 border border-gray-300 dark:border-gray-600">
Gelesen bis hier
</div>
<div className="flex-1 border-t border-gray-300 dark:border-gray-600"></div>
</div>
) : null;
})()}
{messages.map((message) => {
const isOwnMessage = user && message.sender_id === user.id;

View File

@ -6,6 +6,7 @@ interface UnreadMessagesContextType {
unreadDirectMessages: Set<number>;
activeChannelId: number | null;
activeDirectMessageUserId: number | null;
lastReadTimestamps: { [key: string]: Date }; // 'channel-{id}' or 'dm-{userId}' => timestamp
markChannelAsRead: (channelId: number) => void;
markChannelAsUnread: (channelId: number) => void;
markDirectMessageAsRead: (userId: number) => void;
@ -14,6 +15,7 @@ interface UnreadMessagesContextType {
hasUnreadDirectMessage: (userId: number) => boolean;
setActiveChannel: (channelId: number | null) => void;
setActiveDirectMessage: (userId: number | null) => void;
getLastReadTimestamp: (type: 'channel' | 'dm', id: number) => Date | null;
}
const UnreadMessagesContext = createContext<UnreadMessagesContextType | undefined>(undefined);
@ -35,6 +37,7 @@ export const UnreadMessagesProvider: React.FC<UnreadMessagesProviderProps> = ({
const [unreadDirectMessages, setUnreadDirectMessages] = useState<Set<number>>(new Set());
const [activeChannelId, setActiveChannelId] = useState<number | null>(null);
const [activeDirectMessageUserId, setActiveDirectMessageUserId] = useState<number | null>(null);
const [lastReadTimestamps, setLastReadTimestamps] = useState<{ [key: string]: Date }>({});
const { user } = useAuth();
// Listen for unread message events from the presence WebSocket
@ -87,10 +90,24 @@ export const UnreadMessagesProvider: React.FC<UnreadMessagesProviderProps> = ({
const setActiveChannel = (channelId: number | null) => {
setActiveChannelId(channelId);
if (channelId !== null) {
// Set timestamp when channel becomes active
setLastReadTimestamps(prev => ({
...prev,
[`channel-${channelId}`]: new Date()
}));
}
};
const setActiveDirectMessage = (userId: number | null) => {
setActiveDirectMessageUserId(userId);
if (userId !== null) {
// Set timestamp when DM becomes active
setLastReadTimestamps(prev => ({
...prev,
[`dm-${userId}`]: new Date()
}));
}
};
const hasUnreadChannel = (channelId: number) => {
@ -101,6 +118,11 @@ export const UnreadMessagesProvider: React.FC<UnreadMessagesProviderProps> = ({
return unreadDirectMessages.has(userId);
};
const getLastReadTimestamp = (type: 'channel' | 'dm', id: number): Date | null => {
const key = `${type}-${id}`;
return lastReadTimestamps[key] || null;
};
return (
<UnreadMessagesContext.Provider
value={{
@ -108,6 +130,7 @@ export const UnreadMessagesProvider: React.FC<UnreadMessagesProviderProps> = ({
unreadDirectMessages,
activeChannelId,
activeDirectMessageUserId,
lastReadTimestamps,
markChannelAsRead,
markChannelAsUnread,
markDirectMessageAsRead,
@ -116,6 +139,7 @@ export const UnreadMessagesProvider: React.FC<UnreadMessagesProviderProps> = ({
hasUnreadDirectMessage,
setActiveChannel,
setActiveDirectMessage,
getLastReadTimestamp,
}}
>
{children}