Skip to content

Commit 558726e

Browse files
Merge branch 'develop' into about-fix
2 parents 72a3986 + afb3474 commit 558726e

File tree

12 files changed

+244
-366
lines changed

12 files changed

+244
-366
lines changed
Lines changed: 60 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import PropTypes from 'prop-types';
2-
import React from 'react';
2+
import React, { useEffect, useState } from 'react';
33
import { Helmet } from 'react-helmet';
4-
import { connect } from 'react-redux';
5-
import { bindActionCreators } from 'redux';
6-
import { withTranslation } from 'react-i18next';
7-
// import { find } from 'lodash';
8-
import * as ProjectsActions from '../actions/projects';
9-
import * as CollectionsActions from '../actions/collections';
10-
import * as ToastActions from '../actions/toast';
11-
import * as SortingActions from '../actions/sorting';
4+
import { useDispatch, useSelector } from 'react-redux';
5+
import { useTranslation } from 'react-i18next';
6+
import { addToCollection, removeFromCollection } from '../actions/collections';
7+
import { getProjects } from '../actions/projects';
128
import getSortedSketches from '../selectors/projects';
139
import Loader from '../../App/components/loader';
1410
import QuickAddList from './QuickAddList';
@@ -17,149 +13,79 @@ import {
1713
QuickAddWrapper
1814
} from './AddToCollectionList';
1915

