rearangement

pull/924/head
yann300 4 years ago
parent 3bd07e9a55
commit 99196493b4
  1. 37
      apps/remix-ide/src/app/panels/file-panel.js
  2. 199
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -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(
<Workspace
setWorkspace={this.setWorkspace.bind(this)}
renameWorkspace={this.renameWorkspace.bind(this)}
deleteWorkspace={this.deleteWorkspace.bind(this)}
createWorkspace={this.createWorkspace.bind(this)}
workspaceRenamed={this.workspaceRenamed.bind(this)}
workspaceDeleted={this.workspaceDeleted.bind(this)}
workspaceCreated={this.workspaceCreated.bind(this)}
workspace={this._deps.fileProviders.workspace}
browser={this._deps.fileProviders.browser}
localhost={this._deps.fileProviders.localhost}
@ -76,12 +85,22 @@ module.exports = class Filepanel extends ViewPlugin {
registry={this._components.registry}
plugin={this}
request={this.request}
registeredMenuItems={this.registeredMenuItems}
/>
, 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 */

@ -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 (
<div className='remixui_container'>
<ModalDialog
id={ state.renameModal.id }
title={ state.renameModal.title }
message={ state.renameModal.message }
hide={ state.renameModal.hide }
ok={ state.renameModal.ok }
cancel={ state.renameModal.cancel }
handleHide={ handleHideRenameModal }>
<input placeholder={ state.currentWorkspace } onChange={(e) => { worspaceNewName = e.target.value } }/>
handleHide={ state.renameModal.handleHide }>
<span>{ state.renameModal.message }</span>
<input placeholder={ state.currentWorkspace } ref={workspaceRenameInput} className="form-control" />
</ModalDialog>
<ModalDialog
id={ state.createModal.id }
title={ state.createModal.title }
message={ state.createModal.message }
hide={ state.createModal.hide }
ok={ state.createModal.ok }
cancel={ state.createModal.cancel }
handleHide={ handleHideCreateModal }>
<input placeholder={ `workspace_${Date.now()}` } onChange={(e) => { worspaceNewName = e.target.value } }/>
handleHide={ state.createModal.handleHide }>
<span>{ state.createModal.message }</span>
<input placeholder={ `workspace_${Date.now()}` } ref={workspaceCreateInput} className="form-control" />
</ModalDialog>
<ModalDialog
id={ state.deleteModal.id }
@ -326,7 +351,7 @@ export const Workspace = (props: WorkspaceProps) => {
hide={ state.deleteModal.hide }
ok={ state.deleteModal.ok }
cancel={ state.deleteModal.cancel }
handleHide={ handleHideDeleteModal }>
handleHide={ state.deleteModal.handleHide }>
</ModalDialog>
<div className='remixui_fileexplorer' onClick={() => resetFocus(true)}>
<div>
@ -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}
/>
}
</div>
@ -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}
/>

Loading…
Cancel
Save