From c8a621b522f0f8a5204ba7543689e40df12c4f07 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 25 Feb 2021 11:53:02 +0100 Subject: [PATCH] rearangement --- apps/remix-ide/src/app/panels/file-panel.js | 37 +++- .../workspace/src/lib/remix-ui-workspace.tsx | 199 ++++++++++-------- 2 files changed, 140 insertions(+), 96 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index fd86d35ffa..6fd79c40ed 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -58,14 +58,23 @@ module.exports = class Filepanel extends ViewPlugin { this.remixdHandle = new RemixdHandle(this.remixdExplorer, this._deps.fileProviders.localhost, appManager) this.gitHandle = new GitHandle() - + this.registeredMenuItems = [] this.request = {} + + this.renderComponent() + } + + render () { + return this.el + } + + renderComponent() { ReactDOM.render( , this.el) } - render () { - return this.el + /** + * @param item { id: string, name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } + * @param callback (...args) => void + */ + registerContextMenuItem (item) { + if (!item) throw new Error('Invalid register context menu argument') + if (!item.name || !item.id) throw new Error('Item name and id is mandatory') + if (!item.type && !item.path && !item.extension && !item.pattern) throw new Error('Invalid file matching criteria provided') + + this.registeredMenuItems = [...this.registeredMenuItems, item] + this.renderComponent() } async getCurrentWorkspace () { @@ -115,15 +134,15 @@ module.exports = class Filepanel extends ViewPlugin { this.emit('setWorkspace', workspace) } - renameWorkspace (workspace) { + workspaceRenamed (workspace) { this.emit('renameWorkspace', workspace) } - deleteWorkspace (workspace) { + workspaceDeleted (workspace) { this.emit('deleteWorkspace', workspace) } - createWorkspace (workspace) { + workspaceCreated (workspace) { this.emit('createWorkspace', workspace) } /** end section */ diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 9930f4f8f1..c2e1042efb 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import ethutil from 'ethereumjs-util' import { FileExplorer } from '@remix-ui/file-explorer' // eslint-disable-line import './remix-ui-workspace.css'; @@ -10,9 +10,9 @@ type CodeExamples = { /* eslint-disable-next-line */ export interface WorkspaceProps { setWorkspace: ({ name: string, isLocalhost: boolean }) => void, - renameWorkspace: ({ name: string }) => void, - createWorkspace: ({ name: string }) => void, - deleteWorkspace: ({ name: string }) => void, + workspaceRenamed: ({ name: string }) => void, + workspaceCreated: ({ name: string }) => void, + workspaceDeleted: ({ name: string }) => void, workspace: any // workspace provider, browser: any // browser provider localhost: any // localhost provider @@ -22,7 +22,8 @@ export interface WorkspaceProps { gistHandler: any // handle load gist registry: any // registry plugin: any // plugin call and resetFocus - request: any // api request + request: any // api request, + registeredMenuItems: [] // menu items } var canUpload = window.File || window.FileReader || window.FileList || window.Blob @@ -30,8 +31,23 @@ export const Workspace = (props: WorkspaceProps) => { const LOCALHOST = ' - connect to localhost - ' const NO_WORKSPACE = ' - none - ' + /* extends the parent 'plugin' with some function needed by the file explorer */ + props.plugin.resetFocus = () => { + setState(prevState => { + return { ...prevState, reset: true } + }) + } + + props.plugin.resetNewFile = () => { + setState(prevState => { + return { ...prevState, displayNewFile: !state.displayNewFile } + }) + } + /**** ****/ + + /* implement an external API, consumed by the parent */ props.request.createWorkspace = () => { - createWorkspace() + return createWorkspace() } props.request.getWorkspaces = () => { @@ -39,9 +55,7 @@ export const Workspace = (props: WorkspaceProps) => { } props.request.createNewFile = () => { - setState(prevState => { - return { ...prevState, displayNewFile: true } - }) + props.plugin.resetNewFile() } props.request.uploadFile = (target) => { @@ -53,59 +67,15 @@ export const Workspace = (props: WorkspaceProps) => { props.request.getCurrentWorkspace = () => { return state.currentWorkspace } + /**** ****/ - useEffect(() => { - initWorkspace() - }, []) - - const handleHideCreateModal = () => { - setState(prevState => { - state.createModal.hide = true - return { ...prevState, ...state.createModal } - }) - } - - const handleHideDeleteModal = () => { - setState(prevState => { - state.deleteModal.hide = true - return { ...prevState, ...state.deleteModal } - }) - } - - const handleHideRenameModal = () => { - setState(prevState => { - state.renameModal.hide = true - return { ...prevState, ...state.renameModal } - }) - } - - const createWorkspace = () => { - setState(prevState => { - state.createModal.hide = false - return { ...prevState, ...state.createModal } - }) - } - - const renameCurrentWorkspace = () => { - setState(prevState => { - state.renameModal.hide = false - return { ...prevState, ...state.renameModal } - }) - } - - const deleteCurrentWorkspace = () => { - setState(prevState => { - state.deleteModal.hide = false - return { ...prevState, ...state.deleteModal } - }) - } + useEffect(() => { initWorkspace() }, []) const [state, setState] = useState({ workspaces: [], reset: false, currentWorkspace: NO_WORKSPACE, hideRemixdExplorer: true, - registeredMenuItems: [], displayNewFile: false, externalUploads: null, uploadFileEvent: null, @@ -122,7 +92,12 @@ export const Workspace = (props: WorkspaceProps) => { label: '', fn: () => {} }, - handleHide: handleHideRenameModal + handleHide: () => { + setState(prevState => { + state.renameModal.hide = true + return { ...prevState, ...state.renameModal } + }) + } }, deleteModal: { id: 'deleteWorkspace', @@ -137,7 +112,12 @@ export const Workspace = (props: WorkspaceProps) => { label: '', fn: () => {} }, - handleHide: handleHideDeleteModal + handleHide: () => { + setState(prevState => { + state.deleteModal.hide = true + return { ...prevState, ...state.deleteModal } + }) + } }, createModal: { id: 'createWorkspace', @@ -152,29 +132,79 @@ export const Workspace = (props: WorkspaceProps) => { label: '', fn: () => {} }, - handleHide: handleHideCreateModal + handleHide: () => { + setState(prevState => { + state.createModal.hide = true + return { ...prevState, ...state.createModal } + }) + } } }) - let worspaceNewName // used for renaming and creation + /* workspace creation, renaming and deletion */ + + const modal = (title: string, message: string, ok: { label: string, fn: () => void }, cancel: { label: string, fn: () => void }) => { + setState(prevState => { + return { + ...prevState, + modals: [...prevState.modals, + { + message, + title, + ok, + cancel, + handleHide: handleHideModal + }] + } + }) + } + + const workspaceRenameInput = useRef() + const workspaceCreateInput = useRef() + + const createWorkspace = () => { + modal() + setState(prevState => { + state.createModal.hide = false + return { ...prevState, ...state.createModal } + }) + } + + const renameCurrentWorkspace = () => { + setState(prevState => { + state.renameModal.hide = false + return { ...prevState, ...state.renameModal } + }) + } + const deleteCurrentWorkspace = () => { + setState(prevState => { + state.deleteModal.hide = false + return { ...prevState, ...state.deleteModal } + }) + } + const onFinishRenameWorkspace = async () => { + if (workspaceRenameInput.current === undefined) return + // @ts-ignore: Object is possibly 'null'. + const workspaceName = workspaceRenameInput.current.value const workspacesPath = props.workspace.workspacesPath - await props.fileManager.rename('browser/' + workspacesPath + '/' + state.currentWorkspace, 'browser/' + workspacesPath + '/' + worspaceNewName) - setWorkspace(worspaceNewName) - worspaceNewName = '' - props.renameWorkspace({ name: state.currentWorkspace }) + await props.fileManager.rename('browser/' + workspacesPath + '/' + state.currentWorkspace, 'browser/' + workspacesPath + '/' + workspaceName) + setWorkspace(workspaceName) + props.workspaceRenamed({ name: state.currentWorkspace }) } const onFinishCreateWorkspace = async () => { + if (workspaceCreateInput.current === undefined) return + // @ts-ignore: Object is possibly 'null'. + const workspaceName = workspaceCreateInput.current.value const workspacesPath = props.workspace.workspacesPath - props.browser.createDir(workspacesPath + '/' + worspaceNewName, async () => { - setWorkspace(worspaceNewName) + props.browser.createDir(workspacesPath + '/' + workspaceName, async () => { + setWorkspace(workspaceName) for (const file in props.examples) { await props.fileManager.writeFile(`${props.examples[file].name}`, props.examples[file].content) } - worspaceNewName = '' - props.createWorkspace({ name: state.currentWorkspace }) + props.workspaceCreated({ name: state.currentWorkspace }) }) } @@ -183,13 +213,14 @@ export const Workspace = (props: WorkspaceProps) => { props.browser.remove(workspacesPath + '/' + state.currentWorkspace) const name = state.currentWorkspace setWorkspace(NO_WORKSPACE) - props.deleteWorkspace({ name }) + props.workspaceDeleted({ name }) } + /**** ****/ const resetFocus = (reset) => { - /*setState(prevState => { + setState(prevState => { return { ...prevState, reset } - })*/ + }) } const setWorkspace = async (name) => { @@ -233,7 +264,7 @@ export const Workspace = (props: WorkspaceProps) => { if (Object.keys(filesList).length === 0) { for (const file in props.examples) { try { - await props.fileManager.writeFile('browser/' + workspacesPath + '/default_workspace/' + props.examples[file].name, props.examples[file].content) + await props.fileManager.writeFile('browser/' + workspacesPath + '/default_workspace/' + props.examples[file].name, props.examples[file].content) } catch (error) { console.error(error) } @@ -290,34 +321,28 @@ export const Workspace = (props: WorkspaceProps) => { props.localhost.event.register('closed', (event) => { remixdExplorer.hide() }) - - props.plugin.resetFocus = () => { - setState(prevState => { - return { ...prevState, reset: true } - }) - } return (
- { worspaceNewName = e.target.value } }/> + handleHide={ state.renameModal.handleHide }> + { state.renameModal.message } + - { worspaceNewName = e.target.value } }/> + handleHide={ state.createModal.handleHide }> + { state.createModal.message } + { hide={ state.deleteModal.hide } ok={ state.deleteModal.ok } cancel={ state.deleteModal.cancel } - handleHide={ handleHideDeleteModal }> + handleHide={ state.deleteModal.handleHide }>
resetFocus(true)}>
@@ -393,7 +418,7 @@ export const Workspace = (props: WorkspaceProps) => { menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']} plugin={props.plugin} focusRoot={state.reset} - contextMenuItems={state.registeredMenuItems} + contextMenuItems={props.registeredMenuItems} displayInput={state.displayNewFile} externalUploads={state.uploadFileEvent} /> @@ -408,7 +433,7 @@ export const Workspace = (props: WorkspaceProps) => { menuItems={['createNewFile', 'createNewFolder']} plugin={props.plugin} focusRoot={state.reset} - contextMenuItems={state.registeredMenuItems} + contextMenuItems={props.registeredMenuItems} /> }
@@ -420,7 +445,7 @@ export const Workspace = (props: WorkspaceProps) => { menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']} plugin={props.plugin} focusRoot={state.reset} - contextMenuItems={state.registeredMenuItems} + contextMenuItems={props.registeredMenuItems} displayInput={state.displayNewFile} externalUploads={state.uploadFileEvent} />