37 lines · 1.4 KB
export const REACTION_CONTENTS = ["+1", "-1", "laugh", "hooray", "confused", "heart", "rocket", "eyes"] as const;

export type ReactionContent = (typeof REACTION_CONTENTS)[number];

export const REACTION_EMOJI: Record<ReactionContent, string> = {
  "+1": "👍",
  "-1": "👎",
  laugh: "😄",
  hooray: "🎉",
  confused: "😕",
  heart: "❤️",
  rocket: "🚀",
  eyes: "👀",
};

export const REACTION_SUBJECTS = ["issue", "comment", "review_comment", "discussion", "discussion_comment"] as const;

export type ReactionSubject = (typeof REACTION_SUBJECTS)[number];

/** Names shown when hovering a reaction pill; the pill itself carries the total count. */
export const REACTORS_SHOWN = 5;

export type ReactionSummary = { content: ReactionContent; count: number; viewerReacted: boolean };

const COUNT_FORMAT = new Intl.NumberFormat("en-US");

/** "alice, bob and 49,998 others": at most REACTORS_SHOWN names whatever the count. */
export function reactorsLabel(names: string[], count: number): string {
  const shown = names.slice(0, REACTORS_SHOWN);
  const others = Math.max(0, count - shown.length);
  if (shown.length === 0) return `${COUNT_FORMAT.format(count)} reacted`;
  if (others === 0) {
    return shown.length === 1 ? shown[0] : `${shown.slice(0, -1).join(", ")} and ${shown[shown.length - 1]}`;
  }
  return `${shown.join(", ")} and ${COUNT_FORMAT.format(others)} other${others === 1 ? "" : "s"}`;
}