fix: handle scope change

This commit is contained in:
EnixCoda 2021-05-02 22:04:19 +08:00
parent 69614104ec
commit 5ddd6c6948
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
6 changed files with 70 additions and 11 deletions

View file

@ -52,7 +52,12 @@ const RawGitako: React.FC<Props & ConnectorState> = function RawGitako(props) {
* Catch unexpected PJAX, force trigger init on scope change.
*/
const pageScope = useStateIO(platform.resolvePageScope?.())
useOnPJAXDone(() => pageScope.onChange(platform.resolvePageScope?.()))
useOnPJAXDone(
React.useCallback(
() => pageScope.onChange(platform.resolvePageScope?.(metaData?.defaultBranchName)),
[metaData?.defaultBranchName],
),
)
React.useEffect(() => {
props.init()
}, [accessToken, pageScope.value])

View file

@ -43,7 +43,7 @@ export const init: BoundMethodCreator = dispatch => async () => {
dispatch.set({ state: 'disabled' })
return
}
const { userName, repoName, branchName } = metaData
const { userName, repoName, branchName, defaultBranchName } = metaData
DOMHelper.markGitakoReadyState(true)
dispatch.set({
@ -70,10 +70,11 @@ export const init: BoundMethodCreator = dispatch => async () => {
getTreeData.catch(error => error) // catch it early to prevent the error being raised higher
if (branchName) {
const safeMetaData = {
const safeMetaData: MetaData = {
userName,
repoName,
branchName,
defaultBranchName,
}
dispatch.set({ metaData: safeMetaData })
getTreeData.catch(error => {
@ -89,10 +90,11 @@ export const init: BoundMethodCreator = dispatch => async () => {
throw new Error(`Failed resolving default branch name`)
}
const safeMetaData = {
const safeMetaData: MetaData = {
userName,
repoName,
branchName: defaultBranchName,
defaultBranchName,
}
dispatch.set({ metaData: safeMetaData })

1
src/global.d.ts vendored
View file

@ -2,6 +2,7 @@ type MetaData = {
userName: string
repoName: string
branchName: string
defaultBranchName?: string
type?: EnumString<'tree' | 'blob' | 'pull'>
}

View file

@ -232,3 +232,23 @@ export function attachCopySnippet() {
)
})
}
export function getPath() {
const folderPathElementSelector = '.file-navigation .position-relative' // available when in path like '/tree/...'
const blobPathElementSelector = '#blob-path' // available when in path like '/blob/...'
const pathElement =
document.querySelector(blobPathElementSelector) ||
document.querySelector(folderPathElementSelector)?.nextElementSibling
if (!pathElement || !pathElement.querySelector('.js-repo-root')) {
raiseError(new Error(`Path element not found`))
return ''
}
const path = ((pathElement as HTMLDivElement).innerText || '')
.replace(/ \/ Jump to $/, '')
.trim()
.split('/')
.filter(Boolean)
.slice(1) // the first is the repo's name
.join('/')
return path
}

View file

@ -1,3 +1,4 @@
import { raiseError } from 'analytics'
import { GITHUB_OAUTH } from 'env'
import { Base64 } from 'js-base64'
import { platform } from 'platforms'
@ -82,6 +83,40 @@ export function isEnterprise() {
return !window.location.host.endsWith('github.com')
}
function getBranchName() {
const pathFromDOM = DOMHelper.getPath()
const pathAndBranchFromURL = URLHelper.parse().path.filter(Boolean).join('/')
if (pathAndBranchFromURL.endsWith(pathFromDOM)) {
return pathAndBranchFromURL
.slice(0, pathAndBranchFromURL.length - pathFromDOM.length)
.replace(/\/$/, '')
}
raiseError(new Error(`Parsed path not end with path from DOM`))
}
function resolvePageScope(defaultBranchName?: string) {
const parsed = URLHelper.parse()
switch (parsed.type) {
// case undefined:
// return `branch-${defaultBranchName}`
case 'blob':
case 'tree': {
// handle URLs like {user}/{repo}/tree/{sha|branch}, issue#131
const branchName = getBranchName()
if (branchName && branchName !== defaultBranchName) return `branch-${branchName}`
break
}
case 'tags':
return 'tags'
case 'releases':
return 'releases'
case 'pull':
const pullId = URLHelper.isInPullPage()
if (pullId) return `pull-${pullId}`
}
return 'general'
}
const pathSHAMap = new Map<string, string>()
export const GitHub: Platform = {
@ -115,15 +150,11 @@ export const GitHub: Platform = {
repoName,
type,
branchName,
defaultBranchName: type ? undefined : branchName,
}
return metaData
},
resolvePageScope() {
if (URLHelper.parse().type === 'releases') return 'releases'
const pullId = URLHelper.isInPullPage()
if (pullId) return `pull-${pullId}`
return 'general'
},
resolvePageScope,
async getDefaultBranchName({ userName, repoName }, accessToken) {
const data = await API.getRepoMeta(userName, repoName, accessToken)
return data.default_branch

View file

@ -2,7 +2,7 @@ type Platform = {
isEnterprise(): boolean
// branch name might not be available when resolving from DOM and URL
resolveMeta(): MakeOptional<MetaData, 'branchName'> | null
resolvePageScope?(): string
resolvePageScope?(branchName?: string): string
getDefaultBranchName(
metaData: Pick<MetaData, 'userName' | 'repoName'>,
accessToken?: string,