mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
refactor: access token and intelligent toggle
This commit is contained in:
parent
ddb86fa4ef
commit
819fc17faf
3 changed files with 82 additions and 70 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<
|
||||
|
|
|
|||
Loading…
Reference in a new issue