feat: resolve OAuth token before sending request

This commit is contained in:
EnixCoda 2021-05-10 00:07:26 +08:00
parent 56e55812fc
commit c43a5c2311
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
3 changed files with 63 additions and 53 deletions

View file

@ -5,6 +5,7 @@ import * as React from 'react'
import { useLoadedContext } from 'utils/hooks/useLoadedContext'
import { ErrorBoundary } from './ErrorBoundary'
import { StateBarErrorContextWrapper } from './ErrorContext'
import { OAuthWrapper } from './OAuthWrapper'
import { RepoContext, RepoContextWrapper } from './RepoContext'
import { SideBarStateContext, StateBarStateContextWrapper } from './SideBarState'
@ -14,17 +15,19 @@ export function Gitako() {
<ConfigsContextWrapper>
<StateBarStateContextWrapper>
<StateBarErrorContextWrapper>
<RepoContextWrapper>
<IIFC>
{() => (
<SideBar
configContext={useConfigs()}
stateContext={useLoadedContext(SideBarStateContext)}
metaData={React.useContext(RepoContext)}
/>
)}
</IIFC>
</RepoContextWrapper>
<OAuthWrapper>
<RepoContextWrapper>
<IIFC>
{() => (
<SideBar
configContext={useConfigs()}
stateContext={useLoadedContext(SideBarStateContext)}
metaData={useLoadedContext(RepoContext)}
/>
)}
</IIFC>
</RepoContextWrapper>
</OAuthWrapper>
</StateBarErrorContextWrapper>
</StateBarStateContextWrapper>
</ConfigsContextWrapper>

View file

@ -0,0 +1,48 @@
import { useConfigs } from 'containers/ConfigsContext'
import { platform } from 'platforms'
import * as React from 'react'
import { parseURLSearch, run } from 'utils/general'
import { useStateIO } from 'utils/hooks/useStateIO'
/**
* Setup access token before sending other requests
*/
export function OAuthWrapper({ children }: React.PropsWithChildren<{}>) {
const running = useSetAccessToken()
return running ? null : <>{children}</>
}
function useSetAccessToken() {
const $block = useStateIO(() => Boolean(getCodeSearchParam()))
const configContext = useConfigs()
const { accessToken } = configContext.value
React.useEffect(() => {
run(async function () {
const code = getCodeSearchParam()
if (code && !accessToken) {
const accessToken = await getAccessTokenWithCode(code)
if (accessToken) configContext.onChange({ accessToken })
}
$block.onChange(false)
})
}, [])
return $block.value
}
function getCodeSearchParam() {
return parseURLSearch().get('code')
}
async function getAccessTokenWithCode(code: string) {
const accessToken = await platform.setOAuth(code)
if (!accessToken) alert(`Gitako: The OAuth token may have expired, please try again.`)
const search = parseURLSearch()
search.delete('code')
window.history.replaceState(
{},
'removed search param',
window.location.pathname.replace(window.location.search, search.toString()),
)
return accessToken
}

View file

@ -1,7 +1,6 @@
import { useConfigs } from 'containers/ConfigsContext'
import { platform } from 'platforms'
import * as React from 'react'
import { parseURLSearch, run } from 'utils/general'
import { useEffectOnSerializableUpdates } from 'utils/hooks/useEffectOnSerializableUpdates'
import { useLoadedContext } from 'utils/hooks/useLoadedContext'
import { useOnPJAXDone } from 'utils/hooks/usePJAX'
@ -15,13 +14,8 @@ export function RepoContextWrapper({ children }: React.PropsWithChildren<{}>) {
const partialMetaData = usePartialMetaData()
const defaultBranch = useDefaultBranch(partialMetaData)
const metaData = useMetaData(partialMetaData, defaultBranch)
const fetchingAccessToken = useSetAccessToken()
return (
<RepoContext.Provider value={metaData}>
{metaData && !fetchingAccessToken && children}
</RepoContext.Provider>
)
return <RepoContext.Provider value={metaData}>{metaData && children}</RepoContext.Provider>
}
function resolvePartialMetaData() {
@ -103,38 +97,3 @@ function useMetaData(
}, [partialMetaData, branchName, defaultBranchName])
return $metaData.value
}
function useSetAccessToken() {
const $running = useStateIO(() => Boolean(getCodeSearchParam()))
const configContext = useConfigs()
const { accessToken } = configContext.value
React.useEffect(() => {
run(async function () {
const code = getCodeSearchParam()
if (code && !accessToken) {
const accessToken = await getAccessTokenWithCode(code)
if (accessToken) configContext.onChange({ accessToken })
}
$running.onChange(false)
})
}, [])
return $running.value
}
function getCodeSearchParam() {
return parseURLSearch().get('code')
}
async function getAccessTokenWithCode(code: string) {
const accessToken = await platform.setOAuth(code)
if (!accessToken) alert(`Gitako: The OAuth token may have expired, please try again.`)
const search = parseURLSearch()
search.delete('code')
window.history.replaceState(
{},
'removed search param',
window.location.pathname.replace(window.location.search, search.toString()),
)
return accessToken
}