refactor: access token and intelligent toggle

This commit is contained in:
EnixCoda 2019-11-12 23:36:17 +08:00
parent ddb86fa4ef
commit 819fc17faf
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
3 changed files with 82 additions and 70 deletions

View file

@ -1,9 +1,8 @@
import { raiseError } from 'analytics'
import { Icon } from 'components/Icon'
import { useConfigs } from 'containers/ConfigsContext'
import { oauth, VERSION } from 'env'
import * as React from 'react'
import { friendlyFormatShortcut, JSONRequest, parseURLSearch } from 'utils/general'
import { friendlyFormatShortcut } from 'utils/general'
import { useStates } from 'utils/hooks'
import * as keyHelper from 'utils/keyHelper'
import { SimpleField, SimpleFieldInput } from './MoreOption'
@ -60,19 +59,21 @@ function SettingsBarContent() {
const useToggleShowSideBarShortcut = useStates(configContext.val.shortcut)
const useReloadHint = useStates<React.ReactNode>('')
React.useEffect(() => {
if (!configContext.val.access_token) {
trySetUpAccessTokenWithCode().then(accessToken => {
useAccessToken.set(accessToken)
saveToken('')
})
}
}, [])
const { val: accessTokenHint } = useAccessTokenHint
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
const { val: shortcutHint } = useShortcutHint
const { val: accessToken } = useAccessToken
const { val: reloadHint } = useReloadHint
React.useEffect(() => {
useToggleShowSideBarShortcut.set(configContext.val.shortcut)
}, [configContext.val.shortcut])
React.useEffect(() => {
// clear input when access token updates
useAccessToken.set('')
}, [configContext.val.access_token])
const onInputAccessToken = React.useCallback(
({ currentTarget: { value } }: React.FormEvent<HTMLInputElement>) => {
useAccessToken.set(value)
@ -87,28 +88,25 @@ function SettingsBarContent() {
if (key === 'Enter') saveToken()
}, [])
const saveToken = React.useCallback(async (hint?: typeof useAccessTokenHint.val) => {
const { val: accessToken } = useAccessToken
if (accessToken) {
configContext.set({ access_token: accessToken })
useAccessToken.set('')
useAccessTokenHint.set(
hint || (
<span>
<a href="#" onClick={() => window.location.reload()}>
Reload
</a>{' '}
to activate!
</span>
),
)
}
}, [])
const clearToken = React.useCallback(async () => {
configContext.set({ access_token: '' })
useAccessToken.set('')
}, [])
const saveToken = React.useCallback(
async (hint?: typeof useAccessTokenHint.val) => {
if (accessToken) {
configContext.set({ access_token: accessToken })
useAccessToken.set('')
useAccessTokenHint.set(
hint || (
<span>
<a href="#" onClick={() => window.location.reload()}>
Reload
</a>{' '}
to activate!
</span>
),
)
}
},
[accessToken],
)
const saveShortcut = React.useCallback(async () => {
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
@ -140,12 +138,6 @@ function SettingsBarContent() {
[],
)
const { val: accessTokenHint } = useAccessTokenHint
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
const { val: shortcutHint } = useShortcutHint
const { val: accessToken } = useAccessToken
const { val: reloadHint } = useReloadHint
return (
<>
<h3 className={'gitako-settings-bar-title'}>Settings</h3>
@ -182,7 +174,7 @@ function SettingsBarContent() {
onKeyPress={onPressAccessToken}
/>
{hasAccessToken && !accessToken ? (
<button className={'btn'} onClick={clearToken}>
<button className={'btn'} onClick={() => configContext.set({ access_token: '' })}>
Clear
</button>
) : (
@ -264,24 +256,3 @@ export function SettingsBar(props: Props) {
</div>
)
}
async function trySetUpAccessTokenWithCode() {
try {
const search = parseURLSearch()
if ('code' in search) {
const res = await JSONRequest('https://github.com/login/oauth/access_token', {
code: search.code,
client_id: oauth.clientId,
client_secret: oauth.clientSecret,
})
const { access_token: accessToken, scope } = res
if (scope !== 'repo' || !accessToken) {
throw new Error(`Cannot resolve token response: '${JSON.stringify(res)}'`)
}
window.history.pushState({}, 'removed code', window.location.pathname.replace(/#.*$/, ''))
return accessToken
}
} catch (err) {
raiseError(err)
}
}

View file

@ -1,30 +1,43 @@
import { raiseError } from 'analytics'
import { FileExplorer } from 'components/FileExplorer'
import { MetaBar } from 'components/MetaBar'
import { Portal } from 'components/Portal'
import { Resizable } from 'components/Resizable'
import { SettingsBar } from 'components/SettingsBar'
import { ToggleShowButton } from 'components/ToggleShowButton'
import { useConfigs } from 'containers/ConfigsContext'
import { connect } from 'driver/connect'
import { SideBarCore } from 'driver/core'
import { ConnectorState, Props } from 'driver/core/SideBar'
import { oauth } from 'env'
import * as React from 'react'
import { cx } from 'utils/cx'
import { JSONRequest, parseURLSearch } from 'utils/general'
const RawGitako: React.FC<Props & ConnectorState> = function RawGitako(props) {
const configContext = useConfigs()
const accessToken = props.configContext.val.access_token
React.useEffect(() => {
const { init, useListeners } = props
init()
const { init } = props
;(async function() {
if (!accessToken) {
const accessToken = await trySetUpAccessTokenWithCode()
configContext.set({ access_token: accessToken })
}
init()
})()
}, [])
React.useEffect(() => {
const { useListeners } = props
useListeners(true)
return () => useListeners(false)
}, [])
const accessToken = props.configContext.val.access_token
React.useEffect(() => {
if (accessToken) {
// reload when setting new accessToken
if (accessToken) props.init()
}
}, [accessToken, props.init])
// reload when setting new accessToken
// special way to implement didUpdate
React.useEffect(() => () => props.init(), [accessToken])
const {
errorDueToAuth,
@ -99,3 +112,24 @@ function renderAccessDeniedError() {
</div>
)
}
async function trySetUpAccessTokenWithCode() {
try {
const search = parseURLSearch()
if ('code' in search) {
const res = await JSONRequest('https://github.com/login/oauth/access_token', {
code: search.code,
client_id: oauth.clientId,
client_secret: oauth.clientSecret,
})
const { access_token: accessToken, scope } = res
if (scope !== 'repo' || !accessToken) {
throw new Error(`Cannot resolve token response: '${JSON.stringify(res)}'`)
}
window.history.pushState({}, 'removed code', window.location.pathname.replace(/#.*$/, ''))
return accessToken
}
} catch (err) {
raiseError(err)
}
}

View file

@ -194,8 +194,15 @@ export const onKeyDown: BoundMethodCreator<[KeyboardEvent]> = dispatch => e => {
}
export const toggleShowSideBar: BoundMethodCreator = dispatch => () => {
const [{ shouldShow }] = dispatch.get()
const [{ shouldShow }, { configContext }] = dispatch.get()
dispatch.call(setShouldShow, !shouldShow)
const {
val: { intelligentToggle },
} = configContext
if (intelligentToggle !== null) {
configContext.set({ intelligentToggle: !shouldShow })
}
}
export const setShouldShow: BoundMethodCreator<