diff --git a/client/constants.js b/client/constants.js
index 565d716fa6..4529d25efb 100644
--- a/client/constants.js
+++ b/client/constants.js
@@ -90,6 +90,8 @@ export const SHOW_EDITOR_OPTIONS = 'SHOW_EDITOR_OPTIONS';
export const CLOSE_EDITOR_OPTIONS = 'CLOSE_EDITOR_OPTIONS';
export const SHOW_KEYBOARD_SHORTCUT_MODAL = 'SHOW_KEYBOARD_SHORTCUT_MODAL';
export const CLOSE_KEYBOARD_SHORTCUT_MODAL = 'CLOSE_KEYBOARD_SHORTCUT_MODAL';
+export const SHOW_FUNDRAISER_MODAL = 'SHOW_FUNDRAISER_MODAL';
+export const CLOSE_FUNDRAISER_MODAL = 'CLOSE_FUNDRAISER_MODAL';
export const SHOW_TOAST = 'SHOW_TOAST';
export const HIDE_TOAST = 'HIDE_TOAST';
export const SET_TOAST_TEXT = 'SET_TOAST_TEXT';
diff --git a/client/images/processing-foundation-logo.svg b/client/images/processing-foundation-logo.svg
new file mode 100644
index 0000000000..013501f44e
--- /dev/null
+++ b/client/images/processing-foundation-logo.svg
@@ -0,0 +1,1025 @@
+
+
+
+
diff --git a/client/modules/IDE/actions/ide.js b/client/modules/IDE/actions/ide.js
index 80a43443bc..7a23535713 100644
--- a/client/modules/IDE/actions/ide.js
+++ b/client/modules/IDE/actions/ide.js
@@ -184,6 +184,18 @@ export function closeKeyboardShortcutModal() {
};
}
+export function showFundraiserModal() {
+ return {
+ type: ActionTypes.SHOW_FUNDRAISER_MODAL
+ };
+}
+
+export function closeFundraiserModal() {
+ return {
+ type: ActionTypes.CLOSE_FUNDRAISER_MODAL
+ };
+}
+
export function setUnsavedChanges(value) {
return {
type: ActionTypes.SET_UNSAVED_CHANGES,
diff --git a/client/modules/IDE/components/About.jsx b/client/modules/IDE/components/About.jsx
index e9a17f141d..9d2459c48b 100644
--- a/client/modules/IDE/components/About.jsx
+++ b/client/modules/IDE/components/About.jsx
@@ -162,6 +162,20 @@ function About(props) {
Discord
+
+
+
+ Donate
+
+
+ {t('Fundraiser.Description')}
+
+
+ {t('Fundraiser.CallToAction')}
+
+
+ );
+}
diff --git a/client/modules/IDE/components/Header/MobileNav.jsx b/client/modules/IDE/components/Header/MobileNav.jsx
index 5f86233101..eeef49e3c6 100644
--- a/client/modules/IDE/components/Header/MobileNav.jsx
+++ b/client/modules/IDE/components/Header/MobileNav.jsx
@@ -23,7 +23,8 @@ import {
newFile,
newFolder,
openPreferences,
- showKeyboardShortcutModal
+ showKeyboardShortcutModal,
+ showFundraiserModal
} from '../../actions/ide';
import { logoutUser } from '../../../User/actions';
import { useSketchActions, useWhatPage } from '../../hooks';
@@ -434,6 +435,9 @@ const MoreMenu = () => {
{t('Nav.Help.Reference')}
{t('Nav.Help.About')}
+ dispatch(showFundraiserModal())}>
+ {t('Nav.Fundraiser')}
+
diff --git a/client/modules/IDE/components/Header/Nav.jsx b/client/modules/IDE/components/Header/Nav.jsx
index b4f7cb151f..591f9b5740 100644
--- a/client/modules/IDE/components/Header/Nav.jsx
+++ b/client/modules/IDE/components/Header/Nav.jsx
@@ -24,6 +24,7 @@ import {
newFile,
newFolder,
showKeyboardShortcutModal,
+ showFundraiserModal,
startSketch,
stopSketch
} from '../../actions/ide';
@@ -37,6 +38,7 @@ const Nav = ({ layout }) => (
matches ? (
+
) : (
@@ -85,6 +87,24 @@ const UserMenu = () => {
return null;
};
+const FundraiserSection = () => {
+ const { t } = useTranslation();
+ const dispatch = useDispatch();
+
+ return (
+ <>
+ dispatch(showFundraiserModal())}
+ aria-label="2023-fundraiser-button"
+ title="2023 Fundraiser Button"
+ >
+ {t('Nav.Fundraiser')}
+
+ >
+ );
+};
+
const DashboardMenu = () => {
const { t } = useTranslation();
const editorLink = useSelector(selectSketchPath);
diff --git a/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap b/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap
index 3b55bfae67..81161448d8 100644
--- a/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap
+++ b/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap
@@ -39,6 +39,13 @@ exports[`Nav renders dashboard version for desktop 1`] = `
+
+ Support p5.js and the Processing Foundation!
+
@@ -450,6 +457,13 @@ exports[`Nav renders dashboard version for mobile 1`] = `
About
+
+
+ Support p5.js and the Processing Foundation!
+
+
@@ -666,6 +680,13 @@ exports[`Nav renders editor version for desktop 1`] = `
+
+ Support p5.js and the Processing Foundation!
+
@@ -1077,6 +1098,13 @@ exports[`Nav renders editor version for mobile 1`] = `
About
+
+
+ Support p5.js and the Processing Foundation!
+
+
diff --git a/client/modules/IDE/components/IDEOverlays.jsx b/client/modules/IDE/components/IDEOverlays.jsx
index 6dba0e76f5..789caeb753 100644
--- a/client/modules/IDE/components/IDEOverlays.jsx
+++ b/client/modules/IDE/components/IDEOverlays.jsx
@@ -5,6 +5,7 @@ import { useLocation, useParams } from 'react-router-dom';
import Overlay from '../../App/components/Overlay';
import {
closeKeyboardShortcutModal,
+ closeFundraiserModal,
closePreferences,
closeShareModal,
hideErrorModal
@@ -14,6 +15,7 @@ import AddToCollectionList from './AddToCollectionList';
import ErrorModal from './ErrorModal';
import Feedback from './Feedback';
import KeyboardShortcutModal from './KeyboardShortcutModal';
+import FundraiserModal from './FundraiserModal';
import NewFileModal from './NewFileModal';
import NewFolderModal from './NewFolderModal';
import Preferences from './Preferences';
@@ -33,6 +35,7 @@ export default function IDEOverlays() {
uploadFileModalVisible,
preferencesIsVisible,
keyboardShortcutVisible,
+ fundraiserContentVisible,
shareModalVisible,
shareModalProjectId,
shareModalProjectName,
@@ -106,6 +109,15 @@ export default function IDEOverlays() {
)}
+ {fundraiserContentVisible && (
+ dispatch(closeFundraiserModal())}
+ >
+
+
+ )}
{errorType && (
{
return Object.assign({}, state, { keyboardShortcutVisible: true });
case ActionTypes.CLOSE_KEYBOARD_SHORTCUT_MODAL:
return Object.assign({}, state, { keyboardShortcutVisible: false });
+ case ActionTypes.SHOW_FUNDRAISER_MODAL:
+ return Object.assign({}, state, { fundraiserContentVisible: true });
+ case ActionTypes.CLOSE_FUNDRAISER_MODAL:
+ return Object.assign({}, state, { fundraiserContentVisible: false });
case ActionTypes.SET_UNSAVED_CHANGES:
return Object.assign({}, state, { unsavedChanges: action.value });
case ActionTypes.DETECT_INFINITE_LOOPS:
diff --git a/client/styles/abstracts/_variables.scss b/client/styles/abstracts/_variables.scss
index 17cd04bab8..e3c539e0dc 100644
--- a/client/styles/abstracts/_variables.scss
+++ b/client/styles/abstracts/_variables.scss
@@ -50,6 +50,10 @@ $themes: (
button-nav-inactive-color: $middle-gray,
button-hover-color: $lightest,
button-active-color: $lightest,
+ fundraiser-button-nav-color: $p5js-pink,
+ fundraiser-button-background-color: $p5js-pink,
+ fundraiser-button-color: $white,
+ fundraiser-button-hover-active-color: $medium-dark,
modal-background-color: $light,
preferences-button-background-color: $medium-light,
modal-border-color: $middle-light,
@@ -164,6 +168,9 @@ $themes: (
editor-gutter-color: $darker,
file-hover-color: $dark,
file-selected-color: $medium-dark,
+ fundraiser-button-background-color: $p5js-pink,
+ fundraiser-button-color: $white,
+ fundraiser-button-hover-active-color: $medium-dark,
input-text-color: $lightest,
input-background-color: $dark,
input-secondary-background-color: $medium-dark,
@@ -258,6 +265,9 @@ $themes: (
editor-gutter-color: $darker,
file-hover-color: $dark,
file-selected-color: $medium-dark,
+ fundraiser-button-background-color: $yellow,
+ fundraiser-button-color: $dark,
+ fundraiser-button-hover-active-color: $medium-light,
input-text-color: $lightest,
input-background-color: $dark,
input-secondary-background-color: $medium-dark,
diff --git a/client/styles/components/_fundraiser.scss b/client/styles/components/_fundraiser.scss
new file mode 100644
index 0000000000..2d3a989782
--- /dev/null
+++ b/client/styles/components/_fundraiser.scss
@@ -0,0 +1,53 @@
+.fundraiser {
+ padding: #{20 / $base-font-size}rem;
+ margin-right: #{20 / $base-font-size}rem;
+ padding-bottom: #{40 / $base-font-size}rem;
+ width: #{500 / $base-font-size}rem;
+ text-align: center;
+ overflow-y: auto;
+}
+
+.fundraiser__CTA {
+ font-size: #{23 / $base-font-size}rem;
+ font-weight: bold;
+ margin-top: #{10 / $base-font-size}rem;
+ padding: #{20 / $base-font-size}rem;
+ border-radius: #{35 / $base-font-size}rem;
+
+ @include themify() {
+ color: getThemifyVariable('fundraiser-button-color');
+ background-color: getThemifyVariable('fundraiser-button-background-color');
+ }
+
+ &:hover,
+ &:focus {
+ @include themify() {
+ color: getThemifyVariable('fundraiser-button-color');
+ background-color: getThemifyVariable('fundraiser-button-hover-active-color');
+ }
+ }
+}
+
+.fundraiser__description {
+ margin: #{20 / $base-font-size}rem 0;
+ font-size: #{20 / $base-font-size}rem;
+}
+
+.fundraiser__img-container {
+ display: flex;
+ justify-content: center;
+ margin: #{40 / $base-font-size}rem 0 #{55 / $base-font-size}rem 0;
+}
+
+.fundraiser__logo-p5 {
+ margin: 0 #{15 / $base-font-size}rem 0 #{30 / $base-font-size}rem;
+ width:#{150 / $base-font-size}rem;
+ height:#{150 / $base-font-size}rem;
+}
+
+.fundraiser__logo-PF {
+ margin-left: #{20 / $base-font-size}rem;
+ padding-bottom: #{15 / $base-font-size}rem;
+ width:#{250 / $base-font-size}rem;
+ height:#{150 / $base-font-size}rem;
+}
\ No newline at end of file
diff --git a/client/styles/components/_nav.scss b/client/styles/components/_nav.scss
index 69f267955e..4ca31ee872 100644
--- a/client/styles/components/_nav.scss
+++ b/client/styles/components/_nav.scss
@@ -23,6 +23,15 @@
align-items: center;
}
+.nav__fundraiser-btn {
+ font-weight: bold;
+ font-size: #{14 / $base-font-size}rem;
+ @include themify() {
+ color: getThemifyVariable('fundraiser-button-nav-color');
+ }
+}
+
+
.preview-nav__editor-svg {
@include icon();
}
diff --git a/client/styles/main.scss b/client/styles/main.scss
index 9018fe6273..96d279d964 100644
--- a/client/styles/main.scss
+++ b/client/styles/main.scss
@@ -43,6 +43,7 @@
@import 'components/asset-list';
@import 'components/asset-size';
@import 'components/keyboard-shortcuts';
+@import 'components/fundraiser';
@import 'components/copyable-input';
@import 'components/feedback';
@import 'components/console-input';
diff --git a/client/testData/testReduxStore.js b/client/testData/testReduxStore.js
index 6af5989a66..551edb742b 100644
--- a/client/testData/testReduxStore.js
+++ b/client/testData/testReduxStore.js
@@ -35,6 +35,7 @@ const initialTestState = {
shareModalProjectName: 'My Cute Sketch',
shareModalProjectUsername: 'p5_user',
keyboardShortcutVisible: false,
+ fundraiserContentVisible: false,
unsavedChanges: false,
infiniteLoop: false,
previewIsRefreshing: false,
diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json
index e6877b0f58..a3dde037de 100644
--- a/translations/locales/en-US/translations.json
+++ b/translations/locales/en-US/translations.json
@@ -45,7 +45,8 @@
"Asset": "Asset",
"MyAssets": "My Assets",
"LogOut": "Log Out"
- }
+ },
+ "Fundraiser": "Support p5.js and the Processing Foundation!"
},
"CodemirrorFindAndReplace": {
"ToggleReplace": "Toggle Replace",
@@ -201,6 +202,11 @@
"TurnOffAccessibleOutput": "Turn Off Accessible Output"
}
},
+ "Fundraiser": {
+ "Title": "Support Our Software and Team",
+ "Description": "🎉 Join us in celebrating a Decade of Code! 🎉 Support p5.js and the Processing Foundation and earn unique rewards. 🙂",
+ "CallToAction": "Contribute and learn more!"
+ },
"Sidebar": {
"Title": "Sketch Files",
"ToggleARIA": "Toggle open/close sketch file options",
@@ -230,6 +236,7 @@
"ErrorARIA": "Error",
"Save": "Save",
"p5logoARIA": "p5.js Logo",
+ "PFlogoARIA": "Processing Foundation Logo",
"DeleteConfirmation": "Are you sure you want to delete {{name}}?"
},
"IDEView": {