master
 1import { define, Reaction } from '#src'
 2
 3type Where = {
 4  count: number
 5  url: string
 6  content?: Reaction['content']
 7}
 8
 9export default define({
10  url: import.meta.url,
11  badges: ['confused', 'self-upvote'] as const,
12  present(data, grant) {
13    const moreThan10: Where[] = []
14    const selfUpvotes: Where[] = []
15
16    for (const x of [
17      ...data.issues,
18      ...data.pulls,
19      ...data.discussionComments,
20      ...data.issueComments,
21    ]) {
22      if (x.reactions && x.reactions.length > 0) {
23        const counts = count(x.reactions)
24        if (counts.CONFUSED > 10) {
25          moreThan10.push({ count: counts.CONFUSED, url: x.url })
26        }
27
28        for (const reaction of x.reactions) {
29          if (reaction.user?.login === data.user.login) {
30            selfUpvotes.push({
31              count: 1,
32              url: x.url,
33              content: reaction.content,
34            })
35          }
36        }
37      }
38    }
39
40    moreThan10.sort((a, b) => b.count - a.count)
41    if (moreThan10.length > 0) {
42      grant('confused', `I confused more than 10 people.`)
43        .evidence(textWithCount(moreThan10))
44        .tier(1)
45    }
46
47    if (selfUpvotes.length > 0) {
48      grant('self-upvote', `I liked my own comment so much that I upvoted it.`)
49        .evidence(textWithContent(selfUpvotes))
50        .tier(1)
51    }
52  },
53})
54
55function count(reactions: Reaction[] | undefined) {
56  const counts: Record<Reaction['content'], number> = {
57    CONFUSED: 0,
58    EYES: 0,
59    HEART: 0,
60    HOORAY: 0,
61    LAUGH: 0,
62    ROCKET: 0,
63    THUMBS_DOWN: 0,
64    THUMBS_UP: 0,
65  }
66  for (const reaction of reactions ?? []) {
67    counts[reaction.content] = (counts[reaction.content] || 0) + 1
68  }
69  return counts
70}
71
72function textWithCount(entries: Where[]): string {
73  const lines: string[] = []
74  for (const where of entries) {
75    lines.push(`* <a href="${where.url}">${where.count} 😕</a>`)
76  }
77  return lines.join('\n')
78}
79
80const emoji: Record<Reaction['content'], string> = {
81  CONFUSED: '😕',
82  EYES: '👀',
83  HEART: '❤️',
84  HOORAY: '🎉',
85  LAUGH: '😄',
86  ROCKET: '🚀',
87  THUMBS_DOWN: '👎',
88  THUMBS_UP: '👍',
89} as const
90
91function textWithContent(entries: Where[]): string {
92  const lines: string[] = []
93  for (const where of entries) {
94    if (!where.content) continue
95    lines.push(`* <a href="${where.url}">${emoji[where.content]}</a>`)
96  }
97  return lines.join('\n')
98}