Initialize workspace in reducer.

pull/1575/head
ioedeveloper 4 years ago
parent 26db081037
commit 0881f25d57
  1. 14
      apps/remix-ide/src/app/panels/file-panel.js
  2. 112
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  3. 30
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts
  4. 99
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -300,19 +300,5 @@ module.exports = class Filepanel extends ViewPlugin {
workspaceCreated (workspace) {
this.emit('createWorkspace', workspace)
}
resetFocus (reset) {
// setState(prevState => {
// return { ...prevState, reset }
// })
}
resetNewFile () {
// setState(prevState => {
// return { ...prevState, displayNewFile: !state.displayNewFile }
// })
}
resetUploadFile = () => {}
/** end section */
}

@ -0,0 +1,112 @@
import { bufferToHex, keccakFromString } from 'ethereumjs-util'
import { checkSpecialChars, checkSlash } from '../../../../../../apps/remix-ide/src/lib/helper'
const GistHandler = require('../../../../../../apps/remix-ide/src/lib/gist-handler')
const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params')
const examples = require('../../../../../../apps/remix-ide/src/app/editor/examples')
let plugin
export const setCurrentWorkspace = (workspace: string) => {
return {
type: 'SET_CURRENT_WORKSPACE',
payload: workspace
}
}
export const initWorkspace = (filePanelPlugin) => async (dispatch: React.Dispatch<any>) => {
plugin = filePanelPlugin
const queryParams = new QueryParams()
const gistHandler = new GistHandler()
const params = queryParams.get()
// get the file from gist
let loadedFromGist = false
if (params.gist) {
await processCreateWorkspace('gist-sample')
plugin.initialWorkspace = 'gist-sample'
loadedFromGist = gistHandler.loadFromGist(params, plugin.fileManager)
}
if (loadedFromGist) return
if (params.code) {
try {
await processCreateWorkspace('code-sample')
const hash = bufferToHex(keccakFromString(params.code))
const fileName = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol'
const path = fileName
await plugin.fileProviders.workspace.set(path, atob(params.code))
plugin.initialWorkspace = 'code-sample'
await plugin.fileManager.openFile(fileName)
} catch (e) {
console.error(e)
}
return
}
return new Promise((resolve, reject) => {
plugin.fileProviders.browser.resolveDirectory('/', async (error, filesList) => {
if (error) return reject(error)
if (Object.keys(filesList).length === 0) {
await createWorkspace('default_workspace')
return resolve('default_workspace')
} else {
plugin.fileProviders.browser.resolveDirectory('.workspaces', async (error, filesList) => {
if (error) return reject(error)
if (Object.keys(filesList).length > 0) {
const workspacePath = Object.keys(filesList)[0].split('/').filter(val => val)
const workspaceName = workspacePath[workspacePath.length - 1]
plugin.fileProviders.workspace.setWorkspace(workspaceName)
return resolve(workspaceName)
}
return reject(new Error('Can\'t find available workspace.'))
})
}
})
})
}
const processCreateWorkspace = async (name: string) => {
const workspaceProvider = plugin.fileProviders.workspace
const browserProvider = plugin.fileProviders.browser
const workspacePath = 'browser/' + workspaceProvider.workspacesPath + '/' + name
const workspaceRootPath = 'browser/' + workspaceProvider.workspacesPath
const workspaceRootPathExists = await browserProvider.exists(workspaceRootPath)
const workspacePathExists = await browserProvider.exists(workspacePath)
if (!workspaceRootPathExists) browserProvider.createDir(workspaceRootPath)
if (!workspacePathExists) browserProvider.createDir(workspacePath)
plugin.fileProviders.workspace.setWorkspace(name)
}
const createWorkspace = async (workspaceName, setDefaults = true) => {
if (!workspaceName) throw new Error('name cannot be empty')
if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed')
if (await workspaceExists(workspaceName)) throw new Error('workspace already exists')
else {
const workspaceProvider = plugin.fileProviders.workspace
await processCreateWorkspace(workspaceName)
workspaceProvider.setWorkspace(workspaceName)
plugin.workspaceName = workspaceName
if (setDefaults) {
// insert example contracts if there are no files to show
for (const file in examples) {
try {
await workspaceProvider.set(examples[file].name, examples[file].content)
} catch (error) {
console.error(error)
}
}
}
}
}
const workspaceExists = async (name) => {
const workspaceProvider = plugin.fileProviders.workspace
const browserProvider = plugin.fileProviders.browser
const workspacePath = 'browser/' + workspaceProvider.workspacesPath + '/' + name
return browserProvider.exists(workspacePath)
}

@ -0,0 +1,30 @@
interface Action {
type: string
payload: Record<string, any> | string
}
export const browserInitialState = {
browser: {
currentWorkspace: '',
workspaces: [],
isRequesting: false,
isSuccessful: false,
error: null
}
}
export const browserReducer = (state = browserInitialState, action: Action) => {
switch (action.type) {
case 'SET_CURRENT_WORKSPACE': {
return {
...state,
browser: {
...state.browser,
currentWorkspace: typeof action.payload === 'string' ? action.payload : ''
}
}
}
default:
throw new Error()
}
}

