refactor: scroll to focused element

This commit is contained in:
EnixCoda 2022-05-18 22:36:52 +08:00
parent ded704d6c0
commit 536d191fb8
3 changed files with 12 additions and 32 deletions

View file

@ -1,7 +1,7 @@
import { useConfigs } from 'containers/ConfigsContext'
import { platform } from 'platforms'
import * as React from 'react'
import { Align as ReactWindowAlign, FixedSizeList } from 'react-window'
import { FixedSizeList } from 'react-window'
import { useOnLocationChange } from 'utils/hooks/useOnLocationChange'
import { useOnPJAXDone } from 'utils/hooks/usePJAX'
import { NodeRendererContext } from '.'
@ -11,7 +11,6 @@ type ListViewProps = {
height: number
width: number
nodeRendererContext: NodeRendererContext
alignMode: ReactWindowAlign
metaData: MetaData
expandTo: (path: string[]) => void
}
@ -22,25 +21,22 @@ export function ListView({
metaData,
expandTo,
nodeRendererContext,
alignMode,
}: ListViewProps) {
const { visibleNodes } = nodeRendererContext
const { focusedNode, nodes } = visibleNodes
const listRef = React.useRef<FixedSizeList<NodeRendererContext>>(null)
// Scroll to focused node
const index = React.useMemo(
() =>
width && height && focusedNode?.path
? nodes.findIndex(node => node.path === focusedNode.path)
: -1,
[focusedNode?.path, nodes, width, height],
)
React.useEffect(() => {
if (listRef.current && focusedNode?.path) {
const index = nodes.findIndex(node => node.path === focusedNode.path)
if (index !== -1) {
listRef.current.scrollToItem(index, alignMode)
}
}
}, [focusedNode?.path, nodes, alignMode])
if (listRef.current && index !== -1) listRef.current.scrollToItem(index, 'smart')
}, [index])
// For some reason, removing the deps array above results in bug:
// If scroll fast and far, then clicking on items would result in redirect
// Not know the reason :(
const goToCurrentItem = React.useCallback(() => {
const targetPath = platform.getCurrentPath(metaData.branchName)
if (targetPath) expandTo(targetPath)
@ -54,7 +50,7 @@ export function ListView({
return (
<FixedSizeList<NodeRendererContext>
ref={listRef}
itemKey={(index, { visibleNodes }) => visibleNodes?.nodes[index]?.path}
itemKey={(index, { visibleNodes }) => visibleNodes.nodes[index]?.path}
itemData={nodeRendererContext}
itemCount={visibleNodes.nodes.length}
itemSize={compactFileTree ? 24 : 37}

View file

@ -1,13 +0,0 @@
import * as React from 'react'
import { Align as ReactWindowAlign } from 'react-window'
import { useStateIO } from 'utils/hooks/useStateIO'
export function useReactWindowAlignMode(searched: boolean) {
const $scrollMode = useStateIO<ReactWindowAlign>('start')
React.useEffect(() => {
// Use `auto` as default mode to prevent initial misalignment
// Switch to `smart` mode when start searching to make sure alignment is user-friendly when jump to files
if (searched && $scrollMode.value === 'start') $scrollMode.onChange('smart')
}, [searched, $scrollMode])
return $scrollMode.value
}

View file

@ -23,7 +23,6 @@ import {
import { useHandleNodeClick } from './hooks/useOnNodeClick'
import { useOnSearch } from './hooks/useOnSearch'
import { useVisibleNodesGeneratorMethods } from './hooks/useOnVisibleNodesGeneratorReady'
import { useReactWindowAlignMode } from './hooks/useReactWindowAlignMode'
import { useRenderLabelText } from './hooks/useRenderLabelText'
import { useVisibleNodesGenerator } from './hooks/useSetupTree'
import { ListView } from './ListView'
@ -75,7 +74,6 @@ export function FileExplorer({ freeze, metaData }: Props) {
renderLabelText,
)
const alignMode = useReactWindowAlignMode(searched)
const state = useLoadedContext(SideBarStateContext).value
useFocusFileExplorerOnFirstRender()
@ -125,7 +123,6 @@ export function FileExplorer({ freeze, metaData }: Props) {
nodeRendererContext={nodeRendererContext}
expandTo={expandTo}
metaData={metaData}
alignMode={alignMode}
/>
</div>
)}