import React from 'dom-chef'; import cache from 'webext-storage-cache'; import select from 'select-dom'; import elementReady from 'element-ready'; import * as pageDetect from 'github-url-detection'; import features from '.'; import * as api from '../github-helpers/api'; import pluralize from '../helpers/pluralize'; import {getForkedRepo, getUsername, getRepo} from '../github-helpers'; function getLinkCopy(count: number): string { return pluralize(count, 'one open pull request', '$$ open pull requests'); } const countPRs = cache.function(async (forkedRepo: string): Promise<[prCount: number, singlePrNumber?: number]> => { const {search} = await api.v4(` search( first: 100, type: ISSUE, query: "repo:${forkedRepo} is:pr is:open author:${getUsername()}" ) { nodes { ... on PullRequest { number headRepository { nameWithOwner } } } } `); // Only show PRs originated from the current repo const prs = search.nodes.filter((pr: AnyObject) => pr.headRepository.nameWithOwner === getRepo()!.nameWithOwner); // If only one is found, pass the PR number so we can link to the PR directly if (prs.length === 1) { return [1, prs[0].number]; } return [prs.length]; }, { maxAge: {hours: 1}, staleWhileRevalidate: {days: 2}, cacheKey: ([forkedRepo]): string => 'prs-on-forked-repo:' + forkedRepo + ':' + getRepo()!.nameWithOwner }); async function getPRs(): Promise<[prCount: number, url: string] | []> { // Wait for the tab bar to be loaded await elementReady([ '.pagehead + *', // Pre "Repository refresh" layout '.UnderlineNav-body + *' ].join()); if (!pageDetect.canUserEditRepo()) { return []; } const forkedRepo = getForkedRepo()!; const [count, firstPr] = await countPRs(forkedRepo); if (count === 1) { return [count, `/${forkedRepo}/pull/${firstPr!}`]; } return [count, `/${forkedRepo}/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc+author%3A${getUsername()}`]; } async function initHeadHint(): Promise { const [count, url] = await getPRs(); if (!count) { return false; } select(`[data-hovercard-type="repository"][href="/${getForkedRepo()!}"]`)!.after( <> with {getLinkCopy(count)} ); } async function initDeleteHint(): Promise { const [count, url] = await getPRs(); if (!count) { return false; } select('details-dialog[aria-label*="Delete"] .Box-body p:first-child')!.after(

It will also abandon your {getLinkCopy(count)} in {getForkedRepo()!} and you’ll no longer be able to edit {count === 1 ? 'it' : 'them'}.

); } void features.add(__filebasename, { include: [ pageDetect.isRepo ], exclude: [ () => !pageDetect.isForkedRepo() ], awaitDomReady: false, init: initHeadHint }, { include: [ pageDetect.isRepoMainSettings ], exclude: [ () => !pageDetect.isForkedRepo() ], awaitDomReady: false, init: initDeleteHint });