Skip to content

Commit

Permalink
feat: aggregate notification PR and Issue data
Browse files Browse the repository at this point in the history
  • Loading branch information
zugdev committed Dec 5, 2024
1 parent d0e6ed2 commit 0544b6b
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 50 deletions.
4 changes: 2 additions & 2 deletions src/home/fetch-github/fetch-and-display-previews.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GitHubNotifications } from "../github-types";
import { notifications } from "../home";
import { pullRequestNotifications } from "../home";
import { applyAvatarsToIssues, renderNotifications } from "../rendering/render-github-issues";
import { renderOrgHeaderLabel } from "../rendering/render-org-header";
import { closeModal } from "../rendering/render-preview-modal";
Expand Down Expand Up @@ -84,7 +84,7 @@ export async function displayNotifications({
//const sortedIssues = sortIssuesController(cachedTasks, sorting, options);
//let sortedAndFiltered = sortedIssues.filter(getProposalsOnlyFilter(isProposalOnlyViewer));
//sortedAndFiltered = filterIssuesByOrganization(sortedAndFiltered);
renderNotifications(notifications, skipAnimation);
renderNotifications(pullRequestNotifications, skipAnimation);
applyAvatarsToIssues();
}

Expand Down
2 changes: 1 addition & 1 deletion src/home/fetch-github/fetch-avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Octokit } from "@octokit/rest";
import { getGitHubAccessToken } from "../getters/get-github-access-token";
import { getImageFromCache, saveImageToCache } from "../getters/get-indexed-db";
import { renderErrorInModal } from "../rendering/display-popup-modal";
import { organizationImageCache } from "./fetch-notifications";
import { organizationImageCache } from "./fetch-data";
import { GitHubNotifications } from "../github-types";
import { notifications } from "../home";

Expand Down
86 changes: 86 additions & 0 deletions src/home/fetch-github/fetch-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Octokit } from "@octokit/rest";
import { GitHubAggregated, GitHubIssue, GitHubNotification, GitHubNotifications, GitHubPullRequest } from "../github-types";
import { getGitHubAccessToken } from "../getters/get-github-access-token";
import { handleRateLimit } from "./handle-rate-limit";
import { RequestError } from "@octokit/request-error";
export const organizationImageCache = new Map<string, Blob | null>(); // this should be declared in image related script

