Skip to content

Commit 37a5396

Browse files
authored
Merge branch 'main' into 415-attrib
2 parents 9353c52 + da3a49c commit 37a5396

File tree

267 files changed

+6534
-3603
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

267 files changed

+6534
-3603
lines changed

public/reference/data.json

Lines changed: 1437 additions & 1646 deletions
Large diffs are not rendered by default.

public/search-indices/en.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

public/search-indices/es.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

public/search-indices/hi.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

public/search-indices/ko.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

public/search-indices/zh-Hans.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/api/OpenProcessing.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ export type OpenProcessingCurationResponse = Array<{
2323
title: string;
2424
/** Description of sketch */
2525
description: string;
26+
instructions: string;
27+
mode: string;
28+
createdOn: string;
2629
userID: string;
2730
submittedOn: string;
2831
/** Author's name */
@@ -36,16 +39,19 @@ export type OpenProcessingCurationResponse = Array<{
3639
* @param limit max number of sketches to return
3740
* @returns sketches
3841
*/
39-
export const getCurationSketches = async (
42+
export const getCurationSketches = memoize(async (
4043
limit?: number,
4144
): Promise<OpenProcessingCurationResponse> => {
4245
const limitParam = limit ? `limit=${limit}` : "";
4346
const response = await fetch(
4447
`${openProcessingEndpoint}curation/${curationId}/sketches?${limitParam}`,
4548
);
49+
if(!response.ok){ //log error instead of throwing error to not cache result in memoize
50+
console.error('getCurationSketches', response.status, response.statusText)
51+
}
4652
const payload = await response.json();
4753
return payload as OpenProcessingCurationResponse;
48-
};
54+
});
4955

5056
/**
5157
* API Response from a call to the Sketch endpoint
@@ -69,26 +75,50 @@ export type OpenProcessingSketchResponse = {
6975

7076
/**
7177
* Get info about a specific sketch from the OpenProcessing API
78+
* First checks if the sketch is in the memoized curated sketches and returns the data if so,
79+
* Otherwise calls OpenProcessing API for this specific sketch
7280
*
7381
* https://documenter.getpostman.com/view/16936458/2s9YC1Xa6X#7cd344f6-6e87-426a-969b-2b4a79701dd1
7482
* @param id
7583
* @returns
7684
*/
77-
export const getSketch = memoize(async (
78-
id: string,
79-
): Promise<OpenProcessingSketchResponse> => {
85+
export const getSketch = memoize(
86+
async (id: string): Promise<OpenProcessingSketchResponse> => {
87+
// check for memoized sketch in curation sketches
88+
const curationSketches = await getCurationSketches();
89+
const memoizedSketch = curationSketches.find((el) => el.visualID === id);
90+
if (memoizedSketch) {
91+
return {
92+
...memoizedSketch,
93+
license: "",
94+
} as OpenProcessingSketchResponse;
95+
}
96+
97+
// check for sketch data in Open Processing API
8098
const response = await fetch(`${openProcessingEndpoint}sketch/${id}`);
99+
if (!response.ok) {
100+
//log error instead of throwing error to not cache result in memoize
101+
console.error("getSketch", id, response.status, response.statusText);
102+
}
81103
const payload = await response.json();
82104
return payload as OpenProcessingSketchResponse;
83105
});
84106

107+
/**
108+
* Note: this currently calls `/api/sketch/:id/code`
109+
* But only uses the width and height properties from this call
110+
* Width and height should instead be added to properties for `/api/sketch/:id` or `api/curation/:curationId/sketches` instead
111+
*/
85112
export const getSketchSize = memoize(async (id: string) => {
86113
const sketch = await getSketch(id)
87114
if (sketch.mode !== 'p5js') {
88115
return { width: undefined, height: undefined };
89116
}
90117

91118
const response = await fetch(`${openProcessingEndpoint}sketch/${id}/code`);
119+
if(!response.ok){ //log error instead of throwing error to not cache result in memoize
120+
console.error('getSketchSize', id, response.status, response.statusText)
121+
}
92122
const payload = await response.json();
93123

94124
for (const tab of payload) {

src/components/CodeEmbed/frame.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef, useLayoutEffect, useEffect } from "preact/hooks";
1+
import { useRef, useLayoutEffect, useEffect, useState } from "preact/hooks";
22
import { cdnLibraryUrl } from "@/src/globals/globals";
33

44
interface CodeBundle {
@@ -42,7 +42,9 @@ canvas {
4242
}
4343
${code.css || ""}
4444
</style>
45-
${(code.scripts ? [cdnLibraryUrl, ...code.scripts] : []).map((src) => `<script type="text/javascript" src="${src}"></script>`).join('\n')}
45+
<!-- If we need an addon script, load p5 the usual way with no caching to make sure
46+
the import order doesn't get messed up. -->
47+
${((code.scripts?.length ?? 0) > 0 ? [cdnLibraryUrl, ...(code.scripts ?? [])] : []).map((src) => `<script type="text/javascript" src="${src}"></script>`).join('\n')}
4648
<body>${code.htmlBody || ""}</body>
4749
<script id="code" type="text/javascript">${wrapSketch(code.js) || ""}</script>
4850
${(code.scripts?.length ?? 0) > 0 ? '' : `
@@ -84,6 +86,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
8486
const p5ScriptTag = document.getElementById(
8587
"p5ScriptTag",
8688
) as HTMLScriptElement;
89+
const [mounted, setMounted] = useState(false);
8790

8891
// For performance, set the iframe to display:none when
8992
// not visible on the page. This will stop the browser
@@ -99,11 +102,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
99102
(entries) => {
100103
entries.forEach((entry) => {
101104
if (!iframeRef.current) return;
102-
if (entry.isIntersecting) {
103-
iframeRef.current.style.removeProperty("display");
104-
} else {
105-
iframeRef.current.style.display = "none";
106-
}
105+
setMounted(entry.isIntersecting);
107106
});
108107
},
109108
{ rootMargin: "20px" },
@@ -116,6 +115,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
116115
useEffect(() => {
117116
(async () => {
118117
if (!p5ScriptTag || !iframeRef.current) return;
118+
if (!mounted) return;
119119

120120
/*
121121
* Uses postMessage to receive the text content of p5.min.js, to be included
@@ -146,7 +146,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
146146
return;
147147
}
148148
})();
149-
}, [props.jsCode]);
149+
}, [props.jsCode, mounted]);
150150

151151
return (
152152
<div
@@ -155,13 +155,13 @@ export const CodeFrame = (props: CodeFrameProps) => {
155155
>
156156
<iframe
157157
ref={iframeRef}
158-
srcDoc={wrapInMarkup({
158+
srcDoc={mounted ? wrapInMarkup({
159159
js: props.jsCode,
160160
css: props.cssCode,
161161
htmlBody: props.htmlBodyCode,
162162
base: props.base,
163163
scripts: props.scripts,
164-
})}
164+
}) : undefined}
165165
sandbox="allow-scripts allow-popups allow-modals allow-forms allow-same-origin"
166166
aria-label="Code Preview"
167167
title="Code Preview"

src/components/CodeEmbed/index.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ export const CodeEmbed = (props) => {
6767
setRendered(true);
6868

6969
// Includes p5.min.js script to be used by `CodeFrame` iframe(s)
70-
const p5ScriptElement = document.createElement("script");
71-
p5ScriptElement.id = "p5ScriptTag";
72-
p5ScriptElement.src = cdnLibraryUrl;
73-
document.head.appendChild(p5ScriptElement);
70+
if (!document.getElementById("p5ScriptTag")) {
71+
const p5ScriptElement = document.createElement("script");
72+
p5ScriptElement.id = "p5ScriptTag";
73+
p5ScriptElement.src = cdnLibraryUrl;
74+
document.head.appendChild(p5ScriptElement);
75+
}
7476
}, []);
7577

7678
if (!rendered) return <div className="code-placeholder" />;

src/components/ReferenceDirectoryWithFilter/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,25 @@ export const ReferenceDirectoryWithFilter = ({
7272

7373
return categoryData.reduce((acc: FilteredCategoryData[], category) => {
7474
const filteredSubcats = category.subcats.reduce(
75-
(subAcc, subcat) => {
75+
(subAcc: typeof category.subcats, subcat) => {
7676
const filteredEntries = subcat.entries.filter((entry) =>
7777
entry.data.title
7878
.toLowerCase()
7979
.includes(searchKeyword.toLowerCase()),
8080
);
81+
if (
82+
subcat.entry &&
83+
subcat.entry.data.title.toLowerCase().includes(searchKeyword.toLowerCase())
84+
) {
85+
filteredEntries.push(subcat.entry);
86+
}
87+
8188
if (filteredEntries.length > 0) {
8289
subAcc.push({ ...subcat, entries: filteredEntries });
8390
}
8491
return subAcc;
8592
},
86-
[] as typeof category.subcats,
93+
[],
8794
);
8895

8996
if (filteredSubcats.length > 0) {

0 commit comments

Comments
 (0)