From cf05a97d8824db22e8a164cd2516343cfaa4848e Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 8 Sep 2021 04:17:20 +0100 Subject: [PATCH] Sort files and folders --- .../src/app/files/workspaceFileProvider.js | 2 +- .../workspace/src/lib/actions/workspace.ts | 56 ++++++++-------- .../workspace/src/lib/reducers/workspace.ts | 64 ++++++++++++++++++- 3 files changed, 94 insertions(+), 28 deletions(-) diff --git a/apps/remix-ide/src/app/files/workspaceFileProvider.js b/apps/remix-ide/src/app/files/workspaceFileProvider.js index 5d7966afa4..bdc9abed32 100644 --- a/apps/remix-ide/src/app/files/workspaceFileProvider.js +++ b/apps/remix-ide/src/app/files/workspaceFileProvider.js @@ -51,7 +51,7 @@ class WorkspaceFileProvider extends FileProvider { } resolveDirectory (path, callback) { - if (!this.workspace) this.createWorkspace() + // if (!this.workspace) this.createWorkspace() super.resolveDirectory(path, (error, files) => { if (error) return callback(error) const unscoped = {} diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 5599c763f3..3f57060b7b 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -86,6 +86,13 @@ const fileRemovedSuccess = (removePath: string) => { } } +const fileRenamedSuccess = (oldPath: string, newPath: string) => { + return { + type: 'FILE_RENAMED_SUCCESS', + payload: { oldPath, newPath } + } +} + const rootFolderChangedSuccess = (path: string) => { return { type: 'ROOT_FOLDER_CHANGED', @@ -232,19 +239,23 @@ const getWorkspaces = async (): Promise | undefined => { } const listenOnEvents = (provider) => { - provider.event.on('fileAdded', async (filePath) => { + provider.event.on('fileAdded', async (filePath: string) => { await executeEvent('fileAdded', filePath) }) - provider.event.on('folderAdded', async (folderPath) => { + provider.event.on('folderAdded', async (folderPath: string) => { await executeEvent('folderAdded', folderPath) }) - provider.event.on('fileRemoved', async (removePath) => { + provider.event.on('fileRemoved', async (removePath: string) => { await executeEvent('fileRemoved', removePath) }) - plugin.on('remixd', 'rootFolderChanged', async (path) => { + provider.event.on('fileRenamed', async (oldPath: string, newPath: string) => { + await executeEvent('fileRenamed', oldPath, newPath) + }) + + plugin.on('remixd', 'rootFolderChanged', async (path: string) => { await executeEvent('rootFolderChanged', path) }) @@ -331,10 +342,6 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React. listenOnEvents(workspaceProvider) listenOnEvents(localhostProvider) - // provider.event.on('fileRenamed', async (oldPath) => { - // await executeEvent('fileRenamed', oldPath) - // }) - // provider.event.on('createWorkspace', (name) => { // createNewWorkspace(name) // }) @@ -413,26 +420,23 @@ const fileRemoved = async (removePath: string) => { await dispatch(fileRemovedSuccess(removePath)) } -const fileRenamed = async (oldPath: string) => { - const path = extractParentFromKey(oldPath) || provider.workspace || provider.type || '' - const data = await fetchDirectoryContent(provider, path) - - await dispatch(fileRenamedSuccess(path, oldPath, data)) +const fileRenamed = async (oldPath: string, newPath: string) => { + await dispatch(fileRenamedSuccess(oldPath, newPath)) } const rootFolderChanged = async (path) => { await dispatch(rootFolderChangedSuccess(path)) } -const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemoved' | 'fileRenamed' | 'rootFolderChanged', path?: string) => { +const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemoved' | 'fileRenamed' | 'rootFolderChanged', ...args) => { if (Object.keys(pendingEvents).length) { - return queuedEvents.push({ eventName, path }) + return queuedEvents.push({ eventName, path: args[0] }) } - pendingEvents[eventName + path] = { eventName, path } + pendingEvents[eventName + args[0]] = { eventName, path: args[0] } switch (eventName) { case 'fileAdded': - await fileAdded(path) - delete pendingEvents[eventName + path] + await fileAdded(args[0]) + delete pendingEvents[eventName + args[0]] if (queuedEvents.length) { const next = queuedEvents.pop() @@ -441,8 +445,8 @@ const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemove break case 'folderAdded': - await folderAdded(path) - delete pendingEvents[eventName + path] + await folderAdded(args[0]) + delete pendingEvents[eventName + args[0]] if (queuedEvents.length) { const next = queuedEvents.pop() @@ -451,8 +455,8 @@ const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemove break case 'fileRemoved': - await fileRemoved(path) - delete pendingEvents[eventName + path] + await fileRemoved(args[0]) + delete pendingEvents[eventName + args[0]] if (queuedEvents.length) { const next = queuedEvents.pop() @@ -461,8 +465,8 @@ const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemove break case 'fileRenamed': - await fileRenamed(path) - delete pendingEvents[eventName + path] + await fileRenamed(args[0], args[1]) + delete pendingEvents[eventName + args[0]] if (queuedEvents.length) { const next = queuedEvents.pop() @@ -471,8 +475,8 @@ const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemove break case 'rootFolderChanged': - await rootFolderChanged(path) - delete pendingEvents[eventName + path] + await rootFolderChanged(args[0]) + delete pendingEvents[eventName + args[0]] if (queuedEvents.length) { const next = queuedEvents.pop() diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index 73e8e926ef..049d124709 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -1,4 +1,5 @@ import { extractNameFromKey, File } from '@remix-ui/file-explorer' +import { extractParentFromKey } from '@remix-ui/helper' import * as _ from 'lodash' interface Action { type: string @@ -288,6 +289,22 @@ export const browserReducer = (state = browserInitialState, action: Action) => { } } + case 'FILE_RENAMED_SUCCESS': { + const payload = action.payload as { oldPath: string, newPath: string } + + return { + ...state, + browser: { + ...state.browser, + files: state.mode === 'browser' ? fileRenamed(state, payload) : state.browser.files + }, + localhost: { + ...state.localhost, + files: state.mode === 'localhost' ? fileRenamed(state, payload) : state.localhost.files + } + } + } + default: throw new Error() } @@ -309,6 +326,14 @@ const fileAdded = (state: BrowserState, path: string): { [x: string]: Record } => { let files = state.mode === 'browser' ? state.browser.files : state.localhost.files const _path = splitPath(state, path) + const _dir = splitPath(state, extractParentFromKey(path)) + const prevFiles = _.get(files, _dir) + + if (prevFiles.child) { + + } else { + + } files = _.set(files, _path, { path: path, @@ -327,6 +352,28 @@ const fileRemoved = (state: BrowserState, path: string): { [x: string]: Record } => { + let files = state.mode === 'browser' ? state.browser.files : state.localhost.files + const _oldPath = splitPath(state, payload.oldPath) + const _newPath = splitPath(state, payload.newPath) + const prevFiles = _.get(files, _oldPath) + const nextFiles = { + ...prevFiles, + path: payload.newPath, + name: extractNameFromKey(payload.newPath) + } + + if (nextFiles.child) { + nextFiles.child = sortFolderAndFiles(nextFiles.child) + files = _.set(files, _newPath, nextFiles) + } else { + files = _.set(files, _newPath, nextFiles) + files = state.mode === 'browser' ? { [state.browser.currentWorkspace]: sortFolderAndFiles(files[state.browser.currentWorkspace]) } : { [state.mode]: sortFolderAndFiles(files[state.mode]) } + } + _.unset(files, _oldPath) + return files +} + // IDEA: Modify function to remove blank input field without fetching content const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: string, type?: 'file' | 'folder' }, deletePath?: string) => { if (state.mode === 'browser') { @@ -417,7 +464,7 @@ const normalize = (filesList, directory?: string, newInputType?: 'folder' | 'fil const splitPath = (state: BrowserState, path: string): string[] | string => { const root = state.mode === 'browser' ? state.browser.currentWorkspace : 'localhost' - const pathArr: string[] = path.split('/').filter(value => value) + const pathArr: string[] = (path || '').split('/').filter(value => value) if (pathArr[0] !== root) pathArr.unshift(root) const _path = pathArr.map((key, index) => index > 1 ? ['child', key] : key).reduce((acc: string[], cur) => { @@ -426,3 +473,18 @@ const splitPath = (state: BrowserState, path: string): string[] | string => { return _path } + +const sortFolderAndFiles = (filesList: Record): Record => { + const folders = {} + const files = {} + + Object.keys(filesList || {}).forEach(key => { + if (filesList[key].isDirectory) { + folders[key] = filesList[key] + } else { + files[key] = filesList[key] + } + }) + + return Object.assign({}, folders, files) +}