import type { WorkOrderComment } from "@/domain/work-orders/types/work-order-detail"; import { isOwnWorkOrderComment } from "@/domain/work-orders/utils/comment-ownership"; import { extractMentionIds } from "@/domain/work-orders/utils/comment-mentions"; import type { CommentHighlight } from "@/domain/work-orders/utils/work-order-deep-link"; /** * Ids of the comments a notification was raised for. The feed starts a comment item at its first * unanswered comment and a mention item at the mentioning comment, so this is every comment by * someone else from that moment on, split the same way the feed splits them: comments that * mention the user belong to Mentions, the rest to Recent activity. */ // why: Board comment times arrive as UTC without a zone designator; read them as UTC, not local time. function parseUtc(value: string): number { return Date.parse(/(Z|[+-]\d{2}:?\d{2})$/i.test(value) ? value : `${value}Z`); } export function highlightedCommentIds( comments: WorkOrderComment[], highlight: CommentHighlight | null | undefined, currentUserId: string | number | null | undefined, ): Set { const ids = new Set(); const since = highlight == null ? Number.NaN : parseUtc(highlight.since); if (highlight == null || Number.isNaN(since) || currentUserId == null || currentUserId === "") { return ids; } const userId = String(currentUserId); for (const comment of comments) { const createdAt = parseUtc(comment.createdDate); if (Number.isNaN(createdAt) || createdAt < since || isOwnWorkOrderComment(comment, userId)) { continue; } // why: Board comments expose mentions two ways: an encoded `@[id:name]` token in the text, or a // `mentions` id array alongside plain `@Name` text. Treat either as a mention of the user. const mentionIds = new Set(extractMentionIds(comment.commenttext ?? "")); for (const id of comment.mentions ?? []) { mentionIds.add(String(id)); } const mentionsUser = mentionIds.has(userId); if (mentionsUser === highlight.mentions) { ids.add(String(comment.id)); } } return ids; }