forked from coala/gh-board
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
loadable.jsx: Show modal on API limit exceed
This shows a modal with error message on exceeding API limit. Fixes coala#127
- Loading branch information
Showing
1 changed file
with
98 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,119 @@ | ||
import {Component} from 'react'; | ||
import {SyncIcon} from 'react-octicons'; | ||
import * as BS from 'react-bootstrap'; | ||
|
||
const STATUS = { | ||
INITIAL: 'initial', | ||
RESOLVED: 'resolved', | ||
ERROR: 'error' | ||
INITIAL: 'initial', | ||
RESOLVED: 'resolved', | ||
ERROR: 'error' | ||
}; | ||
|
||
class Loadable extends Component { | ||
static defaultProps = { | ||
renderError: (err) => { | ||
console.error(err); | ||
// If it is a permissions error then it might be a rate limi | ||
if (err.status === 403) { | ||
return ( | ||
<div> | ||
<h2>Insufficient Permissions (or rate limit exceeded)</h2> | ||
<p> | ||
It looks like either you do not have permission to see this repository or the rate limit for requests to GitHub has been exceeded. This usually happens when you are not logged in to gh-board. Try signing in to continue. | ||
</p> | ||
<code>{err.message}</code> | ||
</div> | ||
); | ||
} else if (err.name === 'InvalidStateError') { | ||
return ( | ||
<span>It looks like your browser is in private browsing mode. gh-board uses IndexedDB to cache requests to GitHub. Please disable Private Browsing to see it work.</span> | ||
); | ||
} else { | ||
return ( | ||
<span> | ||
Problem loading. Is it a valid repo? And have you exceeded your number of requests? Usually happens when not logged in because GitHub limits anonymous use of their API. | ||
{err.message} | ||
{JSON.stringify(err)} | ||
</span> | ||
); | ||
} | ||
} | ||
}; | ||
static defaultProps = { | ||
renderError: (err) => { | ||
console.error(err); | ||
// If it is a permissions error then it might be a rate limit | ||
if (err.status === 403) { | ||
return ( | ||
<BS.Modal show > | ||
<BS.Modal.Header> | ||
<BS.Modal.Title><h2>Insufficient Permissions </h2>(or rate limit exceeded)</BS.Modal.Title> | ||
</BS.Modal.Header> | ||
<BS.Modal.Body > | ||
<div> | ||
<p> | ||
It looks like either you do not have permission to see this repository or the rate limit for requests to GitHub has been exceeded. This usually happens when you are not logged in to gh-board. Try signing in to continue. | ||
</p> | ||
<code> | ||
{JSON.parse(err.message).message} | ||
<br /> | ||
<a href={JSON.parse(err.message).documentation_url}>Documentation URL</a> | ||
</code> | ||
<br /> | ||
<br /> | ||
</div> | ||
</BS.Modal.Body> | ||
</BS.Modal> | ||
); | ||
} else if (err.name === 'InvalidStateError') { | ||
return ( | ||
<span>It looks like your browser is in private browsing mode. gh-board uses IndexedDB to cache requests to GitHub. Please disable Private Browsing to see it work.</span> | ||
); | ||
} else { | ||
return ( | ||
<BS.Modal show > | ||
<BS.Modal.Header> | ||
</BS.Modal.Header> | ||
<BS.Modal.Body > | ||
<div> | ||
<p> | ||
Problem loading. Is it a valid repo? And have you exceeded your number of requests? Usually happens when not logged in because GitHub limits anonymous use of their API. | ||
</p> | ||
<code> | ||
{JSON.parse(err.message).message} | ||
<br /> | ||
<a href={JSON.parse(err.message).documentation_url}>Documentation URL</a> | ||
</code> | ||
<br /> | ||
<br /> | ||
</div> | ||
</BS.Modal.Body> | ||
</BS.Modal> | ||
); | ||
} | ||
} | ||
}; | ||
|
||
state = {status: STATUS.INITIAL, value: null}; | ||
state = {status: STATUS.INITIAL, value: null, show: false}; | ||
|
||
componentDidMount() { | ||
const {promise} = this.props; | ||
promise.then(this.onResolve, this.onError); | ||
} | ||
componentDidMount() { | ||
const {promise} = this.props; | ||
promise.then(this.onResolve, this.onError); | ||
} | ||
|
||
componentDidUpdate(prevProps) { | ||
if (this.props.promise !== prevProps.promise) { | ||
const {promise} = this.props; | ||
promise.then(this.onResolve, this.onError); | ||
componentDidUpdate(prevProps) { | ||
if (this.props.promise !== prevProps.promise) { | ||
const {promise} = this.props; | ||
promise.then(this.onResolve, this.onError); | ||
} | ||
} | ||
} | ||
|
||
onResolve = (value) => { | ||
// TODO: Find out why this is being called multiple times | ||
this.setState({status: STATUS.RESOLVED, value}); | ||
}; | ||
onResolve = (value) => { | ||
// TODO: Find out why this is being called multiple times | ||
this.setState({status: STATUS.RESOLVED, value}); | ||
}; | ||
|
||
onError = (value) => { | ||
// TODO: Find out why this is being called multiple times | ||
if (this.state.status !== STATUS.ERROR) { | ||
this.setState({status: STATUS.ERROR, value}); | ||
} | ||
}; | ||
onError = (value) => { | ||
// TODO: Find out why this is being called multiple times | ||
if (this.state.status !== STATUS.ERROR) { | ||
this.setState({status: STATUS.ERROR, value}); | ||
} | ||
}; | ||
|
||
renderLoading = () => { | ||
const {loadingText} = this.props; | ||
return ( | ||
<span className='loadable is-loading'> | ||
<SyncIcon className='icon-spin'/> | ||
{' ' + (loadingText || 'Loading...')} | ||
</span> | ||
); | ||
}; | ||
renderLoading = () => { | ||
const {loadingText} = this.props; | ||
return ( | ||
<span className='loadable is-loading'> | ||
<SyncIcon className='icon-spin'/> | ||
{' ' + (loadingText || 'Loading...')} | ||
</span> | ||
); | ||
}; | ||
|
||
render() { | ||
const {status, value} = this.state; | ||
let {renderLoading, renderLoaded, renderError} = this.props; | ||
render() { | ||
const {status, value} = this.state; | ||
let {renderLoading, renderLoaded, renderError} = this.props; | ||
|
||
renderLoading = renderLoading || this.renderLoading; | ||
renderLoading = renderLoading || this.renderLoading; | ||
|
||
if (status === STATUS.INITIAL) { | ||
return renderLoading(); | ||
} else if (status === STATUS.RESOLVED) { | ||
return renderLoaded(value); | ||
} else { | ||
return renderError(value); | ||
if (status === STATUS.INITIAL) { | ||
return renderLoading(); | ||
} else if (status === STATUS.RESOLVED) { | ||
return renderLoaded(value); | ||
} else { | ||
return renderError(value); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default Loadable; |