20-
class SketchList extends React.Component {
21-
constructor(props) {
22-
super(props);
23-
this.props.getProjects(this.props.username);
16+
const AddToCollectionSketchList = ({ collection }) => {
17+
const { t } = useTranslation();
2418

25-
this.state = {
26-
isInitialDataLoad: true
27-
};
28-
}
19+
const dispatch = useDispatch();
2920

30-
componentWillReceiveProps(nextProps) {
31-
if (
32-
this.props.sketches !== nextProps.sketches &&
33-
Array.isArray(nextProps.sketches)
34-
) {
35-
this.setState({
36-
isInitialDataLoad: false
37-
});
38-
}
39-
}
21+
const username = useSelector((state) => state.user.username);
4022

41-
getSketchesTitle() {
42-
if (this.props.username === this.props.user.username) {
43-
return this.props.t('AddToCollectionSketchList.Title');
44-
}
45-
return this.props.t('AddToCollectionSketchList.AnothersTitle', {
46-
anotheruser: this.props.username
47-
});
48-
}
23+
const sketches = useSelector(getSortedSketches);
4924

50-
handleCollectionAdd = (sketch) => {
51-
this.props.addToCollection(this.props.collection.id, sketch.id);
52-
};
53-
54-
handleCollectionRemove = (sketch) => {
55-
this.props.removeFromCollection(this.props.collection.id, sketch.id);
56-
};
25+
// TODO: improve loading state
26+
const loading = useSelector((state) => state.loading);
27+
const [hasLoadedData, setHasLoadedData] = useState(false);
28+
const showLoader = loading && !hasLoadedData;
5729

58-
inCollection = (sketch) =>
59-
this.props.collection.items.find((item) =>
60-
item.isDeleted ? false : item.project.id === sketch.id
61-
) != null;
30+
useEffect(() => {
31+
dispatch(getProjects(username)).then(() => setHasLoadedData(true));
32+
}, [dispatch, username]);
6233

63-
render() {
64-
const hasSketches = this.props.sketches.length > 0;
65-
const sketchesWithAddedStatus = this.props.sketches.map((sketch) => ({
66-
...sketch,
67-
isAdded: this.inCollection(sketch),
68-
url: `/${this.props.username}/sketches/${sketch.id}`
69-
}));
34+
const handleCollectionAdd = (sketch) => {
35+
dispatch(addToCollection(collection.id, sketch.id));
36+
};
7037

71-
let content = null;
38+
const handleCollectionRemove = (sketch) => {
39+
dispatch(removeFromCollection(collection.id, sketch.id));
40+
};
7241

73-
if (this.props.loading && this.state.isInitialDataLoad) {
74-
content = <Loader />;
75-
} else if (hasSketches) {
76-
content = (
77-
<QuickAddList
78-
items={sketchesWithAddedStatus}
79-
onAdd={this.handleCollectionAdd}
80-
onRemove={this.handleCollectionRemove}
81-
/>
82-
);
83-
} else {
84-
content = this.props.t('AddToCollectionSketchList.NoCollections');
42+
const sketchesWithAddedStatus = sketches.map((sketch) => ({
43+
...sketch,
44+
url: `/${username}/sketches/${sketch.id}`,
45+
isAdded: collection.items.some(
46+
(item) => item.projectId === sketch.id && !item.isDeleted
47+
)
48+
}));
49+
50+
const getContent = () => {
51+
if (showLoader) {
52+
return <Loader />;
53+
} else if (sketches.length === 0) {
54+
// TODO: shouldn't it be NoSketches? -Linda
55+
return t('AddToCollectionSketchList.NoCollections');
8556
}
86-
8757
return (
88-
<CollectionAddSketchWrapper>
89-
<QuickAddWrapper>
90-
<Helmet>
91-
<title>{this.getSketchesTitle()}</title>
92-
</Helmet>
93-
{content}
94-
</QuickAddWrapper>
95-
</CollectionAddSketchWrapper>
58+
<QuickAddList
59+
items={sketchesWithAddedStatus}
60+
onAdd={handleCollectionAdd}
61+
onRemove={handleCollectionRemove}
62+
/>
9663
);
97-
}
98-
}
64+
};
9965

100-
SketchList.propTypes = {
101-
user: PropTypes.shape({
102-
username: PropTypes.string,
103-
authenticated: PropTypes.bool.isRequired
104-
}).isRequired,
105-
getProjects: PropTypes.func.isRequired,
106-
sketches: PropTypes.arrayOf(
107-
PropTypes.shape({
108-
id: PropTypes.string.isRequired,
109-
name: PropTypes.string.isRequired,
110-
createdAt: PropTypes.string.isRequired,
111-
updatedAt: PropTypes.string.isRequired
112-
})
113-
).isRequired,
66+
return (
67+
<CollectionAddSketchWrapper>
68+
<QuickAddWrapper>
69+
<Helmet>
70+
<title>{t('AddToCollectionSketchList.Title')}</title>
71+
</Helmet>
72+
{getContent()}
73+
</QuickAddWrapper>
74+
</CollectionAddSketchWrapper>
75+
);
76+
};
77+
78+
AddToCollectionSketchList.propTypes = {
11479
collection: PropTypes.shape({
11580
id: PropTypes.string.isRequired,
11681
name: PropTypes.string.isRequired,
11782
items: PropTypes.arrayOf(
11883
PropTypes.shape({
119-
project: PropTypes.shape({
120-
id: PropTypes.string.isRequired
121-
})
84+
projectId: PropTypes.string.isRequired,
85+
isDeleted: PropTypes.bool
12286
})
12387
)
124-
}).isRequired,
125-
username: PropTypes.string,
126-
loading: PropTypes.bool.isRequired,
127-
sorting: PropTypes.shape({
128-
field: PropTypes.string.isRequired,
129-
direction: PropTypes.string.isRequired
130-
}).isRequired,
131-
addToCollection: PropTypes.func.isRequired,
132-
removeFromCollection: PropTypes.func.isRequired,
133-
t: PropTypes.func.isRequired
134-
};
135-
136-
SketchList.defaultProps = {
137-
username: undefined
88+
}).isRequired
13889
};
13990

140-
function mapStateToProps(state) {
141-
return {
142-
user: state.user,
143-
sketches: getSortedSketches(state),
144-
sorting: state.sorting,
145-
loading: state.loading,
146-
project: state.project
147-
};
148-
}
149-
150-
function mapDispatchToProps(dispatch) {
151-
return bindActionCreators(
152-
Object.assign(
153-
{},
154-
ProjectsActions,
155-
CollectionsActions,
156-
ToastActions,
157-
SortingActions
158-
),
159-
dispatch
160-
);
161-
}
162-
163-
export default withTranslation()(
164-
connect(mapStateToProps, mapDispatchToProps)(SketchList)
165-
);
91+
export default AddToCollectionSketchList;

