Skip to content
This repository has been archived by the owner on Apr 23, 2022. It is now read-only.

Commit

Permalink
fix: 第一次安裝的時候無法輸入 access token
Browse files Browse the repository at this point in the history
  • Loading branch information
henry40408 committed May 17, 2018
1 parent ec7908a commit e580947
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"presets": [
["env", {
"targets": {
"browsers": "last 2 versions"
"browsers": "last 2 Chrome versions"
},
"useBuiltIns": true,
"debug": false
Expand Down
3 changes: 2 additions & 1 deletion app/scripts/background/githubService.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { cacheAdapterEnhancer } from 'axios-extensions'
import axios from 'axios/index'
import gql from 'graphql-tag'
import includes from 'lodash/includes'
import set from 'lodash/set'
import LRU from 'lru-cache'

import DIConstants from '../constants'
Expand Down Expand Up @@ -50,7 +51,7 @@ class GithubService {
}

// suppress any GraphQL errors
let onError = ({ response }) => { response.errors = [] }
let onError = ({ response }) => set(response, 'errors', [])

/** @type {ApolloClient} */
this.apolloClient = new ApolloClient({
Expand Down
10 changes: 5 additions & 5 deletions app/scripts/components/AccessTokenForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let ATFContainer = styled(Flex)`
`

let ATFField = styled.input`
border: 2px ${({ invalid }) => (invalid ? colors.red : 'transparent')} solid;
border: 2px ${({ hasError }) => (hasError ? colors.red : 'transparent')} solid;
box-sizing: border-box;
font-size: ${({ heightInRem }) => heightInRem * 1.1}rem;
padding: ${({ heightInRem }) => heightInRem * 0.5}rem;
Expand Down Expand Up @@ -52,7 +52,7 @@ class AccessTokenForm extends React.Component {
}

render () {
let { heightInRem, invalid, saving, onSubmit } = this.props
let { heightInRem, hasError, saving, onSubmit } = this.props
let { accessToken } = this.state
return (
<ATFContainer>
Expand All @@ -62,7 +62,7 @@ class AccessTokenForm extends React.Component {
value={accessToken}
onChange={e => this.updateAccessToken(e.target.value)}
heightInRem={heightInRem}
invalid={invalid}
hasError={hasError}
/>
</Box>
<ATFButtonContainer w={1 / 4} heightInRem={heightInRem}>
Expand All @@ -80,15 +80,15 @@ class AccessTokenForm extends React.Component {
AccessTokenForm.propTypes = {
accessToken: PropTypes.string,
heightInRem: PropTypes.number,
invalid: PropTypes.bool,
hasError: PropTypes.bool,
onSubmit: PropTypes.func,
saving: PropTypes.bool
}

AccessTokenForm.defaultProps = {
accessToken: '',
heightInRem: 1,
invalid: false,
hasError: false,
onSubmit: () => {},
saving: false
}
Expand Down
107 changes: 64 additions & 43 deletions app/scripts/components/OptionPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import colors from '../themes/colors'

import AccessTokenForm from '../components/AccessTokenForm'
import RateLimit from '../components/RateLimit'
import { logError } from '../common'

let Container = styled(Flex)`
font-family: 'Roboto', Helvetica, sans-serif;
Expand Down Expand Up @@ -89,73 +90,87 @@ class OptionPage extends React.Component {

state = {
accessToken: '',
invalid: false,
hasError: false,
limit: 0,
remaining: 0,
saving: false
}

componentDidMount () {
this.loadInitialDataAsync()
this._loadInitialDataAsync()
}

getMessage = (messageName, subsitutions = []) => (
_getMessage = (messageName, subsitutions = []) => (
chrome.i18n.getMessage(messageName, subsitutions)
)

loadAccessTokenAsync = async () => {
_loadAccessTokenAsync = async () => {
let { data: accessToken } = await this.client.message('/access-token/get')
return { accessToken }
}

loadInitialDataAsync = async () => {
this.setState({ saving: true })
let { accessToken } = await this.loadAccessTokenAsync()
let { invalid, limit, remaining } = await this.loadRateLimitAsync()
this.setState({ accessToken, invalid, limit, remaining, saving: false })
_loadInitialDataAsync = async () => {
try {
this.setState({ saving: true })
let { accessToken } = await this._loadAccessTokenAsync()
let { limit, remaining } = await this._loadRateLimitAsync()
this.setState({ accessToken, hasError: false, limit, remaining, saving: false })
} catch (error) {
logError(error)
this.setState({ hasError: true })
} finally {
this.setState({ saving: false })
}
}

loadRateLimitAsync = async () => {
_loadRateLimitAsync = async () => {
let { data: { remaining, limit } } = await this.client.message('/rate-limit')
let invalid = remaining === -1 || limit === -1
return { invalid, limit, remaining }
return { limit, remaining }
}

saveAccessTokenAsync = async (accessToken) => {
this.setState({ saving: true, accessToken })
await this.client.message('/access-token/set', { accessToken })
let { invalid, limit, remaining } = await this.loadRateLimitAsync()
this.setState({ saving: false, invalid, limit, remaining })
_saveAccessTokenAsync = async (accessToken) => {
try {
this.setState({ saving: true })
await this.client.message('/access-token/set', { accessToken })
this.setState({ accessToken })
let { invalid, limit, remaining } = await this._loadRateLimitAsync()
this.setState({ hasError: false, invalid, limit, remaining, saving: false })
} catch (error) {
logError(error)
this.setState({ hasError: true })
} finally {
this.setState({ saving: false })
}
}

renderLeftPane = () => (
<Box w={[58 / 60, 26 / 60, 28 / 60]} p={2}>
<h3>{this.getMessage('opHowHotAreThoseStars')}</h3>
<p>{this.getMessage('opHowHotAreThoseStarsDescription')}</p>
<h3>{this._getMessage('opHowHotAreThoseStars')}</h3>
<p>{this._getMessage('opHowHotAreThoseStarsDescription')}</p>
<ColorList>
<ColorItem color={colors.lightBlue}>{
this.getMessage('colorForLess', [
capitalize(this.getMessage('blue')),
this._getMessage('colorForLess', [
capitalize(this._getMessage('blue')),
'1,000'
])
}</ColorItem>
<ColorItem color={colors.white}>{
this.getMessage('colorForRange', [
capitalize(this.getMessage('white')),
this._getMessage('colorForRange', [
capitalize(this._getMessage('white')),
'1,000',
'4,999'
])
}</ColorItem>
<ColorItem color={colors.yellow}>{
this.getMessage('colorForRange', [
capitalize(this.getMessage('yellow')),
this._getMessage('colorForRange', [
capitalize(this._getMessage('yellow')),
'5,000',
'9,999'
])
}</ColorItem>
<ColorItem color={colors.orange}>{
this.getMessage('colorForMore', [
capitalize(this.getMessage('orange')),
this._getMessage('colorForMore', [
capitalize(this._getMessage('orange')),
'10,000'
])
}</ColorItem>
Expand All @@ -165,37 +180,43 @@ class OptionPage extends React.Component {
)

renderRightPane = () => {
let { accessToken, invalid, remaining, limit, saving } = this.state
let { accessToken, hasError, remaining, limit, saving } = this.state
return (
<Box w={[58 / 60, 26 / 60, 28 / 60]} p={2}>
<CapitalizedH3>{this.getMessage('setupAccessToken')}</CapitalizedH3>
<CapitalizedH3>{this._getMessage('setupAccessToken')}</CapitalizedH3>
<AccessTokenForm
accessToken={accessToken}
invalid={invalid}
onSubmit={this.saveAccessTokenAsync}
hasError={hasError}
onSubmit={this._saveAccessTokenAsync}
saving={saving}
/>
<p>
{this.getMessage('ifYouDontHaveOneYet')}
{this._getMessage('ifYouDontHaveOneYet')}
<a href='https://github.com/settings/tokens/new?description=Awesome%20Stars'>
{this.getMessage('getAnAccessToken')}
{this._getMessage('getAnAccessToken')}
</a>
<br />
<AlertText>{this.getMessage('pleaseDoNotSelectAnyScopes')}</AlertText>
<AlertText>{this._getMessage('pleaseDoNotSelectAnyScopes')}</AlertText>
</p>
<h3>{this.getMessage('rateLimit')}</h3>
<RateLimit inverse remaining={remaining} total={limit} heightInRem={2.5} />
<h3>{this._getMessage('rateLimit')}</h3>
<RateLimit
inverse
hasError={hasError}
remaining={remaining}
total={limit}
heightInRem={2.5}
/>
<p>
<small>{this.getMessage('rateLimitDescription')}</small>
<small>{this._getMessage('rateLimitDescription')}</small>
</p>
<h4>{this.getMessage('whyDoYouNeedAnAccessToken')}</h4>
<h4>{this._getMessage('whyDoYouNeedAnAccessToken')}</h4>
<p>
<small>
{this.getMessage('whyDoYouNeedAnAccessTokenDescription1')}
{this._getMessage('whyDoYouNeedAnAccessTokenDescription1')}
<a href='https://developer.github.com/v3/#rate-limiting'>
{this.getMessage('githubDocumentation')}
{this._getMessage('githubDocumentation')}
</a>
{this.getMessage('whyDoYouNeedAnAccessTokenDescription2')}
{this._getMessage('whyDoYouNeedAnAccessTokenDescription2')}
</small>
</p>
</Box>
Expand All @@ -207,8 +228,8 @@ class OptionPage extends React.Component {
<Container column>
<Header p={2}>
<img src='../../images/options-logo.png' alt='Awesome Stars logo' />
<h1>{this.getMessage('appName')}</h1>
<h2>{this.getMessage('appDescription')}</h2>
<h1>{this._getMessage('appName')}</h1>
<h2>{this._getMessage('appDescription')}</h2>
</Header>
<Main>
<Flex wrap w={1}>
Expand Down
15 changes: 7 additions & 8 deletions app/scripts/components/RateLimit.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,13 @@ let BaseRLNumber = styled.div`

let RLNumber = reflex(BaseRLNumber)

let RateLimit = ({ heightInRem, inverse, remaining, total }) => {
let RateLimit = ({ heightInRem, hasError, inverse, remaining, total }) => {
let formatter = new Intl.NumberFormat('en-US')
let ratio = 0
let formatted = 'N/A'

let ratio = total === 0 ? 0 : remaining / total
let formatted

if (remaining === -1 || total === -1) {
ratio = 0
formatted = 'N/A'
} else {
if (!hasError) {
ratio = total === 0 ? 0 : remaining / total
formatted = formatter.format(remaining)
}

Expand All @@ -80,13 +77,15 @@ let RateLimit = ({ heightInRem, inverse, remaining, total }) => {

RateLimit.propTypes = {
heightInRem: PropTypes.number,
hasError: PropTypes.bool,
inverse: PropTypes.bool,
remaining: PropTypes.number,
total: PropTypes.number
}

RateLimit.defaultProps = {
heightInRem: 1,
hasError: false,
inverse: false,
remaining: 0,
total: 0
Expand Down
36 changes: 21 additions & 15 deletions app/scripts/contentscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,33 @@ function appendStars (tuples) {
return stars
}

async function batchUpdateCountAsync (stars) {
let chunks = chunkize(stars, CHUNK_SIZE)
async function batchUpdateChunkAsync (chunk) {
let tuples = chunk.map(star => star.tuple)

for (let chunk of chunks) {
let tuples = chunk.map(star => star.tuple)
let { data: tuplesWithStar } = await messageClient.message('/stars/get/batch', { tuples })

try {
let { data: tuplesWithStar } = await messageClient.message('/stars/get/batch', { tuples })
for (let star of chunk) {
let tuple = find(tuplesWithStar, star.tuple)
if (tuple.error) {
star.updateError(true)
} else {
star.updateCount(tuple.star)
}
}
}

for (let star of chunk) {
let tuple = find(tuplesWithStar, star.tuple)
if (tuple.error) {
star.updateError(true)
} else {
star.updateCount(tuple.star)
}
}
async function batchUpdateStarsAsync (stars) {
let chunks = chunkize(stars, CHUNK_SIZE)

for (let chunk of chunks) {
try {
await batchUpdateChunkAsync(chunk)
await messageClient.message('/rate-limit')
} catch (error) {
logError(error)
for (let star of chunk) {
star.updateError(true)
}
}
}
}
Expand Down Expand Up @@ -106,7 +112,7 @@ async function attachStarsOnLinksAsync (links) {
.filter(tuple => tuple.valid)

let stars = appendStars(tuples)
await batchUpdateCountAsync(stars)
await batchUpdateStarsAsync(stars)
}

async function initForReadmeAsync () {
Expand Down
3 changes: 2 additions & 1 deletion app/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ storiesOf('RateLimit', module).add('default', () => {
return (
<RateLimitContainer inverse={inverse}>
<RateLimit
hasError={boolean('Has error?',false)}
inverse={inverse}
remaining={number('Remaining', MAXIMUM)}
total={number('Total', MAXIMUM)}
Expand All @@ -39,7 +40,7 @@ storiesOf('AccessTokenForm', module).add('default', () => (
<AccessTokenForm
accessToken='accessToken'
heightInRem={number('Height in rem', 1)}
invalid={boolean('Invalid', false)}
hasError={boolean('Has error?', false)}
onSubmit={accessToken => action(`access token submitted: ${accessToken}`)}
saving={boolean('Saving', false)}
/>
Expand Down

0 comments on commit e580947

Please sign in to comment.