Skip to content

Commit

Permalink
Merge pull request #4976 from ethereum/fe-shortcut-keys
Browse files Browse the repository at this point in the history
FE Delete & Rename shortcut keys
  • Loading branch information
joeizang authored Jul 15, 2024
2 parents 60a00e5 + 198a93d commit 5d5f356
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
103 changes: 102 additions & 1 deletion libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState, useRef, SyntheticEvent } from 'react' // eslint-disable-line
import React, { useEffect, useState, useRef, SyntheticEvent, useContext } from 'react' // eslint-disable-line
import { useIntl } from 'react-intl'
import { TreeView } from '@remix-ui/tree-view' // eslint-disable-line
import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line
Expand All @@ -11,6 +11,7 @@ import { checkSpecialChars, extractNameFromKey, extractParentFromKey, getPathIco
import { ROOT_PATH } from '../utils/constants'
import { moveFileIsAllowed, moveFilesIsAllowed, moveFolderIsAllowed, moveFoldersIsAllowed } from '../actions'
import { FlatTree } from './flat-tree'
import { FileSystemContext } from '../contexts'

export const FileExplorer = (props: FileExplorerProps) => {
const intl = useIntl()
Expand All @@ -35,7 +36,11 @@ export const FileExplorer = (props: FileExplorerProps) => {
const [state, setState] = useState<WorkSpaceState>(workspaceState)
// const [isPending, startTransition] = useTransition();
const treeRef = useRef<HTMLDivElement>(null)

const { plugin } = useContext(FileSystemContext)
const [feTarget, setFeTarget] = useState<{ key: string, type: 'file' | 'folder' }[]>({} as { key: string, type: 'file' | 'folder' }[])
const [filesSelected, setFilesSelected] = useState<string[]>([])
const feWindow = (window as any)

useEffect(() => {
if (contextMenuItems) {
Expand Down Expand Up @@ -97,6 +102,100 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
}, [treeRef.current])

useEffect(() => {
const performDeletion = async () => {
const path: string[] = []
if (feTarget?.length > 0 && feTarget[0]?.key.length > 0) {
feTarget.forEach((one) => {
path.push(one.key)
})
await deletePath(path)
}
}

if (treeRef.current) {
const deleteKeyPressHandler = async (eve: KeyboardEvent) => {
if (eve.key === 'Delete' ) {
feWindow._paq.push(['trackEvent', 'fileExplorer', 'deleteKey', 'deletePath'])
setState((prevState) => {
return { ...prevState, deleteKey: true }
})
performDeletion()
return
}
if (eve.metaKey) {
if (eve.key === 'Backspace') {
feWindow._paq.push(['trackEvent', 'fileExplorer', 'osxDeleteKey', 'deletePath'])
setState((prevState) => {
return { ...prevState, deleteKey: true }
})
performDeletion()
return
}
}
}
const deleteKeyPressUpHandler = async (eve: KeyboardEvent) => {
if (eve.key === 'Delete' ) {
setState((prevState) => {
return { ...prevState, deleteKey: false }
})
return
}
if (eve.metaKey) {
if (eve.key === 'Backspace') {
setState((prevState) => {
return { ...prevState, deleteKey: false }
})
return
}
}
}

treeRef.current?.addEventListener('keydown', deleteKeyPressHandler)
treeRef.current?.addEventListener('keyup', deleteKeyPressUpHandler)
return () => {
treeRef.current?.removeEventListener('keydown', deleteKeyPressHandler)
treeRef.current?.removeEventListener('keyup', deleteKeyPressUpHandler)
}
}
}, [treeRef.current, feTarget])

useEffect(() => {
const performRename = async () => {
if (feTarget?.length > 1 && feTarget[0]?.key.length > 1) {
await plugin.call('notification', 'alert', { id: 'renameAlert', message: 'You cannot rename multiple files at once!' })
}
props.editModeOn(feTarget[0].key, feTarget[0].type, false)
}
if (treeRef.current) {
const F2KeyPressHandler = async (eve: KeyboardEvent) => {
if (eve.key === 'F2' ) {
feWindow._paq.push(['trackEvent', 'fileExplorer', 'f2ToRename', 'RenamePath'])
await performRename()
setState((prevState) => {
return { ...prevState, F2Key: true }
})
return
}
}
const F2KeyPressUpHandler = async (eve: KeyboardEvent) => {
if (eve.key === 'F2' ) {
setState((prevState) => {
return { ...prevState, F2Key: false }
})
return
}
}

treeRef.current?.addEventListener('keydown', F2KeyPressHandler)
treeRef.current?.addEventListener('keyup', F2KeyPressUpHandler)
return () => {
treeRef.current?.removeEventListener('keydown', F2KeyPressHandler)
treeRef.current?.removeEventListener('keyup', F2KeyPressUpHandler)
}
}
}, [treeRef.current, feTarget])

const hasReservedKeyword = (content: string): boolean => {
if (state.reservedKeywords.findIndex((value) => content.startsWith(value)) !== -1) return true
else return false
Expand Down Expand Up @@ -433,6 +532,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
createNewFolder={props.createNewFolder}
deletePath={deletePath}
editPath={props.editModeOn}
fileTarget={feTarget}
setTargetFiles={setFeTarget}
/>
</div>
</div>
Expand Down
8 changes: 8 additions & 0 deletions libs/remix-ui/workspace/src/lib/components/flat-tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export default function useOnScreen(ref: RefObject<HTMLElement>) {
return isIntersecting
}
interface FlatTreeProps {
fileTarget: any
setTargetFiles: React.Dispatch<any>
files: { [x: string]: Record<string, FileType> },
flatTree: FileType[],
expandPath: string[],
Expand Down Expand Up @@ -84,6 +86,12 @@ export const FlatTree = (props: FlatTreeProps) => {
? 'bg-light border-no-shift'
: ''

useEffect(() => {
if (props.focusElement && props.focusElement.length > 0) {
props.setTargetFiles(props.focusElement)
}
}, [props.focusElement, props.focusElement.length])

const getIndentLevelDiv = (path: string) => {
// remove double slash
path = path.replace(/\/\//g, '/')
Expand Down
2 changes: 2 additions & 0 deletions libs/remix-ui/workspace/src/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ export interface FileExplorerContextMenuProps {

export interface WorkSpaceState {
ctrlKey: boolean
deleteKey?: boolean
F2Key?: boolean
newFileName: string
actions: {
id: string
Expand Down

0 comments on commit 5d5f356

Please sign in to comment.