Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { fetchGithubIssues } from "@/lib/github"
import { GitHubLogoIcon } from "@radix-ui/react-icons"
import { Suspense } from "react"

export const revalidate = 3600 // Revalidate every hour
export const revalidate = 600 // Revalidate every 10 minutes

export default async function Home() {
const issues = await fetchGithubIssues(process.env.GITHUB_TOKEN || "")
Expand Down
58 changes: 53 additions & 5 deletions lib/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,69 @@ export async function fetchGithubIssues(
)

// Flatten and filter issues
const processedIssues = allIssues
const openIssues = allIssues
.flatMap((result) => (result.status === "fulfilled" ? result.value : []))
.filter(
(issue) =>
!issue.pull_request && // Not a PR
!issue.assignees?.length, // Not assigned
)
.map((issue) => {

const processedIssues = await Promise.all(
openIssues.map(async (issue) => {
// Check for bounty label and parse amount
const hasBountyLabel = issue.labels?.some(
(label: any) => label.name === "💎 Bounty",
(label: any) => {
const name = typeof label === 'string' ? label : label.name;
return name === "💎 Bounty" || (name && name.toLowerCase().includes("bounty"));
}
)

let bountyAmount = 0
if (hasBountyLabel) {

// 1. Try to extract from labels like "$50"
if (issue.labels) {
for (const label of issue.labels) {
const labelName = typeof label === 'string' ? label : label.name;
if (labelName) {
const match = labelName.match(/\$(\d+)/)
if (match) {
bountyAmount = parseInt(match[1], 10)
break
}
}
}
}

// 2. Try to extract from issue body
if (bountyAmount === 0 && hasBountyLabel) {
const bountyMatch = (issue.body || "").match(/\/bounty\s*\$(\d+)/i)
bountyAmount = bountyMatch ? parseInt(bountyMatch[1], 10) : 0
if (bountyMatch) {
bountyAmount = parseInt(bountyMatch[1], 10)
}
}

// 3. Try to extract from Algora bot comments
if (bountyAmount === 0 && hasBountyLabel && issue.number) {
try {
const comments = await octokit.paginate(octokit.issues.listComments, {
owner: org,
repo: issue.repository.name,
issue_number: issue.number,
})

for (const comment of comments) {
if (comment.user?.login === "algora-bot" || comment.body?.includes("bounty")) {
const match = (comment.body || "").match(/\$(\d+)/)
if (match) {
bountyAmount = parseInt(match[1], 10)
break
}
}
}
} catch (e) {
console.error(`Failed to fetch comments for ${issue.repository.full_name}#${issue.number}`, e)
}
}

return {
Expand All @@ -94,6 +141,7 @@ export async function fetchGithubIssues(
bountyAmount,
}
})
)

// Calculate dates for weighting
const now = new Date()
Expand Down