Skip to content

Commit

Permalink
feat: display issues
Browse files Browse the repository at this point in the history
  • Loading branch information
0x4007 committed Nov 29, 2023
1 parent fe77dbf commit 80af145
Show file tree
Hide file tree
Showing 7 changed files with 434 additions and 76 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"@typescript-eslint/parser": "^6.13.1",
"esbuild": "^0.19.8",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"husky": "^8.0.3",
"knip": "^3.3.0",
"lint-staged": "^15.1.0",
Expand Down
48 changes: 48 additions & 0 deletions static/main-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Octokit } from "@octokit/rest";
import { GitHubIssue } from "./github-types";
import { displayIssues } from "./scripts/display-issues";

export async function mainModule() {
const container = document.getElementById("issues-container") as HTMLDivElement;
if (!container) {
throw new Error("Could not find issues container");
}
await fetchIssues();

async function fetchIssues() {
try {
const cachedIssues = localStorage.getItem("githubIssues");

if (cachedIssues) {
try {
const issues = JSON.parse(cachedIssues);
const sortedIssues = sortIssuesByComments(issues);
displayIssues(container, sortedIssues);
} catch (error) {
console.error(error);
}
}

const octokit = new Octokit();

const freshIssues = (await octokit.paginate("GET /repos/ubiquity/devpool-directory/issues")) as GitHubIssue[];
localStorage.setItem("githubIssues", JSON.stringify(freshIssues));
const sortedIssues = sortIssuesByComments(freshIssues);
displayIssues(container, sortedIssues);
} catch (error) {
container.innerHTML = `<p>Error loading issues: ${error}</p>`;
}
}

function sortIssuesByComments(issues: GitHubIssue[]) {
return issues.sort((a, b) => {
if (a.comments > b.comments) {
return -1;
}
if (a.comments < b.comments) {
return 1;
}
return 0;
});
}
}
60 changes: 1 addition & 59 deletions static/main.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,5 @@
import { Octokit } from "@octokit/rest";
import { GitHubIssue } from "./github-types";
import { mainModule } from "./main-module";

