diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index 544a1b0bab..999587c7e0 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -67,7 +67,7 @@ class FileProvider { // todo check the type (directory/file) as well #2386 // currently it is not possible to have a file and folder with same path const ret = this._exists(path) - if (cb) cb(null, ret) + return ret } diff --git a/apps/remix-ide/src/app/files/workspaceFileProvider.js b/apps/remix-ide/src/app/files/workspaceFileProvider.js index 742d85a775..156723b622 100644 --- a/apps/remix-ide/src/app/files/workspaceFileProvider.js +++ b/apps/remix-ide/src/app/files/workspaceFileProvider.js @@ -33,7 +33,7 @@ class WorkspaceFileProvider extends FileProvider { if (!this.workspace) this.createWorkspace() path = path.replace(/^\/|\/$/g, '') // remove first and last slash if (path.startsWith(this.workspacesPath + '/' + this.workspace)) return path - if (path.startsWith(this.workspace)) return this.workspacesPath + '/' + this.workspace + if (path.startsWith(this.workspace)) return path.replace(this.workspace, this.workspacesPath + '/' + this.workspace) path = super.removePrefix(path) let ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path) diff --git a/apps/remix-ide/src/lib/helper.js b/apps/remix-ide/src/lib/helper.js index ac3f71a0e5..2757fc84da 100644 --- a/apps/remix-ide/src/lib/helper.js +++ b/apps/remix-ide/src/lib/helper.js @@ -52,6 +52,27 @@ module.exports = { createNonClashingName (name, fileProvider, cb) { this.createNonClashingNameWithPrefix(name, fileProvider, '', cb) }, + async checkNonClashingNameAsync (name, fileManager, prefix = '') { + if (!name) name = 'Undefined' + let counter = '' + let ext = 'sol' + const reg = /(.*)\.([^.]+)/g + const split = reg.exec(name) + if (split) { + name = split[1] + ext = split[2] + } + let exist = true + + do { + const isDuplicate = await fileManager.exists(name + counter + prefix + '.' + ext) + + if (isDuplicate) counter = (counter | 0) + 1 + else exist = false + } while (exist) + + return name + counter + prefix + '.' + ext + }, checkSpecialChars (name) { return name.match(/[:*?"<>\\'|]/) != null }, diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 49a95ec4f9..7e552115e7 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -151,9 +151,13 @@ export const fetchProviderSuccess = (provider: any) => { } } -export const setProvider = (provider) => (dispatch: React.Dispatch) => { +export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatch) => { if (provider) { + provider.event.register('fileAdded', async (filePath) => { + resolveDirectory(provider, extractParentFromKey(filePath) || workspaceName)(dispatch) + }) dispatch(fetchProviderSuccess(provider)) + dispatch(setCurrentWorkspace(workspaceName)) } else { dispatch(fetchProviderError('No provider available')) } @@ -166,12 +170,6 @@ export const setCurrentWorkspace = (name: string) => { } } -export const setWorkspace = (name: string) => (dispatch: React.Dispatch) => { - if (name) { - dispatch(setCurrentWorkspace(name)) - } -} - export const addInputFieldSuccess = (path: string, files: File[]) => { return { type: 'ADD_INPUT_FIELD', diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index a65cffb003..9d1bc176a3 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' -import { fetchDirectory, setProvider, resolveDirectory, setWorkspace, addInputField, removeInputField } from './actions/fileSystem' +import { fetchDirectory, setProvider, resolveDirectory, addInputField, removeInputField } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -108,8 +108,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (props.filesProvider) { - setProvider(props.filesProvider)(dispatch) - setWorkspace(props.name)(dispatch) + setProvider(props.filesProvider, props.name)(dispatch) } }, [props.filesProvider]) @@ -217,7 +216,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [state.modals]) - const extractNameFromKey = (key: string):string => { const keyPath = key.split('/') @@ -232,36 +230,28 @@ export const FileExplorer = (props: FileExplorerProps) => { return keyPath.join('/') } - // const createNewFile = (newFilePath: string) => { - // const fileManager = state.fileManager + const createNewFile = async (newFilePath: string) => { + const fileManager = state.fileManager - // try { - // helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => { - // if (error) { - // modal('Create File Failed', error, { - // label: 'Close', - // fn: async () => {} - // }, null) - // } else { - // const createFile = await fileManager.writeFile(newName, '') - - // if (!createFile) { - // return toast('Failed to create file ' + newName) - // } else { - // await fileManager.open(newName) - // setState(prevState => { - // return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } - // }) - // } - // } - // }) - // } catch (error) { - // return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { - // label: 'Close', - // fn: async () => {} - // }, null) - // } - // } + try { + const newName = await helper.checkNonClashingNameAsync(newFilePath, fileManager) + const createFile = await fileManager.writeFile(newName, '') + + if (!createFile) { + return toast('Failed to create file ' + newName) + } else { + await fileManager.open(newName) + setState(prevState => { + return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } + }) + } + } catch (error) { + return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { + label: 'Close', + fn: async () => {} + }, null) + } + } // const createNewFolder = async (newFolderPath: string) => { // const fileManager = state.fileManager @@ -347,23 +337,6 @@ export const FileExplorer = (props: FileExplorerProps) => { // }) // } - // const fileAdded = async (filePath: string) => { - // const pathArr = filePath.split('/') - // const expandPath = pathArr.map((path, index) => { - // return [...pathArr.slice(0, index)].join('/') - // }).filter(path => path && (path !== props.name)) - // const files = await fetchDirectoryContent(props.name) - - // setState(prevState => { - // const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] - - // return { ...prevState, files, expandPath: uniquePaths } - // }) - // if (filePath.includes('_test.sol')) { - // plugin.event.trigger('newTestFileCreated', [filePath]) - // } - // } - // const folderAdded = async (folderPath: string) => { // const pathArr = folderPath.split('/') // const expandPath = pathArr.map((path, index) => { @@ -659,6 +632,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleClickFile = (path: string) => { + console.log('path: ', path) state.fileManager.open(path) setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'file' }] } @@ -750,6 +724,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } else { if (state.focusEdit.isNew) { // state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) + createNewFile(joinPath(parentFolder, content)) removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) } else { const oldPath: string = state.focusEdit.element @@ -767,7 +742,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleNewFileInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) : name + if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name : name const expandPath = [...new Set([...state.expandPath, parentFolder])] await addInputField(fileSystem.provider.provider, 'file', parentFolder)(dispatch) @@ -778,7 +753,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleNewFolderInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) : name + if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name : name else if ((parentFolder.indexOf('.sol') !== -1) || (parentFolder.indexOf('.js') !== -1)) parentFolder = extractParentFromKey(parentFolder) const expandPath = [...new Set([...state.expandPath, parentFolder])] @@ -1008,8 +983,8 @@ async function packageFiles (filesProvider, directory, callback) { } } -// function joinPath (...paths) { -// paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) -// if (paths.length === 1) return paths[0] -// return paths.join('/') -// } +function joinPath (...paths) { + paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) + if (paths.length === 1) return paths[0] + return paths.join('/') +} diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index bc2b96e409..e673efba75 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -167,6 +167,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } const resolveDirectory = (root, path: string, files, content) => { + if (path === root) return { [root]: { ...content[root], ...files[root] } } const pathArr = path.split('/') if (pathArr[0] !== root) pathArr.unshift(root)