85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
import { getRoom, getRoomMessages, getMember } from "../../../../db/chat-rooms";
|
||
import { getUsersMeta } from "../../../../utils/getUsersMeta";
|
||
|
||
/** GET /api/chat/rooms/[roomId] – Room detail + messages */
|
||
export default defineEventHandler(async (event) => {
|
||
const user = await requireUser(event);
|
||
const roomId = getRouterParam(event, "roomId");
|
||
if (!roomId) throw createError({ statusCode: 400, message: "roomId fehlt" });
|
||
|
||
const room = await getRoom(roomId);
|
||
if (!room)
|
||
throw createError({ statusCode: 404, message: "Raum nicht gefunden" });
|
||
|
||
// Access check: public rooms or member
|
||
const member = await getMember(roomId, user.id);
|
||
if (!room.isPublic && (!member || member.status !== "active")) {
|
||
throw createError({ statusCode: 403, message: "Kein Zugang" });
|
||
}
|
||
|
||
const cursor = getQuery(event).cursor as string | undefined;
|
||
const messages = await getRoomMessages(roomId, cursor, 50);
|
||
|
||
// Resolve user meta for all message senders
|
||
const userIds = [...new Set(messages.map((m) => m.userId))];
|
||
// Also collect replyTo userIds
|
||
messages.forEach((m) => {
|
||
if (m.replyTo?.userId && !userIds.includes(m.replyTo.userId)) {
|
||
userIds.push(m.replyTo.userId);
|
||
}
|
||
});
|
||
const meta = userIds.length > 0 ? await getUsersMeta(userIds) : {};
|
||
|
||
// Get member list
|
||
const memberIds = room.members.map((m) => m.userId);
|
||
const memberMeta = await getUsersMeta(memberIds);
|
||
|
||
return {
|
||
room: {
|
||
id: room.id,
|
||
name: room.name,
|
||
description: room.description,
|
||
isPublic: room.isPublic,
|
||
isDefault: room.isDefault,
|
||
joinMode: room.joinMode,
|
||
avatarUrl: room.avatarUrl ?? null,
|
||
inviteCode:
|
||
member?.role === "owner" || member?.role === "admin"
|
||
? room.inviteCode
|
||
: null,
|
||
memberCount: room.memberCount,
|
||
createdBy: room.createdBy,
|
||
myRole: member?.role ?? null,
|
||
isMember: !!member && member.status === "active",
|
||
},
|
||
members: room.members.map((m) => ({
|
||
userId: m.userId,
|
||
role: m.role,
|
||
nickname: memberMeta[m.userId]?.nickname ?? "Anonym",
|
||
avatar: memberMeta[m.userId]?.avatar ?? null,
|
||
})),
|
||
messages: messages.reverse().map((m) => ({
|
||
id: m.id,
|
||
userId: m.userId,
|
||
nickname: meta[m.userId]?.nickname ?? "Anonym",
|
||
avatar: meta[m.userId]?.avatar ?? null,
|
||
content: m.content,
|
||
replyTo: m.replyTo
|
||
? {
|
||
id: m.replyTo.id,
|
||
userId: m.replyTo.userId,
|
||
nickname: meta[m.replyTo.userId]?.nickname ?? "Anonym",
|
||
content: m.replyTo.content.slice(0, 100),
|
||
}
|
||
: null,
|
||
attachmentUrl: m.attachmentUrl,
|
||
attachmentType: m.attachmentType,
|
||
attachmentName: m.attachmentName,
|
||
likesCount: m.likesCount,
|
||
createdAt: m.createdAt,
|
||
isOwn: m.userId === user.id,
|
||
})),
|
||
hasMore: messages.length === 50,
|
||
};
|
||
});
|