export async function mainModule() {
await fetchIssues();

async function fetchIssues() {
const container = document.getElementById("issues-container");
if (!container) {
throw new Error("Could not find issues container");
}
container.innerHTML = "<p>Loading issues...</p>";

try {
const cachedIssues = localStorage.getItem("githubIssues");
let issues: GitHubIssue[];

const octokit = new Octokit();
const freshIssues = await octokit.paginate("GET /repos/ubiquity/devpool-directory/issues") as GitHubIssue[];

if (cachedIssues) {
issues = JSON.parse(cachedIssues);
// Update the cache with fresh issues
localStorage.setItem("githubIssues", JSON.stringify(freshIssues));
} else {
issues = freshIssues;
localStorage.setItem("githubIssues", JSON.stringify(issues));
}

const sortedIssues = sortIssuesByComments(issues);
displayIssues(sortedIssues);
} catch (error) {
container.innerHTML = `<p>Error loading issues: ${error}</p>`;
}
}

function displayIssues(issues: GitHubIssue[]) {
const container = document.getElementById("issues-container");
issues.forEach((issue) => {
const issueElement = document.createElement("div");
issueElement.innerHTML = `
<h3>${issue.title}</h3>
<p>${issue.body}</p>
`;
container?.appendChild(issueElement);
});
}

function sortIssuesByComments(issues: GitHubIssue[]) {
return issues.sort((a, b) => {
if (a.comments > b.comments) {
return -1;
}
if (a.comments < b.comments) {
return 1;
}
return 0;
});
}
}
mainModule()
.then(() => {
console.log("mainModule loaded");
Expand Down
52 changes: 52 additions & 0 deletions static/scripts/display-issues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { GitHubIssue } from "../github-types";

export function displayIssues(container: HTMLDivElement, issues: GitHubIssue[]) {
container.innerHTML = "";
let delay = 0;
const baseDelay = 125; // Base delay in milliseconds

issues.forEach((issue, index) => {
const issueWrapper = document.createElement("div");
const issueElement = document.createElement("div");
issueWrapper.classList.add("issue-element-wrapper");
issueElement.classList.add("issue-element-inner");
issueWrapper.classList.add("issue-fade-in");

// Calculate the delay using an approximation of the cubic-bezier(0,1,1,1) easing function
delay = baseDelay * ((index * index) / (issues.length - 1));

issueElement.style.animationDelay = `${delay}ms`;

// Parse organization name and repository name from the issue's URL

const urlRegex = /(https?:\/\/[^\s]+)/g;
const mirrorUrls = issue.body.match(urlRegex);

const urlPattern = /https:\/\/github\.com\/([^/]+)\/([^/]+)\//;
const match = mirrorUrls?.shift()?.match(urlPattern);
const organizationName = match?.[1];
const repositoryName = match?.[2];

issueElement.innerHTML = `
<h3>${issue.title}</h3>
<p class="organization-name">${organizationName}</p>
<p class="repository-name">${repositoryName}</p>
`;

issueElement.addEventListener("click", () => {
console.log(issue);

// console.log(foundUrls);
// window.open(foundUrls?.shift(), "_blank");
});

issueWrapper.appendChild(issueElement);

// Append the issue element after the delay
setTimeout(() => {
container.appendChild(issueWrapper);
// Trigger the animation by adding the 'visible' class
issueElement.classList.add("visible");
}, delay);
});
}
105 changes: 91 additions & 14 deletions static/style.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
html,
body {
font-family: "Proxima Nova", "Ubiquity Nova", sans-serif;
background-color: #06061aff;
color: #fff;
margin: 0;
padding: 0;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABYWlDQ1BrQ0dDb2xvclNwYWNlRGlzcGxheVAzAAAokWNgYFJJLCjIYWFgYMjNKykKcndSiIiMUmB/yMAOhLwMYgwKicnFBY4BAT5AJQwwGhV8u8bACKIv64LMOiU1tUm1XsDXYqbw1YuvRJsw1aMArpTU4mQg/QeIU5MLikoYGBhTgGzl8pICELsDyBYpAjoKyJ4DYqdD2BtA7CQI+whYTUiQM5B9A8hWSM5IBJrB+API1klCEk9HYkPtBQFul8zigpzESoUAYwKuJQOUpFaUgGjn/ILKosz0jBIFR2AopSp45iXr6SgYGRiaMzCAwhyi+nMgOCwZxc4gxJrvMzDY7v////9uhJjXfgaGjUCdXDsRYhoWDAyC3AwMJ3YWJBYlgoWYgZgpLY2B4dNyBgbeSAYG4QtAPdHFacZGYHlGHicGBtZ7//9/VmNgYJ/MwPB3wv//vxf9//93MVDzHQaGA3kAFSFl7jXH0fsAAAA4ZVhJZk1NACoAAAAIAAGHaQAEAAAAAQAAABoAAAAAAAKgAgAEAAAAAQAAABigAwAEAAAAAQAAABgAAAAAwf1XlwAAACNJREFUSA3t0IEAAAAMBKFHm7/UTaQQWnXDgAEDBgwYMGDgAXaJAz4RVVHYAAAAAElFTkSuQmCC");
}
* {
font-family: "Proxima Nova", "Ubiquity Nova", sans-serif;
color: #fff;
font-weight: 400;
/* opacity:0.875; */
}
@font-face {
font-family: "Ubiquity Nova";
font-style: normal;
Expand All @@ -15,28 +22,98 @@ body {
url(./fonts/ubiquity-nova-standard.ttf) format("truetype");
}

#issues-container {
margin: 20px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 8px;
@keyframes fadeIn {
from {
opacity: 0;
/* background-color: #fff; */
filter: blur(16px);
margin-left: 100vw;
}
to {
opacity: 0.75;
/* background-color: transparent; */
filter: blur(0px);
margin-left: 1px;
}
}

.issue-fade-in {
animation-name: fadeIn;
animation-duration: 0.5s;
animation-fill-mode: forwards;
opacity: 0;
animation-timing-function: cubic-bezier(0, 1, 1, 1);
}

#issues-container div {
padding: 10px;
border-bottom: 1px solid #eee;
#issues-container {
/* margin: 20px; */
/* padding: 10px; */
/* border: 1px solid #808080; */
/* border-radius: 8px; */
padding: 8px;
/* border-left: 1px solid; */
}

#issues-container div:last-child {
#issues-container > div:first-child {
border-top: 1px solid #80808040;
}
#issues-container > div:last-child {
border-bottom: 1px solid #80808040;
}
/* #issues-container > div:last-child {
border-bottom: none;
} */
#issues-container > div {
padding: 8px 16px;
border-bottom: 1px solid #80808040;
/* opacity: 0.875 */
/* margin: 24px auto; */
/* line-height: 1; */
overflow: hidden;
border-left: 1px solid #80808040;
cursor: pointer;
}
#issues-container > div:hover {
opacity: 1 !important;
border-left: 4px solid #808080;
padding-left: 13px;
}
#issues-container > div:active {
border-left: 4px solid #fff;
}

h3 {
margin: 0 0 10px 0;
color: #333;
margin: auto;
line-height: 1;
white-space: pre;
font-size: 16px;
/* font-weight: 100; */
}

p {
margin: 0;
color: #666;
line-height: 1;
color: #ffffffbf;
font-size: 12px;
text-align: right;
letter-spacing: 0.5px;
text-rendering: geometricPrecision;
position: absolute;
top: 0;
right: 0;
}

.issue-element-inner {
margin: 12px auto;
position: relative;
}

p.organization-name {
/* margin-bottom: 12px; */
opacity: 0.5;
transform: translateY(-50%);
}
p.repository-name {
/* margin-top: 12px; */
transform: translateY(50%);
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./static/dist", /* Specify an output folder for all emitted files. */
"outDir": "./static/dist" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
Expand Down
Loading

0 comments on commit 80af145

Please sign in to comment.