Commit 59339da

Anton Medvedev <anton@medv.io>
2024-11-28 23:27:43
Add reactions.ts
1 parent b0d6ed2
badges/most-reactions/most-reactions.ts
@@ -1,58 +0,0 @@
-import { define, plural } from '#src'
-
-export default define({
-  url: import.meta.url,
-  badges: ['most-reactions'] as const,
-  present(data, grant) {
-    const reactions: Record<string, { count: number; repository: string }> = {}
-
-    for (const issue of data.issues) {
-      if (issue.reactions.totalCount > 0) {
-        reactions[issue.url] = {
-          count: issue.reactions.totalCount,
-          repository: issue.repository.nameWithOwner,
-        }
-      }
-    }
-
-    for (const pull of data.pulls) {
-      if (pull.reactions.totalCount > 0) {
-        reactions[pull.url] = {
-          count: pull.reactions.totalCount,
-          repository: pull.repository.nameWithOwner,
-        }
-      }
-    }
-
-    for (const comment of data.issueComments) {
-      if (comment.reactions.totalCount > 0) {
-        reactions[comment.repository.nameWithOwner] = {
-          count: comment.reactions.totalCount,
-          repository: comment.repository.nameWithOwner,
-        }
-      }
-    }
-
-    for (const discussion of data.discussionComments) {
-      if (discussion.reactions.totalCount > 0 && discussion.discussion) {
-        reactions[discussion.discussion.repository.nameWithOwner] = {
-          count: discussion.reactions.totalCount,
-          repository: discussion.discussion?.repository.nameWithOwner,
-        }
-      }
-    }
-
-    const pairs = Object.entries(reactions)
-    pairs.sort((a, b) => b[1].count - a[1].count)
-    if (pairs.length === 0) return
-
-    const topReactions = pairs.slice(0, 10)
-    // grant(
-    //   'most-reactions',
-    //   `I have received the most reactions on issues!\n\n` +
-    //     topReactions
-    //       .map((p) => `- ${p[1].repository}: ${p[1].count} reactions`)
-    //       .join('\n'),
-    // )
-  },
-})
badges/reactions/confused.png
Binary file
badges/reactions/reactions.ts
@@ -0,0 +1,120 @@
+import { define } from '#src'
+import { Reactions } from '../../src/collect/comments.graphql.js'
+
+export default define({
+  url: import.meta.url,
+  badges: ['thumbs-up', 'thumbs-down', 'confused'] as const,
+  present(data, grant) {
+    type Reaction =
+      | 'CONFUSED'
+      | 'EYES'
+      | 'HEART'
+      | 'HOORAY'
+      | 'LAUGH'
+      | 'ROCKET'
+      | 'THUMBS_DOWN'
+      | 'THUMBS_UP'
+
+    const reactions: {
+      totalCount: number
+      counts: Record<Reaction, number>
+      where: string
+    }[] = []
+
+    function count(reactions: Reactions['reactions']['nodes']) {
+      const counts: Record<Reaction, number> = {
+        CONFUSED: 0,
+        EYES: 0,
+        HEART: 0,
+        HOORAY: 0,
+        LAUGH: 0,
+        ROCKET: 0,
+        THUMBS_DOWN: 0,
+        THUMBS_UP: 0,
+      }
+      for (const reaction of reactions ?? []) {
+        counts[reaction.content] = (counts[reaction.content] || 0) + 1
+      }
+      return counts
+    }
+
+    for (const issue of data.issues) {
+      if (issue.reactions.totalCount > 0) {
+        reactions.push({
+          totalCount: issue.reactions.totalCount,
+          counts: count(issue.reactions.nodes),
+          where: issue.url,
+        })
+      }
+    }
+
+    for (const pull of data.pulls) {
+      if (pull.reactions.totalCount > 0) {
+        reactions.push({
+          totalCount: pull.reactions.totalCount,
+          counts: count(pull.reactions.nodes),
+          where: pull.url,
+        })
+      }
+    }
+
+    for (const comment of data.issueComments) {
+      if (comment.reactions.totalCount > 0) {
+        reactions.push({
+          totalCount: comment.reactions.totalCount,
+          counts: count(comment.reactions.nodes),
+          where: comment.url,
+        })
+      }
+    }
+
+    for (const discussion of data.discussionComments) {
+      if (discussion.reactions.totalCount > 0 && discussion.discussion) {
+        reactions.push({
+          totalCount: discussion.reactions.totalCount,
+          counts: count(discussion.reactions.nodes),
+          where: discussion.url,
+        })
+      }
+    }
+
+    const up = Object.values(reactions)
+    up.sort((a, b) => b.counts.THUMBS_UP - a.counts.THUMBS_UP)
+    if (up.length > 0 && up[0].counts.THUMBS_UP > 10) {
+      grant(
+        'thumbs-up',
+        `I have received a lot of thumbs up ๐Ÿ‘ reactions!\n\n` +
+          up
+            .slice(0, 10)
+            .map((p) => `- [${p.totalCount} reactions](${p.where})`)
+            .join('\n'),
+      )
+    }
+
+    const down = Object.values(reactions)
+    down.sort((a, b) => b.counts.THUMBS_DOWN - a.counts.THUMBS_DOWN)
+    if (down.length > 0 && down[0].counts.THUMBS_DOWN > 10) {
+      grant(
+        'thumbs-down',
+        `I have received a lot of thumbs down ๐Ÿ‘Ž reactions!\n\n` +
+          down
+            .slice(0, 10)
+            .map((p) => `- [${p.totalCount} reactions](${p.where})`)
+            .join('\n'),
+      )
+    }
+
+    const confused = Object.values(reactions)
+    confused.sort((a, b) => b.counts.CONFUSED - a.counts.CONFUSED)
+    if (confused.length > 0 && confused[0].counts.CONFUSED > 10) {
+      grant(
+        'confused',
+        `I have received a lot of confused ๐Ÿ˜• reactions!\n\n` +
+          confused
+            .slice(0, 10)
+            .map((p) => `- [${p.totalCount} reactions](${p.where})`)
+            .join('\n'),
+      )
+    }
+  },
+})
badges/reactions/thumbs-down.png
Binary file
badges/reactions/thumbs-up.png
Binary file
badges/index.ts
@@ -13,7 +13,7 @@ export default [
   await import('./fix-commit/fix-commit.js'),
   await import('./github-anniversary/github-anniversary.js'),
   await import('./mass-delete-commit/mass-delete-commit.js'),
-  // TODO: await import('./most-reactions/most-reactions.js'),
+  await import('./reactions/reactions.js'),
   await import('./my-badges-contributor/my-badges-contributor.js'),
   await import('./old-issue/old-issue.js'),
   await import('./polite-coder/polite-coder.js'),