mirror of
https://github.com/OHV-IT/collabrix.git
synced 2025-12-15 08:38:36 +01:00
Add 'read up to here' marker line in chat messages
This commit is contained in:
parent
f52fb50a39
commit
df394b3b7d
@ -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;
|
||||
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user