@ -1,13 +1,14 @@
import React, { useState, useEffect, useRef } from 'react' // eslint-disable-line
import React, { useState, useEffect, useRef, useReducer } from 'react' // eslint-disable-line
import { FileExplorer } from '@remix-ui/file-explorer' // eslint-disable-line
import './remix-ui-workspace.css'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
import { MenuItems } from 'libs/remix-ui/file-explorer/src/lib/types'
import { initWorkspace } from './actions/workspace'
import { browserReducer, browserInitialState } from './reducers/workspace'
/* eslint-disable-next-line */
export interface WorkspaceProps {
plugin: {
setWorkspace: ({ name: string, isLocalhost: boolean }, setEvent: boolean) => void,
createWorkspace: (name: string) => void,
renameWorkspace: (oldName: string, newName: string) => void
@ -19,40 +20,34 @@ export interface WorkspaceProps {
localhost: any // localhost provider
fileManager : any
registry: any // registry
plugin: any // plugin call and resetFocus
request: any // api request,
workspaces: any,
registeredMenuItems: MenuItems // menu items
removedMenuItems: MenuItems
initialWorkspace: string
}
}
var canUpload = window.File || window.FileReader || window.FileList || window.Blob
export const Workspace = (props: WorkspaceProps) => {
const {
plugin,
plugin: {
setWorkspace,
createWorkspace,
renameWorkspace,
workspaceRenamed,
workspaceCreated,
workspaceDeleted,
workspace,
browser,
localhost,
fileManager,
registry,
request,
workspaces,
registeredMenuItems,
removedMenuItems,
initialWorkspace
}
} = props
const LOCALHOST = ' - connect to localhost - '
const NO_WORKSPACE = ' - none - '
/* extends the parent 'plugin' with some function needed by the file explorer */
props.plugin.resetFocus = (reset) => {
setState(prevState => {
return { ...prevState, reset }
})
}
props.plugin.resetNewFile = () => {
setState(prevState => {
return { ...prevState, displayNewFile: !state.displayNewFile }
})
}
props.plugin.resetUploadFile = () => {}
/* implement an external API, consumed by the parent */
props.request.createWorkspace = () => {
return createWorkspace()
@ -112,32 +107,36 @@ export const Workspace = (props: WorkspaceProps) => {
}
}
useEffect(() => {
props.localhost.event.off('disconnected', localhostDisconnect)
props.localhost.event.on('disconnected', localhostDisconnect)
props.localhost.event.on('connected', () => {
remixdExplorer.show()
setWorkspace(LOCALHOST)
})
// useEffect(() => {
// props.localhost.event.off('disconnected', localhostDisconnect)
// props.localhost.event.on('disconnected', localhostDisconnect)
// props.localhost.event.on('connected', () => {
// remixdExplorer.show()
// setWorkspace(LOCALHOST)
// })
props.localhost.event.on('disconnected', () => {
remixdExplorer.hide()
})
// props.localhost.event.on('disconnected', () => {
// remixdExplorer.hide()
// })
props.localhost.event.on('loading', () => {
remixdExplorer.loading()
})
// props.localhost.event.on('loading', () => {
// remixdExplorer.loading()
// })
props.workspace.event.on('createWorkspace', (name) => {
createNewWorkspace(name)
})
// props.workspace.event.on('createWorkspace', (name) => {
// createNewWorkspace(name)
// })
if (props.initialWorkspace) {
props.workspace.setWorkspace(props.initialWorkspace)
setState(prevState => {
return { ...prevState, currentWorkspace: props.initialWorkspace }
})
}
// if (props.initialWorkspace) {
// props.workspace.setWorkspace(props.initialWorkspace)
// setState(prevState => {
// return { ...prevState, currentWorkspace: props.initialWorkspace }
// })
// }
// }, [])
useEffect(() => {
initWorkspace(props.plugin)(dispatch)
}, [])
const createNewWorkspace = async (workspaceName) => {
@ -174,6 +173,8 @@ export const Workspace = (props: WorkspaceProps) => {
toasterMsg: ''
})
const [fs, dispatch] = useReducer(browserReducer, browserInitialState)
const toast = (message: string) => {
setState(prevState => {
return { ...prevState, toasterMsg: message }
@ -394,7 +395,7 @@ export const Workspace = (props: WorkspaceProps) => {
title='Delete'>
</span>
</span>
<select id="workspacesSelect" value={state.currentWorkspace} data-id="workspacesSelect" onChange={(e) => setWorkspace(e.target.value)} className="form-control custom-select">
<select id="workspacesSelect" value={fs.browser.currentWorkspace} data-id="workspacesSelect" onChange={(e) => setWorkspace(e.target.value)} className="form-control custom-select">
{
state.workspaces
.map((folder, index) => {
@ -416,7 +417,7 @@ export const Workspace = (props: WorkspaceProps) => {
registry={props.registry}
filesProvider={props.workspace}
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']}
plugin={plugin}
plugin={props.plugin}
focusRoot={state.reset}
contextMenuItems={props.registeredMenuItems}
removedContextMenuItems={props.removedMenuItems}
@ -434,7 +435,7 @@ export const Workspace = (props: WorkspaceProps) => {
registry={props.registry}
filesProvider={props.localhost}
menuItems={['createNewFile', 'createNewFolder']}
plugin={plugin}
plugin={props.plugin}
focusRoot={state.reset}
contextMenuItems={props.registeredMenuItems}
removedContextMenuItems={props.removedMenuItems}

Loading…
Cancel
Save