fix(contacts): keep unread inbound-only while refreshing outbound preview
This commit is contained in:
@@ -434,13 +434,13 @@ async function getContacts(auth: AuthContext | null) {
|
|||||||
const messageWhere = visibleMessageWhere(hiddenInboxIds);
|
const messageWhere = visibleMessageWhere(hiddenInboxIds);
|
||||||
const hiddenInboxIdSet = new Set(hiddenInboxIds);
|
const hiddenInboxIdSet = new Set(hiddenInboxIds);
|
||||||
|
|
||||||
const [contactsRaw, contactInboxesRaw, communicationsRaw, threadReadsRaw] = await Promise.all([
|
const [contactsRaw, contactInboxesRaw, communicationsRaw, threadReadsRaw, latestInboundAtByContactIdRaw] = await Promise.all([
|
||||||
prisma.contact.findMany({
|
prisma.contact.findMany({
|
||||||
where: { teamId: ctx.teamId },
|
where: { teamId: ctx.teamId },
|
||||||
include: {
|
include: {
|
||||||
note: { select: { content: true } },
|
note: { select: { content: true } },
|
||||||
messages: {
|
messages: {
|
||||||
where: { direction: "IN", ...(messageWhere ?? {}) },
|
where: messageWhere,
|
||||||
select: { content: true, channel: true, occurredAt: true },
|
select: { content: true, channel: true, occurredAt: true },
|
||||||
orderBy: { occurredAt: "desc" as const },
|
orderBy: { occurredAt: "desc" as const },
|
||||||
take: 1,
|
take: 1,
|
||||||
@@ -468,9 +468,23 @@ async function getContacts(auth: AuthContext | null) {
|
|||||||
where: { teamId: ctx.teamId, userId: ctx.userId },
|
where: { teamId: ctx.teamId, userId: ctx.userId },
|
||||||
select: { contactId: true, readAt: true },
|
select: { contactId: true, readAt: true },
|
||||||
}),
|
}),
|
||||||
|
prisma.contactMessage.groupBy({
|
||||||
|
by: ["contactId"],
|
||||||
|
where: {
|
||||||
|
contact: { teamId: ctx.teamId },
|
||||||
|
direction: "IN",
|
||||||
|
...(messageWhere ?? {}),
|
||||||
|
},
|
||||||
|
_max: { occurredAt: true },
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const readAtByContactId = new Map(threadReadsRaw.map((r) => [r.contactId, r.readAt]));
|
const readAtByContactId = new Map(threadReadsRaw.map((r) => [r.contactId, r.readAt]));
|
||||||
|
const latestInboundAtByContactId = new Map(
|
||||||
|
latestInboundAtByContactIdRaw
|
||||||
|
.map((row) => [row.contactId, row._max.occurredAt] as const)
|
||||||
|
.filter((entry): entry is readonly [string, Date] => entry[1] instanceof Date),
|
||||||
|
);
|
||||||
|
|
||||||
const channelsByContactId = new Map<string, Set<string>>();
|
const channelsByContactId = new Map<string, Set<string>>();
|
||||||
const totalInboxesByContactId = new Map<string, number>();
|
const totalInboxesByContactId = new Map<string, number>();
|
||||||
@@ -497,6 +511,7 @@ async function getContacts(auth: AuthContext | null) {
|
|||||||
})
|
})
|
||||||
.map((c) => {
|
.map((c) => {
|
||||||
const channels = Array.from(channelsByContactId.get(c.id) ?? []);
|
const channels = Array.from(channelsByContactId.get(c.id) ?? []);
|
||||||
|
const lastInboundAt = latestInboundAtByContactId.get(c.id);
|
||||||
return {
|
return {
|
||||||
id: c.id,
|
id: c.id,
|
||||||
name: c.name,
|
name: c.name,
|
||||||
@@ -505,8 +520,8 @@ async function getContacts(auth: AuthContext | null) {
|
|||||||
lastContactAt: c.messages[0]?.occurredAt?.toISOString?.() ?? c.updatedAt.toISOString(),
|
lastContactAt: c.messages[0]?.occurredAt?.toISOString?.() ?? c.updatedAt.toISOString(),
|
||||||
lastMessageText: c.messages[0]?.content ?? "",
|
lastMessageText: c.messages[0]?.content ?? "",
|
||||||
lastMessageChannel: c.messages[0]?.channel ? mapChannel(c.messages[0].channel) : "",
|
lastMessageChannel: c.messages[0]?.channel ? mapChannel(c.messages[0].channel) : "",
|
||||||
hasUnread: c.messages[0]?.occurredAt
|
hasUnread: lastInboundAt
|
||||||
? (!readAtByContactId.has(c.id) || c.messages[0].occurredAt > readAtByContactId.get(c.id)!)
|
? (!readAtByContactId.has(c.id) || lastInboundAt > readAtByContactId.get(c.id)!)
|
||||||
: false,
|
: false,
|
||||||
description: c.note?.content ?? "",
|
description: c.note?.content ?? "",
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user