Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
cae1399
backend done, frontend progress
vivekbopaliya Feb 16, 2024
907c057
frontend done
vivekbopaliya Feb 17, 2024
3bf54c4
Merge branch 'develop' of https://github.com/vivekbopaliya/p5.js-web-…
vivekbopaliya Feb 18, 2024
c9da6cc
icons added
vivekbopaliya Feb 18, 2024
ae08e56
UI changes
vivekbopaliya May 4, 2024
02726cb
Merge branch 'develop' of https://github.com/processing/p5.js-web-edi…
vivekbopaliya May 4, 2024
70b8df1
snapshots updated
vivekbopaliya May 29, 2024
dfb7797
small bug fixed
vivekbopaliya Jun 1, 2024
0ba7467
Merge branch 'processing:develop' into feat/privatesketch
vivekbopaliya Jun 1, 2024
64bdb22
Merge branch 'feat/privatesketch' of https://github.com/vivekbopaliya…
vivekbopaliya Jun 1, 2024
89e9716
bug fixed
vivekbopaliya Jun 1, 2024
d2cbc60
fix bugs and added protected route for private sketch
vivekbopaliya Apr 20, 2025
eafb1aa
fixed bug conflict
vivekbopaliya Apr 20, 2025
edc54da
Merge branch 'develop' into feat/privatesketch
raclim May 7, 2025
9b54f58
fix redirect bug
vivekbopaliya Jun 5, 2025
da1c2c8
Merge branch 'develop' into feat/privatesketch
vivekbopaliya Jun 5, 2025
2bb37c5
Merge branch 'develop' into feat/privatesketch
raclim Jun 10, 2025
f5864b1
refactoring code for private sketch feat
vivekbopaliya Jun 24, 2025
374e971
test error fixex
vivekbopaliya Jun 24, 2025
24b3faa
fixed bug
vivekbopaliya Jul 5, 2025
65d3021
merged main
vivekbopaliya Jul 5, 2025
c2cacf7
replaced visibility checkbox with dropdown
vivekbopaliya Jul 19, 2025
ccafec4
test cases fixed
vivekbopaliya Jul 19, 2025
4c5f9c9
test cases snapsho fixed
vivekbopaliya Jul 19, 2025
de05842
test
vivekbopaliya Jul 20, 2025
6901103
test
vivekbopaliya Jul 20, 2025
673457f
lint fixes
vivekbopaliya Jul 20, 2025
5473069
Merge branch 'develop' into feat/privatesketch
vivekbopaliya Jul 20, 2025
205b238
fixed merge conflict
vivek-oppex Jul 31, 2025
a19ae27
Merge branch 'develop' into feat/privatesketch
raclim Aug 9, 2025
7618f85
Merge pull request #3034 from vivekbopaliya/feat/privatesketch
raclim Aug 9, 2025
c768735
needded
vivekbopaliya Aug 10, 2025
f405d6e
Changed scss for visibility dropdown
vivekbopaliya Aug 10, 2025
f27efc8
Msd
vivekbopaliya Aug 10, 2025
76d3e27
Merge branch 'develop' into feature-develop
raclim Aug 14, 2025
f687b6e
Merge branch 'develop' into feat/privatesketch
raclim Aug 14, 2025
c3e160e
Merge pull request #3587 from vivekbopaliya/feat/privatesketch
raclim Aug 14, 2025
6cd666a
Merge pull request #3588 from processing/feat/privatesketch
raclim Aug 14, 2025
be8d50a
update toolbar arrangement and styling
raclim Aug 15, 2025
d76a0f9
update styling for version picker to match toolbar
raclim Aug 15, 2025
bb2980c
let svg be styled by css
raclim Aug 15, 2025
6c92cbe
Merge branch 'develop' into feature-develop
raclim Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ ENV NODE_ENV=production
COPY package.json package-lock.json index.js ./
RUN npm install --production
COPY --from=build $APP_HOME/dist ./dist
CMD ["npm", "run", "start:prod"]
CMD ["npm", "run", "start:prod"]
2 changes: 2 additions & 0 deletions client/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
13 changes: 13 additions & 0 deletions client/images/checkmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions client/images/earth.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions client/images/lock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 49 additions & 1 deletion client/modules/IDE/actions/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export function setProject(project) {
type: ActionTypes.SET_PROJECT,
project,
files: project.files,
owner: project.user
owner: project.user,
visibility: project.visibility
};
}

