Skip to content

Commit d64498e

Browse files
authored
RE #168, Feature/asset totalsize limit (#1123)
* re #168, add totalsize to response from API, add loader to asset list, add totalsize to asset list ui * re #168, add totalsize to response from API, add loader to asset list, add totalsize to asset list ui * update asset list copy to remove limit, since that's not implemented yet
1 parent 4c1ebdf commit d64498e

File tree

5 files changed

+61
-20
lines changed

5 files changed

+61
-20
lines changed

client/modules/IDE/actions/assets.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
import axios from 'axios';
2-
32
import * as ActionTypes from '../../../constants';
3+
import { startLoader, stopLoader } from './loader';
44

55
const __process = (typeof global !== 'undefined' ? global : window).process;
66
const ROOT_URL = __process.env.API_URL;
77

8-
function setAssets(assets) {
8+
function setAssets(assets, totalSize) {
99
return {
1010
type: ActionTypes.SET_ASSETS,
11-
assets
11+
assets,
12+
totalSize
1213
};
1314
}
1415

1516
export function getAssets() {
16-
return (dispatch, getState) => {
17+
return (dispatch) => {
18+
dispatch(startLoader());
1719
axios.get(`${ROOT_URL}/S3/objects`, { withCredentials: true })
1820
.then((response) => {
19-
dispatch(setAssets(response.data.assets));
21+
dispatch(setAssets(response.data.assets, response.data.totalSize));
22+
dispatch(stopLoader());
2023
})
21-
.catch(response => dispatch({
22-
type: ActionTypes.ERROR
23-
}));
24+
.catch(() => {
25+
dispatch({
26+
type: ActionTypes.ERROR
27+
});
28+
dispatch(stopLoader());
29+
});
2430
};
2531
}
2632

client/modules/IDE/components/AssetList.jsx

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ import { connect } from 'react-redux';
44
import { bindActionCreators } from 'redux';
55
import { Link } from 'react-router';
66
import { Helmet } from 'react-helmet';
7-
87
import prettyBytes from 'pretty-bytes';
98

9+
import Loader from '../../App/components/loader';
1010
import * as AssetActions from '../actions/assets';
1111

12-
1312
class AssetList extends React.Component {
1413
constructor(props) {
1514
super(props);
@@ -23,17 +22,37 @@ class AssetList extends React.Component {
2322
return `p5.js Web Editor | ${this.props.username}'s assets`;
2423
}
2524

25+
hasAssets() {
26+
return !this.props.loading && this.props.assetList.length > 0;
27+
}
28+
29+
renderLoader() {
30+
if (this.props.loading) return <Loader />;
31+
return null;
32+
}
33+
34+
renderEmptyTable() {
35+
if (!this.props.loading && this.props.assetList.length === 0) {
36+
return (<p className="asset-table__empty">No uploaded assets.</p>);
37+
}
38+
return null;
39+
}
40+
2641
render() {
2742
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
43+
const { assetList, totalSize } = this.props;
2844
return (
2945
<div className="asset-table-container">
46+
{/* Eventually, this copy should be Total / 250 MB Used */}
47+
{this.hasAssets() &&
48+
<p className="asset-table__total">{`${prettyBytes(totalSize)} Total`}</p>
49+
}
3050
<Helmet>
3151
<title>{this.getAssetsTitle()}</title>
3252
</Helmet>
33-
{this.props.assets.length === 0 &&
34-
<p className="asset-table__empty">No uploaded assets.</p>
35-
}
36-
{this.props.assets.length > 0 &&
53+
{this.renderLoader()}
54+
{this.renderEmptyTable()}
55+
{this.hasAssets() &&
3756
<table className="asset-table">
3857
<thead>
3958
<tr>
@@ -44,7 +63,7 @@ class AssetList extends React.Component {
4463
</tr>
4564
</thead>
4665
<tbody>
47-
{this.props.assets.map(asset =>
66+
{assetList.map(asset =>
4867
(
4968
<tr className="asset-table__row" key={asset.key}>
5069
<td>{asset.name}</td>
@@ -65,20 +84,24 @@ AssetList.propTypes = {
6584
username: PropTypes.string
6685
}).isRequired,
6786
username: PropTypes.string.isRequired,
68-
assets: PropTypes.arrayOf(PropTypes.shape({
87+
assetList: PropTypes.arrayOf(PropTypes.shape({
6988
key: PropTypes.string.isRequired,
7089
name: PropTypes.string.isRequired,
7190
url: PropTypes.string.isRequired,
7291
sketchName: PropTypes.string.isRequired,
7392
sketchId: PropTypes.string.isRequired
7493
})).isRequired,
94+
totalSize: PropTypes.number.isRequired,
7595
getAssets: PropTypes.func.isRequired,
96+
loading: PropTypes.bool.isRequired
7697
};
7798

7899
function mapStateToProps(state) {
79100
return {
80101
user: state.user,
81-
assets: state.assets
102+
assetList: state.assets.list,
103+
totalSize: state.assets.totalSize,
104+
loading: state.loading
82105
};
83106
}
84107

client/modules/IDE/reducers/assets.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import * as ActionTypes from '../../../constants';
22

3-
const assets = (state = [], action) => {
3+
// 1,000,000 bytes in a MB. can't upload if totalSize is bigger than this.
4+
const initialState = {
5+
list: [],
6+
totalSize: 0
7+
};
8+
9+
const assets = (state = initialState, action) => {
410
switch (action.type) {
511
case ActionTypes.SET_ASSETS:
6-
return action.assets;
12+
return { list: action.assets, totalSize: action.totalSize };
713
default:
814
return state;
915
}

client/styles/components/_asset-list.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,7 @@
5454
text-align: center;
5555
font-size: #{16 / $base-font-size}rem;
5656
}
57+
58+
.asset-table__total {
59+
padding: 0 #{20 / $base-font-size}rem;
60+
}

server/controllers/aws.controller.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export function listObjectsInS3ForUser(req, res) {
126126
.on('end', () => {
127127
const projectAssets = [];
128128
getProjectsForUserId(userId).then((projects) => {
129+
let totalSize = 0;
129130
assets.forEach((asset) => {
130131
const name = asset.key.split('/').pop();
131132
const foundAsset = {
@@ -134,6 +135,7 @@ export function listObjectsInS3ForUser(req, res) {
134135
size: asset.size,
135136
url: `${process.env.S3_BUCKET_URL_BASE}${asset.key}`
136137
};
138+
totalSize += asset.size;
137139
projects.some((project) => {
138140
let found = false;
139141
project.files.some((file) => {
@@ -152,7 +154,7 @@ export function listObjectsInS3ForUser(req, res) {
152154
});
153155
projectAssets.push(foundAsset);
154156
});
155-
res.json({ assets: projectAssets });
157+
res.json({ assets: projectAssets, totalSize });
156158
});
157159
});
158160
});

0 commit comments

Comments
 (0)