98 lines
3.8 KiB
TypeScript
98 lines
3.8 KiB
TypeScript
import { GetUserChatsQuery } from './ChatQueries';
|
|
import { IChatRepository } from '../../../Domain/IRepository/IChatRepository';
|
|
import { IChatArchiveRepository } from '../../../Domain/IRepository/IChatArchiveRepository';
|
|
import { ChatAggregate } from '../../../Domain/Chat/ChatAggregate';
|
|
import { ChatArchiveAggregate } from '../../../Domain/Chat/ChatArchiveAggregate';
|
|
import { logAuth, logError } from '../../Services/Logger';
|
|
|
|
interface ChatWithMetadata {
|
|
id: string;
|
|
type: string;
|
|
name: string | null;
|
|
gameId: string | null;
|
|
users: string[];
|
|
lastActivity: Date | null;
|
|
isArchived: boolean;
|
|
messageCount: number;
|
|
unreadCount?: number;
|
|
}
|
|
|
|
export class GetUserChatsQueryHandler {
|
|
constructor(
|
|
private chatRepository: IChatRepository,
|
|
private chatArchiveRepository: IChatArchiveRepository
|
|
) {}
|
|
|
|
async execute(query: GetUserChatsQuery): Promise<ChatWithMetadata[]> {
|
|
try {
|
|
const result: ChatWithMetadata[] = [];
|
|
|
|
// Get active chats
|
|
const activeChats = await this.chatRepository.findActiveChatsForUser(query.userId);
|
|
result.push(...activeChats.map(chat => ({
|
|
id: chat.id,
|
|
type: chat.type,
|
|
name: chat.name,
|
|
gameId: chat.gameId,
|
|
users: chat.users,
|
|
lastActivity: chat.lastActivity,
|
|
isArchived: false,
|
|
messageCount: chat.messages.length,
|
|
unreadCount: this.calculateUnreadMessages(chat, query.userId)
|
|
})));
|
|
|
|
// Get archived chats if requested
|
|
if (query.includeArchived) {
|
|
const userActiveChats = await this.chatRepository.findByUserId(query.userId);
|
|
const archivedChatIds = userActiveChats
|
|
.filter(chat => chat.archiveDate !== null)
|
|
.map(chat => chat.id);
|
|
|
|
const archives = await Promise.all(
|
|
archivedChatIds.map(id => this.chatArchiveRepository.findByChatId(id))
|
|
);
|
|
|
|
archives.forEach(archiveArray => {
|
|
archiveArray.forEach(archive => {
|
|
if (archive.participants.includes(query.userId)) {
|
|
result.push({
|
|
id: archive.chatId,
|
|
type: archive.chatType,
|
|
name: archive.chatName,
|
|
gameId: archive.gameId,
|
|
users: archive.participants,
|
|
lastActivity: archive.archivedAt,
|
|
isArchived: true,
|
|
messageCount: archive.archivedMessages.length,
|
|
unreadCount: 0 // Archived chats have no unread messages
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
logAuth('User chats retrieved', query.userId, {
|
|
activeCount: activeChats.length,
|
|
totalCount: result.length,
|
|
includeArchived: query.includeArchived
|
|
});
|
|
|
|
return result.sort((a, b) => {
|
|
if (!a.lastActivity) return 1;
|
|
if (!b.lastActivity) return -1;
|
|
return new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime();
|
|
});
|
|
|
|
} catch (error) {
|
|
logError('GetUserChatsQueryHandler error', error as Error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
private calculateUnreadMessages(chat: ChatAggregate, userId: string): number {
|
|
// Simple implementation - count messages from other users
|
|
// In production, you'd store lastSeen timestamp per user per chat
|
|
return chat.messages.filter(msg => msg.userid !== userId).length;
|
|
}
|
|
}
|