Skip to content

Commit

Permalink
feat: added open in finder/explorer button in File Explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
EduardIvanov22 committed Nov 16, 2021
1 parent eaab28b commit 0578eb6
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 10 deletions.
39 changes: 39 additions & 0 deletions src/components/atoms/Dots/Dots.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import styled from 'styled-components';

import Colors from '@styles/Colors';

const DotsContainer = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
margin-right: 10px;
`;

const Dot = styled.div`
width: 6px;
height: 6px;
border-radius: 50%;
background-color: ${props => props.color};
&:not(:last-child) {
margin-right: 2px;
}
`;

interface DotsProps {
dotNumber?: number;
color?: Colors;
}

const Dots: React.FC<DotsProps> = props => {
const {dotNumber = 3, color = Colors.blue6} = props;

const dots = Array.from({length: dotNumber}).map(() => {
return <Dot color={color} />;
});

return <DotsContainer>{dots}</DotsContainer>;
};

export default Dots;
1 change: 1 addition & 0 deletions src/components/atoms/Dots/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default} from './Dots';
17 changes: 17 additions & 0 deletions src/components/molecules/ContextMenu/ContextMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Dropdown} from 'antd';

interface ContextMenuProps {
overlay: React.ReactElement;
}

const ContextMenu: React.FC<ContextMenuProps> = props => {
const {overlay, children} = props;

return (
<Dropdown overlay={overlay} trigger={['click', 'hover']} placement="bottomCenter">
{children}
</Dropdown>
);
};

export default ContextMenu;
1 change: 1 addition & 0 deletions src/components/molecules/ContextMenu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default} from './ContextMenu';
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Colors from '@styles/Colors';
import styled from 'styled-components';

import Colors from '@styles/Colors';

export const ItemContainer = styled.li<{
isSelected: boolean;
isHighlighted: boolean;
Expand Down Expand Up @@ -52,6 +53,9 @@ export const ItemName = styled.span<{
}>`
padding: 2px 0;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
${props => {
if (props.isSelected) {
return `font-weight: 700;`;
Expand Down
89 changes: 80 additions & 9 deletions src/components/organisms/FileTreePane/FileTreePane.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {Button, Row, Skeleton, Tooltip, Tree, Typography} from 'antd';
import {ipcRenderer} from 'electron';
import {Button, Menu, Row, Skeleton, Tooltip, Tree, Typography} from 'antd';
import {ipcRenderer, shell} from 'electron';
import micromatch from 'micromatch';
import os from 'os';
import path from 'path';
import React, {useCallback, useContext, useEffect, useMemo} from 'react';
import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
import {useSelector} from 'react-redux';
import styled from 'styled-components';

Expand All @@ -20,7 +21,9 @@ import {FileEntry} from '@models/fileentry';
import {MonoPaneTitle, MonoPaneTitleCol} from '@atoms';
import FileExplorer from '@atoms/FileExplorer';

import Dots from '@components/atoms/Dots';
import Icon from '@components/atoms/Icon';
import ContextMenu from '@components/molecules/ContextMenu';

import {useFileExplorer} from '@hooks/useFileExplorer';

Expand Down Expand Up @@ -121,7 +124,7 @@ const FileTreeContainer = styled.div`
margin-left: 0px !important;
border-left: 8px hidden transparent;
padding-left: 8px;
padding-bottom: 2px;
padding-bottom: 0px;
background: ${Colors.selectionGradient} !important;
}
& .ant-tree-treenode-selected::before {
Expand Down Expand Up @@ -218,6 +221,18 @@ const RightButtons = styled.div`
}
`;

const TreeTitleWrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
`;

const TreeTitleText = styled.span`
flex: 1;
overflow: hidden;
color: black;
`;

const StyledSkeleton = styled(Skeleton)`
margin: 20px;
width: 90%;
Expand All @@ -227,6 +242,59 @@ const ReloadButton = styled(Button)``;

const BrowseButton = styled(Button)``;

const TreeItem: React.FC<any> = props => {
const {title, treeKey} = props;

const fileMap = useAppSelector(state => state.main.fileMap);
const [isTitleHovered, setTitleHoverState] = useState(false);

const platformFilemanagerNames: {[name: string]: string} = {
darwin: 'finder',
};

const platformFilemanagerName = platformFilemanagerNames[os.platform()] || 'explorer';

const pathToFile =
fileMap[ROOT_FILE_ENTRY].filePath === treeKey
? fileMap[ROOT_FILE_ENTRY].filePath
: `${fileMap[ROOT_FILE_ENTRY].filePath}${treeKey}`;

const menu = (
<Menu>
<Menu.Item
onClick={e => {
e.domEvent.stopPropagation();

shell.showItemInFolder(pathToFile);
}}
key="reveal_in_finder"
>
Reveal in {platformFilemanagerName}
</Menu.Item>
</Menu>
);

return (
<TreeTitleWrapper
onMouseEnter={() => {
setTitleHoverState(true);
}}
onMouseLeave={() => {
setTitleHoverState(false);
}}
>
<TreeTitleText>{title}</TreeTitleText>
{isTitleHovered ? (
<ContextMenu overlay={menu}>
<div>
<Dots />
</div>
</ContextMenu>
) : null}
</TreeTitleWrapper>
);
};

const FileTreePane = () => {
const {windowSize} = useContext(AppContext);
const windowHeight = windowSize.height;
Expand All @@ -245,11 +313,11 @@ const FileTreePane = () => {
const recentFolders = useAppSelector(state => state.config.recentFolders);
const fileIncludes = useAppSelector(state => state.config.fileIncludes);
const shouldExpandAllNodes = useAppSelector(state => state.ui.shouldExpandAllNodes);
const [tree, setTree] = React.useState<TreeNode | null>(null);
const [expandedKeys, setExpandedKeys] = React.useState<Array<React.Key>>([]);
const [highlightNode, setHighlightNode] = React.useState<TreeNode>();
const [autoExpandParent, setAutoExpandParent] = React.useState(true);
const treeRef = React.useRef<any>();
const [tree, setTree] = useState<TreeNode | null>(null);
const [expandedKeys, setExpandedKeys] = useState<Array<React.Key>>([]);
const [highlightNode, setHighlightNode] = useState<TreeNode>();
const [autoExpandParent, setAutoExpandParent] = useState(true);
const treeRef = useRef<any>();

const isButtonDisabled = !fileMap[ROOT_FILE_ENTRY];

Expand Down Expand Up @@ -473,6 +541,9 @@ const FileTreePane = () => {
ref={treeRef}
expandedKeys={expandedKeys}
onExpand={onExpand}
titleRender={event => {
return <TreeItem treeKey={event.key} title={event.title} />;
}}
autoExpandParent={autoExpandParent}
selectedKeys={[selectedPath || '-']}
filterTreeNode={node => {
Expand Down

0 comments on commit 0578eb6

Please sign in to comment.