|
|
|
@ -7,10 +7,13 @@ import { FileExplorer } from '@remix-ui/file-explorer' // eslint-disable-line |
|
|
|
|
import './styles/file-panel-styles.css' |
|
|
|
|
var yo = require('yo-yo') |
|
|
|
|
var EventManager = require('../../lib/events') |
|
|
|
|
// var FileExplorer = require('../files/file-explorer')
|
|
|
|
|
var { RemixdHandle } = require('../files/remixd-handle.js') |
|
|
|
|
var { GitHandle } = require('../files/git-handle.js') |
|
|
|
|
var globalRegistry = require('../../global/registry') |
|
|
|
|
var examples = require('../editor/examples') |
|
|
|
|
var GistHandler = require('../../lib/gist-handler') |
|
|
|
|
var QueryParams = require('../../lib/query-params') |
|
|
|
|
const modalDialog = require('../ui/modal-dialog-custom') |
|
|
|
|
|
|
|
|
|
var canUpload = window.File || window.FileReader || window.FileList || window.Blob |
|
|
|
|
|
|
|
|
@ -54,13 +57,16 @@ module.exports = class Filepanel extends ViewPlugin { |
|
|
|
|
fileManager: this._components.registry.get('filemanager').api, |
|
|
|
|
config: this._components.registry.get('config').api |
|
|
|
|
} |
|
|
|
|
this.LOCALHOST = '<Connect Localhost>' |
|
|
|
|
this.hideRemixdExplorer = true |
|
|
|
|
this.remixdExplorer = { |
|
|
|
|
hide: () => { |
|
|
|
|
this._deps.fileManager.setMode('browser') |
|
|
|
|
this.hideRemixdExplorer = true |
|
|
|
|
this.renderComponent() |
|
|
|
|
}, |
|
|
|
|
show: () => { |
|
|
|
|
this._deps.fileManager.setMode('localhost') |
|
|
|
|
this.hideRemixdExplorer = false |
|
|
|
|
this.renderComponent() |
|
|
|
|
} |
|
|
|
@ -93,9 +99,54 @@ module.exports = class Filepanel extends ViewPlugin { |
|
|
|
|
this.remixdExplorer.hide() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
this.currentWorkspace = null |
|
|
|
|
|
|
|
|
|
this.renderComponent() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
initWorkspace () { |
|
|
|
|
const queryParams = new QueryParams() |
|
|
|
|
const params = queryParams.get() |
|
|
|
|
// get the file from gist
|
|
|
|
|
const gistHandler = new GistHandler() |
|
|
|
|
const loadedFromGist = gistHandler.loadFromGist(params, this._deps.fileManager) |
|
|
|
|
if (!loadedFromGist) { |
|
|
|
|
// insert example contracts if there are no files to show
|
|
|
|
|
this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => { |
|
|
|
|
if (error) console.error(error) |
|
|
|
|
if (Object.keys(filesList).length === 0) { |
|
|
|
|
const workspacesPath = this._deps.fileProviders.workspace.workspacesPath |
|
|
|
|
for (const file in examples) { |
|
|
|
|
await this._deps.fileManager.writeFile('browser/' + workspacesPath + '/default_workspace/' + examples[file].name, examples[file].content) |
|
|
|
|
} |
|
|
|
|
this.setWorkspace('default_workspace') |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} else { |
|
|
|
|
this.setWorkspace('gists') |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
refreshWorkspacesList () { |
|
|
|
|
if (!document.getElementById('workspacesSelect')) return |
|
|
|
|
const workspacesPath = this._deps.fileProviders.workspace.workspacesPath |
|
|
|
|
this._deps.fileProviders.browser.resolveDirectory('/' + workspacesPath, (error, fileTree) => { |
|
|
|
|
if (error) console.error(error) |
|
|
|
|
const items = fileTree |
|
|
|
|
items[this.LOCALHOST] = { isLocalHost: true } |
|
|
|
|
ReactDOM.render( |
|
|
|
|
( |
|
|
|
|
Object.keys(items) |
|
|
|
|
.filter((item) => fileTree[item].isDirectory || fileTree[item].isLocalHost) |
|
|
|
|
.map((folder) => { |
|
|
|
|
folder = folder.replace(workspacesPath + '/', '') |
|
|
|
|
return <option selected={this.currentWorkspace === folder} value={folder}>{folder}</option> |
|
|
|
|
})), document.getElementById('workspacesSelect') |
|
|
|
|
) |
|
|
|
|
if (!this.currentWorkspace) this.setWorkspace(Object.keys(fileTree)[0].replace(workspacesPath + '/', '')) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resetFocus (value) { |
|
|
|
|
this.reset = value |
|
|
|
|
this.renderComponent() |
|
|
|
@ -125,6 +176,19 @@ module.exports = class Filepanel extends ViewPlugin { |
|
|
|
|
return this.el |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setWorkspace (name) { |
|
|
|
|
this._deps.fileManager.removeTabsOf(this._deps.fileProviders.workspace) |
|
|
|
|
this.currentWorkspace = name |
|
|
|
|
if (name === this.LOCALHOST) { |
|
|
|
|
this.call('manager', 'activatePlugin', 'remixd') |
|
|
|
|
} else { |
|
|
|
|
this._deps.fileProviders.workspace.setWorkspace(name) |
|
|
|
|
this.call('manager', 'deactivatePlugin', 'remixd') |
|
|
|
|
} |
|
|
|
|
// TODO remove the opened tabs from the previous workspace
|
|
|
|
|
this.renderComponent() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
* @param item { id: string, name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } |
|
|
|
@ -139,24 +203,104 @@ module.exports = class Filepanel extends ViewPlugin { |
|
|
|
|
this.renderComponent() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
renameWorkspace () { |
|
|
|
|
modalDialog.prompt('Rename Workspace', 'Please choose a name for the workspace', this.currentWorkspace, async (value) => { |
|
|
|
|
const workspacesPath = this._deps.fileProviders.workspace.workspacesPath |
|
|
|
|
await this._deps.fileManager.rename('browser/' + workspacesPath + '/' + this.currentWorkspace, 'browser/workspaces/' + value) |
|
|
|
|
setTimeout(async () => { |
|
|
|
|
this.setWorkspace(value) |
|
|
|
|
}, 2000) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async createWorkspace () { |
|
|
|
|
const workspace = `workspace_${Date.now()}` |
|
|
|
|
modalDialog.prompt('New Workspace', 'Please choose a name for the workspace', workspace, (value) => { |
|
|
|
|
const workspacesPath = this._deps.fileProviders.workspace.workspacesPath |
|
|
|
|
this._deps.fileProviders.browser.createDir(workspacesPath + '/' + value, async () => { |
|
|
|
|
this.setWorkspace(value) |
|
|
|
|
setTimeout(async () => { |
|
|
|
|
for (const file in examples) { |
|
|
|
|
await this._deps.fileManager.writeFile(`${examples[file].name}`, examples[file].content) |
|
|
|
|
} |
|
|
|
|
}, 2000) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
deleteCurrentWorkspace () { |
|
|
|
|
if (!this.currentWorkspace) return |
|
|
|
|
modalDialog.confirm('Delete Workspace', 'Please confirm workspace deletion', () => { |
|
|
|
|
const workspacesPath = this._deps.fileProviders.workspace.workspacesPath |
|
|
|
|
this._deps.fileProviders.browser.remove(workspacesPath + '/' + this.currentWorkspace) |
|
|
|
|
this.currentWorkspace = null |
|
|
|
|
this.renderComponent() |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
renderComponent () { |
|
|
|
|
ReactDOM.render( |
|
|
|
|
<div className='remixui_container'> |
|
|
|
|
<div className='remixui_fileexplorer' onClick={() => this.resetFocus(true)}> |
|
|
|
|
<div> |
|
|
|
|
<header> |
|
|
|
|
<div class="mb-2"> |
|
|
|
|
<label className="form-check-label" htmlFor="workspacesSelect"> |
|
|
|
|
Workspaces |
|
|
|
|
</label> |
|
|
|
|
<span className="remixui_menu"> |
|
|
|
|
<span |
|
|
|
|
id='workspaceCreate' |
|
|
|
|
data-id='workspaceCreate' |
|
|
|
|
onClick={(e) => { |
|
|
|
|
e.stopPropagation() |
|
|
|
|
this.createWorkspace() |
|
|
|
|
}} |
|
|
|
|
className='far fa-plus-square remixui_menuicon' |
|
|
|
|
title='Create a new Workspace'> |
|
|
|
|
</span> |
|
|
|
|
<span |
|
|
|
|
hidden={this.currentWorkspace === this.LOCALHOST} |
|
|
|
|
id='workspaceRename' |
|
|
|
|
data-id='workspaceRename' |
|
|
|
|
onClick={(e) => { |
|
|
|
|
e.stopPropagation() |
|
|
|
|
this.renameWorkspace() |
|
|
|
|
}} |
|
|
|
|
className='far fa-edit remixui_menuicon' |
|
|
|
|
title='Rename current Workspace'> |
|
|
|
|
</span> |
|
|
|
|
<span |
|
|
|
|
hidden={this.currentWorkspace === this.LOCALHOST} |
|
|
|
|
id='workspaceDelete' |
|
|
|
|
data-id='workspaceDelete' |
|
|
|
|
onClick={(e) => { |
|
|
|
|
e.stopPropagation() |
|
|
|
|
this.deleteCurrentWorkspace() |
|
|
|
|
}} |
|
|
|
|
className='fas fa-trash' |
|
|
|
|
title='Delete current Workspace'> |
|
|
|
|
</span> |
|
|
|
|
</span> |
|
|
|
|
<select id="workspacesSelect" data-id="workspacesSelect" onChange={(e) => this.setWorkspace(e.target.value)} className="form-control custom-select"> |
|
|
|
|
</select> |
|
|
|
|
</div> |
|
|
|
|
</header> |
|
|
|
|
</div> |
|
|
|
|
<div className='remixui_fileExplorerTree'> |
|
|
|
|
<div> |
|
|
|
|
<div className='pl-2 remixui_treeview' data-id='filePanelFileExplorerTree'> |
|
|
|
|
{ this.hideRemixdExplorer && this.currentWorkspace && |
|
|
|
|
<FileExplorer |
|
|
|
|
name='browser' |
|
|
|
|
name={this.currentWorkspace} |
|
|
|
|
registry={this._components.registry} |
|
|
|
|
filesProvider={this._deps.fileProviders.browser} |
|
|
|
|
filesProvider={this._deps.fileProviders.workspace} |
|
|
|
|
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']} |
|
|
|
|
plugin={this} |
|
|
|
|
focusRoot={this.reset} |
|
|
|
|
contextMenuItems={this.registeredMenuItems} |
|
|
|
|
displayInput={this.displayNewFile} |
|
|
|
|
externalUploads={this.uploadFileEvent} |
|
|
|
|
/> |
|
|
|
|
} |
|
|
|
|
</div> |
|
|
|
|
<div className='pl-2 filesystemexplorer remixui_treeview'> |
|
|
|
|
{ !this.hideRemixdExplorer && |
|
|
|
@ -171,10 +315,27 @@ module.exports = class Filepanel extends ViewPlugin { |
|
|
|
|
/> |
|
|
|
|
} |
|
|
|
|
</div> |
|
|
|
|
<div className='pl-2 remixui_treeview'> |
|
|
|
|
{ false && <FileExplorer |
|
|
|
|
name='browser' |
|
|
|
|
registry={this._components.registry} |
|
|
|
|
filesProvider={this._deps.fileProviders.browser} |
|
|
|
|
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']} |
|
|
|
|
plugin={this} |
|
|
|
|
focusRoot={this.reset} |
|
|
|
|
contextMenuItems={this.registeredMenuItems} |
|
|
|
|
displayInput={this.displayNewFile} |
|
|
|
|
externalUploads={this.uploadFileEvent} |
|
|
|
|
/> |
|
|
|
|
} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
, this.el) |
|
|
|
|
setTimeout(() => { |
|
|
|
|
this.refreshWorkspacesList() |
|
|
|
|
}, 500) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|