fs integration

rdesktop
filip mertens 1 year ago
parent 218a56bdc7
commit 892915b138
  1. 18
      apps/remix-ide/src/app.js
  2. 5
      apps/remix-ide/src/app/files/fileManager.ts
  3. 3
      apps/remix-ide/src/app/files/fileProvider.js
  4. 71
      apps/remix-ide/src/app/plugins/fsPlugin.ts
  5. 13
      apps/remixdesktop/src/fsPlugin.ts
  6. 16
      libs/remix-ui/workspace/src/lib/actions/index.ts
  7. 11
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  8. 4
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts
  9. 2
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  10. 18
      package.json
  11. 133
      yarn.lock

@ -188,8 +188,7 @@ class AppComponent {
//----- search
const search = new SearchPlugin()
//---- fs plugin
const FSPlugin = new fsPlugin()
//---------------- Solidity UML Generator -------------------------
const solidityumlgen = new SolidityUmlGen(appManager)
@ -313,9 +312,14 @@ class AppComponent {
solidityumlgen,
contractFlattener,
solidityScript,
FSPlugin
])
//---- fs plugin
if (isElectron()) {
const FSPlugin = new fsPlugin()
this.engine.register([FSPlugin])
}
// LAYOUT & SYSTEM VIEWS
const appPanel = new MainPanel()
Registry.getInstance().put({ api: this.mainview, name: 'mainview' })
@ -430,7 +434,10 @@ class AppComponent {
await this.appManager.activatePlugin(['settings'])
await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder'])
await this.appManager.activatePlugin(['solidity-script'])
if(isElectron()){
await this.appManager.activatePlugin(['fs'])
}
this.appManager.on(
'filePanel',
@ -444,11 +451,6 @@ class AppComponent {
}
)
this.appManager.on('fs', 'loaded', async () => {
console.log('fs loaded')
const files = await this.appManager.call('fs', 'readdir', './')
console.log('files', files)
})
await this.appManager.activatePlugin(['filePanel'])
// Set workspace after initial activation

@ -9,6 +9,8 @@ import { fileChangedToastMsg, recursivePasteToastMsg, storageFullMessage } from
import helper from '../../lib/helper.js'
import { RemixAppManager } from '../../remixAppManager'
const isElectron = require('is-electron')
/*
attach to files event (removed renamed)
trigger: currentFileChanged
@ -408,7 +410,6 @@ class FileManager extends Plugin {
return new Promise((resolve, reject) => {
const provider = this.fileProviderOf(path)
provider.resolveDirectory(path, (error, filesProvider) => {
if (error) reject(error)
resolve(filesProvider)
@ -721,7 +722,7 @@ class FileManager extends Plugin {
if (file.startsWith('localhost') || this.mode === 'localhost') {
return this._deps.filesProviders.localhost
}
if (file.startsWith('browser')) {
if (file.startsWith('browser') || isElectron()) {
return this._deps.filesProviders.browser
}
return this._deps.filesProviders.workspace

@ -161,7 +161,8 @@ class FileProvider {
async isDirectory (path) {
const unprefixedpath = this.removePrefix(path)
return path === this.type ? true : (await window.remixFileSystem.stat(unprefixedpath)).isDirectory()
const isDirectory = path === this.type ? true : (await window.remixFileSystem.stat(unprefixedpath)).isDirectory()
return isDirectory
}
async isFile (path) {

@ -1,18 +1,83 @@
import { ElectronPlugin } from '@remixproject/engine-electron';
export class fsPlugin extends ElectronPlugin {
const fixPath = (path: string) => {
const workingDir = '/Volumes/bunsen/code/rmproject2/remix-project/apps/remix-ide/contracts/'
// if it starts with /, it's an absolute path remove it
if (path.startsWith('/')) {
path = path.slice(1)
}
path = workingDir + path
return path
}
constructor(){
export class fsPlugin extends ElectronPlugin {
public fs: any
constructor() {
super({
displayName: 'fs',
name: 'fs',
description: 'fs',
})
this.methods = ['readdir', 'readFile', 'writeFile', 'mkdir', 'rmdir', 'unlink', 'rename', 'stat', 'exists']
this.fs = {
exists: async (path: string) => {
path = fixPath(path)
const exists = await this.call('fs', 'exists', path)
return exists
},
rmdir: async (path: string) => {
path = fixPath(path)
return await this.call('fs', 'rmdir', path)
},
readdir: async (path: string) => {
path = fixPath(path)
const files = await this.call('fs', 'readdir', path)
return files
},
unlink: async (path: string) => {
path = fixPath(path)
return await this.call('fs', 'unlink', path)
},
mkdir: async (path: string) => {
path = fixPath(path)
return await this.call('fs', 'mkdir', path)
},
readFile: async (path: string) => {
path = fixPath(path)
return await this.call('fs', 'readFile', path)
}
,
rename: async (from: string, to: string) => {
return await this.call('fs', 'rename', from, to)
},
writeFile: async (path: string, content: string) => {
path = fixPath(path)
return await this.call('fs', 'writeFile', path, content)
}
,
stat: async (path: string) => {
path = fixPath(path)
const stat = await this.call('fs', 'stat', path)
stat.isDirectory = () => stat.isDirectoryValue
stat.isFile = () => !stat.isDirectoryValue
//console.log('stat', path, stat)
return stat
}
}
}
async onActivation() {
console.log('fsPluginClient onload')
console.log('fsPluginClient onload', this.fs);
(window as any).remixFileSystem = this.fs
}
}

@ -38,13 +38,14 @@ class FSPluginClient extends PluginClient {
super()
this.methods = ['readdir', 'readFile', 'writeFile', 'mkdir', 'rmdir', 'unlink', 'rename', 'stat', 'exists', 'watch', 'closeWatch', 'currentPath']
createElectronClient(this, profile, mainWindow)
console.log(mainWindow)
this.onload(() => {
console.log('fsPluginClient onload')
})
}
async readdir(path: string): Promise<string[]> {
// call node fs.readdir
return fs.readdir(path)
}
@ -72,8 +73,14 @@ class FSPluginClient extends PluginClient {
return fs.rename(oldPath, newPath)
}
async stat(path: string): Promise<Stats> {
return fs.stat(path)
async stat(path: string): Promise<any> {
const stat = await fs.stat(path)
//console.log('stat', path, stat)
const isDirectory = stat.isDirectory()
return {
...stat,
isDirectoryValue: isDirectory
}
}
async exists(path: string): Promise<boolean> {

@ -50,6 +50,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
setPlugin(plugin, dispatch)
const workspaceProvider = filePanelPlugin.fileProviders.workspace
const localhostProvider = filePanelPlugin.fileProviders.localhost
const electrOnProvider = filePanelPlugin.fileProviders.browser
const params = queryParams.get() as UrlParametersType
const workspaces = await getWorkspaces() || []
dispatch(setWorkspaces(workspaces))
@ -112,10 +113,11 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
await basicWorkspaceInit(workspaces, workspaceProvider)
}
} else await basicWorkspaceInit(workspaces, workspaceProvider)
} else if (isElectron() && false) {
plugin.call('notification', 'toast', `connecting to localhost...`)
await basicWorkspaceInit(workspaces, workspaceProvider)
await plugin.call('manager', 'activatePlugin', 'remixd')
} else if (isElectron()) {
plugin.call('notification', 'toast', `connecting to electron...`)
plugin.setWorkspace({ name: 'electron', isLocalhost: false })
dispatch(setCurrentWorkspace({ name: 'electron', isGitRepo: false }))
} else if (localStorage.getItem("currentWorkspace")) {
const index = workspaces.findIndex(element => element.name == localStorage.getItem("currentWorkspace"))
if (index !== -1) {
@ -134,7 +136,13 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
listenOnPluginEvents(plugin)
listenOnProviderEvents(workspaceProvider)(dispatch)
listenOnProviderEvents(localhostProvider)(dispatch)
listenOnProviderEvents(electrOnProvider)(dispatch)
if(isElectron()){
dispatch(setMode('browser'))
}else{
dispatch(setMode('browser'))
}
plugin.setWorkspaces(await getWorkspaces())
dispatch(fsInitializationCompleted())
plugin.emit('workspaceInitializationCompleted')

@ -22,6 +22,7 @@ declare global {
const LOCALHOST = ' - connect to localhost - '
const NO_WORKSPACE = ' - none - '
const ELECTRON = 'electron'
const queryParams = new QueryParams()
const _paq = window._paq = window._paq || [] //eslint-disable-line
let plugin, dispatch: React.Dispatch<any>
@ -267,12 +268,14 @@ export const workspaceExists = async (name: string) => {
}
export const fetchWorkspaceDirectory = async (path: string) => {
if (!path) return
const provider = plugin.fileManager.currentFileProvider()
console.log('fetchWorkspaceDirectory', path, provider)
const promise = new Promise((resolve) => {
provider.resolveDirectory(path, (error, fileTree) => {
if (error) console.error(error)
console.log('fetchWorkspaceDirectory', fileTree)
resolve(fileTree)
})
})
@ -341,6 +344,12 @@ export const switchToWorkspace = async (name: string) => {
// if there is no other workspace, create remix default workspace
plugin.call('notification', 'toast', `No workspace found! Creating default workspace ....`)
await createWorkspace('default_workspace', 'remixDefault')
} else if(name === ELECTRON) {
await plugin.fileProviders.workspace.setWorkspace(name)
await plugin.setWorkspace({ name, isLocalhost: false })
dispatch(setMode('browser'))
dispatch(setCurrentWorkspace({ name, isGitRepo:false }))
} else {
const isActive = await plugin.call('manager', 'isActive', 'remixd')

@ -720,7 +720,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
case 'SET_GIT_CONFIG' : {
case 'SET_GIT_CONFIG': {
const payload: { username: string, token: string, email: string } = action.payload
return {
...state,
@ -728,7 +728,6 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
default:
throw new Error()
}
@ -849,7 +848,6 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s
const fetchWorkspaceDirectoryContent = (state: BrowserState, payload: { fileTree, path: string }): { [x: string]: Record<string, FileType> } => {
const files = normalize(payload.fileTree, ROOT_PATH)
return { [ROOT_PATH]: files }
}

@ -20,6 +20,7 @@ const canUpload = window.File || window.FileReader || window.FileList || window.
export function Workspace () {
const LOCALHOST = ' - connect to localhost - '
const NO_WORKSPACE = ' - none - '
const ELECTRON = 'electron'
const [currentWorkspace, setCurrentWorkspace] = useState<string>(NO_WORKSPACE)
const [selectedWorkspace, setSelectedWorkspace] = useState<{ name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }>(null)
const [showDropdown, setShowDropdown] = useState<boolean>(false)
@ -743,6 +744,7 @@ export function Workspace () {
}
</Dropdown.Item>
<Dropdown.Item onClick={() => { switchWorkspace(LOCALHOST) }}>{currentWorkspace === LOCALHOST ? <span>&#10003; localhost </span> : <span className="pl-3"> { LOCALHOST } </span>}</Dropdown.Item>
<Dropdown.Item onClick={() => { switchWorkspace(ELECTRON) }}>{currentWorkspace === ELECTRON ? <span>&#10003; electron </span> : <span className="pl-3"> { ELECTRON } </span>}</Dropdown.Item>
{
global.fs.browser.workspaces.map(({ name, isGitRepo }, index) => (
<Dropdown.Item

@ -134,15 +134,15 @@
"@openzeppelin/contracts": "^4.7.3",
"@openzeppelin/upgrades-core": "^1.22.0",
"@openzeppelin/wizard": "0.2.0",
"@remixproject/engine": "0.3.34",
"@remixproject/engine-web": "0.3.34",
"@remixproject/engine-electron":" 0.3.34",
"@remixproject/plugin": "0.3.34",
"@remixproject/plugin-api": "0.3.34",
"@remixproject/plugin-utils": "0.3.34",
"@remixproject/plugin-webview": "0.3.34",
"@remixproject/plugin-electron": "0.3.34",
"@remixproject/plugin-ws": "0.3.34",
"@remixproject/engine": "0.3.35",
"@remixproject/engine-electron": " 0.3.35",
"@remixproject/engine-web": "0.3.35",
"@remixproject/plugin": "0.3.35",
"@remixproject/plugin-api": "0.3.35",
"@remixproject/plugin-electron": "0.3.35",
"@remixproject/plugin-utils": "0.3.35",
"@remixproject/plugin-webview": "0.3.35",
"@remixproject/plugin-ws": "0.3.35",
"@types/nightwatch": "^2.3.1",
"@walletconnect/ethereum-provider": "^2.6.2",
"@walletconnect/sign-client": "^2.6.0",

@ -5131,81 +5131,82 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
"@remixproject/engine-electron@ 0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/engine-electron/-/engine-electron-0.3.34.tgz#072575ec61b73ff533c6b72952b2b72c983b00bf"
integrity sha512-8eyKitn8D7PMkfArumaZb6r5Qw59Q3viDEpxv97uBLd8bi2bNIpBY8nT5JGXhZiVDIzNxdANq3rRUhVfkT081Q==
dependencies:
"@remixproject/engine" "0.3.34"
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/engine-web@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/engine-web/-/engine-web-0.3.34.tgz#9ecffec8839dcbdcc03ba22ee8b7b2999740b060"
integrity sha512-a3MxCVHU5szgdnA2XnZ8ve4Fl/qYGy7krv9lM5QygKpPYkA1L+rRWZ1eB29fzLXh/27k0XBUdlbIngah+Fd5Zg==
dependencies:
"@remixproject/engine" "0.3.34"
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/engine@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/engine/-/engine-0.3.34.tgz#100517dc3dc2e0c728be6f8b0a3f41f462ece5ed"
integrity sha512-eWesiIQpXR9clm/NG95SY+2gyvoZICBZO1eO30MQM6wF2/iPJz2W0H+UTN2pA6952CiG6xutR/AgORKXKWkkwQ==
dependencies:
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/plugin-api@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.34.tgz#8c556d7317e797738a26a65c50b9f310a0c9f739"
integrity sha512-4dwjSgeHbMbyCnRd6++GtaHrPFd21birhRWM4e3cJj7AG/8KjykiVYfXi/0aeDJr1QDviEyv4A15a3SyV7rCFg==
dependencies:
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/plugin-electron@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-electron/-/plugin-electron-0.3.34.tgz#6a360171f2be1b16b2f01247bef81fc1197279a3"
integrity sha512-fMJijx2V84WyL6XK8zw0aVNE4ejxYK5MQsfiGggu8gx5XMyHFAk5QGZUCX+msJ0mPQf5W2UyHWnrsefLp3UYXA==
dependencies:
"@remixproject/plugin" "0.3.34"
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/plugin-utils@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.34.tgz#a8366b3ebee491e23861592d69f4ad34feba6b6c"
integrity sha512-TYpiDXZ1uHeYMLe0+P6xAp8F+cfPFnEfUFHgAUbdvDNGLk0H6TxYoK/vJXYpvqcKaVdOyZi9tVc8bQSwq/xu0w==
"@remixproject/engine-electron@ 0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/engine-electron/-/engine-electron-0.3.35.tgz#6c5bf507e7719f9767b837c48f07f29f4bbc5ff5"
integrity sha512-JPKzQ/Bn7QZDQzGceyZI23pZ4jhECf26Ajy/+my38zZWygoUms0J743yD4Z8ClrnXTUa7cXejOMJkwKcMDJ6kQ==
dependencies:
"@remixproject/engine" "0.3.35"
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
"@remixproject/engine-web@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/engine-web/-/engine-web-0.3.35.tgz#34a017fa8675164a762dc8bcec9a2c7f8410f950"
integrity sha512-d0fBA/FjFdMY9FCp2sEs/sL7kSo29IsFY02mM4HA4byjGdXmOtFquNI/bg32IX3aDWgsnTZhgbI1LQLU0vnxwg==
dependencies:
"@remixproject/engine" "0.3.35"
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
"@remixproject/engine@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/engine/-/engine-0.3.35.tgz#4bbb21a7ce6ecdbd021fd231ba3daefbbedb2d6d"
integrity sha512-lK1h7njE/dGLnBayE5X/zcnkjOeAu+UvDkE9PBRCdIte21M6UqmzClslCL1FjHP7j5hrr769OziQqvGajk4nFQ==
dependencies:
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
"@remixproject/plugin-api@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.35.tgz#1f47eda88bb49c14b29614549f9f42387afba054"
integrity sha512-lleQQ4B3QMtnjWflJHmLZYQ19jR/vGDT6ULskbj90qjss/xPp4NGqv18DnH5m8ycI2sTxcCdx9GEljFNieY3Bg==
dependencies:
"@remixproject/plugin-utils" "0.3.35"
"@remixproject/plugin-electron@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-electron/-/plugin-electron-0.3.35.tgz#64646f8deafb6ec816d6bf156a610d8d1c8b8276"
integrity sha512-fdRm4StVdkuZj0nvRk9KxqC1jcwZ4ytjKbdPRpZMXl2rrImvxMt4VDTkz9MHTYufDF6CDprMfHN3zLlFKuelBA==
dependencies:
"@remixproject/engine" "0.3.35"
"@remixproject/plugin" "0.3.35"
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
"@remixproject/plugin-utils@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.35.tgz#7d3b561c1bddea1c1c0bd74970b91052c1a42e5b"
integrity sha512-+QCbOp45+bn5ou6CLmTqDQ2AGsCiQIEXQlg3ULZNWKeo+8yvMXOHWJeLYRPV8TsSJQ6G1t3FeIVg4ZUGEPTFsw==
dependencies:
tslib "2.0.1"
"@remixproject/plugin-webview@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-webview/-/plugin-webview-0.3.34.tgz#c410e22ad5d059ec5efc5d82aa2c95079426240c"
integrity sha512-YxpiA26ngKSUHLwgIEeiGKGbM2KEqzBVOtXagaQ06CkfA+EoeQ+BBLUQS/e3ant6dpA4EhmpcZPNgp0j6VPOXA==
"@remixproject/plugin-webview@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-webview/-/plugin-webview-0.3.35.tgz#d602f954d93dd3cbef8c41e43aa6c0e6da79b293"
integrity sha512-Ch2KjufmMjq+3Ynj7NkPP4lvlxxHmE4TY2k3bII+nn2dEa0ts0/aNCp5fCzMEVMivNzVpZIQBPEMzJhSv+ULcA==
dependencies:
"@remixproject/plugin" "0.3.34"
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/plugin" "0.3.35"
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
axios "^0.21.1"
"@remixproject/plugin-ws@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-ws/-/plugin-ws-0.3.34.tgz#a2a1c78407e1aeb7809758e8ac13120703aa4ea8"
integrity sha512-oj7RYhjfigZPhuxlgQRMmIuWD8bV7p9muYu4KWsp4WaqZqUS7Q4J5RlyHvO0H8vYImnwI1hqI5OlDUh376Nc1A==
"@remixproject/plugin-ws@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/plugin-ws/-/plugin-ws-0.3.35.tgz#16a3f6673bb37288db531dcd063af59fefb01229"
integrity sha512-4sZnd2Fme3T+Ohr0+I4hJlHtZVF0oG2srGds80Cp0MiYmz9pJ3l2lhSe4Dl7Np14nfYrqxiwRGf6s4q2PQx6Ug==
dependencies:
"@remixproject/plugin" "0.3.34"
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/plugin" "0.3.35"
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
"@remixproject/plugin@0.3.34":
version "0.3.34"
resolved "https://registry.yarnpkg.com/@remixproject/plugin/-/plugin-0.3.34.tgz#936d0385acc221c4ce1b54558a7578ac8a0d9692"
integrity sha512-YdOE3K8LKr6EWcmbTBReazNU+r256Y1bWj9bCPn4qJeN6QpEQPeoa1JtDUU8DJBKtvf3OXXcKrbOMTa4/f6XGQ==
"@remixproject/plugin@0.3.35":
version "0.3.35"
resolved "https://registry.yarnpkg.com/@remixproject/plugin/-/plugin-0.3.35.tgz#6e4a8f2d400f70ae5351a9b560d3855f461389b4"
integrity sha512-GGLyAv8sV0X0QhcF7ZqSfS0Fb+xhaFsWzhRZPeVs54d4a6ddOjCrR7A/vyIPGNS2vU4YSVbi8tk1Q1RuVBLAgQ==
dependencies:
"@remixproject/plugin-api" "0.3.34"
"@remixproject/plugin-utils" "0.3.34"
"@remixproject/plugin-api" "0.3.35"
"@remixproject/plugin-utils" "0.3.35"
events "3.2.0"
"@restart/context@^2.1.4":

Loading…
Cancel
Save