diff --git a/src/components/MetaBar.tsx b/src/components/MetaBar.tsx index 32eb650..a210444 100644 --- a/src/components/MetaBar.tsx +++ b/src/components/MetaBar.tsx @@ -1,12 +1,15 @@ import { BranchName, Breadcrumb, Flex, Text } from '@primer/components' import { GitBranchIcon } from '@primer/octicons-react' +import { platform } from 'platforms' import * as React from 'react' type Props = { metaData: MetaData } -export function MetaBar({ metaData: { userName, repoName, branchName, repoUrl, userUrl } }: Props) { +export function MetaBar({ metaData }: Props) { + const { userName, repoName, branchName } = metaData + const { repoUrl, userUrl } = platform.resolveUrlFromMetaData(metaData) return ( diff --git a/src/driver/core/SideBar.ts b/src/driver/core/SideBar.ts index b8bf3c8..aebb81a 100644 --- a/src/driver/core/SideBar.ts +++ b/src/driver/core/SideBar.ts @@ -72,11 +72,8 @@ export const init: BoundMethodCreator = dispatch => async () => { ) getTreeData.catch(error => error) // catch it early to prevent the error being raised higher - const metaDataFromAPI = await platform.getMetaData({ userName, repoName }, accessToken) - if (branchName) { const safeMetaData = { - ...metaDataFromAPI, userName, repoName, branchName, @@ -86,14 +83,16 @@ export const init: BoundMethodCreator = dispatch => async () => { dispatch.call(handleError, error) }) } else { - const { defaultBranchName } = metaDataFromAPI + const defaultBranchName = await platform.getDefaultBranchName( + { userName, repoName }, + accessToken, + ) if (!defaultBranchName) { throw new Error(`Failed resolving default branch name`) } const safeMetaData = { - ...metaDataFromAPI, userName, repoName, branchName: defaultBranchName, diff --git a/src/global.d.ts b/src/global.d.ts index 3c3b5af..a7771b6 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -2,10 +2,7 @@ type MetaData = { userName: string repoName: string branchName: string - defaultBranchName?: string - repoUrl?: string - userUrl?: string - type?: 'tree' | 'blob' | 'pull' | string + type?: EnumString<'tree' | 'blob' | 'pull'> } type TreeNode = { @@ -32,3 +29,4 @@ type MakeOptional = Override< type VoidFN = (payload: T) => void type Async = T | Promise +type EnumString = S | (string & {}) diff --git a/src/platforms/GitHub/DOMHelper.ts b/src/platforms/GitHub/DOMHelper.ts index 8d3e7d7..43e8f14 100644 --- a/src/platforms/GitHub/DOMHelper.ts +++ b/src/platforms/GitHub/DOMHelper.ts @@ -5,6 +5,18 @@ import { $ } from 'utils/DOMHelper' import { renderReact } from 'utils/general' import { CopyFileButton, copyFileButtonClassName } from './CopyFileButton' +export function resolveMeta(): Partial { + const metaData = { + userName: $('[itemprop="author"]', e => e.textContent?.trim()), + repoName: $('[itemprop="name"]', e => e.textContent?.trim()), + branchName: getCurrentBranch(true), + } + if (!metaData.userName || !metaData.repoName) { + raiseError(new Error(`Cannot resolve meta from DOM`)) + } + return metaData +} + export function isInRepoPage() { const repoHeadSelector = '.repohead' // legacy const authorNameSelector = '.author[itemprop="author"]' @@ -23,7 +35,7 @@ export function getIssueTitle() { return title?.trim().replace(/\n/g, '') } -export function getCurrentBranch() { +export function getCurrentBranch(passive = false) { const selectedBranchButtonSelector = [ '.repository-content #branch-select-menu summary', '.repository-content .branch-select-menu summary', @@ -55,7 +67,7 @@ export function getCurrentBranch() { } } - raiseError(new Error('cannot get current branch')) + if (!passive) raiseError(new Error('cannot get current branch')) } /** diff --git a/src/platforms/GitHub/index.ts b/src/platforms/GitHub/index.ts index 7562c0d..0cb8037 100644 --- a/src/platforms/GitHub/index.ts +++ b/src/platforms/GitHub/index.ts @@ -91,21 +91,25 @@ export const GitHub: Platform = { return null } + const metaFromDOM = DOMHelper.resolveMeta() + const metaFromURL = URLHelper.parse() + const userName: MetaData['userName'] | undefined = metaFromDOM.userName || metaFromURL.userName + const repoName: MetaData['repoName'] | undefined = metaFromDOM.repoName || metaFromURL.repoName + if (!userName || !repoName) { + return null + } + + const { type } = metaFromURL let branchName if (URLHelper.isInPullPage()) { branchName = DOMHelper.getIssueTitle() } else if ( DOMHelper.isInCodePage() && - !['releases', 'tags'].includes(URLHelper.parse().type || '') // resolve sentry issue #-CK + !['releases', 'tags'].includes(type || '') // resolve sentry issue #-CK ) { branchName = DOMHelper.getCurrentBranch() || URLHelper.parseSHA() } - const { userName, repoName, type } = URLHelper.parse() - if (!userName || !repoName) { - return null - } - const metaData = { userName, repoName, @@ -114,12 +118,14 @@ export const GitHub: Platform = { } return metaData }, - async getMetaData({ userName, repoName }, accessToken) { + async getDefaultBranchName({ userName, repoName }, accessToken) { const data = await API.getRepoMeta(userName, repoName, accessToken) + return data.default_branch + }, + resolveUrlFromMetaData({ userName, repoName }) { return { - userUrl: data?.owner?.html_url, - repoUrl: data?.html_url, - defaultBranchName: data.default_branch, + repoUrl: `https://${window.location.host}/${userName}/${repoName}`, + userUrl: `https://${window.location.host}/${userName}`, } }, async getTreeData(metaData, path = '/', recursive, accessToken) { diff --git a/src/platforms/Gitea/index.ts b/src/platforms/Gitea/index.ts index f89681d..04d12ee 100644 --- a/src/platforms/Gitea/index.ts +++ b/src/platforms/Gitea/index.ts @@ -101,13 +101,14 @@ export const Gitea: Platform = { return metaData }, - async getMetaData(partialMetaData, accessToken) { - const { userName, repoName } = partialMetaData + async getDefaultBranchName({ userName, repoName }, accessToken) { const data = await API.getRepoMeta(userName, repoName, accessToken) + return data.default_branch + }, + resolveUrlFromMetaData({ userName, repoName }) { return { - userUrl: data?.owner?.html_url, - repoUrl: data?.html_url, - defaultBranchName: data.default_branch, + repoUrl: `https://${window.location.host}/${userName}/${repoName}`, + userUrl: `https://${window.location.host}/${userName}`, } }, async getTreeData(metaData, path, recursive, accessToken) { diff --git a/src/platforms/Gitee/index.ts b/src/platforms/Gitee/index.ts index 3e93575..4781db4 100644 --- a/src/platforms/Gitee/index.ts +++ b/src/platforms/Gitee/index.ts @@ -98,13 +98,14 @@ export const Gitee: Platform = { } return metaData }, - async getMetaData(partialMetaData, accessToken) { - const { userName, repoName } = partialMetaData + async getDefaultBranchName({ userName, repoName }, accessToken) { const data = await API.getRepoMeta(userName, repoName, accessToken) + return data.default_branch + }, + resolveUrlFromMetaData({ userName, repoName }) { return { - userUrl: data?.html_url?.replace(/(.*)\/.*?$/, '$1'), - repoUrl: data?.html_url, - defaultBranchName: data.default_branch, + repoUrl: `https://${window.location.host}/${userName}/${repoName}`, + userUrl: `https://${window.location.host}/${userName}`, } }, async getTreeData(metaData, path, recursive, accessToken) { diff --git a/src/platforms/dummyPlatformForTypeSafety.ts b/src/platforms/dummyPlatformForTypeSafety.ts index 8f40194..6cf5c8d 100644 --- a/src/platforms/dummyPlatformForTypeSafety.ts +++ b/src/platforms/dummyPlatformForTypeSafety.ts @@ -5,7 +5,8 @@ export const dummyPlatformForTypeSafety: Platform = { resolveMeta() { return null }, - getMetaData: dummyPlatformMethod, + getDefaultBranchName: dummyPlatformMethod, + resolveUrlFromMetaData: dummyPlatformMethod, getTreeData: dummyPlatformMethod, shouldShow() { return false diff --git a/src/platforms/platform.d.ts b/src/platforms/platform.d.ts index d2b20a2..480e555 100644 --- a/src/platforms/platform.d.ts +++ b/src/platforms/platform.d.ts @@ -2,10 +2,16 @@ type Platform = { isEnterprise(): boolean // branch name might not be available when resolving from DOM and URL resolveMeta(): MakeOptional | null - getMetaData( + getDefaultBranchName( metaData: Pick, accessToken?: string, - ): Promise> + ): Promise + resolveUrlFromMetaData( + metaData: MetaData, + ): { + userUrl: string + repoUrl: string + } getTreeData( metaData: MetaData, path?: string,