From 453ed1d588f5d603bada67dbc17a2ccc70d7cbd2 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Mon, 26 Oct 2020 02:12:33 +0800 Subject: [PATCH] refactor: enhance code --- src/components/FileExplorer.tsx | 29 ++++++++-------------- src/utils/VisibleNodesGenerator.ts | 39 ++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/components/FileExplorer.tsx b/src/components/FileExplorer.tsx index 3054946..a1f9a48 100644 --- a/src/components/FileExplorer.tsx +++ b/src/components/FileExplorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerCore } from 'driver/core' import { ConnectorState, Props } from 'driver/core/FileExplorer' import { platform } from 'platforms' import * as React from 'react' -import { useEvent, usePrevious } from 'react-use' +import { useEvent } from 'react-use' import { FixedSizeList, ListChildComponentProps } from 'react-window' import { cx } from 'utils/cx' import { isValidRegexpSource } from 'utils/general' @@ -39,7 +39,7 @@ const RawFileExplorer: React.FC = function RawFileExplor function renderFiles(visibleNodes: VisibleNodes) { const inSearch = searchKey !== '' - const { nodes, focusedNode } = visibleNodes + const { nodes } = visibleNodes if (inSearch && nodes.length === 0) { return ( @@ -51,8 +51,6 @@ const RawFileExplorer: React.FC = function RawFileExplor {({ width = 0, height = 0 }) => ( , node: TreeNode): void renderActions?(node: TreeNode): React.ReactNode @@ -175,18 +169,15 @@ function ListView({ } & Pick & Pick) { const listRef = React.useRef(null) + const { focusedNode, nodes } = visibleNodes React.useEffect(() => { - if (focusedNode && listRef.current) { - listRef.current.scrollToItem(nodes.indexOf(focusedNode), 'smart') + if (listRef.current && focusedNode) { + const index = nodes.indexOf(focusedNode) + if (index !== -1) { + listRef.current.scrollToItem(index, 'smart') } - }, [listRef.current, focusedNode]) - - const lastNodeLength = usePrevious(nodes.length) - React.useEffect(() => { - if (listRef.current && !focusedNode && lastNodeLength !== nodes.length) { - listRef.current.scrollTo(0) } - }, [listRef.current, focusedNode, nodes.length]) + }, [focusedNode]) const goToCurrentItem = React.useCallback(() => { const targetPath = platform.getCurrentPath(metaData.branchName) @@ -197,8 +188,8 @@ function ListView({ return ( nodes[index]?.path} - itemData={{ nodes, searchKey, onNodeClick, renderActions, visibleNodes }} + itemKey={(index, { visibleNodes }) => visibleNodes?.nodes[index]?.path} + itemData={{ searchKey, onNodeClick, renderActions, visibleNodes }} itemCount={nodes.length} itemSize={36} height={height} diff --git a/src/utils/VisibleNodesGenerator.ts b/src/utils/VisibleNodesGenerator.ts index 2327641..b8c5741 100644 --- a/src/utils/VisibleNodesGenerator.ts +++ b/src/utils/VisibleNodesGenerator.ts @@ -155,9 +155,8 @@ class CompressLayer extends ShakeLayer { this.shakeHub.addEventListener('emit', () => this.compressTree()) } - compressTree = withEffect( + private compressTree = withEffect( () => { - this.depths.clear() this.compressedRoot = this.shackedRoot && this.compress ? { @@ -166,13 +165,16 @@ class CompressLayer extends ShakeLayer { } : this.shackedRoot - const recordDepth = (node: TreeNode, depth = 0) => { - this.depths.set(node, depth) - for (const $node of node.contents || []) { - recordDepth($node, depth + 1) + if (this.compressedRoot) { + this.depths.clear() + const recordDepth = (node: TreeNode, depth = 0) => { + this.depths.set(node, depth) + for (const $node of node.contents || []) { + recordDepth($node, depth + 1) + } } + recordDepth(this.compressedRoot, -1) } - if (this.compressedRoot) recordDepth(this.compressedRoot, -1) }, () => this.compressHub.emit('emit', this.compressedRoot), ) @@ -193,6 +195,28 @@ class FlattenLayer extends CompressLayer { generateVisibleNodes = withEffect( async () => { const nodes: TreeNode[] = [] + + const focusedNode = this.focusedNode + + if ( + focusedNode && + this.compressedRoot && + (await findNode(this.compressedRoot, focusedNode.path)) !== focusedNode + ) { + // rescue the focus after expanding async singleton folder + await traverse( + this.compressedRoot.contents, + node => { + if (node.type === 'tree' && node.path.startsWith(focusedNode.path)) { + this.focusNode(node) + } + + return node.type === 'tree' && this.expandedNodes.has(node.path) + }, + node => node.contents || [], + ) + } + await traverse( this.compressedRoot?.contents, node => { @@ -295,7 +319,6 @@ export class VisibleNodesGenerator extends FlattenLayer { this.focusNode = withEffect(this.focusNode.bind(this), this.update.bind(this)) - this.search(null) this.flattenHub.addEventListener('emit', () => this.update()) this.baseHub.addEventListener('loadingChange', () => this.update()) }