2026-06-01 01:15:38 +02:00

151 lines
5.5 KiB
TypeScript

import type { ApiMessage } from '../../../api/types';
import type { IAlbum, IDocumentGroup } from '../../../types';
import { isActionMessage } from '../../../global/helpers';
import { getDayStartAt } from '../../../util/dates/oldDateFormat';
type SenderGroup = (ApiMessage | IAlbum | IDocumentGroup)[];
const GROUP_INTERVAL_SECONDS = 600; // 10 minutes
export type MessageDateGroup = {
originalDate: number;
datetime: number;
senderGroups: SenderGroup[];
};
export function isAlbum(messageOrAlbum: ApiMessage | IAlbum | IDocumentGroup): messageOrAlbum is IAlbum {
return 'albumId' in messageOrAlbum;
}
export function isDocumentGroup(
messageOrAlbum: ApiMessage | IAlbum | IDocumentGroup,
): messageOrAlbum is IDocumentGroup {
return 'documentGroupId' in messageOrAlbum;
}
export function groupMessages(
messages: ApiMessage[], firstUnreadId?: number, topMessageId?: number, isChatWithSelf?: boolean, withUsers?: boolean,
) {
const initDateGroup: MessageDateGroup = {
originalDate: messages[0].date,
datetime: getDayStartAt(messages[0].date * 1000),
senderGroups: [[]],
};
let currentAlbum: IAlbum | undefined;
let currentDocumentGroup: IDocumentGroup | undefined;
const dateGroups: MessageDateGroup[] = [initDateGroup];
messages.forEach((message, index) => {
const currentDateGroup = dateGroups[dateGroups.length - 1];
const currentSenderGroup = currentDateGroup.senderGroups[currentDateGroup.senderGroups.length - 1];
if (message.isInAlbum) {
if (!currentAlbum) {
currentAlbum = {
albumId: message.groupedId!,
messages: [message],
mainMessage: message,
hasMultipleCaptions: false,
commentsMessage: message.hasComments ? message : undefined,
captionMessage: message.content.text ? message : undefined,
} satisfies IAlbum;
} else {
currentAlbum.messages.push(message);
if (message.hasComments) {
currentAlbum.commentsMessage = message;
}
if (message.content.text && !currentAlbum.hasMultipleCaptions) {
if (currentAlbum.captionMessage) {
currentAlbum.hasMultipleCaptions = true;
currentAlbum.captionMessage = undefined;
} else {
currentAlbum.captionMessage = message;
}
}
}
} else if ((message.content.paidMedia?.extendedMedia.length || 0) > 1) {
currentSenderGroup.push({
albumId: `paid-${message.id}`,
messages: [message],
mainMessage: message,
hasMultipleCaptions: false,
isPaidMedia: true,
} satisfies IAlbum);
} else if (message.groupedId) {
if (!currentDocumentGroup) {
currentDocumentGroup = {
documentGroupId: message.groupedId,
messages: [message],
firstMessageId: message.id,
commentsMessage: message.hasComments ? message : undefined,
} satisfies IDocumentGroup;
} else {
currentDocumentGroup.messages.push(message);
if (message.hasComments) {
currentDocumentGroup.commentsMessage = message;
}
}
} else {
currentSenderGroup.push(message);
}
const nextMessage = messages[index + 1];
if (
currentAlbum
&& (!nextMessage || !nextMessage.groupedId || nextMessage.groupedId !== currentAlbum.albumId)
) {
currentSenderGroup.push(currentAlbum);
currentAlbum = undefined;
}
if (
currentDocumentGroup
&& (!nextMessage || !nextMessage.groupedId || nextMessage.groupedId !== currentDocumentGroup.documentGroupId)
) {
currentSenderGroup.push(currentDocumentGroup);
currentDocumentGroup = undefined;
}
const lastMessageInSenderGroup = currentSenderGroup[currentSenderGroup.length - 1];
if (nextMessage && !currentAlbum && !currentDocumentGroup) {
const nextMessageDayStartsAt = getDayStartAt(nextMessage.date * 1000);
if (currentDateGroup.datetime !== nextMessageDayStartsAt) {
const newDateGroup: MessageDateGroup = {
originalDate: nextMessage.date,
datetime: nextMessageDayStartsAt,
senderGroups: [[]],
};
dateGroups.push(newDateGroup);
} else if (
nextMessage.id === firstUnreadId
|| message.senderId !== nextMessage.senderId
|| message.guestChatViaId !== nextMessage.guestChatViaId
|| (!withUsers && message.paidMessageStars)
|| (nextMessage.suggestedPostInfo)
|| message.isOutgoing !== nextMessage.isOutgoing
|| message.postAuthorTitle !== nextMessage.postAuthorTitle
|| (isActionMessage(message) && message.content.action?.type !== 'phoneCall')
|| (isActionMessage(nextMessage) && nextMessage.content.action?.type !== 'phoneCall')
|| message.inlineButtons
|| nextMessage.inlineButtons
|| (nextMessage.date - message.date) > GROUP_INTERVAL_SECONDS
|| (topMessageId
&& (message.id === topMessageId
|| (lastMessageInSenderGroup && (
(isAlbum(lastMessageInSenderGroup) && lastMessageInSenderGroup.mainMessage.id === topMessageId)
|| (isDocumentGroup(lastMessageInSenderGroup) && lastMessageInSenderGroup.firstMessageId === topMessageId)
)))
&& nextMessage.id !== topMessageId
&& !(message.groupedId && message.groupedId === nextMessage.groupedId))
|| (isChatWithSelf && message.forwardInfo?.fromId !== nextMessage.forwardInfo?.fromId)
) {
currentDateGroup.senderGroups.push([]);
}
}
});
return dateGroups;
}