From ed662197db6fd5c9cdc8ccaaf755f5ba906e0c19 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Fri, 3 May 2024 06:48:02 -0500 Subject: [PATCH] Load initialState for udapp after pinning --- apps/remix-ide/src/app.js | 8 ++++-- .../src/app/components/pinned-panel.tsx | 9 ++++--- .../src/app/components/side-panel.tsx | 19 +++++++++----- apps/remix-ide/src/app/tabs/state-logger.js | 26 +++++++++++++++++++ .../panel/src/lib/plugins/panel-header.tsx | 1 - .../panel/src/lib/plugins/panel-plugin.tsx | 18 +++++++++++-- .../panel/src/lib/plugins/remix-ui-panel.tsx | 7 ++--- libs/remix-ui/run-tab/src/lib/run-tab.tsx | 15 +++++++---- libs/remix-ui/run-tab/src/lib/types/index.ts | 3 ++- 9 files changed, 83 insertions(+), 23 deletions(-) create mode 100644 apps/remix-ide/src/app/tabs/state-logger.js diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index ed8f148b95..98d9269342 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -7,6 +7,7 @@ import {LocaleModule} from './app/tabs/locale-module' import {NetworkModule} from './app/tabs/network-module' import {Web3ProviderModule} from './app/tabs/web3-provider' import {CompileAndRun} from './app/tabs/compile-and-run' +import {PluginStateLogger} from './app/tabs/state-logger' import {SidePanel} from './app/components/side-panel' import {HiddenPanel} from './app/components/hidden-panel' import {PinnedPanel} from './app/components/pinned-panel' @@ -301,7 +302,8 @@ class AppComponent { this.layout = new Layout() const permissionHandler = new PermissionHandlerPlugin() - + // ----------------- run script after each compilation results ----------- + const pluginStateLogger = new PluginStateLogger() this.engine.register([ permissionHandler, @@ -352,6 +354,7 @@ class AppComponent { templates, openaigpt, solcoder, + pluginStateLogger ]) //---- fs plugin @@ -468,7 +471,8 @@ class AppComponent { 'compilerArtefacts', 'network', 'web3Provider', - 'offsetToLineColumnConverter' + 'offsetToLineColumnConverter', + 'pluginStateLogger' ]) await this.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs']) await this.appManager.activatePlugin(['sidePanel']) // activating host plugin separately diff --git a/apps/remix-ide/src/app/components/pinned-panel.tsx b/apps/remix-ide/src/app/components/pinned-panel.tsx index 70b39672a0..f435e03f69 100644 --- a/apps/remix-ide/src/app/components/pinned-panel.tsx +++ b/apps/remix-ide/src/app/components/pinned-panel.tsx @@ -17,6 +17,7 @@ const pinnedPanel = { export class PinnedPanel extends AbstractPanel { sideelement: any dispatch: React.Dispatch = () => {} + loggedState: any constructor() { super(pinnedPanel) @@ -26,11 +27,12 @@ export class PinnedPanel extends AbstractPanel { this.renderComponent() } - pinView (profile, view) { + async pinView (profile, view) { const activePlugin = this.currentFocus() if (activePlugin === profile.name) throw new Error(`Plugin ${profile.name} already pinned`) if (activePlugin) this.remove(activePlugin) + this.loggedState = await this.call('pluginStateLogger', 'getPluginState', profile.name) this.addView(profile, view) this.plugins[profile.name].pinned = true this.plugins[profile.name].active = true @@ -59,12 +61,13 @@ export class PinnedPanel extends AbstractPanel { } updateComponent(state: any) { - return } plugins={state.plugins} /> + return } plugins={state.plugins} pluginState={state.pluginState} /> } renderComponent() { this.dispatch({ - plugins: this.plugins + plugins: this.plugins, + pluginState: this.loggedState }) } } diff --git a/apps/remix-ide/src/app/components/side-panel.tsx b/apps/remix-ide/src/app/components/side-panel.tsx index 3e32827183..9861b8f35c 100644 --- a/apps/remix-ide/src/app/components/side-panel.tsx +++ b/apps/remix-ide/src/app/components/side-panel.tsx @@ -18,7 +18,9 @@ const sidePanel = { export class SidePanel extends AbstractPanel { // lastPinned sideelement: any + loggedState: any dispatch: React.Dispatch = () => {} + constructor() { super(sidePanel) this.sideelement = document.createElement('section') @@ -65,7 +67,6 @@ export class SidePanel extends AbstractPanel { } addView(profile, view) { - console.log(profile.name) super.addView(profile, view) this.call('menuicons', 'linkContent', profile) this.renderComponent() @@ -79,15 +80,20 @@ export class SidePanel extends AbstractPanel { } showView(profile) { + const activePlugin = this.currentFocus() + + this.plugins[activePlugin].active = false + this.plugins[profile.name].active = true this.call('menuicons', 'linkContent', profile) this.renderComponent() } - pinView (profile, view) { + pinView (profile) { if (this.plugins[profile.name].pinned) return this.plugins[profile.name].pinned = true - this.call('pinnedPanel', 'pinView', profile, view) - this.hideView(profile) + this.call('pinnedPanel', 'pinView', profile, this.plugins[profile.name].view) + this.removeView(profile) + // this.hideView(profile) } unPinView (profile) { @@ -120,12 +126,13 @@ export class SidePanel extends AbstractPanel { } updateComponent(state: any) { - return } plugins={state.plugins} /> + return } plugins={state.plugins} pluginState={state.loggedState} /> } renderComponent() { this.dispatch({ - plugins: this.plugins + plugins: this.plugins, + pluginState: this.loggedState }) } } diff --git a/apps/remix-ide/src/app/tabs/state-logger.js b/apps/remix-ide/src/app/tabs/state-logger.js new file mode 100644 index 0000000000..fa5d371dfb --- /dev/null +++ b/apps/remix-ide/src/app/tabs/state-logger.js @@ -0,0 +1,26 @@ +import { Plugin } from "@remixproject/engine" +import { EventEmitter } from 'events' +import * as packageJson from '../../../../../package.json' + +const profile = { + name: 'pluginStateLogger', + events: [], + methods: ['logPluginState', 'getPluginState'], + version: packageJson.version, +} + +export class PluginStateLogger extends Plugin { + constructor() { + super(profile) + this.events = new EventEmitter() + this.stateLogs = {} + } + + logPluginState(name, state) { + this.stateLogs[name] = state + } + + getPluginState(name) { + return this.stateLogs[name] + } +} \ No newline at end of file diff --git a/libs/remix-ui/panel/src/lib/plugins/panel-header.tsx b/libs/remix-ui/panel/src/lib/plugins/panel-header.tsx index cf5c63003f..687d2cfd50 100644 --- a/libs/remix-ui/panel/src/lib/plugins/panel-header.tsx +++ b/libs/remix-ui/panel/src/lib/plugins/panel-header.tsx @@ -28,7 +28,6 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => { } const pinPlugin = () => { - console.log('called pinPlugin') props.pinView && props.pinView(plugin.profile, plugin.view) } diff --git a/libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx b/libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx index 2c9d3d71ee..fa6760dc08 100644 --- a/libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx +++ b/libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx @@ -3,7 +3,9 @@ import React, {forwardRef, useEffect, useRef, useState} from 'react' // eslint-d import { PluginRecord } from '../types' import './panel.css' interface panelPLuginProps { - pluginRecord: PluginRecord + pluginRecord: PluginRecord, + initialState?: any, + children?: any } const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => { @@ -14,7 +16,19 @@ const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => { if (ref.current) { if (props.pluginRecord.view) { if (React.isValidElement(props.pluginRecord.view)) { - setView(props.pluginRecord.view) + let view = props.pluginRecord.view + + if (props.initialState) { + view = React.Children.map((props.pluginRecord.view.props as any).children, child => { + if (React.isValidElement(child) && typeof child.type === 'function') { + // Safe to clone and pass `initialState` + return React.cloneElement(child, { ...props, initialState: props.initialState } as any) + } + return child + }) + } + + setView(view) } else { ref.current.appendChild(props.pluginRecord.view) } diff --git a/libs/remix-ui/panel/src/lib/plugins/remix-ui-panel.tsx b/libs/remix-ui/panel/src/lib/plugins/remix-ui-panel.tsx index 1b3d668a35..7ff51827bd 100644 --- a/libs/remix-ui/panel/src/lib/plugins/remix-ui-panel.tsx +++ b/libs/remix-ui/panel/src/lib/plugins/remix-ui-panel.tsx @@ -6,8 +6,9 @@ import { PluginRecord } from '../types' /* eslint-disable-next-line */ export interface RemixPanelProps { - plugins: Record - header: JSX.Element + plugins: Record, + header: JSX.Element, + pluginState?: any, } export function RemixPluginPanel(props: RemixPanelProps) { @@ -17,7 +18,7 @@ export function RemixPluginPanel(props: RemixPanelProps) {
{Object.values(props.plugins).map((pluginRecord) => { - return + return })}
diff --git a/libs/remix-ui/run-tab/src/lib/run-tab.tsx b/libs/remix-ui/run-tab/src/lib/run-tab.tsx index 3e3985a772..15c9be5bb6 100644 --- a/libs/remix-ui/run-tab/src/lib/run-tab.tsx +++ b/libs/remix-ui/run-tab/src/lib/run-tab.tsx @@ -74,18 +74,23 @@ export function RunTabUI(props: RunTabProps) { storage: null, contract: null }) - runTabInitialState.selectExEnv = plugin.blockchain.getProvider() - const [runTab, dispatch] = useReducer(runTabReducer, runTabInitialState) - const REACT_API = { runTab } + const initialState = props.initialState || runTabInitialState + + initialState.selectExEnv = plugin.blockchain.getProvider() + const [runTab, dispatch] = useReducer(runTabReducer, initialState) + const REACT_API = {runTab} const currentfile = plugin.config.get('currentFile') useEffect(() => { - initRunTab(plugin)(dispatch) - plugin.onInitDone() + if (!props.initialState) { + initRunTab(plugin)(dispatch) + plugin.onInitDone() + } }, [plugin]) useEffect(() => { plugin.onReady(runTab) + plugin.call('pluginStateLogger', 'logPluginState', 'udapp', runTab) }, [REACT_API]) useEffect(() => { diff --git a/libs/remix-ui/run-tab/src/lib/types/index.ts b/libs/remix-ui/run-tab/src/lib/types/index.ts index 6e19d45b3a..7e4ae84533 100644 --- a/libs/remix-ui/run-tab/src/lib/types/index.ts +++ b/libs/remix-ui/run-tab/src/lib/types/index.ts @@ -5,7 +5,8 @@ import { RunTab } from './run-tab' import { SolcInput, SolcOutput } from '@openzeppelin/upgrades-core' import { LayoutCompatibilityReport } from '@openzeppelin/upgrades-core/dist/storage/report' export interface RunTabProps { - plugin: RunTab + plugin: RunTab, + initialState: RunTabState } export interface Contract {