From 34abe45ebc6a674e882dec99324da38f021bc023 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Wed, 7 Jun 2023 11:54:41 +0200 Subject: [PATCH] fs integration --- apps/remix-ide/src/app.js | 20 +-- apps/remix-ide/src/app/files/fileManager.ts | 5 +- apps/remix-ide/src/app/files/fileProvider.js | 3 +- apps/remix-ide/src/app/plugins/fsPlugin.ts | 71 +++++++++- apps/remixdesktop/src/fsPlugin.ts | 13 +- .../workspace/src/lib/actions/index.ts | 18 ++- .../workspace/src/lib/actions/workspace.ts | 11 +- .../workspace/src/lib/reducers/workspace.ts | 4 +- .../workspace/src/lib/remix-ui-workspace.tsx | 2 + package.json | 18 +-- yarn.lock | 133 +++++++++--------- 11 files changed, 196 insertions(+), 102 deletions(-) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 72b2432c10..7bd5a2be04 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -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']) - await this.appManager.activatePlugin(['fs']) + + 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 diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index db42bc3335..63c1a8d009 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -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 diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index 9b7e63efdf..e78f68cf14 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -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) { diff --git a/apps/remix-ide/src/app/plugins/fsPlugin.ts b/apps/remix-ide/src/app/plugins/fsPlugin.ts index 3f28d02a44..fb1b1549e9 100644 --- a/apps/remix-ide/src/app/plugins/fsPlugin.ts +++ b/apps/remix-ide/src/app/plugins/fsPlugin.ts @@ -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 - constructor(){ + return path +} + +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 } } \ No newline at end of file diff --git a/apps/remixdesktop/src/fsPlugin.ts b/apps/remixdesktop/src/fsPlugin.ts index c039ac64f8..363d506711 100644 --- a/apps/remixdesktop/src/fsPlugin.ts +++ b/apps/remixdesktop/src/fsPlugin.ts @@ -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 { - // 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 { - return fs.stat(path) + async stat(path: string): Promise { + const stat = await fs.stat(path) + //console.log('stat', path, stat) + const isDirectory = stat.isDirectory() + return { + ...stat, + isDirectoryValue: isDirectory + } } async exists(path: string): Promise { diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 2122510714..1c609b153f 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -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) - dispatch(setMode('browser')) + listenOnProviderEvents(electrOnProvider)(dispatch) + if(isElectron()){ + dispatch(setMode('browser')) + }else{ + dispatch(setMode('browser')) + } + plugin.setWorkspaces(await getWorkspaces()) dispatch(fsInitializationCompleted()) plugin.emit('workspaceInitializationCompleted') diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 0e23965cdb..b40fcc6101 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -21,6 +21,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 @@ -266,12 +267,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) }) }) @@ -340,6 +343,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') diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index cceec06c7f..760354b54e 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -720,14 +720,13 @@ 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, gitConfig: payload } } - 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 } => { const files = normalize(payload.fileTree, ROOT_PATH) - return { [ROOT_PATH]: files } } diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index de26194620..5c99926a39 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -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(NO_WORKSPACE) const [selectedWorkspace, setSelectedWorkspace] = useState<{ name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }>(null) const [showDropdown, setShowDropdown] = useState(false) @@ -757,6 +758,7 @@ export function Workspace () { } { switchWorkspace(LOCALHOST) }}>{currentWorkspace === LOCALHOST ? ✓ localhost : { LOCALHOST } } + { switchWorkspace(ELECTRON) }}>{currentWorkspace === ELECTRON ? ✓ electron : { ELECTRON } } { global.fs.browser.workspaces.map(({ name, isGitRepo }, index) => (