fix: handle profile repositories <-> repository redirecting

This commit is contained in:
EnixCoda 2022-07-04 21:24:24 +08:00
parent ce3dffb84d
commit f6675e8163
7 changed files with 69 additions and 60 deletions

View file

@ -25,6 +25,7 @@ import { SettingsBarContent } from './settings/SettingsBar'
export function SideBar() {
const state = useLoadedContext(SideBarStateContext).value
const error = useLoadedContext(SideBarErrorContext).value
const configContext = useConfigs()
const { sideBarWidth } = configContext.value
@ -59,17 +60,18 @@ export function SideBar() {
: false
: intelligentToggle,
)
const shouldShow = $shouldShow.value
const toggleBodyIndent = React.useCallback(() => {
if (sidebarToggleMode === 'persistent') {
DOMHelper.setBodyIndent(shouldShow)
} else {
DOMHelper.setBodyIndent(false)
}
// Lock false on error
const setShowSideBar = $shouldShow.onChange
if (shouldShow) {
DOMHelper.focusFileExplorer() // TODO: verify if it works
}
const shouldShow = React.useMemo(
() => !error && state !== 'disabled' && $shouldShow.value,
[error, state, $shouldShow.value],
)
const toggleBodyIndent = React.useCallback(() => {
DOMHelper.setBodyIndent(sidebarToggleMode === 'persistent' ? shouldShow : false)
if (shouldShow) DOMHelper.focusFileExplorer() // TODO: verify if it works
}, [shouldShow, sidebarToggleMode])
React.useEffect(() => {
@ -85,24 +87,7 @@ export function SideBar() {
}
}, [shouldShow, intelligentToggle]) // eslint-disable-line react-hooks/exhaustive-deps
const error = useLoadedContext(SideBarErrorContext).value
// Lock shouldShow on error
React.useEffect(() => {
if (error && shouldShow) {
$shouldShow.onChange(false)
}
}, [error]) // eslint-disable-line react-hooks/exhaustive-deps
const setShowSideBar = React.useCallback(
(show: boolean) => {
if (!error) $shouldShow.onChange(show)
},
[error], // eslint-disable-line react-hooks/exhaustive-deps
)
const toggleShowSideBar = React.useCallback(() => {
if (!error) $shouldShow.onChange(show => !show)
}, [error]) // eslint-disable-line react-hooks/exhaustive-deps
const toggleShowSideBar = React.useCallback(() => setShowSideBar(show => !show), [setShowSideBar])
useToggleSideBarWithKeyboard(state, toggleShowSideBar)
const updateSideBarVisibility = React.useCallback(() => {
@ -126,22 +111,24 @@ export function SideBar() {
}
}, [hideSidebarOnInvalidToken, setShowSideBar])
if (state === 'disabled') return null
return (
<Theme>
<Portal into={$logoContainerElement.value}>
<ToggleShowButton
error={error}
className={cx({
hidden: shouldShow,
})}
onHover={sidebarToggleMode === 'float' ? () => setShowSideBar(true) : undefined}
onClick={toggleShowSideBar}
/>
</Portal>
<div className={'gitako-side-bar'}>
<Portal into={$logoContainerElement.value}>
<ToggleShowButton
error={error}
className={cx({
hidden: shouldShow,
})}
onHover={sidebarToggleMode === 'float' ? () => setShowSideBar(true) : undefined}
onClick={toggleShowSideBar}
/>
</Portal>
<SideBarBodyWrapper
className={cx(`toggle-mode-${sidebarToggleMode}`, {
collapsed: error || !shouldShow,
collapsed: !shouldShow,
})}
baseSize={baseSize}
onLeave={sidebarToggleMode === 'float' ? () => setShowSideBar(false) : undefined}
@ -183,8 +170,6 @@ export function SideBar() {
</div>
{run(() => {
switch (state) {
case 'disabled':
return null
case 'getting-access-token':
return <LoadingIndicator text={'Getting access token...'} />
case 'after-getting-access-token':

View file

@ -27,9 +27,9 @@ function resolvePartialMetaData() {
repoName,
type: type === 'pull' ? type : undefined,
}
} else {
return partialMetaData
}
return null
}
function usePartialMetaData(): PartialMetaData | null {
@ -75,8 +75,10 @@ function useDefaultBranch(partialMetaData: PartialMetaData | null) {
catchNetworkError(async () => {
if (!partialMetaData) return
$state.onChange('meta-loading')
const { userName, repoName } = partialMetaData
if (!userName || !repoName) return
const defaultBranch = await platform.getDefaultBranchName(partialMetaData, accessToken)
const defaultBranch = await platform.getDefaultBranchName({ userName, repoName }, accessToken)
$defaultBranch.onChange(defaultBranch)
})
}, [partialMetaData, accessToken]) // eslint-disable-line react-hooks/exhaustive-deps
@ -94,6 +96,8 @@ function useMetaData(
React.useEffect(() => {
if (partialMetaData && defaultBranchName && theBranch) {
const { userName, repoName } = partialMetaData
if (!userName || !repoName) return
const safeMetaData: MetaData = {
userName,
repoName,

View file

@ -1,16 +1,13 @@
import { Gitako } from 'components/Gitako'
import { platform } from 'platforms'
import * as React from 'react'
import { createRoot } from 'react-dom/client'
import { insertSideBarMountPoint, persistGitakoElements } from 'utils/DOMHelper'
import './content.scss'
if (platform.resolvePartialMetaData()) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init)
} else {
init()
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init)
} else {
init()
}
async function init() {

5
src/global.d.ts vendored
View file

@ -8,7 +8,10 @@ type MetaData = {
type?: EnumString<'tree' | 'blob' | 'pull' | 'commit'>
}
type PartialMetaData = Omit<MakeOptional<MetaData, 'branchName'>, 'defaultBranchName'>
type PartialMetaData = Omit<
MakeOptional<MetaData, 'repoName' | 'userName' | 'branchName'>,
'defaultBranchName'
>
type TreeNode = {
name: string

View file

@ -2,6 +2,7 @@ import { useConfigs } from 'containers/ConfigsContext'
import { GITHUB_OAUTH } from 'env'
import { Base64 } from 'js-base64'
import { configRef } from 'utils/config/helper'
import { $ } from 'utils/DOMHelper'
import { resolveGitModules } from 'utils/gitSubmodule'
import { sortFoldersToFront } from 'utils/treeParser'
import * as API from './API'
@ -82,12 +83,28 @@ function getUrlForRedirect(
}
export function isEnterprise() {
return !window.location.host.endsWith('github.com')
return (
(window.location.host !== 'github.com' &&
/**
* <a class="Header-link " href="https://host.com/" data-hotkey="g d" aria-label="Homepage Enterprise">
* <span>Enterprise</span>
* </a>
*/
$('a.Header-link[aria-label="Homepage Enterprise"]', e => e.textContent === 'Enterprise')) ||
false
)
}
const pathSHAMap = new Map<string, string>()
export const GitHub: Platform = {
shouldActivate() {
return (
window.location.host === 'github.com' ||
// <link rel="fluid-icon" href="https://host.com/fluidicon.png" title="GitHub">
!!document.querySelector('link[rel="fluid-icon"][title="GitHub"]')
)
},
isEnterprise,
resolvePartialMetaData() {
if (!DOMHelper.isInRepoPage()) {

View file

@ -5,16 +5,18 @@ import { Gitee } from './Gitee'
import { GitHub } from './GitHub'
const platforms = {
GitHub: GitHub,
Gitee: Gitee,
Gitea: Gitea,
GitHub,
Gitee,
Gitea,
}
function resolvePlatform() {
for (const platform of Object.values(platforms)) {
if (platform.resolvePartialMetaData()) return platform
}
return dummyPlatformForTypeSafety
return (
forOf(platforms, (platformName, platform) => {
const { shouldActivate = () => !!platform.resolvePartialMetaData() } = platform
if (shouldActivate()) return platform
}) || dummyPlatformForTypeSafety
)
}
function getPlatformName() {

View file

@ -1,4 +1,5 @@
type Platform = {
shouldActivate?(): boolean
isEnterprise(): boolean
// branch name might not be available when resolving from DOM and URL
resolvePartialMetaData(): PartialMetaData | null