// Fetches notifications from GitHub, must be authenticated
export async function fetchPullRequestNotifications(): Promise<GitHubAggregated[] | null> {
const providerToken = await getGitHubAccessToken();
const octokit = new Octokit({ auth: providerToken });

const aggregatedData : GitHubAggregated[] = [];

try {
const notifications = ((await octokit.request("GET /notifications")).data) as GitHubNotifications;
console.log("unfilteredNotifications", notifications);
const filteredNotifications = filterPullRequestNotifications(notifications);
console.log("filteredNotifications", filteredNotifications);
for (const notification of filteredNotifications) {
const pullRequestUrl = notification.subject.url;
const pullRequest = ((await octokit.request(`GET ${pullRequestUrl}`)).data) as GitHubPullRequest;
console.log("unfilteredPullRequest", pullRequest);
// remove notification if PR is a draft
if (pullRequest.draft || pullRequest.state === "closed") {
filteredNotifications.splice(filteredNotifications.indexOf(notification), 1);
continue;
}

// get issue number from PR body
const issueNumberMatch = pullRequest.body ? pullRequest.body.match(/Resolves .*\/issues\/(\d+)/) || pullRequest.body.match(/Resolves #(\d+)/) : null;

// if issue number is not found, remove notification
if (!issueNumberMatch) {
filteredNotifications.splice(filteredNotifications.indexOf(notification), 1);
continue;
}

const issueNumber = issueNumberMatch[1];
const issueUrl = pullRequest.issue_url.replace(/issues\/\d+$/, `issues/${issueNumber}`);
const issue = ((await octokit.request(`GET ${issueUrl}`)).data) as GitHubIssue;
console.log("unfilteredIssue", issue);
// remove notification if PR is not from assignee, or issue is closed
// if(issue.assignee?.id !== pullRequest.user.id || issue.state === "closed") {
// filteredNotifications.splice(filteredNotifications.indexOf(notification), 1);
// continue;
// }

console.log("issue", issue);
aggregatedData.push({ "notification": notification, "pullRequest": pullRequest, "issue": issue });
}

console.log("aggregatedData", aggregatedData);
return aggregatedData;
} catch(error) {
if (!!error && typeof error === "object" && "status" in error && error.status === 403) {
await handleRateLimit(providerToken ? octokit : undefined, error as RequestError);
}
console.warn("You have been logged out. Please login again.", error);
}
return null;
}

function preFilterNotifications(notifications: GitHubNotification[]): GitHubNotifications {
return notifications.filter(notification => {
// Ignore CI activity notifications
if (notification.reason === 'ci_activity') {
return false;
}

// Ignore notifications from repos that are not Ubiquity
const repoName = notification.repository.full_name.split('/')[0];
if (repoName !== 'ubiquity' && repoName !== 'ubiquity-os' && repoName !== 'ubiquity-os-marketplace') {
return false;
}

return true;
});
}

function filterPullRequestNotifications(notifications: GitHubNotification[]): GitHubNotifications {
return preFilterNotifications(notifications).filter(notification => {
// Only return pull request notifications
return notification.subject.type === 'PullRequest';
});
}
41 changes: 0 additions & 41 deletions src/home/fetch-github/fetch-notifications.ts

This file was deleted.

7 changes: 7 additions & 0 deletions src/home/github-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ export type TaskStorageItems = {

export type GitHubUserResponse = RestEndpointMethodTypes["users"]["getByUsername"]["response"];
export type GitHubUser = GitHubUserResponse["data"];
export type GitHubIssue = RestEndpointMethodTypes["issues"]["get"]["response"]["data"];
export type GitHubPullRequest = RestEndpointMethodTypes["pulls"]["get"]["response"]["data"];
export type GitHubNotifications = RestEndpointMethodTypes["activity"]["listNotificationsForAuthenticatedUser"]["response"]["data"];
export type GitHubNotification = GitHubNotifications[0];
export type GitHubAggregated = {
"issue": GitHubIssue,
"pullRequest": GitHubPullRequest,
"notification": GitHubNotification
};
export type GitHubLabel =
| {
id?: number;
Expand Down
8 changes: 4 additions & 4 deletions src/home/home.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { grid } from "../the-grid";
import { authentication } from "./authentication";
import { displayNotifications } from "./fetch-github/fetch-and-display-previews";
import { fetchNotifications } from "./fetch-github/fetch-notifications";
import { fetchPullRequestNotifications } from "./fetch-github/fetch-data";
import { readyToolbar } from "./ready-toolbar";
import { renderServiceMessage } from "./render-service-message";
import { renderErrorInModal } from "./rendering/display-popup-modal";
Expand All @@ -28,12 +28,12 @@ if (!notificationsContainer) {
throw new Error("Could not find issues container");
}

export const notifications = void fetchNotifications();
export const pullRequestNotifications = void fetchPullRequestNotifications();

void (async function home() {
void authentication();
// void readyToolbar();
void displayNotifications();
void readyToolbar();
// void displayNotifications();

// Register service worker for PWA
// if ("serviceWorker" in navigator) {
Expand Down
2 changes: 1 addition & 1 deletion src/home/rendering/render-github-issues.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { marked } from "marked";
import { organizationImageCache } from "../fetch-github/fetch-notifications";
import { organizationImageCache } from "../fetch-github/fetch-data";
import { GitHubNotification, GitHubNotifications } from "../github-types";
import { renderErrorInModal } from "./display-popup-modal";
import { closeModal, modal, modalBodyInner, bottomBar, titleAnchor, titleHeader, bottomBarClearLabels } from "./render-preview-modal";
Expand Down
2 changes: 1 addition & 1 deletion src/home/rendering/render-org-header.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { organizationImageCache } from "../fetch-github/fetch-notifications";
import { organizationImageCache } from "../fetch-github/fetch-data";

export function renderOrgHeaderLabel(orgName: string): void {
const brandingDiv = document.getElementById("branding");
Expand Down

0 comments on commit 0544b6b

Please sign in to comment.