refactor: raise error context higher than state context

fixes #275
This commit is contained in:
EnixCoda 2023-01-05 18:39:00 +08:00
parent a1853ec3d2
commit 593ba27557
4 changed files with 54 additions and 29 deletions

View file

@ -18,15 +18,15 @@ export function Gitako() {
<ReloadContextWrapper>
<ErrorBoundary>
<ConfigsContextWrapper>
<StateBarStateContextWrapper>
<StateBarErrorContextWrapper>
<StateBarErrorContextWrapper>
<StateBarStateContextWrapper>
<OAuthWrapper>
<RepoContextWrapper>
<SideBar />
</RepoContextWrapper>
</OAuthWrapper>
</StateBarErrorContextWrapper>
</StateBarStateContextWrapper>
</StateBarStateContextWrapper>
</StateBarErrorContextWrapper>
</ConfigsContextWrapper>
</ErrorBoundary>
</ReloadContextWrapper>

View file

@ -65,24 +65,12 @@ export function SideBar() {
return (
<Theme>
<ToggleShowButtonWrapper
shouldExpand={shouldExpand}
setShouldExpand={setShouldExpand}
toggleShowSideBar={toggleShowSideBar}
/>
<SidebarContext.Provider value={sidebarContextValue}>
<IIFC>
{() => {
const logoContainerElement = useLogoContainerElement()
return (
<Portal into={logoContainerElement}>
<ToggleShowButton
error={error}
className={cx({
hidden: shouldExpand,
})}
onHover={sidebarToggleMode === 'float' ? () => setShouldExpand(true) : undefined}
onClick={toggleShowSideBar}
/>
</Portal>
)
}}
</IIFC>
<div className={'gitako-side-bar'}>
<div
className={cx('gitako-side-bar-body-wrapper', `toggle-mode-${sidebarToggleMode}`, {
@ -174,6 +162,30 @@ export function SideBar() {
)
}
function ToggleShowButtonWrapper({
shouldExpand,
setShouldExpand,
toggleShowSideBar,
}: {
shouldExpand: boolean
setShouldExpand: React.Dispatch<React.SetStateAction<boolean>>
toggleShowSideBar: () => void
}) {
const logoContainerElement = useLogoContainerElement()
const { sidebarToggleMode } = useConfigs().value
return (
<Portal into={logoContainerElement}>
<ToggleShowButton
className={cx({
hidden: shouldExpand,
})}
onHover={sidebarToggleMode === 'float' ? () => setShouldExpand(true) : undefined}
onClick={toggleShowSideBar}
/>
</Portal>
)
}
function useFocusSidebarOnExpand(shouldExpand: boolean) {
React.useEffect(() => {
// prevent keeping focus within Gitako

View file

@ -1,15 +1,16 @@
import { SyncIcon } from '@primer/octicons-react'
import iconURL from 'assets/icons/Gitako.png'
import { useConfigs } from 'containers/ConfigsContext'
import { SideBarErrorContext } from 'containers/ErrorContext'
import { ReloadContext } from 'containers/ReloadContext'
import * as React from 'react'
import { useDebounce, useWindowSize } from 'react-use'
import { cx } from 'utils/cx'
import { useLoadedContext } from 'utils/hooks/useLoadedContext'
import { useResizeHandler } from 'utils/hooks/useResizeHandler'
import { RoundIconButton } from './RoundIconButton'
type Props = {
error?: string | null
className?: React.HTMLAttributes<HTMLButtonElement>['className']
onHover?: React.HTMLAttributes<HTMLButtonElement>['onMouseEnter']
onClick?: (e: PointerEvent) => void
@ -21,8 +22,10 @@ function getSafeDistance(y: number, height: number) {
return Math.max(0, Math.min(y, height - buttonHeight))
}
export function ToggleShowButton({ error, className, onClick, onHover }: Props) {
export function ToggleShowButton({ className, onClick, onHover }: Props) {
const reload = React.useContext(ReloadContext)
const error = useLoadedContext(SideBarErrorContext).value
const ref = React.useRef<HTMLDivElement>(null)
const config = useConfigs()
const [distance, setDistance] = React.useState(config.value.toggleButtonVerticalDistance)

View file

@ -1,6 +1,8 @@
import { PropsWithChildren } from 'common'
import * as React from 'react'
import { useLoadedContext } from 'utils/hooks/useLoadedContext'
import { useStateIO } from 'utils/hooks/useStateIO'
import { SideBarErrorContext } from './ErrorContext'
import { useInspector } from './StateInspector'
export type SideBarState =
@ -13,7 +15,8 @@ export type SideBarState =
| 'tree-rendering'
| 'tree-rendered'
| 'idle'
| 'error-due-to-auth'
| 'error' // when error occurs, sidebar should never expand
| 'error-due-to-auth' // this is a special error, user can expand sidebar and set token to fix the error
export type SideBarStateContextShape = IO<SideBarState>
@ -22,10 +25,17 @@ export const SideBarStateContext = React.createContext<SideBarStateContextShape
export function StateBarStateContextWrapper({ children }: PropsWithChildren) {
const $state = useStateIO<SideBarState>('disabled')
useInspector('SideBarStateContext', $state.value)
return (
<SideBarStateContext.Provider value={$state}>
{$state.value !== null && children}
</SideBarStateContext.Provider>
const error = useLoadedContext(SideBarErrorContext).value
const $$state: IO<SideBarState> = React.useMemo(
() =>
error && $state.value !== 'error'
? {
...$state,
value: 'error',
}
: $state,
[$state, error],
)
return <SideBarStateContext.Provider value={$$state}>{children}</SideBarStateContext.Provider>
}