diff --git a/.env.example b/.env.example index ea00adf9d9..0a7df9314f 100644 --- a/.env.example +++ b/.env.example @@ -19,7 +19,7 @@ MAILGUN_KEY= ML5_LIBRARY_USERNAME=ml5 ML5_LIBRARY_EMAIL=examples@ml5js.org ML5_LIBRARY_PASS=helloml5 -MONGO_URL=mongodb://localhost:27017/p5js-web-editor +MONGO_URL=mongodb://localhost:27017/local PORT=8000 PREVIEW_PORT=8002 EDITOR_URL=http://localhost:8000 diff --git a/client/constants.js b/client/constants.js index 57c85f4e85..4470d8eb29 100644 --- a/client/constants.js +++ b/client/constants.js @@ -41,6 +41,8 @@ export const DELETE_COLLECTION = 'DELETE_COLLECTION'; export const ADD_TO_COLLECTION = 'ADD_TO_COLLECTION'; export const REMOVE_FROM_COLLECTION = 'REMOVE_FROM_COLLECTION'; export const EDIT_COLLECTION = 'EDIT_COLLECTION'; +export const CHANGE_VISIBILITY = 'CHANGE_VISIBILITY'; +export const SET_PROJECT_VISIBILITY = 'SET_PROJECT_VISIBILITY'; export const DELETE_PROJECT = 'DELETE_PROJECT'; diff --git a/client/modules/IDE/actions/project.js b/client/modules/IDE/actions/project.js index 1d8943336b..7b7e4fa9df 100644 --- a/client/modules/IDE/actions/project.js +++ b/client/modules/IDE/actions/project.js @@ -410,3 +410,45 @@ export function deleteProject(id) { }); }; } +export function changeVisibility(projectId, projectName, visibility) { + return (dispatch, getState) => { + const state = getState(); + + apiClient + .patch('/project/visibility', { projectId, visibility }) + .then((response) => { + if (response.status === 200) { + const { visibility: newVisibility } = response.data; + + dispatch({ + type: ActionTypes.CHANGE_VISIBILITY, + payload: { + id: response.data.id, + visibility: newVisibility + } + }); + + if (state.project.id === response.data.id) { + dispatch({ + type: ActionTypes.SET_PROJECT_VISIBILITY, + visibility: newVisibility + }); + dispatch({ + type: ActionTypes.SET_PROJECT_NAME, + name: response.data.name + }); + } + dispatch( + setToastText(`${projectName} is now ${newVisibility.toLowerCase()}`) + ); + dispatch(showToast(2000)); + } + }) + .catch((error) => { + dispatch({ + type: ActionTypes.ERROR, + error: error?.response?.data + }); + }); + }; +} diff --git a/client/modules/IDE/components/Header/MobileNav.jsx b/client/modules/IDE/components/Header/MobileNav.jsx index 349d3d1709..a24a9f9737 100644 --- a/client/modules/IDE/components/Header/MobileNav.jsx +++ b/client/modules/IDE/components/Header/MobileNav.jsx @@ -35,6 +35,7 @@ import { setLanguage } from '../../actions/preferences'; import Overlay from '../../../App/components/Overlay'; import ProjectName from './ProjectName'; import CollectionCreate from '../../../User/components/CollectionCreate'; +import { changeVisibility } from '../../actions/project'; const Nav = styled(Menubar)` background: ${prop('MobilePanel.default.background')}; @@ -75,6 +76,13 @@ const Title = styled.div` margin: 0; } + > 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,21 +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 (