140 lines
3.6 KiB
TypeScript
140 lines
3.6 KiB
TypeScript
import { usePrisma } from "../utils/prisma";
|
|
|
|
// ─── Gruppen-Chat ─────────────────────────────────────────────────────────────
|
|
|
|
export async function getChatMessages(limit = 100) {
|
|
const db = usePrisma();
|
|
return db.chatMessage.findMany({
|
|
where: { roomId: null },
|
|
orderBy: { createdAt: "asc" },
|
|
take: limit,
|
|
select: { id: true, content: true, createdAt: true, userId: true },
|
|
});
|
|
}
|
|
|
|
export async function createChatMessage(userId: string, content: string) {
|
|
const db = usePrisma();
|
|
return db.chatMessage.create({
|
|
data: { userId, content, roomId: null },
|
|
select: { id: true, content: true, createdAt: true, userId: true },
|
|
});
|
|
}
|
|
|
|
// ─── Direktnachrichten ───────────────────────────────────────────────────────
|
|
|
|
export async function sendDirectMessage(
|
|
senderId: string,
|
|
receiverId: string,
|
|
content: string,
|
|
opts?: {
|
|
replyToId?: string;
|
|
attachmentUrl?: string;
|
|
attachmentType?: string;
|
|
attachmentName?: string;
|
|
},
|
|
) {
|
|
const db = usePrisma();
|
|
return db.directMessage.create({
|
|
data: {
|
|
senderId,
|
|
receiverId,
|
|
content,
|
|
replyToId: opts?.replyToId || null,
|
|
attachmentUrl: opts?.attachmentUrl || null,
|
|
attachmentType: opts?.attachmentType || null,
|
|
attachmentName: opts?.attachmentName || null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
content: true,
|
|
createdAt: true,
|
|
replyToId: true,
|
|
attachmentUrl: true,
|
|
attachmentType: true,
|
|
attachmentName: true,
|
|
likesCount: true,
|
|
replyTo: {
|
|
select: { id: true, senderId: true, content: true },
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function getDmHistory(
|
|
userId: string,
|
|
partnerId: string,
|
|
page = 1,
|
|
limit = 50,
|
|
) {
|
|
const db = usePrisma();
|
|
const offset = (page - 1) * limit;
|
|
return db.directMessage.findMany({
|
|
where: {
|
|
OR: [
|
|
{ senderId: userId, receiverId: partnerId },
|
|
{ senderId: partnerId, receiverId: userId },
|
|
],
|
|
},
|
|
orderBy: { createdAt: "desc" },
|
|
skip: offset,
|
|
take: limit,
|
|
select: {
|
|
id: true,
|
|
senderId: true,
|
|
receiverId: true,
|
|
content: true,
|
|
createdAt: true,
|
|
readAt: true,
|
|
replyToId: true,
|
|
attachmentUrl: true,
|
|
attachmentType: true,
|
|
attachmentName: true,
|
|
likesCount: true,
|
|
replyTo: {
|
|
select: { id: true, senderId: true, content: true },
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function markDmsAsRead(senderId: string, receiverId: string) {
|
|
const db = usePrisma();
|
|
return db.directMessage.updateMany({
|
|
where: { senderId, receiverId, readAt: null },
|
|
data: { readAt: new Date() },
|
|
});
|
|
}
|
|
|
|
export async function getDmConversations(userId: string) {
|
|
const db = usePrisma();
|
|
// Alle DMs als Sender oder Empfänger, neueste zuerst
|
|
return db.directMessage.findMany({
|
|
where: {
|
|
OR: [{ senderId: userId }, { receiverId: userId }],
|
|
},
|
|
orderBy: { createdAt: "desc" },
|
|
take: 500,
|
|
select: {
|
|
id: true,
|
|
senderId: true,
|
|
receiverId: true,
|
|
content: true,
|
|
createdAt: true,
|
|
readAt: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function countUnreadDms(receiverId: string) {
|
|
const db = usePrisma();
|
|
const rows = await db.directMessage.findMany({
|
|
where: { receiverId, readAt: null },
|
|
select: { senderId: true },
|
|
});
|
|
const byPartner: Record<string, number> = {};
|
|
for (const r of rows) {
|
|
byPartner[r.senderId] = (byPartner[r.senderId] ?? 0) + 1;
|
|
}
|
|
return byPartner;
|
|
}
|