diff --git a/Dockerfile b/Dockerfile
index ac21908220..3c18288058 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,6 +14,7 @@ COPY .babelrc index.js nodemon.json ./
COPY ./webpack ./webpack
COPY client ./client
COPY server ./server
+COPY common ./common
COPY translations/locales ./translations/locales
COPY public ./public
CMD ["npm", "start"]
diff --git a/client/modules/IDE/components/Preferences/index.jsx b/client/modules/IDE/components/Preferences/index.jsx
index 2b8b8e19fd..b9f5dd2b3a 100644
--- a/client/modules/IDE/components/Preferences/index.jsx
+++ b/client/modules/IDE/components/Preferences/index.jsx
@@ -21,7 +21,12 @@ import {
setLinewrap,
setPreferencesTab
} from '../../actions/preferences';
-import { p5SoundURL, p5URL, useP5Version } from '../../hooks/useP5Version';
+import {
+ majorVersion,
+ p5SoundURL,
+ p5URL,
+ useP5Version
+} from '../../hooks/useP5Version';
import VersionPicker from '../VersionPicker';
import { updateFileContent } from '../../actions/files';
import { CmControllerContext } from '../../pages/IDEView';
@@ -55,7 +60,7 @@ export default function Preferences() {
const timerRef = useRef(null);
const pickerRef = useRef(null);
const onChangeVersion = (version) => {
- const shouldShowStars = version.startsWith('2.');
+ const shouldShowStars = majorVersion(version) === '2';
const box = pickerRef.current?.getBoundingClientRect();
if (shouldShowStars) {
setShowStars({ left: box?.left || 0, top: box?.top || 0 });
@@ -578,17 +583,7 @@ export default function Preferences() {
{
- if (versionInfo.lastP5SoundURL) {
- // If the sketch previously used a nonstandard p5.sound
- // URL, restore that URL
- updateHTML(
- versionInfo.setP5SoundURL(versionInfo.lastP5SoundURL)
- );
- versionInfo.setLastP5SoundURL(undefined);
- } else {
- // Otherwise, turn on the default p5.sound URL
- updateHTML(versionInfo.setP5Sound(true));
- }
+ updateHTML(versionInfo.setP5Sound(true));
}}
aria-label={`${t('Preferences.SoundAddon')} ${t(
'Preferences.AddonOn'
@@ -605,12 +600,6 @@ export default function Preferences() {
{
- // If the previous p5.sound.js script tag is not the
- // default version that one will get via this toggle,
- // record it so we can give the option to put it back
- if (versionInfo.p5SoundURL !== p5SoundURL) {
- versionInfo.setLastP5SoundURL(versionInfo.p5SoundURL);
- }
updateHTML(versionInfo.setP5Sound(false));
}}
aria-label={`${t('Preferences.SoundAddon')} ${t(
@@ -628,11 +617,20 @@ export default function Preferences() {
>
{t('Preferences.Off')}
- {versionInfo.lastP5SoundURL && (
-
- )}
+
diff --git a/client/modules/IDE/components/VersionPicker.jsx b/client/modules/IDE/components/VersionPicker.jsx
index a42743d353..c80a35e806 100644
--- a/client/modules/IDE/components/VersionPicker.jsx
+++ b/client/modules/IDE/components/VersionPicker.jsx
@@ -5,7 +5,8 @@ import PropTypes from 'prop-types';
import styled from 'styled-components';
import { prop } from '../../../theme';
-import { useP5Version, p5Versions } from '../hooks/useP5Version';
+import { useP5Version } from '../hooks/useP5Version';
+import { p5Versions } from '../../../../common/p5Versions';
import MenuItem from '../../../components/Dropdown/MenuItem';
import DropdownMenu from '../../../components/Dropdown/DropdownMenu';
import { updateFileContent } from '../actions/files';
diff --git a/client/modules/IDE/hooks/useP5Version.jsx b/client/modules/IDE/hooks/useP5Version.jsx
index 03ba3d0da4..643a01cf7e 100644
--- a/client/modules/IDE/hooks/useP5Version.jsx
+++ b/client/modules/IDE/hooks/useP5Version.jsx
@@ -1,150 +1,17 @@
/* eslint-disable func-names */
-import React, { useContext, useMemo, useState } from 'react';
+import React, { useContext, useMemo } from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
+import { currentP5Version, p5Versions } from '../../../../common/p5Versions';
-// Generated from https://www.npmjs.com/package/p5?activeTab=versions
-// Run this in the console:
-// JSON.stringify([...document.querySelectorAll('._132722c7')].map(n => n.innerText), null, 2)
-// TODO: use their API for this to grab these at build time?
-export const p5Versions = [
- '2.0.3',
- '2.0.2',
- '2.0.1',
- '2.0.0',
- '1.11.8',
- '1.11.7',
- '1.11.6',
- '1.11.5',
- '1.11.4',
- '1.11.3',
- '1.11.2',
- '1.11.1',
- '1.11.0',
- '1.10.0',
- '1.9.4',
- '1.9.3',
- '1.9.2',
- '1.9.1',
- '1.9.0',
- '1.8.0',
- '1.7.0',
- '1.6.0',
- '1.5.0',
- '1.4.2',
- '1.4.1',
- '1.4.0',
- '1.3.1',
- '1.3.0',
- '1.2.0',
- '1.1.9',
- '1.1.8',
- '1.1.7',
- '1.1.5',
- '1.1.4',
- '1.1.3',
- '1.1.2',
- '1.1.1',
- '1.1.0',
- '1.0.0',
- '0.10.2',
- '0.10.1',
- '0.10.0',
- '0.9.0',
- '0.8.0',
- '0.7.3',
- '0.7.2',
- '0.7.1',
- '0.7.0',
- '0.6.1',
- '0.6.0',
- '0.5.16',
- '0.5.15',
- '0.5.14',
- '0.5.13',
- '0.5.12',
- '0.5.11',
- '0.5.10',
- '0.5.9',
- '0.5.8',
- '0.5.7',
- '0.5.6',
- '0.5.5',
- '0.5.4',
- '0.5.3',
- '0.5.2',
- '0.5.1',
- '0.5.0',
- '0.4.24',
- '0.4.23',
- '0.4.22',
- '0.4.21',
- '0.4.20',
- '0.4.19',
- '0.4.18',
- '0.4.17',
- '0.4.16',
- '0.4.15',
- '0.4.14',
- '0.4.13',
- '0.4.12',
- '0.4.11',
- '0.4.10',
- '0.4.9',
- '0.4.8',
- '0.4.7',
- '0.4.6',
- '0.4.5',
- '0.4.4',
- '0.4.3',
- '0.4.2',
- '0.4.1',
- '0.4.0',
- '0.3.16',
- '0.3.15',
- '0.3.14',
- '0.3.13',
- '0.3.12',
- '0.3.11',
- '0.3.10',
- '0.3.9',
- '0.3.8',
- '0.3.7',
- '0.3.6',
- '0.3.5',
- '0.3.4',
- '0.3.3',
- '0.3.2',
- '0.3.1',
- '0.3.0',
- '0.2.23',
- '0.2.22',
- '0.2.21',
- '0.2.20',
- '0.2.19',
- '0.2.18',
- '0.2.17',
- '0.2.16',
- '0.2.15',
- '0.2.14',
- '0.2.13',
- '0.2.12',
- '0.2.11',
- '0.2.10',
- '0.2.9',
- '0.2.8',
- '0.2.7',
- '0.2.6',
- '0.2.5',
- '0.2.4',
- '0.2.3',
- '0.2.2',
- '0.2.1'
-];
+export const majorVersion = (version) => version.split('.')[0];
-export const currentP5Version = '1.11.5'; // Don't update to 2.x until 2026
-
-export const p5SoundURLOld = `https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/addons/p5.sound.min.js`;
+export const p5SoundURLOldTemplate =
+ 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/$VERSION/addons/p5.sound.min.js';
+export const p5SoundURLOld = p5SoundURLOldTemplate.replace(
+ '$VERSION',
+ currentP5Version
+);
export const p5SoundURL =
'https://cdn.jsdelivr.net/npm/p5.sound@0.2.0/dist/p5.sound.min.js';
export const p5PreloadAddonURL =
@@ -168,8 +35,6 @@ export function P5VersionProvider(props) {
const indexSrc = indexFile?.content;
const indexID = indexFile?.id;
- const [lastP5SoundURL, setLastP5SoundURL] = useState(undefined);
-
// { version: string, minified: boolean, replaceVersion: (version: string) => string } | null
const versionInfo = useMemo(() => {
if (!indexSrc) return null;
@@ -207,14 +72,6 @@ export function P5VersionProvider(props) {
// We only know for certain which one we've got if
if (usedP5Versions.length === 1) {
const { version, minified, scriptNode } = usedP5Versions[0];
- const replaceVersion = function (newVersion) {
- const file = minified ? 'p5.min.js' : 'p5.js';
- scriptNode.setAttribute(
- 'src',
- `https://cdn.jsdelivr.net/npm/p5@${newVersion}/lib/${file}`
- );
- return serializeResult();
- };
const p5SoundNode = [
...dom.documentElement.querySelectorAll('script')
@@ -232,7 +89,9 @@ export function P5VersionProvider(props) {
const newNode = document.createElement('script');
newNode.setAttribute(
'src',
- version.startsWith('2') ? p5SoundURL : p5SoundURLOld
+ majorVersion(version) === '2'
+ ? p5SoundURL
+ : p5SoundURLOldTemplate.replace('$VERSION', version)
);
scriptNode.parentNode.insertBefore(newNode, scriptNode.nextSibling);
}
@@ -250,6 +109,31 @@ export function P5VersionProvider(props) {
return serializeResult();
};
+ const replaceVersion = function (newVersion) {
+ const file = minified ? 'p5.min.js' : 'p5.js';
+ scriptNode.setAttribute(
+ 'src',
+ `https://cdn.jsdelivr.net/npm/p5@${newVersion}/lib/${file}`
+ );
+
+ if (p5SoundNode) {
+ if (majorVersion(version) !== majorVersion(newVersion)) {
+ // Turn off p5.sound if the user switched from 1.x to 2.x
+ setP5Sound(false);
+ } else {
+ // Replace the existing p5.sound with the one compatible with
+ // the new version
+ setP5SoundURL(
+ majorVersion(version) === '2'
+ ? p5SoundURL
+ : p5SoundURLOldTemplate.replace('$VERSION', newVersion)
+ );
+ }
+ }
+
+ return serializeResult();
+ };
+
const p5PreloadAddonNode = [
...dom.documentElement.querySelectorAll('script')
].find((s) => s.getAttribute('src') === p5PreloadAddonURL);
@@ -294,14 +178,13 @@ export function P5VersionProvider(props) {
return {
version,
+ isVersion2: majorVersion(version) === '2',
minified,
replaceVersion,
p5Sound: !!p5SoundNode,
setP5Sound,
setP5SoundURL,
p5SoundURL: p5SoundNode?.getAttribute('src'),
- lastP5SoundURL,
- setLastP5SoundURL,
p5PreloadAddon: !!p5PreloadAddonNode,
setP5PreloadAddon,
p5ShapesAddon: !!p5ShapesAddonNode,
diff --git a/client/styles/components/_preferences.scss b/client/styles/components/_preferences.scss
index 0ef44a9e48..b77a6e85fa 100644
--- a/client/styles/components/_preferences.scss
+++ b/client/styles/components/_preferences.scss
@@ -150,8 +150,12 @@
.preference__warning {
@include themify() {
display: contents;
- font-weight: bold;
- color: getThemifyVariable("preferences-warning-color");
+ & a {
+ color: getThemifyVariable('button-background-hover-color');
+ }
+ & a:hover {
+ text-decoration: underline;
+ }
}
}
diff --git a/common/p5Versions.js b/common/p5Versions.js
new file mode 100644
index 0000000000..c467bb7861
--- /dev/null
+++ b/common/p5Versions.js
@@ -0,0 +1,140 @@
+export const currentP5Version = '1.11.8'; // Don't update to 2.x until 2026
+
+// Generated from https://www.npmjs.com/package/p5?activeTab=versions
+// Run this in the console:
+// JSON.stringify([...document.querySelectorAll('._132722c7')].map(n => n.innerText), null, 2)
+// TODO: use their API for this to grab these at build time?
+export const p5Versions = [
+ '2.0.3',
+ '2.0.2',
+ '2.0.1',
+ '2.0.0',
+ '1.11.8',
+ '1.11.7',
+ '1.11.6',
+ '1.11.5',
+ '1.11.4',
+ '1.11.3',
+ '1.11.2',
+ '1.11.1',
+ '1.11.0',
+ '1.10.0',
+ '1.9.4',
+ '1.9.3',
+ '1.9.2',
+ '1.9.1',
+ '1.9.0',
+ '1.8.0',
+ '1.7.0',
+ '1.6.0',
+ '1.5.0',
+ '1.4.2',
+ '1.4.1',
+ '1.4.0',
+ '1.3.1',
+ '1.3.0',
+ '1.2.0',
+ '1.1.9',
+ '1.1.8',
+ '1.1.7',
+ '1.1.5',
+ '1.1.4',
+ '1.1.3',
+ '1.1.2',
+ '1.1.1',
+ '1.1.0',
+ '1.0.0',
+ '0.10.2',
+ '0.10.1',
+ '0.10.0',
+ '0.9.0',
+ '0.8.0',
+ '0.7.3',
+ '0.7.2',
+ '0.7.1',
+ '0.7.0',
+ '0.6.1',
+ '0.6.0',
+ '0.5.16',
+ '0.5.15',
+ '0.5.14',
+ '0.5.13',
+ '0.5.12',
+ '0.5.11',
+ '0.5.10',
+ '0.5.9',
+ '0.5.8',
+ '0.5.7',
+ '0.5.6',
+ '0.5.5',
+ '0.5.4',
+ '0.5.3',
+ '0.5.2',
+ '0.5.1',
+ '0.5.0',
+ '0.4.24',
+ '0.4.23',
+ '0.4.22',
+ '0.4.21',
+ '0.4.20',
+ '0.4.19',
+ '0.4.18',
+ '0.4.17',
+ '0.4.16',
+ '0.4.15',
+ '0.4.14',
+ '0.4.13',
+ '0.4.12',
+ '0.4.11',
+ '0.4.10',
+ '0.4.9',
+ '0.4.8',
+ '0.4.7',
+ '0.4.6',
+ '0.4.5',
+ '0.4.4',
+ '0.4.3',
+ '0.4.2',
+ '0.4.1',
+ '0.4.0',
+ '0.3.16',
+ '0.3.15',
+ '0.3.14',
+ '0.3.13',
+ '0.3.12',
+ '0.3.11',
+ '0.3.10',
+ '0.3.9',
+ '0.3.8',
+ '0.3.7',
+ '0.3.6',
+ '0.3.5',
+ '0.3.4',
+ '0.3.3',
+ '0.3.2',
+ '0.3.1',
+ '0.3.0',
+ '0.2.23',
+ '0.2.22',
+ '0.2.21',
+ '0.2.20',
+ '0.2.19',
+ '0.2.18',
+ '0.2.17',
+ '0.2.16',
+ '0.2.15',
+ '0.2.14',
+ '0.2.13',
+ '0.2.12',
+ '0.2.11',
+ '0.2.10',
+ '0.2.9',
+ '0.2.8',
+ '0.2.7',
+ '0.2.6',
+ '0.2.5',
+ '0.2.4',
+ '0.2.3',
+ '0.2.2',
+ '0.2.1'
+];
diff --git a/server/domain-objects/createDefaultFiles.js b/server/domain-objects/createDefaultFiles.js
index 37349dfd01..70eddee3ed 100644
--- a/server/domain-objects/createDefaultFiles.js
+++ b/server/domain-objects/createDefaultFiles.js
@@ -1,3 +1,5 @@
+import { currentP5Version } from '../../common/p5Versions';
+
export const defaultSketch = `function setup() {
createCanvas(400, 400);
}
@@ -9,8 +11,8 @@ function draw() {
export const defaultHTML = `
-
-
+
+
diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json
index afbb6e5057..0f24da021a 100644
--- a/translations/locales/en-US/translations.json
+++ b/translations/locales/en-US/translations.json
@@ -228,7 +228,7 @@
"DataAddon": "p5.js 1.x Compatibility Add-on Library — Data Structures",
"AddonOnARIA": "on",
"AddonOffARIA": "off",
- "UndoSoundVersion": "Want to use p5.sound.js again? Turning it back on will restore the version you were using before.",
+ "SoundReference": "View the reference for p5.sound compatible with p5.js $VERSION",
"CopyToClipboardSuccess": "Copied to clipboard!",
"CopyToClipboardFailure": "We weren't able to copy the text, try selecting it and copying it manually."
},