mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
fix: strict limit exec order of multiple VisibleNodesGenerator instances
fix #218
This commit is contained in:
parent
dbdc3828ac
commit
1e72cad644
3 changed files with 54 additions and 16 deletions
|
|
@ -15,6 +15,7 @@ import { run } from 'utils/general'
|
|||
import { useLoadedContext } from 'utils/hooks/useLoadedContext'
|
||||
import { useOnLocationChange } from 'utils/hooks/useOnLocationChange'
|
||||
import { useOnPJAXDone } from 'utils/hooks/usePJAX'
|
||||
import { useSequentialEffect } from 'utils/hooks/useSequentialEffect'
|
||||
import { VisibleNodes } from 'utils/VisibleNodesGenerator'
|
||||
import { SideBarStateContext } from '../containers/SideBarState'
|
||||
import { DiffStatGraph } from './DiffStatGraph'
|
||||
|
|
@ -74,16 +75,22 @@ const RawFileExplorer: React.FC<Props & ConnectorState> = function RawFileExplor
|
|||
const stateContext = useLoadedContext(SideBarStateContext)
|
||||
const state = stateContext.value
|
||||
|
||||
React.useEffect(() => {
|
||||
setUpTree({
|
||||
metaData,
|
||||
config: {
|
||||
compressSingletonFolder,
|
||||
accessToken,
|
||||
},
|
||||
stateContext,
|
||||
})
|
||||
}, [setUpTree, metaData, compressSingletonFolder, accessToken])
|
||||
useSequentialEffect(
|
||||
checker => {
|
||||
setUpTree(
|
||||
{
|
||||
metaData,
|
||||
config: {
|
||||
compressSingletonFolder,
|
||||
accessToken,
|
||||
},
|
||||
stateContext,
|
||||
},
|
||||
checker,
|
||||
)
|
||||
},
|
||||
[setUpTree, metaData, compressSingletonFolder, accessToken],
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
focusFileExplorer()
|
||||
|
|
|
|||
|
|
@ -48,10 +48,11 @@ export const setUpTree: BoundMethodCreator<
|
|||
{ stateContext: SideBarStateContextShape } & Required<Pick<Props, 'metaData'>> & {
|
||||
config: Pick<Config, 'compressSingletonFolder' | 'accessToken'>
|
||||
},
|
||||
() => boolean,
|
||||
]
|
||||
> =
|
||||
dispatch =>
|
||||
({ stateContext, metaData, config }) => {
|
||||
({ stateContext, metaData, config }, checker) => {
|
||||
const {
|
||||
props: { catchNetworkErrors },
|
||||
} = dispatch.get()
|
||||
|
|
@ -59,7 +60,9 @@ export const setUpTree: BoundMethodCreator<
|
|||
catchNetworkErrors(async () => {
|
||||
const { userName, repoName, branchName } = metaData
|
||||
|
||||
if (!checker()) return
|
||||
stateContext.onChange('tree-loading')
|
||||
|
||||
const { root: treeRoot, defer = false } = await platform.getTreeData(
|
||||
{
|
||||
branchName: branchName,
|
||||
|
|
@ -71,6 +74,7 @@ export const setUpTree: BoundMethodCreator<
|
|||
config.accessToken,
|
||||
)
|
||||
|
||||
if (!checker()) return
|
||||
stateContext.onChange('tree-rendering')
|
||||
dispatch.set({ defer })
|
||||
|
||||
|
|
@ -82,21 +86,29 @@ export const setUpTree: BoundMethodCreator<
|
|||
return root
|
||||
},
|
||||
})
|
||||
|
||||
if (!checker()) return
|
||||
dispatch.set({ visibleNodesGenerator })
|
||||
visibleNodesGenerator.onUpdate(visibleNodes => dispatch.set({ visibleNodes }))
|
||||
|
||||
visibleNodesGenerator.onUpdate(visibleNodes => {
|
||||
if (!checker()) return
|
||||
dispatch.set({ visibleNodes })
|
||||
})
|
||||
|
||||
if (platform.shouldExpandAll?.()) {
|
||||
const unsubscribe = visibleNodesGenerator.onUpdate(visibleNodes => {
|
||||
unsubscribe()
|
||||
visibleNodes.nodes.forEach(node =>
|
||||
dispatch.call(toggleNodeExpansion, node, { recursive: true }),
|
||||
)
|
||||
visibleNodes.nodes.forEach(node => {
|
||||
if (!checker()) return
|
||||
dispatch.call(toggleNodeExpansion, node, { recursive: true })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const targetPath = platform.getCurrentPath(metaData.branchName)
|
||||
if (targetPath) dispatch.call(goTo, targetPath)
|
||||
if (targetPath && checker()) dispatch.call(goTo, targetPath)
|
||||
}
|
||||
|
||||
if (!checker()) return
|
||||
stateContext.onChange('tree-rendered')
|
||||
})
|
||||
}
|
||||
|
|
|
|||
19
src/utils/hooks/useSequentialEffect.ts
Normal file
19
src/utils/hooks/useSequentialEffect.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { useEffect, useRef } from 'react'
|
||||
|
||||
/**
|
||||
* This effect addresses such a problem:
|
||||
* the later effect ends earlier than the previous one, and the previous effect overlaps later effect's result.
|
||||
*/
|
||||
export function useSequentialEffect(
|
||||
effect: (checker: () => boolean) => (() => void | undefined) | void,
|
||||
deps: React.DependencyList = [],
|
||||
) {
|
||||
const sequenceCounter = useRef(0)
|
||||
useEffect(() => {
|
||||
// The counter is incremented every time a new effect is added.
|
||||
// And the previous effect should stop going forward by finding checker returning false.
|
||||
const counter = ++sequenceCounter.current
|
||||
const checker = () => counter === sequenceCounter.current
|
||||
return effect(checker)
|
||||
}, deps)
|
||||
}
|
||||
Loading…
Reference in a new issue