diff --git a/README.md b/README.md
index aa1807606..cdd7a447d 100644
--- a/README.md
+++ b/README.md
@@ -31,17 +31,6 @@ If you have found a bug in the p5.js Web Editor, you can file it under the ["iss
To see which pull requests and issues are currently being reviewed, check the [PR Review Board](https://github.com/processing/p5.js-web-editor/projects/9) or the following Milestones: [MINOR Release](https://github.com/processing/p5.js-web-editor/milestone/8).
-Issues and Pull Requests categorized under the PATCH or MINOR Release Milestones will be prioritized since they are planned to be merged for the next release to Production. Please feel free to [comment on this pinned issue](https://github.com/processing/p5.js-web-editor/issues/2534) if you would like your issue to be considered for the next release!
-
-
-### When Will the Next Production Release Be?
-
-We will aim to deploy on a 1-2 month basis. Here are some dates we’re working towards:
-
-2.12.0 MINOR Release: By February 27, 2024
-
-[You can read more about Semantic Versioning and the differences between a MINOR and PATCH release](https://semver.org/).
-
## References for Contributing to the p5.js Web Editor
diff --git a/client/common/icons.jsx b/client/common/icons.jsx
index 5fe685be9..13d2e1809 100644
--- a/client/common/icons.jsx
+++ b/client/common/icons.jsx
@@ -25,8 +25,6 @@ import CircleInfo from '../images/circle-info.svg';
import Add from '../images/add.svg';
import Filter from '../images/filter.svg';
import Cross from '../images/cross.svg';
-import Lock from '../images/lock.svg';
-import UnLock from '../images/unlock.svg';
// HOC that adds the right web accessibility props
// https://www.scottohara.me/blog/2019/05/22/contextual-images-svgs-and-a11y.html
@@ -104,5 +102,3 @@ export const CircleFolderIcon = withLabel(CircleFolder);
export const CircleInfoIcon = withLabel(CircleInfo);
export const AddIcon = withLabel(Add);
export const FilterIcon = withLabel(Filter);
-export const LockIcon = withLabel(Lock);
-export const UnlockIcon = withLabel(UnLock);
diff --git a/client/components/Dropdown/TableDropdown.jsx b/client/components/Dropdown/TableDropdown.jsx
index d4db78f96..44f4f27fd 100644
--- a/client/components/Dropdown/TableDropdown.jsx
+++ b/client/components/Dropdown/TableDropdown.jsx
@@ -1,20 +1,18 @@
import React from 'react';
-import { useMediaQuery } from 'react-responsive';
import styled from 'styled-components';
import { prop, remSize } from '../../theme';
import DropdownMenu from './DropdownMenu';
import DownFilledTriangleIcon from '../../images/down-filled-triangle.svg';
import MoreIconSvg from '../../images/more.svg';
+import useIsMobile from '../../modules/IDE/hooks/useIsMobile';
const DotsHorizontal = styled(MoreIconSvg)`
transform: rotate(90deg);
`;
const TableDropdownIcon = () => {
- // TODO: centralize breakpoints
- const isMobile = useMediaQuery({ maxWidth: 770 });
-
+ const isMobile = useIsMobile();
return isMobile ? (
) : (
diff --git a/client/constants.js b/client/constants.js
index bc27fadab..d2b1007b9 100644
--- a/client/constants.js
+++ b/client/constants.js
@@ -138,9 +138,6 @@ export const SET_SORT_PARAMS = 'SET_SORT_PARAMS';
export const SET_SEARCH_TERM = 'SET_SEARCH_TERM';
export const CLOSE_SKETCHLIST_MODAL = 'CLOSE_SKETCHLIST_MODAL';
-export const START_LOADING = 'START_LOADING';
-export const STOP_LOADING = 'STOP_LOADING';
-
export const START_SAVING_PROJECT = 'START_SAVING_PROJECT';
export const END_SAVING_PROJECT = 'END_SAVING_PROJECT';
diff --git a/client/images/lock.svg b/client/images/lock.svg
deleted file mode 100644
index 6f4d4af4c..000000000
--- a/client/images/lock.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/lockgif.gif b/client/images/lockgif.gif
deleted file mode 100644
index b0a08e2cc..000000000
Binary files a/client/images/lockgif.gif and /dev/null differ
diff --git a/client/images/unlock.svg b/client/images/unlock.svg
deleted file mode 100644
index fc20a1fde..000000000
--- a/client/images/unlock.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/client/modules/App/components/ThemeProvider.jsx b/client/modules/App/components/ThemeProvider.jsx
index a168d856d..8bbef6931 100644
--- a/client/modules/App/components/ThemeProvider.jsx
+++ b/client/modules/App/components/ThemeProvider.jsx
@@ -1,23 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
+import { useSelector } from 'react-redux';
import { ThemeProvider } from 'styled-components';
+import theme from '../../../theme';
-import theme, { Theme } from '../../../theme';
-
-const Provider = ({ children, currentTheme }) => (
- {children}
-);
+const Provider = ({ children }) => {
+ const currentTheme = useSelector((state) => state.preferences.theme);
+ return (
+ {children}
+ );
+};
Provider.propTypes = {
- children: PropTypes.node.isRequired,
- currentTheme: PropTypes.oneOf(Object.keys(Theme)).isRequired
+ children: PropTypes.node.isRequired
};
-function mapStateToProps(state) {
- return {
- currentTheme: state.preferences.theme
- };
-}
-
-export default connect(mapStateToProps)(Provider);
+export default Provider;
diff --git a/client/modules/IDE/actions/assets.js b/client/modules/IDE/actions/assets.js
index 333dfd0ab..ecd16fb7c 100644
--- a/client/modules/IDE/actions/assets.js
+++ b/client/modules/IDE/actions/assets.js
@@ -1,6 +1,6 @@
import apiClient from '../../../utils/apiClient';
import * as ActionTypes from '../../../constants';
-import { startLoader, stopLoader } from './loader';
+import { startLoader, stopLoader } from '../reducers/loading';
import { assetsActions } from '../reducers/assets';
const { setAssets, deleteAsset } = assetsActions;
diff --git a/client/modules/IDE/actions/collections.js b/client/modules/IDE/actions/collections.js
index e8bda9623..32790e681 100644
--- a/client/modules/IDE/actions/collections.js
+++ b/client/modules/IDE/actions/collections.js
@@ -1,7 +1,7 @@
import browserHistory from '../../../browserHistory';
import apiClient from '../../../utils/apiClient';
import * as ActionTypes from '../../../constants';
-import { startLoader, stopLoader } from './loader';
+import { startLoader, stopLoader } from '../reducers/loading';
import { setToastText, showToast } from './toast';
const TOAST_DISPLAY_TIME_MS = 1500;
@@ -80,7 +80,7 @@ export function addToCollection(collectionId, projectId) {
const collectionName = response.data.name;
- dispatch(setToastText(`Added to "${collectionName}`));
+ dispatch(setToastText(`Added to "${collectionName}"`));
dispatch(showToast(TOAST_DISPLAY_TIME_MS));
return response.data;
@@ -110,7 +110,7 @@ export function removeFromCollection(collectionId, projectId) {
const collectionName = response.data.name;
- dispatch(setToastText(`Removed from "${collectionName}`));
+ dispatch(setToastText(`Removed from "${collectionName}"`));
dispatch(showToast(TOAST_DISPLAY_TIME_MS));
return response.data;
diff --git a/client/modules/IDE/actions/loader.js b/client/modules/IDE/actions/loader.js
deleted file mode 100644
index f331094c0..000000000
--- a/client/modules/IDE/actions/loader.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as ActionTypes from '../../../constants';
-
-export function startLoader() {
- return { type: ActionTypes.START_LOADING };
-}
-
-export function stopLoader() {
- return { type: ActionTypes.STOP_LOADING };
-}
diff --git a/client/modules/IDE/actions/project.js b/client/modules/IDE/actions/project.js
index 4516fa669..e55bac1a6 100644
--- a/client/modules/IDE/actions/project.js
+++ b/client/modules/IDE/actions/project.js
@@ -411,7 +411,7 @@ export function deleteProject(id) {
};
}
-export function changeVisibility(projectId, visibility) {
+export function changeVisibility(projectId, projectName, visibility) {
return (dispatch) =>
apiClient
.patch('/project/visibility', { projectId, visibility })
@@ -423,7 +423,7 @@ export function changeVisibility(projectId, visibility) {
payload: { visibility: response.data.visibility }
});
- dispatch(setToastText(`Sketch is ${newVisibility}`));
+ dispatch(setToastText(`The ${projectName} is now ${newVisibility}!`));
dispatch(showToast(2000));
})
.catch((error) => {
diff --git a/client/modules/IDE/actions/projects.js b/client/modules/IDE/actions/projects.js
index eb9984cf5..34ca2a35b 100644
--- a/client/modules/IDE/actions/projects.js
+++ b/client/modules/IDE/actions/projects.js
@@ -1,6 +1,6 @@
import apiClient from '../../../utils/apiClient';
import * as ActionTypes from '../../../constants';
-import { startLoader, stopLoader } from './loader';
+import { startLoader, stopLoader } from '../reducers/loading';
// eslint-disable-next-line
export function getProjects(username) {
diff --git a/client/modules/IDE/actions/projects.unit.test.js b/client/modules/IDE/actions/projects.unit.test.js
index 6fce08c79..95a620552 100644
--- a/client/modules/IDE/actions/projects.unit.test.js
+++ b/client/modules/IDE/actions/projects.unit.test.js
@@ -5,6 +5,7 @@ import { rest } from 'msw';
import * as ProjectActions from './projects';
import * as ActionTypes from '../../../constants';
+import { startLoader, stopLoader } from '../reducers/loading';
import {
initialTestState,
mockProjects
@@ -33,9 +34,9 @@ describe('projects action creator tests', () => {
store = mockStore(initialTestState);
const expectedActions = [
- { type: ActionTypes.START_LOADING },
+ { type: startLoader.type },
{ type: ActionTypes.SET_PROJECTS, projects: mockProjects },
- { type: ActionTypes.STOP_LOADING }
+ { type: stopLoader.type }
];
return store
diff --git a/client/modules/IDE/components/About.jsx b/client/modules/IDE/components/About.jsx
index d22ec2c63..67c259c57 100644
--- a/client/modules/IDE/components/About.jsx
+++ b/client/modules/IDE/components/About.jsx
@@ -162,6 +162,20 @@ function About(props) {
{t('About.Discord')}
+
+
+
+ Donate
+
+
section {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 5px;
+ }
+
> h5 {
font-size: ${remSize(13)};
font-weight: normal;
@@ -203,6 +211,7 @@ const LanguageSelect = styled.div`
const MobileNav = () => {
const project = useSelector((state) => state.project);
const user = useSelector((state) => state.user);
+ const dispatch = useDispatch();
const { t } = useTranslation();
@@ -228,19 +237,53 @@ const MobileNav = () => {
}
const title = useMemo(resolveTitle, [pageName, project.name]);
+ const userIsOwner = user?.username === project.owner?.username;
const Logo = AsteriskIcon;
+
+ const toggleVisibility = (e) => {
+ try {
+ const isChecked = e.target.checked;
+
+ dispatch(
+ changeVisibility(
+ project.id,
+ project.name,
+ isChecked ? 'Private' : 'Public'
+ )
+ );
+ } catch (error) {
+ console.log(error);
+ }
+ };
return (