diff --git a/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts b/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts index e84ab52367..56616f1ac9 100644 --- a/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts +++ b/apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts @@ -12,6 +12,7 @@ class GoToVmTraceStep extends EventEmitter { function goToVMtraceStep (browser: NightwatchBrowser, step: number, incr: number, done: VoidFunction) { browser.execute(function (step) { (document.getElementById('slider') as HTMLInputElement).value = (step - 1).toString() }, [step]) .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .pause(1000) .perform(() => { done() }) diff --git a/apps/remix-ide-e2e/src/tests/debugger.test.ts b/apps/remix-ide-e2e/src/tests/debugger.test.ts index cd3fafc3b3..56a1174521 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.test.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.test.ts @@ -39,12 +39,9 @@ module.exports = { 'Should debug transaction using slider #group1': function (browser: NightwatchBrowser) { browser.waitForElementVisible('*[data-id="verticalIconsKindudapp"]') .waitForElementVisible('*[data-id="slider"]') - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '50' }) // It only moves slider to 50 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) - .pause(2000) - .click('*[data-id="dropdownPanelSolidityLocals"]') - .waitForElementContainsText('*[data-id="solidityLocals"]', 'no locals', 60000) + .goToVMTraceStep(51) + .waitForElementContainsText('*[data-id="solidityLocals"]', 'toast', 60000) + .waitForElementContainsText('*[data-id="solidityLocals"]', '999', 60000) .waitForElementContainsText('*[data-id="stepdetail"]', 'vm trace step:\n51', 60000) }, @@ -159,10 +156,7 @@ module.exports = { .pause(2000) .debugTransaction(0) .waitForElementVisible('*[data-id="slider"]').pause(2000) - // .setValue('*[data-id="slider"]', '5000') // Like this, setValue doesn't work properly for input type = range - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '7450' }).pause(10000) // It only moves slider to 7450 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(3).fill(browser.Keys.RIGHT_ARROW)) // This will press NEXT 3 times and will update the trace details + .goToVMTraceStep(7453) .waitForElementPresent('*[data-id="treeViewDivtreeViewItemarray"]') .click('*[data-id="treeViewDivtreeViewItemarray"]') .waitForElementPresent('*[data-id="treeViewDivtreeViewLoadMore"]') @@ -210,15 +204,7 @@ module.exports = { .pause(3000) .clickLaunchIcon('debugger') .waitForElementVisible('*[data-id="slider"]') - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '153' }) // It only moves slider to 153 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) - .pause(1000) - /* - setting the slider to 5 leads to "vm trace step: 91" for chrome and "vm trace step: 92" for firefox - => There is something going wrong with the nightwatch API here. - As we are only testing if debugger is active, this is ok to keep that for now. - */ + .goToVMTraceStep(154) .waitForElementContainsText('*[data-id="stepdetail"]', 'vm trace step:\n154', 60000) }, @@ -241,8 +227,23 @@ module.exports = { .waitForElementVisible('*[data-id="solidityLocals"]', 60000) .pause(10000) .checkVariableDebug('soliditylocals', { num: { value: '2', type: 'uint256' } }) - .checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false, immutable: false } }) - .end() + .checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false, immutable: false } }) + }, + + 'Should debug reverted transactions #group5': function (browser: NightwatchBrowser) { + browser + .testContracts('reverted.sol', sources[6]['reverted.sol'], ['A', 'B', 'C']) + .clickLaunchIcon('udapp') + .selectContract('A') + .createContract('') + .pause(500) + .clickInstance(0) + .clickFunction('callA - transact (not payable)') + .debugTransaction(1) + .goToVMTraceStep(79) + .waitForElementVisible('*[data-id="debugGoToRevert"]', 60000) + .click('*[data-id="debugGoToRevert"]') + .waitForElementContainsText('*[data-id="asmitems"] div[selected="selected"]', '117 REVERT') } } @@ -366,6 +367,46 @@ const sources = [ } ` } + }, + { + 'reverted.sol': { + content: `contract A { + B b; + uint p; + constructor () { + b = new B(); + } + function callA() public { + p = 123; + try b.callB() { + + } + catch (bytes memory reason) { + + } + } + } + + contract B { + C c; + uint p; + constructor () { + c = new C(); + } + function callB() public { + p = 124; + revert("revert!"); + c.callC(); + } + } + + contract C { + uint p; + function callC() public { + p = 125; + } + }` + } } ] diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index 30d1a2c83c..bc1bb12cd7 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -283,9 +283,7 @@ module.exports = { .waitForElementVisible('*[data-id="dropdownPanelSolidityLocals"]').pause(1000) .click('*[data-id="dropdownPanelSolidityLocals"]') .waitForElementContainsText('*[data-id="solidityLocals"]', 'no locals', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '315' }) // It only moves slider to 315 but vm traces are not updated - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(316) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalFailed()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'vote(proposal)', 60000) .pause(5000) @@ -295,9 +293,7 @@ module.exports = { .scrollAndClick('#Check_winning_proposal_passed') .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '1450' }) - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(1451) .waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000) // remix_test.sol should be opened in editor @@ -307,9 +303,7 @@ module.exports = { .scrollAndClick('#Check_winning_proposal_again') .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '1150' }) - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(1151) .waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000) .pause(5000) @@ -317,9 +311,7 @@ module.exports = { .scrollAndClick('#Check_winnin_proposal_with_return_value').pause(5000) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinninProposalWithReturnValue()', 60000) - // eslint-disable-next-line dot-notation - .execute(function () { document.getElementById('slider')['value'] = '320' }) - .setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW)) + .goToVMTraceStep(321) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinninProposalWithReturnValue()', 60000) .clickLaunchIcon('filePanel') .pause(2000) diff --git a/apps/remix-ide/src/app/components/hidden-panel.tsx b/apps/remix-ide/src/app/components/hidden-panel.tsx index bfdff5a11a..31c7a0cb0b 100644 --- a/apps/remix-ide/src/app/components/hidden-panel.tsx +++ b/apps/remix-ide/src/app/components/hidden-panel.tsx @@ -1,9 +1,9 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import ReactDOM from 'react-dom' // eslint-disable-line import { AbstractPanel } from './panel' import * as packageJson from '../../../../../package.json' import { RemixPluginPanel } from '@remix-ui/panel' +import { PluginViewWrapper } from '@remix-ui/helper' const profile = { name: 'hiddenPanel', @@ -15,6 +15,7 @@ const profile = { export class HiddenPanel extends AbstractPanel { el: HTMLElement + dispatch: React.Dispatch = () => {} constructor () { super(profile) this.el = document.createElement('div') @@ -27,11 +28,23 @@ export class HiddenPanel extends AbstractPanel { this.renderComponent() } - render () { - return this.el + updateComponent (state: any) { + return } plugins={state.plugins}/> + } + + setDispatch (dispatch: React.Dispatch) { + this.dispatch = dispatch + } + + render() { + return ( +
+ ); } renderComponent () { - ReactDOM.render(} plugins={this.plugins}/>, this.el) + this.dispatch({ + plugins: this.plugins, + }) } } diff --git a/apps/remix-ide/src/app/components/main-panel.tsx b/apps/remix-ide/src/app/components/main-panel.tsx index b9d180f194..615e03690d 100644 --- a/apps/remix-ide/src/app/components/main-panel.tsx +++ b/apps/remix-ide/src/app/components/main-panel.tsx @@ -1,8 +1,8 @@ import React from 'react' // eslint-disable-line import { AbstractPanel } from './panel' -import ReactDOM from 'react-dom' // eslint-disable-line import { RemixPluginPanel } from '@remix-ui/panel' import packageJson from '../../../../../package.json' +import { PluginViewWrapper } from '@remix-ui/helper' const profile = { name: 'mainPanel', @@ -14,6 +14,7 @@ const profile = { export class MainPanel extends AbstractPanel { element: HTMLDivElement + dispatch: React.Dispatch = () => {} constructor (config) { super(profile) this.element = document.createElement('div') @@ -22,6 +23,10 @@ export class MainPanel extends AbstractPanel { // this.config = config } + setDispatch (dispatch: React.Dispatch) { + this.dispatch = dispatch + } + onActivation () { this.renderComponent() } @@ -47,11 +52,17 @@ export class MainPanel extends AbstractPanel { this.renderComponent() } - render () { - return this.element + renderComponent () { + this.dispatch({ + plugins: this.plugins + }) + } + + render() { + return
} - renderComponent () { - ReactDOM.render(} plugins={this.plugins}/>, this.element) + updateComponent (state: any) { + return } plugins={state.plugins}/> } } diff --git a/apps/remix-ide/src/app/components/plugin-manager-component.js b/apps/remix-ide/src/app/components/plugin-manager-component.js index 72acd7cbf6..00013ee545 100644 --- a/apps/remix-ide/src/app/components/plugin-manager-component.js +++ b/apps/remix-ide/src/app/components/plugin-manager-component.js @@ -1,8 +1,8 @@ import { ViewPlugin } from '@remixproject/engine-web' import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import {RemixUiPluginManager} from '@remix-ui/plugin-manager' // eslint-disable-line import * as packageJson from '../../../../../package.json' +import { PluginViewWrapper } from '@remix-ui/helper' const _paq = window._paq = window._paq || [] const profile = { @@ -31,6 +31,7 @@ class PluginManagerComponent extends ViewPlugin { this.inactivePlugins = [] this.activeProfiles = this.appManager.actives this._paq = _paq + this.dispatch = null this.listenOnEvent() } @@ -40,7 +41,7 @@ class PluginManagerComponent extends ViewPlugin { * RemixAppManager * @param {string} name name of Plugin */ - isActive (name) { + isActive = (name) =>{ return this.appManager.actives.includes(name) } @@ -49,7 +50,7 @@ class PluginManagerComponent extends ViewPlugin { * RemixAppManager to enable plugin activation * @param {string} name name of Plugin */ - activateP (name) { + activateP = (name) => { this.appManager.activatePlugin(name) _paq.push(['trackEvent', 'manager', 'activate', name]) } @@ -60,7 +61,7 @@ class PluginManagerComponent extends ViewPlugin { * @param {Profile} pluginName * @returns {void} */ - async activateAndRegisterLocalPlugin (localPlugin) { + activateAndRegisterLocalPlugin = async (localPlugin) => { if (localPlugin) { this.engine.register(localPlugin) this.appManager.activatePlugin(localPlugin.profile.name) @@ -75,28 +76,33 @@ class PluginManagerComponent extends ViewPlugin { * of the plugin * @param {string} name name of Plugin */ - deactivateP (name) { + deactivateP = (name) => { this.call('manager', 'deactivatePlugin', name) _paq.push(['trackEvent', 'manager', 'deactivate', name]) } - onActivation () { + setDispatch (dispatch) { + this.dispatch = dispatch this.renderComponent() } + updateComponent(state){ + return + } + renderComponent () { - ReactDOM.render( - , - this.htmlElement) + if(this.dispatch) this.dispatch({...this, activePlugins: this.activePlugins, inactivePlugins: this.inactivePlugins}) } render () { - return this.htmlElement + return ( +
+ ); + } - getAndFilterPlugins (filter) { + getAndFilterPlugins = (filter) => { this.filter = typeof filter === 'string' ? filter.toLowerCase() : this.filter const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(this.filter) diff --git a/apps/remix-ide/src/app/components/side-panel.tsx b/apps/remix-ide/src/app/components/side-panel.tsx index b5e9dcd3df..bf82defe55 100644 --- a/apps/remix-ide/src/app/components/side-panel.tsx +++ b/apps/remix-ide/src/app/components/side-panel.tsx @@ -1,10 +1,10 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import ReactDOM from 'react-dom' import { AbstractPanel } from './panel' import { RemixPluginPanel } from '@remix-ui/panel' import packageJson from '../../../../../package.json' import RemixUIPanelHeader from 'libs/remix-ui/panel/src/lib/plugins/panel-header' +import { PluginViewWrapper } from '@remix-ui/helper' // const csjs = require('csjs-inject') const sidePanel = { @@ -17,6 +17,7 @@ const sidePanel = { export class SidePanel extends AbstractPanel { sideelement: any + dispatch: React.Dispatch = () => {} constructor() { super(sidePanel) this.sideelement = document.createElement('section') @@ -78,11 +79,23 @@ export class SidePanel extends AbstractPanel { this.renderComponent() } - render() { - return this.sideelement + setDispatch (dispatch: React.Dispatch) { + this.dispatch = dispatch + } + + render() { + return ( +
+ ); + } + + updateComponent(state: any) { + return } plugins={state.plugins} /> } renderComponent() { - ReactDOM.render(} plugins={this.plugins} />, this.sideelement) + this.dispatch({ + plugins: this.plugins + }) } } diff --git a/apps/remix-ide/src/app/components/vertical-icons.tsx b/apps/remix-ide/src/app/components/vertical-icons.tsx index eea114b637..bc70fd812c 100644 --- a/apps/remix-ide/src/app/components/vertical-icons.tsx +++ b/apps/remix-ide/src/app/components/vertical-icons.tsx @@ -1,11 +1,11 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import ReactDOM from 'react-dom' import packageJson from '../../../../../package.json' import { Plugin } from '@remixproject/engine' import { EventEmitter } from 'events' import { IconRecord, RemixUiVerticalIconsPanel } from '@remix-ui/vertical-icons-panel' import { Profile } from '@remixproject/plugin-utils' +import { PluginViewWrapper } from '@remix-ui/helper' const profile = { name: 'menuicons', @@ -20,6 +20,7 @@ export class VerticalIcons extends Plugin { events: EventEmitter htmlElement: HTMLDivElement icons: Record = {} + dispatch: React.Dispatch = () => {} constructor () { super(profile) this.events = new EventEmitter() @@ -46,12 +47,15 @@ export class VerticalIcons extends Plugin { ...divived.filter((value) => { return !value.isRequired }) ] - ReactDOM.render( - , - this.htmlElement) + this.dispatch({ + verticalIconsPlugin: this, + icons: sorted + }) + + } + + setDispatch (dispatch: React.Dispatch) { + this.dispatch = dispatch } onActivation () { @@ -107,7 +111,16 @@ export class VerticalIcons extends Plugin { this.events.emit('toggleContent', name) } - render () { - return this.htmlElement + updateComponent(state: any){ + return + } + + render() { + return ( +
+ ); } } diff --git a/apps/remix-ide/src/app/editor/editor.js b/apps/remix-ide/src/app/editor/editor.js index d15fe531a1..e7887df7e2 100644 --- a/apps/remix-ide/src/app/editor/editor.js +++ b/apps/remix-ide/src/app/editor/editor.js @@ -1,9 +1,9 @@ 'use strict' import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { EditorUI } from '@remix-ui/editor' // eslint-disable-line import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' +import { PluginViewWrapper } from '@remix-ui/helper' const EventManager = require('../../lib/events') @@ -61,10 +61,29 @@ class Editor extends Plugin { // to be implemented by the react component this.api = {} + this.dispatch = null + this.ref = null + } + + setDispatch (dispatch) { + this.dispatch = dispatch + } + + updateComponent(state) { + return } render () { - if (this.el) return this.el + +/* if (this.el) return this.el this.el = document.createElement('div') this.el.setAttribute('id', 'editorView') @@ -76,22 +95,34 @@ class Editor extends Plugin { } } this.el.gotoLine = (line, column) => this.gotoLine(line, column || 0) - this.el.getCursorPosition = () => this.getCursorPosition() - return this.el + this.el.getCursorPosition = () => this.getCursorPosition() */ + + return
{ + this.ref = element + this.ref.currentContent = () => this.currentContent() // used by e2e test + this.ref.setCurrentContent = (value) => { + if (this.sessions[this.currentFile]) { + this.sessions[this.currentFile].setValue(value) + this._onChange(this.currentFile) + } + } + this.ref.gotoLine = (line, column) => this.gotoLine(line, column || 0) + this.ref.getCursorPosition = () => this.getCursorPosition() + }} id='editorView'> + +
} renderComponent () { - ReactDOM.render( - - , this.el) + this.dispatch({ + api: this.api, + currentThemeType: this.currentThemeType, + currentFile: this.currentFile, + sourceAnnotationsPerFile: this.sourceAnnotationsPerFile, + markerPerFile: this.markerPerFile, + events: this.events, + plugin: this + }) } triggerEvent (name, params) { diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index df40820b27..5ac6f8dd30 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -4,7 +4,7 @@ import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' import { EventEmitter } from 'events' import { RemixAppManager } from '../../../../../libs/remix-ui/plugin-manager/src/types' -import { fileChangedToastMsg } from '@remix-ui/helper' +import { fileChangedToastMsg, storageFullMessage } from '@remix-ui/helper' import helper from '../../lib/helper.js' /* @@ -722,8 +722,22 @@ class FileManager extends Plugin { if ((input !== null) && (input !== undefined)) { const provider = this.fileProviderOf(currentFile) if (provider) { - await provider.set(currentFile, input) + // use old content as default if save operation fails. + provider.get(currentFile, (error, oldContent) => { + provider.set(currentFile, input, (error) => { + if (error) { + if (error.message ) this.call('notification', 'toast', + error.message.indexOf( + 'LocalStorage is full') !== -1 ? storageFullMessage() + : error.message + ) + provider.set(currentFile, oldContent) + return console.error(error) + } else { this.emit('fileSaved', currentFile) + } + }) + }) } else { console.log('cannot save ' + currentFile + '. Does not belong to any explorer') } diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 47e40a2f5f..6c5e4d0235 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -2,7 +2,6 @@ import { ViewPlugin } from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { FileSystemProvider } from '@remix-ui/workspace' // eslint-disable-line import Registry from '../state/registry' import { RemixdHandle } from '../plugins/remixd-handle' @@ -58,18 +57,8 @@ module.exports = class Filepanel extends ViewPlugin { this.currentWorkspaceMetadata = {} } - onActivation () { - this.renderComponent() - } - render () { - return this.el - } - - renderComponent () { - ReactDOM.render( - - , this.el) + return
} /** diff --git a/apps/remix-ide/src/app/panels/tab-proxy.js b/apps/remix-ide/src/app/panels/tab-proxy.js index a713b4bd02..1671648a36 100644 --- a/apps/remix-ide/src/app/panels/tab-proxy.js +++ b/apps/remix-ide/src/app/panels/tab-proxy.js @@ -1,8 +1,7 @@ import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { Plugin } from '@remixproject/engine' import { TabsUI } from '@remix-ui/tabs' -import { getPathIcon } from '@remix-ui/helper' +import { PluginViewWrapper, getPathIcon } from '@remix-ui/helper' const EventEmitter = require('events') const profile = { @@ -11,7 +10,6 @@ const profile = { kind: 'other' } -// @todo(#650) Merge this with MainPanel into one plugin export class TabProxy extends Plugin { constructor (fileManager, editor) { super(profile) @@ -23,6 +21,7 @@ export class TabProxy extends Plugin { this._handlers = {} this.loadedTabs = [] this.el = document.createElement('div') + this.dispatch = null } onActivation () { @@ -286,6 +285,15 @@ export class TabProxy extends Plugin { this.handlers[type] = fn } + setDispatch (dispatch) { + this.dispatch = dispatch + this.renderComponent() + } + + updateComponent(state) { + return + } + renderComponent () { const onSelect = (index) => { if (this.loadedTabs[index]) { @@ -308,12 +316,17 @@ export class TabProxy extends Plugin { const onReady = (api) => { this.tabsApi = api } - ReactDOM.render( - - , this.el) + this.dispatch({ + loadedTabs: this.loadedTabs, + onSelect, + onClose, + onZoomIn, + onZoomOut, + onReady + }) } renderTabsbar () { - return this.el + return
} } diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 0854f7586e..6eaa65f6e9 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -1,15 +1,16 @@ /* global Node, requestAnimationFrame */ // eslint-disable-line import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { RemixUiTerminal } from '@remix-ui/terminal' // eslint-disable-line import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' +import { PluginViewWrapper } from '@remix-ui/helper' const vm = require('vm') const EventManager = require('../../lib/events') import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line + const KONSOLES = [] function register (api) { KONSOLES.push(api) } @@ -79,9 +80,12 @@ class Terminal extends Plugin { this.call('menuicons', 'select', 'debugger') this.call('debugger', 'debug', hash) }) + this.dispatch = null + } + - onActivation () { + onActivation() { this.renderComponent() } @@ -100,19 +104,27 @@ class Terminal extends Plugin { this.terminalApi.log(message) } + setDispatch(dispatch) { + this.dispatch = dispatch + } + render () { - return this.element + return
+ } + + updateComponent(state) { + return } renderComponent () { const onReady = (api) => { this.terminalApi = api } - ReactDOM.render( - , - this.element - ) + this.dispatch({ + plugin: this, + onReady: onReady + }) } scroll2bottom () { diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index dcd894d02c..f17b0da52b 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -1,10 +1,10 @@ import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' -import ReactDOM from 'react-dom' import { EventEmitter } from 'events' import {RemixUiStaticAnalyser} from '@remix-ui/static-analyser' // eslint-disable-line import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' +import { PluginViewWrapper } from '@remix-ui/helper' var EventManager = require('../../lib/events') @@ -35,6 +35,7 @@ class AnalysisTab extends ViewPlugin { offsetToLineColumnConverter: this.registry.get( 'offsettolinecolumnconverter').api } + this.dispatch = null } async onActivation () { @@ -43,33 +44,40 @@ class AnalysisTab extends ViewPlugin { await this.call('manager', 'activatePlugin', 'solidity') } this.renderComponent() + this.event.register('staticAnaysisWarning', (count) => { + if (count > 0) { + this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) + } else if (count === 0) { + this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) + } else { + // count ==-1 no compilation result + this.emit('statusChanged', { key: 'none' }) + } + }) + } + + setDispatch (dispatch) { + this.dispatch = dispatch } render () { - return this.element + return
+ } + + updateComponent(state) { + return } renderComponent () { - ReactDOM.render( - , - this.element, - () => { - this.event.register('staticAnaysisWarning', (count) => { - if (count > 0) { - this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) - } else if (count === 0) { - this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) - } else { - // count ==-1 no compilation result - this.emit('statusChanged', { key: 'none' }) - } - }) - } - ) + this.dispatch({ + registry: this.registry, + analysisModule: this, + event: this.event + }) } } diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index c57a51d089..8e3d17e366 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -1,6 +1,5 @@ /* global */ import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line import { CompileTabLogic } from '@remix-ui/solidity-compiler' // eslint-disable-line import { CompilerApiMixin } from '@remixproject/solidity-compiler-plugin' // eslint-disable-line @@ -42,9 +41,7 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA } renderComponent () { - ReactDOM.render( - - , this.el) + // empty method, is a state update needed? } onCurrentFileChanged () { @@ -72,9 +69,7 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA } render () { - this.renderComponent() - - return this.el + return
} async compileWithParameters (compilationTargets, settings) { diff --git a/apps/remix-ide/src/app/tabs/debugger-tab.js b/apps/remix-ide/src/app/tabs/debugger-tab.js index 6ac7235c09..63debf4553 100644 --- a/apps/remix-ide/src/app/tabs/debugger-tab.js +++ b/apps/remix-ide/src/app/tabs/debugger-tab.js @@ -3,7 +3,6 @@ import { DebuggerApiMixin } from '@remixproject/debugger-plugin' // eslint-disab import { ViewPlugin } from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import * as remixBleach from '../../lib/remixBleach' import { compilationFinishedToastMsg, compilingToastMsg, localCompilationToastMsg, notFoundToastMsg, sourceVerificationNotAvailableToastMsg } from '@remix-ui/helper' const css = require('./styles/debugger-tab-styles') @@ -51,9 +50,7 @@ export class DebuggerTab extends DebuggerApiMixin(ViewPlugin) { this.on('fetchAndCompile', 'sourceVerificationNotAvailable', () => { this.call('notification', 'toast', sourceVerificationNotAvailableToastMsg()) }) - - this.renderComponent() - return this.el + return
} showMessage (title, message) { @@ -68,9 +65,4 @@ export class DebuggerTab extends DebuggerApiMixin(ViewPlugin) { } } - renderComponent () { - ReactDOM.render( - - , this.el) - } } diff --git a/apps/remix-ide/src/app/tabs/settings-tab.js b/apps/remix-ide/src/app/tabs/settings-tab.tsx similarity index 62% rename from apps/remix-ide/src/app/tabs/settings-tab.js rename to apps/remix-ide/src/app/tabs/settings-tab.tsx index 133ae6ee5f..25ea5fb934 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.js +++ b/apps/remix-ide/src/app/tabs/settings-tab.tsx @@ -1,9 +1,9 @@ import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' -import ReactDOM from 'react-dom' import * as packageJson from '../../../../../package.json' import { RemixUiSettings } from '@remix-ui/settings' //eslint-disable-line import Registry from '../state/registry' +import { PluginViewWrapper } from '@remix-ui/helper' const profile = { name: 'settings', @@ -20,6 +20,15 @@ const profile = { } module.exports = class SettingsTab extends ViewPlugin { + config: any = {} + editor: any + private _deps: { + themeModule: any // eslint-disable-line + + } + element: HTMLDivElement + public useMatomoAnalytics: any + dispatch: React.Dispatch = () => {} constructor (config, editor) { super(profile) this.config = config @@ -32,24 +41,31 @@ module.exports = class SettingsTab extends ViewPlugin { this.useMatomoAnalytics = null } - onActivation () { + setDispatch (dispatch: React.Dispatch) { + this.dispatch = dispatch this.renderComponent() } - render () { - return this.element + render() { + return ( +
+ +
+ ); + } + + updateComponent(state: any){ + return } renderComponent () { - ReactDOM.render( - , - this.element - ) + this.dispatch(this) } get (key) { @@ -59,6 +75,8 @@ module.exports = class SettingsTab extends ViewPlugin { updateMatomoAnalyticsChoice (isChecked) { this.config.set('settings/matomo-analytics', isChecked) this.useMatomoAnalytics = isChecked - this.renderComponent() + this.dispatch({ + ...this + }) } -} +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/tabs/test-tab.js b/apps/remix-ide/src/app/tabs/test-tab.js index a03d74a846..c2af5ce7a7 100644 --- a/apps/remix-ide/src/app/tabs/test-tab.js +++ b/apps/remix-ide/src/app/tabs/test-tab.js @@ -1,12 +1,12 @@ /* global */ import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { SolidityUnitTesting } from '@remix-ui/solidity-unit-testing' // eslint-disable-line import { TestTabLogic } from '@remix-ui/solidity-unit-testing' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' import helper from '../../lib/helper' import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity' +import { PluginViewWrapper } from '@remix-ui/helper' var { UnitTestRunner, assertLibCode } = require('@remix-project/remix-tests') @@ -34,6 +34,7 @@ module.exports = class TestTab extends ViewPlugin { this.offsetToLineColumnConverter = offsetToLineColumnConverter this.allFilesInvolved = ['.deps/remix-tests/remix_tests.sol', '.deps/remix-tests/remix_accounts.sol'] this.element = document.createElement('div') + this.dispatch = null } onActivationInternal () { @@ -128,15 +129,25 @@ module.exports = class TestTab extends ViewPlugin { }) } + setDispatch (dispatch) { + this.dispatch = dispatch + this.renderComponent('tests') + } + render () { this.onActivationInternal() - this.renderComponent('tests') - return this.element + return
+ } + + updateComponent(state) { + return } renderComponent (testDirPath) { - ReactDOM.render( - - , this.element) + this.dispatch({ + testTab: this, + helper: this.helper, + testDirPath: testDirPath + }) } } diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 5fe56053fa..05a015c4fc 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -1,5 +1,4 @@ import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import { RunTabUI } from '@remix-ui/run-tab' import { ViewPlugin } from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' @@ -40,9 +39,6 @@ export class RunTab extends ViewPlugin { this.el = document.createElement('div') } - onActivation () { - this.renderComponent() - } setupEvents () { this.blockchain.events.on('newTransaction', (tx, receipt) => { @@ -86,14 +82,9 @@ export class RunTab extends ViewPlugin { } render () { - return this.el + return
} - renderComponent () { - ReactDOM.render( - - , this.el) - } onReady (api) { this.REACT_API = api diff --git a/apps/remix-ide/src/app/ui/landing-page/landing-page.js b/apps/remix-ide/src/app/ui/landing-page/landing-page.js index b05271dc96..2f8819fc5f 100644 --- a/apps/remix-ide/src/app/ui/landing-page/landing-page.js +++ b/apps/remix-ide/src/app/ui/landing-page/landing-page.js @@ -1,6 +1,5 @@ /* global */ import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' import * as packageJson from '../../../../../../package.json' import { ViewPlugin } from '@remixproject/engine-web' import { RemixUiHomeTab } from '@remix-ui/home-tab' // eslint-disable-line @@ -31,15 +30,9 @@ export class LandingPage extends ViewPlugin { } render () { - this.renderComponent() - return this.el + return
} - renderComponent () { - ReactDOM.render( - - , this.el) - } } diff --git a/apps/remix-ide/src/index.tsx b/apps/remix-ide/src/index.tsx index fde108b852..a418ecbd49 100644 --- a/apps/remix-ide/src/index.tsx +++ b/apps/remix-ide/src/index.tsx @@ -33,9 +33,9 @@ import ('./app').then((AppComponent) => { const appComponent = new AppComponent.default() appComponent.run().then(() => { render( - + <> - , + , document.getElementById('root') ) }) diff --git a/apps/remix-ide/src/lib/commands.js b/apps/remix-ide/src/lib/commands.js deleted file mode 100644 index 0f6ca3f897..0000000000 --- a/apps/remix-ide/src/lib/commands.js +++ /dev/null @@ -1,57 +0,0 @@ -const allPrograms = [ - { ethers: 'The ethers.js library is a compact and complete JavaScript library for Ethereum.' }, - { remix: 'Ethereum IDE and tools for the web.' }, - { web3: 'The web3.js library is a collection of modules which contain specific functionality for the ethereum ecosystem.' }, - { swarmgw: 'This library can be used to upload/download files to Swarm via https://swarm-gateways.net/.' } -] - -const allCommands = [ - { 'remix.execute(filepath)': 'Run the script specified by file path. If filepath is empty, script currently displayed in the editor is executed.' }, - { 'remix.exeCurrent()': 'Run the script currently displayed in the editor.' }, - { 'remix.help()': 'Display this help message.' }, - { 'remix.loadgist(id)': 'Load a gist in the file explorer.' }, - { 'remix.loadurl(url)': 'Load the given url in the file explorer. The url can be of type github, swarm or ipfs.' }, - - { 'swarmgw.get(url, cb)': 'Download files from Swarm via https://swarm-gateways.net/' }, - { 'swarmgw.put(content, cb)': 'Upload files to Swarm via https://swarm-gateways.net/' }, - - { 'ethers.Contract': 'This API provides a graceful connection to a contract deployed on the blockchain, simplifying calling and querying its functions and handling all the binary protocol and conversion as necessarily.' }, - { 'ethers.HDNode': 'A Hierarchical Deterministic Wallet represents a large tree of private keys which can reliably be reproduced from an initial seed.' }, - { 'ethers.Interface': 'The Interface Object is a meta-class that accepts a Solidity (or compatible) Application Binary Interface (ABI) and populates functions to deal with encoding and decoding the parameters to pass in and results returned.' }, - { 'ethers.providers': 'A Provider abstracts a connection to the Ethereum blockchain, for issuing queries and sending state changing transactions.' }, - { 'ethers.SigningKey': 'The SigningKey interface provides an abstraction around the secp256k1 elliptic curve cryptography library.' }, - { 'ethers.utils': 'The utility functions exposed in both the ethers umbrella package and the ethers-utils.' }, - { 'ethers.utils.AbiCoder': 'Create a new ABI Coder object' }, - { 'ethers.utils.RLP': 'This encoding method is used internally for several aspects of Ethereum, such as encoding transactions and determining contract addresses.' }, - { 'ethers.Wallet': 'A wallet manages a private/public key pair which is used to cryptographically sign transactions and prove ownership on the Ethereum network.' }, - { 'ethers.version': 'Contains the version of the ethers container object.' }, - - { 'web3.eth': 'Eth module for interacting with the Ethereum network.' }, - { 'web3.eth.accounts': 'The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.' }, - { 'web3.eth.abi': 'The web3.eth.abi functions let you de- and encode parameters to ABI (Application Binary Interface) for function calls to the EVM (Ethereum Virtual Machine).' }, - { 'web3.eth.ens': 'The web3.eth.ens functions let you interacting with ENS.' }, - { 'web3.eth.Iban': 'The web3.eth.Iban function lets convert Ethereum addresses from and to IBAN and BBAN.' }, - { 'web3.eth.net': 'Net module for interacting with network properties.' }, - { 'web3.eth.personal': 'Personal module for interacting with the Ethereum accounts.' }, - { 'web3.eth.subscribe': 'The web3.eth.subscribe function lets you subscribe to specific events in the blockchain.' }, - { 'web3.givenProvider': 'When using web3.js in an Ethereum compatible browser, it will set with the current native provider by that browser. Will return the given provider by the (browser) environment, otherwise null.' }, - { 'web3.modules': 'Contains the version of the web3 container object.' }, - { 'web3.providers': 'Contains the current available providers.' }, - { 'web3.shh': 'Shh module for interacting with the whisper protocol' }, - { 'web3.utils': 'This package provides utility functions for Ethereum dapps and other web3.js packages.' }, - { 'web3.version': 'Contains the version of the web3 container object.' }, - - { 'web3.eth.clearSubscriptions();': 'Resets subscriptions.' }, - { 'web3.eth.Contract(jsonInterface[, address][, options])': 'The web3.eth.Contract object makes it easy to interact with smart contracts on the ethereum blockchain.' }, - { 'web3.eth.accounts.create([entropy]);': 'The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.' }, - { 'web3.eth.getAccounts();': 'Retrieve the list of accounts' }, - { 'web3.eth.accounts.privateKeyToAccount(privateKey [, ignoreLength ]);': 'Get the account from the private key' }, - { 'web3.eth.accounts.signTransaction(tx, privateKey [, callback]);': 'Sign Transaction' }, - { 'web3.eth.accounts.recoverTransaction(rawTransaction);': 'Sign Transaction' }, - { 'web3.eth.accounts.hashMessage(message);': 'Hash message' } -] - -module.exports = { - allPrograms, - allCommands -} diff --git a/apps/remix-ide/src/remixEngine.js b/apps/remix-ide/src/remixEngine.js index cbdf6c86c6..63e94d8669 100644 --- a/apps/remix-ide/src/remixEngine.js +++ b/apps/remix-ide/src/remixEngine.js @@ -15,6 +15,8 @@ export class RemixEngine extends Engine { if (name === 'hardhat') return { queueTimeout: 60000 * 4 } if (name === 'localPlugin') return { queueTimeout: 60000 * 4 } if (name === 'notification') return { queueTimeout: 60000 * 4 } + if (name === 'sourcify') return { queueTimeout: 60000 * 4 } + if (name === 'fetchAndCompile') return { queueTimeout: 60000 * 4 } return { queueTimeout: 10000 } } diff --git a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts index 63a7880382..c6a8a6156b 100644 --- a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts +++ b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts @@ -108,7 +108,7 @@ export class FetchAndCompile extends Plugin { language: data.metadata.language, evmVersion: data.metadata.settings.evmVersion, optimize: data.metadata.settings.optimizer.enabled, - runs: data.metadata.settings.runs + runs: data.metadata.settings.optimizer.runs } try { setTimeout(_ => this.emit('compiling', settings), 0) diff --git a/libs/remix-debug/src/Ethdebugger.ts b/libs/remix-debug/src/Ethdebugger.ts index 0026c97ee9..e0f1a92ab5 100644 --- a/libs/remix-debug/src/Ethdebugger.ts +++ b/libs/remix-debug/src/Ethdebugger.ts @@ -11,7 +11,6 @@ import { SolidityProxy, stateDecoder, localDecoder, InternalCallTree } from './s /** * Ethdebugger is a wrapper around a few classes that helps debugging a transaction * - * - Web3Providers - define which environment (web3) the transaction will be retrieved from * - TraceManager - Load / Analyze the trace and retrieve details of specific test * - CodeManager - Retrieve loaded byte code and help to resolve AST item from vmtrace index * - SolidityProxy - Basically used to extract state variable from AST diff --git a/libs/remix-debug/src/debugger/debugger.ts b/libs/remix-debug/src/debugger/debugger.ts index 231c2d57f2..b77963d302 100644 --- a/libs/remix-debug/src/debugger/debugger.ts +++ b/libs/remix-debug/src/debugger/debugger.ts @@ -68,7 +68,10 @@ export class Debugger { try { const address = this.debugger.traceManager.getCurrentCalledAddressAt(index) const compilationResultForAddress = await this.compilationResult(address) - if (!compilationResultForAddress) return + if (!compilationResultForAddress) { + this.event.trigger('newSourceLocation', [null]) + return + } this.debugger.callTree.sourceLocationTracker.getValidSourceLocationFromVMTraceIndex(address, index, compilationResultForAddress.data.contracts).then(async (rawLocation) => { if (compilationResultForAddress && compilationResultForAddress.data) { @@ -91,6 +94,7 @@ export class Debugger { }) // }) } catch (error) { + this.event.trigger('newSourceLocation', [null]) return console.log(error) } } diff --git a/libs/remix-debug/src/debugger/stepManager.ts b/libs/remix-debug/src/debugger/stepManager.ts index 1a64977e97..6fd2e5fa22 100644 --- a/libs/remix-debug/src/debugger/stepManager.ts +++ b/libs/remix-debug/src/debugger/stepManager.ts @@ -51,15 +51,18 @@ export class DebuggerStepManager { this.traceManager.buildCallPath(index).then((callsPath) => { this.currentCall = callsPath[callsPath.length - 1] if (this.currentCall.reverted) { - const revertedReason = this.currentCall.outofgas ? 'outofgas' : '' + const revertedReason = this.currentCall.outofgas ? 'outofgas' : 'reverted' this.revertionPoint = this.currentCall.return - return this.event.trigger('revertWarning', [revertedReason]) + this.event.trigger('revertWarning', [revertedReason]) + return } for (let k = callsPath.length - 2; k >= 0; k--) { const parent = callsPath[k] - if (!parent.reverted) continue - this.revertionPoint = parent.return - this.event.trigger('revertWarning', ['parenthasthrown']) + if (parent.reverted) { + this.revertionPoint = parent.return + this.event.trigger('revertWarning', ['parenthasthrown']) + return + } } this.event.trigger('revertWarning', ['']) }).catch((error) => { diff --git a/libs/remix-debug/src/storage/storageResolver.ts b/libs/remix-debug/src/storage/storageResolver.ts index 62a9f7df32..c5522f37f9 100644 --- a/libs/remix-debug/src/storage/storageResolver.ts +++ b/libs/remix-debug/src/storage/storageResolver.ts @@ -133,7 +133,7 @@ export class StorageResolver { resolve([{}, null]) } else { this.web3.debug.storageRangeAt( - tx.blockHash, tx.hash, + tx.blockHash, tx.transactionIndex, address, start, maxSize, diff --git a/libs/remix-lib/README.md b/libs/remix-lib/README.md index 35be57053c..31075ad154 100644 --- a/libs/remix-lib/README.md +++ b/libs/remix-lib/README.md @@ -23,11 +23,6 @@ ui: uiHelper, compiler: compilerHelper }, - vm: { - Web3Providers: Web3Providers, - DummyProvider: DummyProvider, - Web3VMProvider: Web3VmProvider - }, Storage: Storage, util: util, execution: { diff --git a/libs/remix-lib/src/execution/eventsDecoder.ts b/libs/remix-lib/src/execution/eventsDecoder.ts index 833cf189f0..4622b245fd 100644 --- a/libs/remix-lib/src/execution/eventsDecoder.ts +++ b/libs/remix-lib/src/execution/eventsDecoder.ts @@ -56,18 +56,19 @@ export class EventsDecoder { return eventsABI } - _event (hash, eventsABI) { - for (const k in eventsABI) { - if (eventsABI[k][hash]) { - const event = eventsABI[k][hash] - for (const input of event.inputs) { - if (input.type === 'function') { - input.type = 'bytes24' - input.baseType = 'bytes24' - } + _event (hash: string, eventsABI: Record, contractName: string) { + const events = eventsABI[contractName] + if (!events) return null + + if (events[hash]) { + const event = events[hash] + for (const input of event.inputs) { + if (input.type === 'function') { + input.type = 'bytes24' + input.baseType = 'bytes24' } - return event } + return event } return null } @@ -94,7 +95,7 @@ export class EventsDecoder { // [address, topics, mem] const log = logs[i] const topicId = log.topics[0] - const eventAbi = this._event(topicId.replace('0x', ''), eventsABI) + const eventAbi = this._event(topicId.replace('0x', ''), eventsABI, contractName) if (eventAbi) { const decodedlog = eventAbi.abi.parseLog(log) const decoded = {} diff --git a/libs/remix-lib/src/index.ts b/libs/remix-lib/src/index.ts index 54646e326e..1f2cdb6676 100644 --- a/libs/remix-lib/src/index.ts +++ b/libs/remix-lib/src/index.ts @@ -2,9 +2,6 @@ import { EventManager } from './eventManager' import * as uiHelper from './helpers/uiHelper' import * as compilerHelper from './helpers/compilerHelper' import * as util from './util' -import { Web3Providers } from './web3Provider/web3Providers' -import { DummyProvider } from './web3Provider/dummyProvider' -import { Web3VmProvider } from './web3Provider/web3VmProvider' import { Storage } from './storage' import { EventsDecoder } from './execution/eventsDecoder' import * as txExecution from './execution/txExecution' @@ -18,6 +15,7 @@ import * as typeConversion from './execution/typeConversion' import { TxRunnerVM } from './execution/txRunnerVM' import { TxRunnerWeb3 } from './execution/txRunnerWeb3' import * as txResultHelper from './helpers/txResultHelper' +export { ConsoleLogs } from './helpers/hhconsoleSigs' export { ICompilerApi, ConfigurationSettings } from './types/ICompilerApi' export { QueryParams } from './query-params' @@ -26,11 +24,6 @@ const helpers = { compiler: compilerHelper, txResultHelper } -const vm = { - Web3Providers: Web3Providers, - DummyProvider: DummyProvider, - Web3VMProvider: Web3VmProvider -} const execution = { EventsDecoder: EventsDecoder, txExecution: txExecution, @@ -44,4 +37,4 @@ const execution = { LogsManager, forkAt } -export { EventManager, helpers, vm, Storage, util, execution } +export { EventManager, helpers, Storage, util, execution } diff --git a/libs/remix-lib/src/web3Provider/dummyProvider.ts b/libs/remix-lib/src/web3Provider/dummyProvider.ts deleted file mode 100644 index c6e4ec8d82..0000000000 --- a/libs/remix-lib/src/web3Provider/dummyProvider.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class DummyProvider { - eth - debug - providers - currentProvider - - constructor () { - this.eth = {} - this.debug = {} - this.eth.getCode = (address, cb) => { return this.getCode(address, cb) } - this.eth.getTransaction = (hash, cb) => { return this.getTransaction(hash, cb) } - this.eth.getTransactionFromBlock = (blockNumber, txIndex, cb) => { return this.getTransactionFromBlock(blockNumber, txIndex, cb) } - this.eth.getBlockNumber = (cb) => { return this.getBlockNumber(cb) } - this.debug.traceTransaction = (hash, options, cb) => { return this.traceTransaction(hash, options, cb) } - this.debug.storageRangeAt = (blockNumber, txIndex, address, start, end, maxLength, cb) => { return this.storageRangeAt(blockNumber, txIndex, address, start, end, maxLength, cb) } - this.providers = { HttpProvider: function (url) {} } - this.currentProvider = { host: '' } - } - - getCode (address, cb) { - cb(null, '') - } - - setProvider (provider) {} - - traceTransaction (txHash, options, cb) { - if (cb) { - cb(null, {}) - } - return {} - } - - storageRangeAt (blockNumber, txIndex, address, start, end, maxLength, cb) { - if (cb) { - cb(null, {}) - } - return {} - } - - getBlockNumber (cb) { cb(null, '') } - - getTransaction (txHash, cb) { - if (cb) { - cb(null, {}) - } - return {} - } - - getTransactionFromBlock (blockNumber, txIndex, cb) { - if (cb) { - cb(null, {}) - } - return {} - } -} diff --git a/libs/remix-lib/src/web3Provider/web3Providers.ts b/libs/remix-lib/src/web3Provider/web3Providers.ts deleted file mode 100644 index dc68edb434..0000000000 --- a/libs/remix-lib/src/web3Provider/web3Providers.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Web3VmProvider } from './web3VmProvider' -import { loadWeb3, extendWeb3 } from '../init' - -export class Web3Providers { - modes - constructor () { - this.modes = {} - } - - addProvider (type, obj) { - if (type === 'INTERNAL') { - const web3 = loadWeb3() - this.addWeb3(type, web3) - } else if (type === 'vm') { - this.addVM(type, obj) - } else { - extendWeb3(obj) - this.addWeb3(type, obj) - } - } - - get (type, cb) { - if (this.modes[type]) { - return cb(null, this.modes[type]) - } - cb('error: this provider has not been setup (' + type + ')', null) - } - - addWeb3 (type, web3) { - this.modes[type] = web3 - } - - addVM (type, vm) { - const vmProvider = new Web3VmProvider() - vmProvider.setVM(vm) - this.modes[type] = vmProvider - } -} diff --git a/libs/remix-lib/src/web3Provider/web3VmProvider.ts b/libs/remix-simulator/src/VmProxy.ts similarity index 89% rename from libs/remix-lib/src/web3Provider/web3VmProvider.ts rename to libs/remix-simulator/src/VmProxy.ts index ecc006da9e..f7090d8b1d 100644 --- a/libs/remix-lib/src/web3Provider/web3VmProvider.ts +++ b/libs/remix-simulator/src/VmProxy.ts @@ -1,12 +1,16 @@ -import { hexListFromBNs, formatMemory } from '../util' -import { normalizeHexAddress } from '../helpers/uiHelper' -import { ConsoleLogs } from '../helpers/hhconsoleSigs' +import { util } from '@remix-project/remix-lib' +const { hexListFromBNs, formatMemory } = util +import { helpers } from '@remix-project/remix-lib' +const { normalizeHexAddress } = helpers.ui +import { ConsoleLogs } from '@remix-project/remix-lib' import { toChecksumAddress, BN, bufferToHex, Address } from 'ethereumjs-util' import Web3 from 'web3' import { ethers } from 'ethers' +import { VMContext } from './vm-context' -export class Web3VmProvider { - web3 +export class VmProxy { + vmContext: VMContext + web3: Web3 vm vmTraces txs @@ -38,7 +42,8 @@ export class Web3VmProvider { blocks latestBlockNumber - constructor () { + constructor (vmContext: VMContext) { + this.vmContext = vmContext this.web3 = new Web3() this.vm = null this.vmTraces = {} @@ -66,15 +71,15 @@ export class Web3VmProvider { this.lastProcessedStorageTxHash = {} this.sha3Preimages = {} // util - this.sha3 = (...args) => this.web3.utils.sha3(...args) - this.toHex = (...args) => this.web3.utils.toHex(...args) - this.toAscii = (...args) => this.web3.utils.hexToAscii(...args) - this.fromAscii = (...args) => this.web3.utils.asciiToHex(...args) - this.fromDecimal = (...args) => this.web3.utils.numberToHex(...args) - this.fromWei = (...args) => this.web3.utils.fromWei(...args) - this.toWei = (...args) => this.web3.utils.toWei(...args) - this.toBigNumber = (...args) => this.web3.utils.toBN(...args) - this.isAddress = (...args) => this.web3.utils.isAddress(...args) + this.sha3 = (...args) => this.web3.utils.sha3.apply(this, args) + this.toHex = (...args) => this.web3.utils.toHex.apply(this, args) + this.toAscii = (...args) => this.web3.utils.toAscii.apply(this, args) + this.fromAscii = (...args) => this.web3.utils.fromAscii.apply(this, args) + this.fromDecimal = (...args) => this.web3.utils.fromDecimal.apply(this, args) + this.fromWei = (...args) => this.web3.utils.fromWei.apply(this, args) + this.toWei = (...args) => this.web3.utils.toWei.apply(this, args) + this.toBigNumber = (...args) => this.web3.utils.toBN.apply(this, args) + this.isAddress = (...args) => this.web3.utils.isAddress.apply(this, args) this.utils = Web3.utils || [] this.txsMapBlock = {} this.blocks = {} @@ -289,16 +294,22 @@ export class Web3VmProvider { } } - storageRangeAt (blockNumber, txIndex, address, start, maxLength, cb) { // txIndex is the hash in the case of the VM + storageRangeAt (blockNumber, txIndex, address, start, maxLength, cb) { // we don't use the range params here address = toChecksumAddress(address) + let txHash if (txIndex === 'latest') { - txIndex = this.lastProcessedStorageTxHash[address] + txHash = this.lastProcessedStorageTxHash[address] + } else { + const block = this.vmContext.blocks[blockNumber] + txHash = '0x' + block.transactions[txIndex].hash().toString('hex') } + + - if (this.storageCache[txIndex] && this.storageCache[txIndex][address]) { - const storage = this.storageCache[txIndex][address] + if (this.storageCache[txHash] && this.storageCache[txHash][address]) { + const storage = this.storageCache[txHash][address] return cb(null, { storage: JSON.parse(JSON.stringify(storage)), nextKey: null diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index e862fd0e3f..9e9afdef0a 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -2,11 +2,15 @@ 'use strict' import Web3 from 'web3' import { rlp, keccak, bufferToHex } from 'ethereumjs-util' -import { vm as remixLibVm, execution } from '@remix-project/remix-lib' +import { execution } from '@remix-project/remix-lib' +const { LogsManager } = execution +import { VmProxy } from './VmProxy' import VM from '@ethereumjs/vm' import Common from '@ethereumjs/common' import StateManager from '@ethereumjs/vm/dist/state/stateManager' import { StorageDump } from '@ethereumjs/vm/dist/state/interface' +import { Block } from '@ethereumjs/block' +import { Transaction } from '@ethereumjs/tx' /* extend vm state manager and instanciate VM @@ -75,6 +79,13 @@ class StateManagerCommonStorageDump extends StateManager { } } +export type CurrentVm = { + vm: VM, + web3vm: VmProxy, + stateManager: StateManagerCommonStorageDump, + common: Common +} + /* trigger contextChanged, web3EndpointChanged */ @@ -82,15 +93,14 @@ export class VMContext { currentFork: string blockGasLimitDefault: number blockGasLimit: number - customNetWorks - blocks - latestBlockNumber - blockByTxHash - txByHash - currentVm - web3vm - logsManager - exeResults + blocks: Record + latestBlockNumber: string + blockByTxHash: Record + txByHash: Record + currentVm: CurrentVm + web3vm: VmProxy + logsManager: any // LogsManager + exeResults: Record constructor (fork?) { this.blockGasLimitDefault = 4300000 @@ -98,11 +108,11 @@ export class VMContext { this.currentFork = fork || 'london' this.currentVm = this.createVm(this.currentFork) this.blocks = {} - this.latestBlockNumber = 0 + this.latestBlockNumber = "0x0" this.blockByTxHash = {} this.txByHash = {} this.exeResults = {} - this.logsManager = new execution.LogsManager() + this.logsManager = new LogsManager() } createVm (hardfork) { @@ -115,7 +125,9 @@ export class VMContext { allowUnlimitedContractSize: true }) - const web3vm = new remixLibVm.Web3VMProvider() + // VmProxy and VMContext are very intricated. + // VmProxy is used to track the EVM execution (to listen on opcode execution, in order for instance to generate the VM trace) + const web3vm = new VmProxy(this) web3vm.setVM(vm) return { vm, web3vm, stateManager, common } } @@ -140,7 +152,7 @@ export class VMContext { return this.currentVm } - addBlock (block) { + addBlock (block: Block) { let blockNumber = '0x' + block.header.number.toString('hex') if (blockNumber === '0x') { blockNumber = '0x0' diff --git a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx index 6845ce88b1..8d0aeec020 100644 --- a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react' +import React, { useContext, useEffect, useRef, useState } from 'react' import './style/remix-app.css' import { RemixUIMainPanel } from '@remix-ui/panel' import MatomoDialog from './components/modals/matomo' @@ -8,6 +8,7 @@ import { AppProvider } from './context/provider' import AppDialogs from './components/modals/dialogs' import DialogViewPlugin from './components/modals/dialogViewPlugin' import { AppContext } from './context/context' +import { RemixUiVerticalIconsPanel } from '@remix-ui/vertical-icons-panel' interface IRemixAppUi { app: any @@ -17,31 +18,8 @@ const RemixApp = (props: IRemixAppUi) => { const [appReady, setAppReady] = useState(false) const [hideSidePanel, setHideSidePanel] = useState(false) const sidePanelRef = useRef(null) - const mainPanelRef = useRef(null) - const iconPanelRef = useRef(null) - const hiddenPanelRef = useRef(null) useEffect(() => { - if (sidePanelRef.current) { - if (props.app.sidePanel) { - sidePanelRef.current.appendChild(props.app.sidePanel.render()) - } - } - if (mainPanelRef.current) { - if (props.app.mainview) { - mainPanelRef.current.appendChild(props.app.mainview.render()) - } - } - if (iconPanelRef.current) { - if (props.app.menuicons) { - iconPanelRef.current.appendChild(props.app.menuicons.render()) - } - } - if (hiddenPanelRef.current) { - if (props.app.hiddenPanel) { - hiddenPanelRef.current.appendChild(props.app.hiddenPanel.render()) - } - } async function activateApp () { props.app.themeModule.initTheme(() => { setAppReady(true) @@ -72,13 +50,6 @@ const RemixApp = (props: IRemixAppUi) => { }) } - const components = { - iconPanel:
, - sidePanel:
, - mainPanel:
, - hiddenPanel:
- } - const value = { settings: props.app.settings, showMatamo: props.app.showMatamo, @@ -93,14 +64,14 @@ const RemixApp = (props: IRemixAppUi) => {
- {components.iconPanel} - {components.sidePanel} +
{props.app.menuicons.render()}
+
{props.app.sidePanel.render()}
- {components.hiddenPanel} +
{props.app.hiddenPanel.render()}
diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css index 8990810a9e..835b54615b 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css @@ -19,4 +19,8 @@ .navigator { } .navigator:hover { +} + +.cursorPointerRemixDebugger { + cursor: pointer; } \ No newline at end of file diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx index 680c3b9ef8..2db94f72cc 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx @@ -65,11 +65,10 @@ export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward,
- - State changes made during this call will be reverted. - This call will run out of gas. - The parent call will throw an exception + This call has reverted, state changes made during the call will be reverted. + This call will run out of gas. + The parent call will throw an exception +
Click { jumpToException && jumpToException() }}>here to jump where the call reverted.
) diff --git a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx index a9a8200e9b..de26b84af9 100644 --- a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx @@ -32,7 +32,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { toastMessage: '', validationError: '', txNumberIsEmpty: true, - isLocalNodeUsed: false + isLocalNodeUsed: false, + sourceLocationStatus: '' }) useEffect(() => { @@ -87,7 +88,13 @@ export const DebuggerUI = (props: DebuggerUIProps) => { }) debuggerInstance.event.register('newSourceLocation', async (lineColumnPos, rawLocation, generatedSources, address) => { - if (!lineColumnPos) return + if (!lineColumnPos) { + await debuggerModule.discardHighlight() + setState(prevState => { + return { ...prevState, sourceLocationStatus: 'Source location not available.' } + }) + return + } const contracts = await debuggerModule.fetchContractAndCompile( address || currentReceipt.contractAddress || currentReceipt.to, currentReceipt) @@ -113,6 +120,9 @@ export const DebuggerUI = (props: DebuggerUIProps) => { } } if (path) { + setState(prevState => { + return { ...prevState, sourceLocationStatus: '' } + }) await debuggerModule.discardHighlight() await debuggerModule.highlight(lineColumnPos, path) } @@ -138,6 +148,12 @@ export const DebuggerUI = (props: DebuggerUIProps) => { const unloadRequested = (blockNumber, txIndex, tx) => { unLoad() + setState(prevState => { + return { + ...prevState, + sourceLocationStatus: '' + } + }) } const unLoad = () => { @@ -168,7 +184,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { setState(prevState => { return { ...prevState, - txNumber: txNumber + txNumber: txNumber, + sourceLocationStatus: '' } }) if (!isValidHash(txNumber)) { @@ -266,7 +283,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => { return { ...prevState, validationError: '', - txNumber: txHash + txNumber: txHash, + sourceLocationStatus: '' } }) startDebugging(null, txHash, null, web3) @@ -315,6 +333,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => { { state.validationError && {state.validationError} } + { state.debugging && state.sourceLocationStatus &&
{state.sourceLocationStatus}
} { state.debugging && } { state.debugging && } diff --git a/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx b/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx index 81e036a8b8..06fe05e949 100644 --- a/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/slider/slider.tsx @@ -1,10 +1,12 @@ -import React, { useState, useEffect } from 'react' // eslint-disable-line +import React, { useState, useEffect, useRef } from 'react' // eslint-disable-line export const Slider = ({ jumpTo, sliderValue, traceLength }) => { const [state, setState] = useState({ currentValue: 0 }) + const onChangeId = useRef(null) + useEffect(() => { setValue(sliderValue) }, [sliderValue]) @@ -18,9 +20,16 @@ export const Slider = ({ jumpTo, sliderValue, traceLength }) => { } const handleChange = (e) => { - const value = parseInt(e.target.value) - - setValue(value) + if (onChangeId.current) { + window.clearTimeout(onChangeId.current) + } + ((value) => { + onChangeId.current = setTimeout(() => { + console.log(value) + value = parseInt(value) + setValue(value) + }, 100) + })(e.target.value) } return ( diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx index eb57159048..b32b229f0b 100644 --- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/assembly-items.tsx @@ -125,7 +125,7 @@ export const AssemblyItems = ({ registerEvent }) => {
-
+
{ assemblyItems.display.map((item, i) => { return
{ refs.current[i] = ref }}>{item}
diff --git a/libs/remix-ui/helper/src/index.ts b/libs/remix-ui/helper/src/index.ts index 31c21f0564..36d73ef523 100644 --- a/libs/remix-ui/helper/src/index.ts +++ b/libs/remix-ui/helper/src/index.ts @@ -1,2 +1,3 @@ export * from './lib/remix-ui-helper' export * from './lib/helper-components' +export * from './lib/components/PluginViewWrapper' \ No newline at end of file diff --git a/libs/remix-ui/helper/src/lib/components/PluginViewWrapper.tsx b/libs/remix-ui/helper/src/lib/components/PluginViewWrapper.tsx new file mode 100644 index 0000000000..058fa3aee0 --- /dev/null +++ b/libs/remix-ui/helper/src/lib/components/PluginViewWrapper.tsx @@ -0,0 +1,24 @@ +import React from "react" +import { useEffect, useState } from "react" + +interface IPluginViewWrapperProps { + plugin: any + } + +export const PluginViewWrapper = (props: IPluginViewWrapperProps) => { + + const [state, setState] = useState(null) + + useEffect(() => { + if(props.plugin.setDispatch){ + props.plugin.setDispatch(setState) + } + }, []) + + return ( + <>{state? + <>{props.plugin.updateComponent(state)} + :<> + } + ) + } \ No newline at end of file diff --git a/libs/remix-ui/helper/src/lib/helper-components.tsx b/libs/remix-ui/helper/src/lib/helper-components.tsx index edd85b1b31..a71950315e 100644 --- a/libs/remix-ui/helper/src/lib/helper-components.tsx +++ b/libs/remix-ui/helper/src/lib/helper-components.tsx @@ -69,3 +69,12 @@ export const envChangeNotification = (env: { context: string, fork: string }, fr
) + +export const storageFullMessage = () => ( +
+ + + Cannot save this file due to full LocalStorage. Backup existing files and free up some space. + +
+) diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx index 1fa810ef79..e13ed5c28b 100644 --- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx +++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx @@ -297,7 +297,7 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
-
+

Featured Plugins

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 9eb30391bc..35a82ea4a5 100644 --- a/libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx +++ b/libs/remix-ui/panel/src/lib/plugins/panel-plugin.tsx @@ -10,6 +10,7 @@ const RemixUIPanelPlugin = (props: panelPLuginProps, panelRef: any) => { const localRef = useRef(null) const [view, setView] = useState() useEffect(() => { + const ref:any = panelRef || localRef if (ref.current) { if (props.pluginRecord.view) { diff --git a/libs/remix-ui/panel/src/lib/plugins/panel.css b/libs/remix-ui/panel/src/lib/plugins/panel.css index d2b2133667..8356d6ef15 100644 --- a/libs/remix-ui/panel/src/lib/plugins/panel.css +++ b/libs/remix-ui/panel/src/lib/plugins/panel.css @@ -76,11 +76,6 @@ iframe { display: block; } -.pluginsContainer { - height: 100%; - overflow-y: hidden; -} - #editorView { height: 100%; width: 100%; diff --git a/libs/remix-ui/terminal/src/lib/commands.ts b/libs/remix-ui/terminal/src/lib/commands.ts index cc3b5e6963..0dc02b371b 100644 --- a/libs/remix-ui/terminal/src/lib/commands.ts +++ b/libs/remix-ui/terminal/src/lib/commands.ts @@ -8,7 +8,6 @@ export const allPrograms = [ export const allCommands = [ { 'remix.execute(filepath)': 'Run the script specified by file path. If filepath is empty, script currently displayed in the editor is executed.' }, { 'remix.exeCurrent()': 'Run the script currently displayed in the editor.' }, - // { 'remix.help()': 'Display this help message.' }, { 'remix.loadgist(id)': 'Load a gist in the file explorer.' }, // { 'remix.loadurl(url)': 'Load the given url in the file explorer. The url can be of type github, swarm or ipfs.' }, diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css index 0ffe440548..13402e45ee 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -53,6 +53,9 @@ element.style { .remix_ui_terminal_block > pre { max-height : 200px; } +.remix_ui_terminal_welcome { + font-weight: bold; +} .remix_ui_terminal_cli { white-space : nowrap; line-height : 1.7em; diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx index f5a2a8868a..73b5b3e424 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -382,7 +382,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const handleAutoComplete = () => (
2)) && autoCompletState.data._options.length > 0 ? 'block' : 'none' }} + style={{ display: (autoCompletState.showSuggestions && autoCompletState.userInput !== '' && (autoCompletState.userInput.length > 0)) && autoCompletState.data._options.length > 0 ? 'block' : 'none' }} >
{autoCompletState.data._options.map((item, index) => { diff --git a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx index f222aca38e..8a18545f67 100644 --- a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx +++ b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx @@ -3,7 +3,7 @@ import React from 'react' // eslint-disable-line const TerminalWelcomeMessage = ({ packageJson }) => { return (
-
- Welcome to Remix {packageJson} -

+
Welcome to Remix {packageJson}

You can use this terminal to:
  • Check transactions details and start debugging.
  • @@ -16,12 +16,14 @@ const TerminalWelcomeMessage = ({ packageJson }) => { - Right click on a JavaScript file in the file explorer and then click \`Run\`
+
The following libraries are accessible:
+
Type the library name to see available commands.
) } diff --git a/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css b/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css index 5fd6e085ee..393ee84773 100644 --- a/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css +++ b/libs/remix-ui/vertical-icons-panel/src/lib/remix-ui-vertical-icons-panel.css @@ -111,6 +111,7 @@ flex-basis: 510px; flex-grow: 2; text-align: center; + margin-top: -6px; /* border-bottom: 3px solid #3f4455; */ } .remixui_scrollbar::-webkit-scrollbar { /* Chrome, Safari and other Webkit browsers*/ diff --git a/package.json b/package.json index b37e2a9cb8..3585888453 100644 --- a/package.json +++ b/package.json @@ -149,13 +149,13 @@ "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", "@monaco-editor/react": "^4.3.1", - "@remixproject/engine": "^0.3.26", - "@remixproject/engine-web": "^0.3.26", - "@remixproject/plugin": "^0.3.26", - "@remixproject/plugin-api": "^0.3.26", - "@remixproject/plugin-utils": "^0.3.26", - "@remixproject/plugin-webview": "^0.3.26", - "@remixproject/plugin-ws": "^0.3.26", + "@remixproject/engine": "^0.3.28", + "@remixproject/engine-web": "^0.3.28", + "@remixproject/plugin": "^0.3.28", + "@remixproject/plugin-api": "^0.3.28", + "@remixproject/plugin-utils": "^0.3.28", + "@remixproject/plugin-webview": "^0.3.28", + "@remixproject/plugin-ws": "^0.3.28", "ansi-gray": "^0.1.1", "async": "^2.6.2", "axios": ">=0.21.1",