client/modules/IDE/components/CollectionList/CollectionList.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ class CollectionList extends React.Component {
227227
isFixedHeight
228228
>
229229
<AddToCollectionSketchList
230-
username={this.props.username}
231230
collection={find(this.props.collections, {
232231
id: this.state.addingSketchesToCollectionId
233232
})}

client/modules/IDE/pages/IDEView.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ const IDEView = () => {
186186
setSidebarSize(size);
187187
}}
188188
allowResize={ide.sidebarIsExpanded}
189-
minSize={125}
189+
minSize={150}
190190
>
191191
<Sidebar />
192192
<SplitPane

client/modules/Preview/EmbedFrame.jsx

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -224,27 +224,23 @@ function injectLocalFiles(files, htmlFile, options) {
224224
resolveScripts(sketchDoc, resolvedFiles);
225225
resolveStyles(sketchDoc, resolvedFiles);
226226

227-
const accessiblelib = sketchDoc.createElement('script');
228-
accessiblelib.setAttribute(
229-
'src',
230-
'https://cdn.jsdelivr.net/gh/processing/[email protected]/dist/p5-accessibility.js'
231-
);
232-
const accessibleOutputs = sketchDoc.createElement('section');
233-
accessibleOutputs.setAttribute('id', 'accessible-outputs');
234-
accessibleOutputs.setAttribute('aria-label', 'accessible-output');
235227
if (textOutput || gridOutput) {
236-
sketchDoc.body.appendChild(accessibleOutputs);
237-
sketchDoc.body.appendChild(accessiblelib);
228+
const scriptElement = sketchDoc.createElement('script');
229+
let textCode = '';
238230
if (textOutput) {
239-
const textSection = sketchDoc.createElement('section');
240-
textSection.setAttribute('id', 'textOutput-content');
241-
sketchDoc.getElementById('accessible-outputs').appendChild(textSection);
231+
textCode = 'if (!this._accessibleOutputs.text) this.textOutput();';
242232
}
233+
let gridCode = '';
243234
if (gridOutput) {
244-
const gridSection = sketchDoc.createElement('section');
245-
gridSection.setAttribute('id', 'tableOutput-content');
246-
sketchDoc.getElementById('accessible-outputs').appendChild(gridSection);
235+
gridCode = 'if (!this._accessibleOutputs.grid) this.gridOutput();';
247236
}
237+
const fxn = `p5.prototype.ensureAccessibleCanvas = function _ensureAccessibleCanvas() {
238+
${textCode}
239+
${gridCode}
240+
};
241+
p5.prototype.registerMethod('afterSetup', p5.prototype.ensureAccessibleCanvas);`;
242+
scriptElement.innerHTML = fxn;
243+
sketchDoc.head.appendChild(scriptElement);
248244
}
249245

250246
const previewScripts = sketchDoc.createElement('script');

client/modules/User/components/CollectionMetadata.jsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,7 @@ function CollectionMetadata({ collectionId }) {
109109
closeOverlay={() => setIsAddingSketches(false)}
110110
isFixedHeight
111111
>
112-
<AddToCollectionSketchList
113-
username={username}
114-
collection={collection}
115-
/>
112+
<AddToCollectionSketchList collection={collection} />
116113
</Overlay>
117114
)}
118115
</header>
Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,17 @@
11
import Collection from '../../models/collection';
22
import User from '../../models/user';
33

4-
export default function collectionForUserExists(
5-
username,
6-
collectionId,
7-
callback
8-
) {
9-
function sendFailure() {
10-
callback(false);
11-
}
12-
13-
function sendSuccess(collection) {
14-
callback(collection != null);
15-
}
16-
17-
function findUser() {
18-
return User.findByUsername(username);
19-
}
20-
21-
function findCollection(owner) {
22-
if (owner == null) {
23-
throw new Error('User not found');
24-
}
25-
26-
return Collection.findOne({ _id: collectionId, owner });
27-
}
28-
29-
return findUser().then(findCollection).then(sendSuccess).catch(sendFailure);
4+
/**
5+
* @param {string} username
6+
* @param {string} collectionId
7+
* @return {Promise<boolean>}
8+
*/
9+
export default async function collectionForUserExists(username, collectionId) {
10+
const user = await User.findByUsername(username);
11+
if (!user) return false;
12+
const collection = await Collection.findOne({
13+
_id: collectionId,
14+
owner: user
15+
}).exec();
16+
return collection != null;
3017
}

0 commit comments

Comments
 (0)