mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
refactor: deprecate driven sidebar
This commit is contained in:
parent
11a4399ea0
commit
79644fba82
5 changed files with 106 additions and 106 deletions
|
|
@ -1,6 +1,7 @@
|
|||
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'
|
||||
|
|
@ -14,8 +15,13 @@ 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 && children}</RepoContext.Provider>
|
||||
return (
|
||||
<RepoContext.Provider value={metaData}>
|
||||
{metaData && !fetchingAccessToken && children}
|
||||
</RepoContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
function resolvePartialMetaData() {
|
||||
|
|
@ -97,3 +103,38 @@ 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,30 +5,32 @@ import { Portal } from 'components/Portal'
|
|||
import { Resizable } from 'components/Resizable'
|
||||
import { SettingsBar } from 'components/settings/SettingsBar'
|
||||
import { ToggleShowButton } from 'components/ToggleShowButton'
|
||||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import { connect } from 'driver/connect'
|
||||
import { SideBarCore } from 'driver/core'
|
||||
import { ConnectorState, Props } from 'driver/core/SideBar'
|
||||
import { ConfigsContextShape, useConfigs } from 'containers/ConfigsContext'
|
||||
import { platform } from 'platforms'
|
||||
import { useGitHubAttachCopyFileButton, useGitHubAttachCopySnippetButton } from 'platforms/GitHub'
|
||||
import * as React from 'react'
|
||||
import { cx } from 'utils/cx'
|
||||
import * as DOMHelper from 'utils/DOMHelper'
|
||||
import { parseURLSearch, run } from 'utils/general'
|
||||
import { run } from 'utils/general'
|
||||
import { useCatchNetworkError } from 'utils/hooks/useCatchNetworkError'
|
||||
import { useLoadedContext } from 'utils/hooks/useLoadedContext'
|
||||
import { loadWithPJAX, useOnPJAXDone, usePJAX } from 'utils/hooks/usePJAX'
|
||||
import { useProgressBar } from 'utils/hooks/useProgressBar'
|
||||
import { useStateIO } from 'utils/hooks/useStateIO'
|
||||
import * as keyHelper from 'utils/keyHelper'
|
||||
import { SideBarErrorContext } from './ErrorContext'
|
||||
import { Icon } from './Icon'
|
||||
import { IIFC } from './IIFC'
|
||||
import { LoadingIndicator } from './LoadingIndicator'
|
||||
import { SideBarStateContext } from './SideBarState'
|
||||
import { SideBarState, SideBarStateContext, SideBarStateContextShape } from './SideBarState'
|
||||
import { Theme } from './Theme'
|
||||
|
||||
const RawSideBar: React.FC<Props & ConnectorState> = function RawGitako(props) {
|
||||
const { metaData, error, shouldShow, toggleShowSideBar } = props
|
||||
export function SideBar(props: {
|
||||
metaData: MetaData | null
|
||||
configContext: ConfigsContextShape
|
||||
stateContext: SideBarStateContextShape
|
||||
}) {
|
||||
const { metaData } = props
|
||||
|
||||
const state = useLoadedContext(SideBarStateContext).value
|
||||
const configContext = useConfigs()
|
||||
|
|
@ -55,30 +57,31 @@ const RawSideBar: React.FC<Props & ConnectorState> = function RawGitako(props) {
|
|||
}
|
||||
}, [hasMetaData])
|
||||
|
||||
React.useEffect(() => {
|
||||
run(async function () {
|
||||
if (!accessToken) {
|
||||
const accessToken = await trySetUpAccessTokenWithCode()
|
||||
if (accessToken) configContext.onChange({ accessToken })
|
||||
}
|
||||
})
|
||||
const $shouldShow = useStateIO(false)
|
||||
const shouldShow = $shouldShow.value
|
||||
const setShouldShow = React.useCallback((shouldShow: boolean) => {
|
||||
$shouldShow.onChange(shouldShow)
|
||||
DOMHelper.setBodyIndent(shouldShow)
|
||||
}, [])
|
||||
React.useEffect(() => {
|
||||
if (shouldShow) {
|
||||
DOMHelper.focusFileExplorer() // TODO: verify if it works
|
||||
}
|
||||
}, [shouldShow])
|
||||
const toggleShowSideBar = React.useCallback(() => {
|
||||
$shouldShow.onChange(shouldShow => {
|
||||
DOMHelper.setBodyIndent(!shouldShow)
|
||||
return !shouldShow
|
||||
})
|
||||
|
||||
React.useEffect(
|
||||
function attachKeyDown() {
|
||||
if (state === 'disabled' || !configContext.value.shortcut) return
|
||||
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
const keys = keyHelper.parseEvent(e)
|
||||
if (keys === configContext.value.shortcut) {
|
||||
toggleShowSideBar()
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
return () => window.removeEventListener('keydown', onKeyDown)
|
||||
},
|
||||
[toggleShowSideBar, state === 'disabled', configContext.value.shortcut],
|
||||
)
|
||||
const {
|
||||
value: { intelligentToggle },
|
||||
} = configContext
|
||||
if (intelligentToggle !== null) {
|
||||
configContext.onChange({ intelligentToggle: !shouldShow })
|
||||
}
|
||||
}, [])
|
||||
useToggleSideBarWithKeyboard(state, configContext, toggleShowSideBar)
|
||||
|
||||
const intelligentToggle = configContext.value.intelligentToggle
|
||||
// Hide sidebar when error due to auth but token is set #128
|
||||
|
|
@ -86,19 +89,26 @@ const RawSideBar: React.FC<Props & ConnectorState> = function RawGitako(props) {
|
|||
intelligentToggle === null && Boolean(state === 'error-due-to-auth' && accessToken)
|
||||
React.useEffect(() => {
|
||||
if (hideSidebarOnInvalidToken) {
|
||||
props.setShouldShow(false)
|
||||
setShouldShow(false)
|
||||
} else {
|
||||
const shouldShow = intelligentToggle === null ? platform.shouldShow() : intelligentToggle
|
||||
props.setShouldShow(shouldShow)
|
||||
setShouldShow(shouldShow)
|
||||
}
|
||||
}, [intelligentToggle, hideSidebarOnInvalidToken, metaData])
|
||||
|
||||
const error = useLoadedContext(SideBarErrorContext).value
|
||||
React.useEffect(() => {
|
||||
if (error) {
|
||||
$shouldShow.onChange(false)
|
||||
}
|
||||
}, [error])
|
||||
|
||||
const updateSideBarVisibility = React.useCallback(
|
||||
function updateSideBarVisibility() {
|
||||
if (hideSidebarOnInvalidToken) {
|
||||
props.setShouldShow(false)
|
||||
setShouldShow(false)
|
||||
} else if (intelligentToggle === null) {
|
||||
props.setShouldShow(platform.shouldShow())
|
||||
setShouldShow(platform.shouldShow())
|
||||
}
|
||||
},
|
||||
[metaData?.branchName, intelligentToggle, hideSidebarOnInvalidToken],
|
||||
|
|
@ -169,22 +179,24 @@ const RawSideBar: React.FC<Props & ConnectorState> = function RawGitako(props) {
|
|||
)
|
||||
}
|
||||
|
||||
RawSideBar.defaultProps = {
|
||||
shouldShow: false,
|
||||
}
|
||||
function useToggleSideBarWithKeyboard(
|
||||
state: SideBarState,
|
||||
configContext: ConfigsContextShape,
|
||||
toggleShowSideBar: () => void,
|
||||
) {
|
||||
React.useEffect(
|
||||
function attachKeyDown() {
|
||||
if (state === 'disabled' || !configContext.value.shortcut) return
|
||||
|
||||
export const SideBar = connect(SideBarCore)(RawSideBar)
|
||||
|
||||
async function trySetUpAccessTokenWithCode() {
|
||||
const search = parseURLSearch()
|
||||
if ('code' in search) {
|
||||
const accessToken = await platform.setOAuth(search.code)
|
||||
if (!accessToken) alert(`Gitako: The OAuth token has expired, please try again.`)
|
||||
window.history.replaceState(
|
||||
{},
|
||||
'removed search param',
|
||||
window.location.pathname.replace(window.location.search, ''),
|
||||
)
|
||||
return accessToken
|
||||
}
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
const keys = keyHelper.parseEvent(e)
|
||||
if (keys === configContext.value.shortcut) {
|
||||
toggleShowSideBar()
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
return () => window.removeEventListener('keydown', onKeyDown)
|
||||
},
|
||||
[toggleShowSideBar, state === 'disabled', configContext.value.shortcut],
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { useDebounce, useWindowSize } from 'react-use'
|
|||
import { Icon } from './Icon'
|
||||
|
||||
type Props = {
|
||||
error?: string
|
||||
error?: string | null
|
||||
} & Pick<React.HTMLAttributes<HTMLButtonElement>, 'onClick'>
|
||||
|
||||
export function ToggleShowButton({ error, onClick }: Props) {
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
import { SideBarStateContextShape } from 'components/SideBarState'
|
||||
import { ConfigsContextShape } from 'containers/ConfigsContext'
|
||||
import { GetCreatedMethod, MethodCreator } from 'driver/connect'
|
||||
import * as DOMHelper from 'utils/DOMHelper'
|
||||
|
||||
export type Props = {
|
||||
// meta data for the repository
|
||||
metaData: MetaData | null
|
||||
configContext: ConfigsContextShape
|
||||
stateContext: SideBarStateContextShape
|
||||
}
|
||||
|
||||
export type ConnectorState = {
|
||||
// error message
|
||||
error?: string
|
||||
// whether Gitako side bar should be shown
|
||||
shouldShow: boolean
|
||||
} & {
|
||||
setShouldShow: GetCreatedMethod<typeof setShouldShow>
|
||||
toggleShowSideBar: GetCreatedMethod<typeof toggleShowSideBar>
|
||||
}
|
||||
|
||||
type BoundMethodCreator<Args extends any[] = []> = MethodCreator<Props, ConnectorState, Args>
|
||||
|
||||
export const toggleShowSideBar: BoundMethodCreator = dispatch => () => {
|
||||
const {
|
||||
state: { shouldShow },
|
||||
props: { configContext },
|
||||
} = dispatch.get()
|
||||
dispatch.call(setShouldShow, !shouldShow)
|
||||
|
||||
const {
|
||||
value: { intelligentToggle },
|
||||
} = configContext
|
||||
if (intelligentToggle !== null) {
|
||||
configContext.onChange({ intelligentToggle: !shouldShow })
|
||||
}
|
||||
}
|
||||
|
||||
export const setShouldShow: BoundMethodCreator<
|
||||
[ConnectorState['shouldShow']]
|
||||
> = dispatch => shouldShow => {
|
||||
dispatch.set({ shouldShow }, shouldShow ? DOMHelper.focusFileExplorer : undefined)
|
||||
DOMHelper.setBodyIndent(shouldShow)
|
||||
}
|
||||
|
||||
export const setError: BoundMethodCreator<[ConnectorState['error']]> = dispatch => error => {
|
||||
dispatch.set({ error })
|
||||
dispatch.call(setShouldShow, false)
|
||||
}
|
||||
|
|
@ -4,8 +4,5 @@ import {
|
|||
ConnectorState as FileExplorerConnectorState,
|
||||
Props as FileExplorerProps,
|
||||
} from './FileExplorer'
|
||||
import * as SideBar from './SideBar'
|
||||
import { ConnectorState as SideBarConnectorState, Props as SideBarProps } from './SideBar'
|
||||
|
||||
export const FileExplorerCore: Sources<FileExplorerProps, FileExplorerConnectorState> = FileExplorer
|
||||
export const SideBarCore: Sources<SideBarProps, SideBarConnectorState> = SideBar
|
||||
|
|
|
|||
Loading…
Reference in a new issue