From 2195088f45409a5dc65368b94b9b0a4766871daf Mon Sep 17 00:00:00 2001 From: Paul Kaplan <pkaplan@media.mit.edu> Date: Tue, 19 Jun 2018 08:39:25 -0400 Subject: [PATCH] Add an error state for backpack loading --- src/components/backpack/backpack.jsx | 57 +++++++++++++++++----------- src/containers/backpack.jsx | 14 +++++-- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/components/backpack/backpack.jsx b/src/components/backpack/backpack.jsx index 81934ae14..83e62ae7f 100644 --- a/src/components/backpack/backpack.jsx +++ b/src/components/backpack/backpack.jsx @@ -8,7 +8,7 @@ import styles from './backpack.css'; // TODO make sprite selector item not require onClick const noop = () => {}; -const Backpack = ({contents, expanded, loading, onToggle}) => ( +const Backpack = ({contents, error, expanded, loading, onToggle}) => ( <div className={styles.backpackContainer}> <div className={styles.backpackHeader} @@ -35,37 +35,47 @@ const Backpack = ({contents, expanded, loading, onToggle}) => ( </div> {expanded ? ( <div className={styles.backpackList}> - {loading ? ( + {error ? ( <div className={styles.statusMessage}> <FormattedMessage - defaultMessage="Loading..." - description="Loading backpack message" - id="gui.backpack.loadingBackpack" + defaultMessage="Error loading backpack" + description="Error backpack message" + id="gui.backpack.errorBackpack" /> </div> ) : ( - contents.length > 0 ? ( - <div className={styles.backpackListInner}> - {contents.map(item => ( - <SpriteSelectorItem - className={styles.backpackItem} - costumeURL={item.thumbnailUrl} - details={item.name} - key={item.id} - name={item.type} - selected={false} - onClick={noop} - /> - ))} - </div> - ) : ( + loading ? ( <div className={styles.statusMessage}> <FormattedMessage - defaultMessage="Backpack is empty" - description="Empty backpack message" - id="gui.backpack.emptyBackpack" + defaultMessage="Loading..." + description="Loading backpack message" + id="gui.backpack.loadingBackpack" /> </div> + ) : ( + contents.length > 0 ? ( + <div className={styles.backpackListInner}> + {contents.map(item => ( + <SpriteSelectorItem + className={styles.backpackItem} + costumeURL={item.thumbnailUrl} + details={item.name} + key={item.id} + name={item.type} + selected={false} + onClick={noop} + /> + ))} + </div> + ) : ( + <div className={styles.statusMessage}> + <FormattedMessage + defaultMessage="Backpack is empty" + description="Empty backpack message" + id="gui.backpack.emptyBackpack" + /> + </div> + ) ) )} </div> @@ -80,6 +90,7 @@ Backpack.propTypes = { type: PropTypes.string, name: PropTypes.string }), + error: PropTypes.bool, expanded: PropTypes.bool, loading: PropTypes.bool, onToggle: PropTypes.func diff --git a/src/containers/backpack.jsx b/src/containers/backpack.jsx index 949b20846..878a6cd5f 100644 --- a/src/containers/backpack.jsx +++ b/src/containers/backpack.jsx @@ -13,6 +13,7 @@ class Backpack extends React.Component { 'refreshContents' ]); this.state = { + error: false, offset: 0, itemsPerPage: 20, loading: false, @@ -29,22 +30,27 @@ class Backpack extends React.Component { } refreshContents () { if (this.props.token && this.props.username) { - this.setState({loading: true}); + this.setState({loading: true, error: false}); getBackpackContents({ host: this.props.host, token: this.props.token, username: this.props.username, offset: this.state.offset, limit: this.state.itemsPerPage - }).then(contents => { - this.setState({contents, loading: false}); - }); + }) + .then(contents => { + this.setState({contents, loading: false}); + }) + .catch(() => { + this.setState({error: true, loading: false}); + }); } } render () { return ( <BackpackComponent contents={this.state.contents} + error={this.state.error} expanded={this.state.expanded} loading={this.state.loading} onToggle={this.props.host ? this.handleToggle : null} -- GitLab