Expand Down Expand Up @@ -410,3 +411,50 @@ 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, updatedAt } = 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,
updatedAt
});

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
});
});
};
}
21 changes: 14 additions & 7 deletions client/modules/IDE/components/Header/MobileNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,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;
Expand Down Expand Up @@ -237,21 +244,21 @@ const MobileNav = () => {
}

const title = useMemo(resolveTitle, [pageName, project.name]);

const userIsOwner = user?.username === project.owner?.username;
const Logo = AsteriskIcon;

const showOwner = project?.owner && title === project.name && !userIsOwner;

return (
<Nav>
<LogoContainer>
<Logo />
</LogoContainer>
<Title>
<h1>{title === project.name ? <ProjectName /> : title}</h1>
{project?.owner && title === project.name && (
<Link to={`/${project.owner.username}/sketches`}>
by {project?.owner?.username}
</Link>
)}
<h1>{title === project?.name ? <ProjectName /> : title}</h1>
{showOwner && <h5>by {project?.owner?.username}</h5>}
</Title>

{/* check if the user is in login page */}
{pageName === 'login' || pageName === 'signup' ? (
// showing the CrossIcon
Expand Down
57 changes: 40 additions & 17 deletions client/modules/IDE/components/Header/Toolbar.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback } from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
Expand All @@ -15,22 +15,26 @@ import {
setGridOutput,
setTextOutput
} from '../../actions/preferences';

import PlayIcon from '../../../../images/play.svg';
import StopIcon from '../../../../images/stop.svg';
import PreferencesIcon from '../../../../images/preferences.svg';
import ProjectName from './ProjectName';
import VersionIndicator from '../VersionIndicator';
import VisibilityDropdown from '../../../User/components/VisibilityDropdown';
import { changeVisibility } from '../../actions/project';

const Toolbar = (props) => {
const { isPlaying, infiniteLoop, preferencesIsVisible } = useSelector(
(state) => state.ide
);
const project = useSelector((state) => state.project);
const user = useSelector((state) => state.user);
const autorefresh = useSelector((state) => state.preferences.autorefresh);
const dispatch = useDispatch();

const { t } = useTranslation();
const userIsOwner = user?.username === project.owner?.username;

const showVisibilityDropdown = project?.owner && userIsOwner;

const playButtonClass = classNames({
'toolbar__play-button': true,
Expand All @@ -45,6 +49,13 @@ const Toolbar = (props) => {
'toolbar__preferences-button--selected': preferencesIsVisible
});

const handleVisibilityChange = useCallback(
(sketchId, sketchName, newVisibility) => {
dispatch(changeVisibility(sketchId, sketchName, newVisibility));
},
[changeVisibility]
);

return (
<div className="toolbar">
<button
Expand Down Expand Up @@ -81,6 +92,7 @@ const Toolbar = (props) => {
>
<StopIcon focusable="false" aria-hidden="true" />
</button>

<div className="toolbar__autorefresh">
<input
id="autorefresh"
Expand All @@ -98,24 +110,35 @@ const Toolbar = (props) => {
{t('Toolbar.Auto-refresh')}
</label>
</div>

<div className="toolbar__project-name-container">
<ProjectName />
{(() => {
if (project.owner) {
return (
<p className="toolbar__project-project.owner">
{t('Toolbar.By')}{' '}
<Link to={`/${project.owner.username}/sketches`}>
{project.owner.username}
</Link>
</p>
);
}
return null;
})()}
</div>
<VersionIndicator />

<div style={{ flex: 1 }} />

{showVisibilityDropdown && (
<div className="toolbar__visibility">
<VisibilityDropdown
sketch={project}
onVisibilityChange={handleVisibilityChange}
location="toolbar"
/>
</div>
)}

{/* Still show owner if not you */}
{project?.owner && !userIsOwner && (
<p className="toolbar__project-owner">
{t('Toolbar.By')}{' '}
<Link to={`/${project.owner.username}/sketches`}>
{project.owner.username}
</Link>
</p>
)}

<VersionIndicator />

<button
className={preferencesButtonClass}
onClick={() => dispatch(openPreferences())}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,22 @@ exports[`Nav renders dashboard version for mobile 1`] = `
margin: 0;
}

.c2 > section {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
gap: 5px;
}

.c2 > h5 {
font-size: 1.0833333333333333rem;
font-weight: normal;
Expand Down Expand Up @@ -757,6 +773,22 @@ exports[`Nav renders editor version for mobile 1`] = `
margin: 0;
}

.c2 > section {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
gap: 5px;
}

.c2 > h5 {
font-size: 1.0833333333333333rem;
font-weight: normal;
Expand Down
9 changes: 7 additions & 2 deletions client/modules/IDE/components/SketchList.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-len */
import PropTypes from 'prop-types';
import classNames from 'classnames';
import React, { useEffect, useState, useMemo, useCallback } from 'react';
Expand All @@ -13,9 +14,9 @@ import getSortedSketches from '../selectors/projects';
import Loader from '../../App/components/loader';
import Overlay from '../../App/components/Overlay';
import AddToCollectionList from './AddToCollectionList';
import SketchListRowBase from './SketchListRowBase';
import ArrowUpIcon from '../../../images/sort-arrow-up.svg';
import ArrowDownIcon from '../../../images/sort-arrow-down.svg';
import SketchListRowBase from './SketchListRowBase';

const SketchList = ({
user,
Expand Down Expand Up @@ -118,6 +119,8 @@ const SketchList = ({
[sorting, getButtonLabel, toggleDirectionForField, t]
);

const userIsOwner = user.username === username;

return (
<article className="sketches-table-container">
<Helmet>
Expand Down Expand Up @@ -145,6 +148,7 @@ const SketchList = ({
context: mobile ? 'mobile' : ''
})
)}
{userIsOwner && renderFieldHeader('visibility', 'Visibility')}
<th scope="col"></th>
</tr>
</thead>
Expand Down Expand Up @@ -187,7 +191,8 @@ SketchList.propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
createdAt: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired
updatedAt: PropTypes.string.isRequired,
visibility: PropTypes.string
})
).isRequired,
username: PropTypes.string,
Expand Down
19 changes: 16 additions & 3 deletions client/modules/IDE/components/SketchList.unit.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,22 @@ describe('<Sketchlist />', () => {
expect(screen.queryByText('Delete')).toBeInTheDocument();
});

it('snapshot testing', () => {
const { asFragment } = subject();
expect(asFragment()).toMatchSnapshot();
it('renders component correctly', () => {
const { container } = subject();

expect(
container.querySelector('.sketches-table-container')
).toBeInTheDocument();
expect(container.querySelector('.sketches-table')).toBeInTheDocument();
expect(container.querySelector('thead')).toBeInTheDocument();
expect(container.querySelector('tbody')).toBeInTheDocument();

// expect(screen.getByText(/Sketch/i)).toBeInTheDocument();
// expect(screen.getByText(/Date created/i)).toBeInTheDocument();
// expect(screen.getByText(/Last updated/i)).toBeInTheDocument();

const sketchRows = container.querySelectorAll('tbody tr');
expect(sketchRows.length).toBeGreaterThan(0);
});

describe('different user than the one who created the sketches', () => {
Expand Down
Loading
Loading