Skip to content

Commit

Permalink
Merge pull request #3654 from ethereum/startCoding
Browse files Browse the repository at this point in the history
recent workspaces & Start Coding
  • Loading branch information
yann300 authored Oct 31, 2023
2 parents 625b343 + 7f9b0f9 commit c57e2f6
Show file tree
Hide file tree
Showing 24 changed files with 810 additions and 357 deletions.
23 changes: 10 additions & 13 deletions apps/remix-ide-e2e/src/tests/homeTab.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import init from '../helpers/init'

module.exports = {

before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},

'Should create new file': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="homeTabNewFile"]')
.click('*[data-id="homeTabNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', 'newTestFile')
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.waitForElementVisible('li[data-id="treeViewLitreeViewItemnewTestFile.sol"]')
}
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},

'Should start coding': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="homeTabStartCoding"]')
.click('*[data-id="homeTabStartCoding"]')
.waitForElementVisible('div[data-id="treeViewDivtreeViewItemcontracts/helloWorld.sol"]')
}
}
4 changes: 2 additions & 2 deletions apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ const sources = [
content:
`
pragma solidity ^0.8.0;
contract helloWorld {
contract HelloWorld {
string public message;
fallback () external {
Expand All @@ -249,7 +249,7 @@ const sources = [
},
'checkBalance.sol': {
content: `pragma solidity ^0.8.0;
contract checkBalance {
contract CheckBalance {
constructor () payable {}
function sendSomeEther(uint256 num) public {
Expand Down
33 changes: 29 additions & 4 deletions apps/remix-ide/src/app/files/fileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ const profile = {
icon: 'assets/img/fileManager.webp',
permission: true,
version: packageJson.version,
methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'writeMultipleFiles', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir',
'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh',
'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory'],
methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'writeMultipleFiles', 'writeFileNoRewrite',
'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile',
'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath',
'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory'
],
kind: 'file-system'
}
const errorMsg = {
Expand All @@ -37,7 +39,6 @@ const errorMsg = {
const createError = (err) => {
return new Error(`${errorMsg[err.code]} ${err.message || ''}`)
}

class FileManager extends Plugin {
mode: string
openedFiles: any
Expand Down Expand Up @@ -249,6 +250,30 @@ class FileManager extends Plugin {
throw new Error(e)
}
}

/**
* Set the content of a specific file, does nnot rewrite file if it exists but creates a new unique name
* @param {string} path path of the file
* @param {string} data content to write on the file
* @returns {void}
*/
async writeFileNoRewrite(path, data) {
try {
path = this.normalize(path)
path = this.limitPluginScope(path)
if (await this.exists(path)) {
const newPath = await helper.createNonClashingNameAsync(path, this)
const content = await this.setFileContent(newPath, data)
return {newContent: content, newPath}
} else {
const ret = await this.setFileContent(path, data)
this.emit('fileAdded', path)
return {newContent: ret, newpath: path}
}
} catch (e) {
throw new Error(e)
}
}

/**
* Return the content of a specific file
Expand Down
95 changes: 69 additions & 26 deletions apps/remix-ide/src/app/panels/file-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,19 @@ const { SlitherHandle } = require('../files/slither-handle.js')
const profile = {
name: 'filePanel',
displayName: 'File explorer',
methods: ['createNewFile', 'uploadFile', 'getCurrentWorkspace', 'getAvailableWorkspaceName', 'getWorkspaces', 'createWorkspace', 'setWorkspace', 'registerContextMenuItem', 'renameWorkspace', 'deleteWorkspace'],
methods: [
'createNewFile',
'uploadFile',
'getCurrentWorkspace',
'getAvailableWorkspaceName',
'getWorkspaces',
'createWorkspace',
'switchToWorkspace',
'setWorkspace',
'registerContextMenuItem',
'renameWorkspace',
'deleteWorkspace',
],
events: ['setWorkspace', 'workspaceRenamed', 'workspaceDeleted', 'workspaceCreated'],
icon: 'assets/img/fileManager.webp',
description: 'Remix IDE file explorer',
Expand All @@ -41,7 +53,7 @@ const profile = {
maintainedBy: 'Remix'
}
module.exports = class Filepanel extends ViewPlugin {
constructor (appManager) {
constructor(appManager) {
super(profile)
this.registry = Registry.getInstance()
this.fileProviders = this.registry.get('fileproviders').api
Expand All @@ -60,13 +72,17 @@ module.exports = class Filepanel extends ViewPlugin {
this.currentWorkspaceMetadata = null
}

render () {
return <div id='fileExplorerView'><FileSystemProvider plugin={this} /></div>
render() {
return (
<div id="fileExplorerView">
<FileSystemProvider plugin={this} />
</div>
)
}

/**
* @param item { id: string, name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] }
* typically:
* typically:
* group 0 for file manipulations
* group 1 for download operations
* group 2 for running operations (script for instance)
Expand All @@ -77,7 +93,7 @@ module.exports = class Filepanel extends ViewPlugin {
* group 7 for generating resource files (UML, documentation, ...)
* @param callback (...args) => void
*/
registerContextMenuItem (item) {
registerContextMenuItem(item) {
return new Promise((resolve, reject) => {
this.emit('registerContextMenuItemReducerEvent', item, (err, data) => {
if (err) reject(err)
Expand All @@ -86,7 +102,7 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

removePluginActions (plugin) {
removePluginActions(plugin) {
return new Promise((resolve, reject) => {
this.emit('removePluginActionsReducerEvent', plugin, (err, data) => {
if (err) reject(err)
Expand All @@ -95,30 +111,30 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

getCurrentWorkspace () {
getCurrentWorkspace() {
return this.currentWorkspaceMetadata
}

getWorkspaces () {
getWorkspaces() {
return this.workspaces
}

getAvailableWorkspaceName (name) {
if(!this.workspaces) return name
getAvailableWorkspaceName(name) {
if (!this.workspaces) return name
let index = 1
let workspace = this.workspaces.find(workspace => workspace.name === name + ' - ' + index)
let workspace = this.workspaces.find((workspace) => workspace.name === name + ' - ' + index)
while (workspace) {
index++
workspace = this.workspaces.find(workspace => workspace.name === name + ' - ' + index)
workspace = this.workspaces.find((workspace) => workspace.name === name + ' - ' + index)
}
return name + ' - ' + index
}

setWorkspaces (workspaces) {
setWorkspaces(workspaces) {
this.workspaces = workspaces
}

createNewFile () {
createNewFile() {
return new Promise((resolve, reject) => {
this.emit('createNewFileInputReducerEvent', '/', (err, data) => {
if (err) reject(err)
Expand All @@ -127,7 +143,7 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

uploadFile (target) {
uploadFile(target) {
return new Promise((resolve, reject) => {
return this.emit('uploadFileReducerEvent', '/', target, (err, data) => {
if (err) reject(err)
Expand All @@ -136,7 +152,7 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

createWorkspace (workspaceName, workspaceTemplateName, isEmpty) {
createWorkspace(workspaceName, workspaceTemplateName, isEmpty) {
return new Promise((resolve, reject) => {
this.emit('createWorkspaceReducerEvent', workspaceName, workspaceTemplateName, isEmpty, (err, data) => {
if (err) reject(err)
Expand All @@ -145,7 +161,7 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

renameWorkspace (oldName, workspaceName) {
renameWorkspace(oldName, workspaceName) {
return new Promise((resolve, reject) => {
this.emit('renameWorkspaceReducerEvent', oldName, workspaceName, (err, data) => {
if (err) reject(err)
Expand All @@ -154,7 +170,7 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

deleteWorkspace (workspaceName) {
deleteWorkspace(workspaceName) {
return new Promise((resolve, reject) => {
this.emit('deleteWorkspaceReducerEvent', workspaceName, (err, data) => {
if (err) reject(err)
Expand All @@ -163,25 +179,52 @@ module.exports = class Filepanel extends ViewPlugin {
})
}

setWorkspace (workspace) {
const workspaceProvider = this.fileProviders.workspace
saveRecent(workspaceName) {
if (!localStorage.getItem('recentWorkspaces')) {
localStorage.setItem('recentWorkspaces', JSON.stringify([ workspaceName ]))
} else {
let recents = JSON.parse(localStorage.getItem('recentWorkspaces'))
// checking if we have a duplication
if (!recents.find((el) => {
return el === workspaceName
})) {
recents = ([workspaceName, ...recents])
recents = recents.filter((el) => { return el != "" })
localStorage.setItem('recentWorkspaces', JSON.stringify(recents))
}
}
}

this.currentWorkspaceMetadata = { name: workspace.name, isLocalhost: workspace.isLocalhost, absolutePath: `${workspaceProvider.workspacesPath}/${workspace.name}` }
if (workspace.name !== " - connect to localhost - ") {
setWorkspace(workspace) {
const workspaceProvider = this.fileProviders.workspace
const current = this.currentWorkspaceMetadata
this.currentWorkspaceMetadata = {
name: workspace.name,
isLocalhost: workspace.isLocalhost,
absolutePath: `${workspaceProvider.workspacesPath}/${workspace.name}`,
}
if (this.currentWorkspaceMetadata.name !== current) {
this.saveRecent(workspace.name)
}
if (workspace.name !== ' - connect to localhost - ') {
localStorage.setItem('currentWorkspace', workspace.name)
}
this.emit('setWorkspace', workspace)
}

workspaceRenamed (oldName, workspaceName) {
switchToWorkspace(workspaceName) {
this.emit('switchToWorkspace', workspaceName)
}

workspaceRenamed(oldName, workspaceName) {
this.emit('workspaceRenamed', oldName, workspaceName)
}

workspaceDeleted (workspace) {
workspaceDeleted(workspace) {
this.emit('workspaceDeleted', workspace)
}

workspaceCreated (workspace) {
workspaceCreated(workspace) {
this.emit('workspaceCreated', workspace)
}
/** end section */
Expand Down
3 changes: 3 additions & 0 deletions apps/remix-ide/src/app/tabs/locales/en/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@
"home.searchDocumentation": "Search Documentation",
"home.files": "Files",
"home.newFile": "New File",
"home.startCoding": "Start Coding",
"home.startCodingPlayground": "Open a playground for prototyping and simply learning",
"home.openFile": "Open File",
"home.openFileTooltip": "Open a File from your File System",
"home.accessFileSystem": "Access File System",
"home.loadFrom": "Load from",
"home.resources": "Resources",
Expand Down
1 change: 1 addition & 0 deletions apps/remix-ide/src/app/tabs/locales/fr/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"home.files": "Files",
"home.newFile": "New File",
"home.openFile": "Open File",
"home.openFileTooltip": "Open a File from you File System",
"home.connectToLocalhost": "Access File System",
"home.loadFrom": "Load from",
"home.resources": "Resources"
Expand Down
6 changes: 3 additions & 3 deletions apps/remix-ide/src/remixAppManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {IframePlugin} from '@remixproject/engine-web'
const _paq = (window._paq = window._paq || [])

// requiredModule removes the plugin from the plugin manager list on UI
const requiredModules = [
// services + layout views + system views
const requiredModules = [ // services + layout views + system views
'manager',
'config',
'compilerArtefacts',
Expand Down Expand Up @@ -74,7 +73,8 @@ const requiredModules = [
'compilationDetails',
'contractflattener',
'solidity-script',
'openaigpt'
'openaigpt',
'home'
]

// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)
Expand Down
Loading

0 comments on commit c57e2f6

Please sign in to comment.