From 3eb44b51f732e6f51dc6f94b1965f2d280cd638f Mon Sep 17 00:00:00 2001
From: Dave Pagurek
Date: Sun, 7 Apr 2024 12:01:24 -0400
Subject: [PATCH 1/4] Fetch extra library info from NPM
---
.../LibrarySourceLink/LinkCopier.tsx | 20 +++
src/components/LibrarySourceLink/index.astro | 8 ++
src/content/libraries/config.ts | 22 ++-
src/layouts/LibrariesLayout.astro | 134 ++++++++++++++----
4 files changed, 159 insertions(+), 25 deletions(-)
create mode 100644 src/components/LibrarySourceLink/LinkCopier.tsx
create mode 100644 src/components/LibrarySourceLink/index.astro
diff --git a/src/components/LibrarySourceLink/LinkCopier.tsx b/src/components/LibrarySourceLink/LinkCopier.tsx
new file mode 100644
index 0000000000..faa40215c0
--- /dev/null
+++ b/src/components/LibrarySourceLink/LinkCopier.tsx
@@ -0,0 +1,20 @@
+import { useState } from "preact/hooks"
+
+export const LinkCopier = (props: { link: string; children: any }) => {
+ const [copied, setCopied] = useState(false);
+ const onClick = () => {
+ navigator.clipboard.writeText(
+ ``
+ );
+ setCopied(true);
+ }
+
+ return (
+ <>
+
+ {props.children}
+
+ {copied && Copied ✔️}
+ >
+ )
+}
diff --git a/src/components/LibrarySourceLink/index.astro b/src/components/LibrarySourceLink/index.astro
new file mode 100644
index 0000000000..648725c2e2
--- /dev/null
+++ b/src/components/LibrarySourceLink/index.astro
@@ -0,0 +1,8 @@
+---
+const { props } = Astro;
+import { LinkCopier } from './LinkCopier'
+---
+
+
+
+
diff --git a/src/content/libraries/config.ts b/src/content/libraries/config.ts
index e818b9d0cf..ba004d8072 100644
--- a/src/content/libraries/config.ts
+++ b/src/content/libraries/config.ts
@@ -1,7 +1,7 @@
import { z, defineCollection } from "astro:content";
import { author } from "../shared";
-const categories = [
+export const categories = [
"drawing",
"color",
"ui",
@@ -21,6 +21,26 @@ const categories = [
"utils",
] as const;
+export const categoryNames: { [key in (typeof categories)[number] ]: string } = {
+ drawing: 'Drawing',
+ color: 'Color',
+ ui: 'User Interface',
+ math: 'Math',
+ physics: 'Physics',
+ algorithms: 'Algorithms',
+ '3d': '3D',
+ 'ai-ml-cv': 'AI, ML, and CV',
+ animation: 'Animation',
+ shaders: 'Shaders',
+ language: 'Language',
+ hardware: 'Hardware',
+ sound: 'Sound',
+ data: 'Data',
+ networking: 'Networking',
+ export: 'Export',
+ utils: 'Utilities',
+}
+
/**
* Content collection for the Libraries section of the site.
*/
diff --git a/src/layouts/LibrariesLayout.astro b/src/layouts/LibrariesLayout.astro
index e64db2008e..c4cfb9e675 100644
--- a/src/layouts/LibrariesLayout.astro
+++ b/src/layouts/LibrariesLayout.astro
@@ -4,37 +4,123 @@ import { getLibraryLink } from "@pages/_utils";
import type { CollectionEntry } from "astro:content";
import BaseLayout from "./BaseLayout.astro";
import { Image } from "astro:assets";
+import { categories, categoryNames } from '../content/libraries/config';
+import LibrarySourceLink from '../components/LibrarySourceLink/index.astro';
+type LibraryEntry = CollectionEntry<"libraries">
interface Props {
- entries: CollectionEntry<"libraries">[];
+ entries: LibraryEntry[];
title: string;
}
const { entries } = Astro.props;
+
+async function npmInfo(lib: LibraryEntry) {
+ try {
+ const res = await fetch(`https://registry.npmjs.org/${lib.data.npm}`);
+ const data = await res.json();
+ return data;
+ } catch (e) {
+ console.error(`Could not fetch ${lib.data.name} on npm via ${lib.data.npm}!`)
+ throw e;
+ }
+}
+
+function cdnLink(lib: LibraryEntry, data: any) {
+ const latestVersion = data['dist-tags'].latest
+ let link = `https://cdn.jsdelivr.net/npm/${lib.data.npm}@${latestVersion}`;
+ if (lib.data.npmFilePath) {
+ link += `/${lib.data.npmFilePath}`;
+ }
+ return link;
+}
+
+function strCompare(a: string, b: string) {
+ if (a < b) {
+ return -1;
+ }
+ if (a > b) {
+ return 1;
+ }
+ return 0;
+}
+
+function descriptionString(lib: LibraryEntry) {
+ let result = lib.data.description.trim();
+ if (/\w$/.test(result)) {
+ result += ', by';
+ } else if (/[\.!?]$/.test(result)) {
+ result += ' By';
+ } else {
+ result += '. By';
+ }
+ return result;
+}
+
+const libraryTag = 'p-1 rounded-full border-solid border-black border mb-1 mr-1 inline-block text-xs'
+
+const sections = await Promise.all(categories.map(async (slug) => {
+ const name = categoryNames[slug];
+ const sectionEntries = await Promise.all(
+ entries
+ .filter((e: LibraryEntry) => e.data.category === slug)
+ .sort((a: LibraryEntry, b: LibraryEntry) => strCompare(a.data.name, b.data.name))
+ .map(async (lib: LibraryEntry) => {
+ if (lib.data.npm) {
+ const data = await npmInfo(lib);
+ const modifiedDate = new Date(data.time.modified);
+ const npmData = {
+ link: cdnLink(lib, data),
+ lastUpdated: `${modifiedDate.toLocaleString('default', { month: 'short' })} ${modifiedDate.getFullYear()}`,
+ };
+ const license = lib.data.license || data.license;
+ return { lib, npmData, license };
+ } else {
+ return { lib, npmData: undefined, license: lib.data.license };
+ }
+ })
+ );
+
+ return { slug, name, sectionEntries };
+}));
---
-
+ {sections.map(({ slug, name, sectionEntries }) => (
+ <>
+ {name}
+
+ >
+ ))}
From 99e82c27d896dd124e9f05f0a1c806d71497f26e Mon Sep 17 00:00:00 2001
From: Dave Pagurek
Date: Tue, 9 Apr 2024 20:16:20 -0400
Subject: [PATCH 2/4] Different tag ui
---
src/layouts/LibrariesLayout.astro | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/layouts/LibrariesLayout.astro b/src/layouts/LibrariesLayout.astro
index c4cfb9e675..ec759172e4 100644
--- a/src/layouts/LibrariesLayout.astro
+++ b/src/layouts/LibrariesLayout.astro
@@ -57,7 +57,7 @@ function descriptionString(lib: LibraryEntry) {
return result;
}
-const libraryTag = 'p-1 rounded-full border-solid border-black border mb-1 mr-1 inline-block text-xs'
+const libraryTag = 'py-1 px-2 rounded-lg bg-[var(--accent-color)] mb-1 mr-1 block text-xs'
const sections = await Promise.all(categories.map(async (slug) => {
const name = categoryNames[slug];
@@ -91,7 +91,7 @@ const sections = await Promise.all(categories.map(async (slug) => {
{name}
{sectionEntries.map(({ lib, npmData, license }) => (
- -
+
-
{lib.data.featuredImageAlt && lib.data.featuredImage && (
{
)}
{lib.data.name}
-
+
{descriptionString(lib)}
{lib.data.author.map((a: { name: string, url?: string }, i) => (
<>
@@ -111,10 +111,10 @@ const sections = await Promise.all(categories.map(async (slug) => {
>
))}
-
+
{npmData && - Updated {npmData.lastUpdated}
}
- Source
- {license && - {license} License
}
+ {/*license && - {license} License
*/}
{lib.data.npm && - NPM
}
{npmData && - Copy Script Tag
}
From cb5e25c8a3cb113b46f9d12074de33bee7fc05aa Mon Sep 17 00:00:00 2001
From: Dave Pagurek
Date: Tue, 9 Apr 2024 20:30:55 -0400
Subject: [PATCH 3/4] Rearrange items a bit
---
src/content/libraries/config.ts | 39 ++++++++++++-----------
src/content/libraries/en/concaveHull.yaml | 2 +-
src/content/libraries/en/p5.teach.js.yaml | 2 +-
src/layouts/LibrariesLayout.astro | 11 ++++---
4 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/src/content/libraries/config.ts b/src/content/libraries/config.ts
index d58b2adf9b..9d57d84a66 100644
--- a/src/content/libraries/config.ts
+++ b/src/content/libraries/config.ts
@@ -22,25 +22,26 @@ export const categories = [
"utils",
] as const;
-export const categoryNames: { [key in (typeof categories)[number] ]: string } = {
- drawing: 'Drawing',
- color: 'Color',
- ui: 'User Interface',
- math: 'Math',
- physics: 'Physics',
- algorithms: 'Algorithms',
- '3d': '3D',
- 'ai-ml-cv': 'AI, ML, and CV',
- animation: 'Animation',
- shaders: 'Shaders',
- language: 'Language',
- hardware: 'Hardware',
- sound: 'Sound',
- data: 'Data',
- networking: 'Networking',
- export: 'Export',
- utils: 'Utilities',
-}
+export const categoryNames: { [key in (typeof categories)[number]]: string } = {
+ drawing: "Drawing",
+ color: "Color",
+ ui: "User Interface",
+ math: "Math",
+ physics: "Physics",
+ algorithms: "Algorithms",
+ "3d": "3D",
+ "ai-ml-cv": "AI, ML, and CV",
+ animation: "Animation",
+ shaders: "Shaders",
+ language: "Language",
+ hardware: "Hardware",
+ sound: "Sound",
+ data: "Data",
+ teaching: "Teaching",
+ networking: "Networking",
+ export: "Export",
+ utils: "Utilities",
+};
/**
* Content collection for the Libraries section of the site.
diff --git a/src/content/libraries/en/concaveHull.yaml b/src/content/libraries/en/concaveHull.yaml
index 007899529e..7eb01dc77b 100644
--- a/src/content/libraries/en/concaveHull.yaml
+++ b/src/content/libraries/en/concaveHull.yaml
@@ -8,4 +8,4 @@ author:
name: Mark Roland
url: https://markroland.com
npm: "@markroland/concave-hull"
-license: Creative Commons Attribution-ShareAlike 4.0 International License
+license: CC BY-SA 4.0
diff --git a/src/content/libraries/en/p5.teach.js.yaml b/src/content/libraries/en/p5.teach.js.yaml
index 2080792f4e..9194cd67a2 100644
--- a/src/content/libraries/en/p5.teach.js.yaml
+++ b/src/content/libraries/en/p5.teach.js.yaml
@@ -1,6 +1,6 @@
name: p5.teach.js
description: A beginner friendly math animation library for p5.js
-category: math
+category: teaching
sourceUrl: https://github.com/two-ticks/p5.teach.js
featuredImage: ../images/p5.teach.js.png
featuredImageAlt: Wave equation on the upper left corner and right upper corner has a graph of cosine function plus some polynomial terms. A logo and description of 'p5.teach.js' library are placed in the center.
diff --git a/src/layouts/LibrariesLayout.astro b/src/layouts/LibrariesLayout.astro
index c83d21b02d..875845b6f4 100644
--- a/src/layouts/LibrariesLayout.astro
+++ b/src/layouts/LibrariesLayout.astro
@@ -58,14 +58,15 @@ function descriptionString(lib: LibraryEntry) {
return result;
}
-const libraryTag = 'py-1 px-2 rounded-lg bg-[var(--accent-color)] mb-1 mr-1 block text-xs'
+const libraryTag = 'whitespace-nowrap py-1 px-2 rounded-lg bg-[var(--accent-color)] mb-1 mr-1 block text-xs'
+const libraryInfo = 'whitespace-nowrap py-1 px-2 mb-1 mr-1 block text-xs'
const sections = await Promise.all(categories.map(async (slug) => {
const name = categoryNames[slug];
const sectionEntries = await Promise.all(
entries
.filter((e: LibraryEntry) => e.data.category === slug)
- .sort((a: LibraryEntry, b: LibraryEntry) => strCompare(a.data.name, b.data.name))
+ .sort((a: LibraryEntry, b: LibraryEntry) => strCompare(a.data.name.toLowerCase(), b.data.name.toLowerCase()))
.map(async (lib: LibraryEntry) => {
if (lib.data.npm) {
const data = await npmInfo(lib);
@@ -112,12 +113,12 @@ const sections = await Promise.all(categories.map(async (slug) => {
>
))}
-
- {npmData && - Updated {npmData.lastUpdated}
}
+
- Source
- {/*license && - {license} License
*/}
{lib.data.npm && - NPM
}
{npmData && - Copy Script Tag
}
+ {npmData && - Updated {npmData.lastUpdated}
}
+ {license && - {license}
}
))}
From f85cf6baa0728168e7d44a56987bfae4328ce711 Mon Sep 17 00:00:00 2001
From: Dave Pagurek
Date: Tue, 9 Apr 2024 20:32:58 -0400
Subject: [PATCH 4/4] Remove duplicate import
---
src/layouts/LibrariesLayout.astro | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/layouts/LibrariesLayout.astro b/src/layouts/LibrariesLayout.astro
index 875845b6f4..76d9f7565f 100644
--- a/src/layouts/LibrariesLayout.astro
+++ b/src/layouts/LibrariesLayout.astro
@@ -3,7 +3,6 @@ import { getLibraryLink } from "@pages/_utils";
import type { CollectionEntry } from "astro:content";
import BaseLayout from "./BaseLayout.astro";
-import { Image } from "astro:assets";
import { categories, categoryNames } from '../content/libraries/config';
import LibrarySourceLink from '../components/LibrarySourceLink/index.astro';
import Image from "@components/Image/index.astro";