Merge pull request #4084 from ethereum/fixdrag

fixing drag drop issues
pull/4098/head^2
Liana Husikyan 1 year ago committed by GitHub
commit dea2043acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      apps/remix-ide/src/app/files/fileManager.ts
  2. 3
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  3. 23
      libs/remix-ui/drag-n-drop/src/lib/drag-n-drop.tsx
  4. 13
      libs/remix-ui/workspace/src/lib/actions/index.ts
  5. 44
      libs/remix-ui/workspace/src/lib/components/file-explorer.tsx

@ -904,6 +904,50 @@ class FileManager extends Plugin {
return exists
}
async moveFileIsAllowed (src: string, dest: string) {
try {
src = this.normalize(src)
dest = this.normalize(dest)
src = this.limitPluginScope(src)
dest = this.limitPluginScope(dest)
await this._handleExists(src, `Cannot move ${src}. Path does not exist.`)
await this._handleExists(dest, `Cannot move content into ${dest}. Path does not exist.`)
await this._handleIsFile(src, `Cannot move ${src}. Path is not a file.`)
await this._handleIsDir(dest, `Cannot move content into ${dest}. Path is not directory.`)
const fileName = helper.extractNameFromKey(src)
if (await this.exists(dest + '/' + fileName)) {
return false
}
return true
} catch (e) {
console.log(e)
return false
}
}
async moveDirIsAllowed (src: string, dest: string) {
try {
src = this.normalize(src)
dest = this.normalize(dest)
src = this.limitPluginScope(src)
dest = this.limitPluginScope(dest)
await this._handleExists(src, `Cannot move ${src}. Path does not exist.`)
await this._handleExists(dest, `Cannot move content into ${dest}. Path does not exist.`)
await this._handleIsDir(src, `Cannot move ${src}. Path is not directory.`)
await this._handleIsDir(dest, `Cannot move content into ${dest}. Path is not directory.`)
const dirName = helper.extractNameFromKey(src)
if (await this.exists(dest + '/' + dirName) || src === dest) {
return false
}
return true
} catch (e) {
console.log(e)
return false
}
}
/**
* Moves a file to a new folder
* @param {string} src path of the source file

@ -73,6 +73,7 @@
"filePanel.features": "Features",
"filePanel.upgradeability": "Upgradeability",
"filePanel.ok": "OK",
"filePanel.yes": "Yes",
"filePanel.cancel": "Cancel",
"filePanel.createNewWorkspace": "create a new workspace",
"filePanel.connectToLocalhost": "connect to localhost",
@ -115,6 +116,8 @@
"filePanel.validationErrorMsg": "Special characters are not allowed",
"filePanel.reservedKeyword": "Reserved Keyword",
"filePanel.reservedKeywordMsg": "File name contains Remix reserved keywords. \"{content}\"",
"filePanel.moveFile": "Moving files",
"filePanel.moveFileMsg1": "Are you sure you want to move {src} to {dest}?",
"filePanel.movingFileFailed": "Moving File Failed",
"filePanel.movingFileFailedMsg": "Unexpected error while moving file: {src}",
"filePanel.movingFolderFailed": "Moving Folder Failed",

@ -27,6 +27,11 @@ export const Draggable = (props: DraggableType) => {
destination = props.file,
context = useContext(MoveContext)
// delay timer
const [timer, setTimer] = useState<NodeJS.Timeout>()
// folder to open
const [folderToOpen, setFolderToOpen] = useState<string>()
const handleDrop = (event: React.DragEvent<HTMLSpanElement>) => {
event.preventDefault()
@ -50,8 +55,15 @@ export const Draggable = (props: DraggableType) => {
const handleDragover = (event: React.DragEvent<HTMLSpanElement>) => {
//Checks if the folder is opened
event.preventDefault()
if (destination.isDirectory && !props.expandedPath.includes(destination.path)) {
props.handleClickFolder(destination.path, destination.type)
if (destination.isDirectory && !props.expandedPath.includes(destination.path) && folderToOpen !== destination.path && props.handleClickFolder) {
setFolderToOpen(destination.path)
timer && clearTimeout(timer)
setTimer(
setTimeout(() => {
props.handleClickFolder(destination.path, destination.type)
setFolderToOpen(null)
}, 600)
)
}
}
@ -75,7 +87,12 @@ export const Draggable = (props: DraggableType) => {
onDrop={(event) => {
handleDrop(event)
}}
onDragStart={() => {
onDragStart={(event) => {
if (destination && destination.path === '/'){
event.preventDefault()
event.stopPropagation
} else
if (destination) {
handleDrag()
}

@ -514,3 +514,16 @@ export const moveFolder = async (src: string, dest: string) => {
dispatch(displayPopUp('Oops! An error ocurred while performing moveDir operation.' + error))
}
}
export const moveFileIsAllowed = async (src: string, dest: string) => {
const fileManager = plugin.fileManager
const isAllowed = await fileManager.moveFileIsAllowed(src, dest)
return isAllowed
}
export const moveFolderIsAllowed = async (src: string, dest: string) => {
const fileManager = plugin.fileManager
const isAllowed = await fileManager.moveDirIsAllowed(src, dest)
return isAllowed
}

@ -9,8 +9,9 @@ import '../css/file-explorer.css'
import {checkSpecialChars, extractNameFromKey, extractParentFromKey, joinPath} from '@remix-ui/helper'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import {FileRender} from './file-render'
import {Drag} from '@remix-ui/drag-n-drop'
import {Drag, Draggable} from '@remix-ui/drag-n-drop'
import {ROOT_PATH} from '../utils/constants'
import { moveFileIsAllowed, moveFolderIsAllowed } from '../actions'
export const FileExplorer = (props: FileExplorerProps) => {
const intl = useIntl()
@ -289,27 +290,43 @@ export const FileExplorer = (props: FileExplorerProps) => {
props.dispatchHandleExpandPath(expandPath)
}
const handleFileMove = (dest: string, src: string) => {
const handleFileMove = async (dest: string, src: string) => {
if(await moveFileIsAllowed(src, dest) === false) return
try {
props.dispatchMoveFile(src, dest)
props.modal(
intl.formatMessage({ id: 'filePanel.moveFile' }),
intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }),
intl.formatMessage({ id: 'filePanel.yes' }),
() => props.dispatchMoveFile(src, dest),
intl.formatMessage({ id: 'filePanel.cancel' }),
() => {}
)
} catch (error) {
props.modal(
intl.formatMessage({id: 'filePanel.movingFileFailed'}),
intl.formatMessage({id: 'filePanel.movingFileFailedMsg'}, {src}),
intl.formatMessage({id: 'filePanel.close'}),
intl.formatMessage({ id: 'filePanel.movingFileFailed' }),
intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src }),
intl.formatMessage({ id: 'filePanel.close' }),
async () => {}
)
}
}
const handleFolderMove = (dest: string, src: string) => {
const handleFolderMove = async (dest: string, src: string) => {
if(await moveFolderIsAllowed(src, dest) === false) return
try {
props.dispatchMoveFolder(src, dest)
props.modal(
intl.formatMessage({ id: 'filePanel.moveFile' }),
intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }),
intl.formatMessage({ id: 'filePanel.yes' }),
() => props.dispatchMoveFolder(src, dest),
intl.formatMessage({ id: 'filePanel.cancel' }),
() => {}
)
} catch (error) {
props.modal(
intl.formatMessage({id: 'filePanel.movingFolderFailed'}),
intl.formatMessage({id: 'filePanel.movingFolderFailedMsg'}, {src}),
intl.formatMessage({id: 'filePanel.close'}),
intl.formatMessage({ id: 'filePanel.movingFolderFailed' }),
intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src }),
intl.formatMessage({ id: 'filePanel.close' }),
async () => {}
)
}
@ -340,7 +357,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
</span>
</div>
</li>
<div className="pb-4 mb-4">
<div>
<TreeView id="treeViewMenu">
{files[ROOT_PATH] &&
Object.keys(files[ROOT_PATH]).map((key, index) => (
@ -364,6 +381,9 @@ export const FileExplorer = (props: FileExplorerProps) => {
))}
</TreeView>
</div>
<Draggable isDraggable={false} file={{ name: '/', path: '/', type: 'folder', isDirectory: true }} expandedPath={props.expandPath} handleClickFolder={null}>
<div className='d-block w-100 pb-4 mb-4'></div>
</Draggable>
</TreeView>
</div>
</Drag>

Loading…
Cancel
Save