From 2984a3b0486cd1caf8a5ac972833df7ca63db0b4 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 29 Jun 2021 12:41:39 +0100 Subject: [PATCH 01/48] initial setup for moving terminal to react --- libs/remix-ui/terminal/.babelrc | 4 +++ libs/remix-ui/terminal/.eslintrc | 19 ++++++++++ libs/remix-ui/terminal/README.md | 7 ++++ libs/remix-ui/terminal/package.json | 4 +++ libs/remix-ui/terminal/src/index.ts | 1 + .../terminal/src/lib/remix-ui-terminal.css | 0 .../terminal/src/lib/remix-ui-terminal.tsx | 16 +++++++++ libs/remix-ui/terminal/tsconfig.json | 16 +++++++++ libs/remix-ui/terminal/tsconfig.lib.json | 13 +++++++ nx.json | 3 ++ tsconfig.json | 3 +- workspace.json | 35 +++++++++++++++++++ 12 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 libs/remix-ui/terminal/.babelrc create mode 100644 libs/remix-ui/terminal/.eslintrc create mode 100644 libs/remix-ui/terminal/README.md create mode 100644 libs/remix-ui/terminal/package.json create mode 100644 libs/remix-ui/terminal/src/index.ts create mode 100644 libs/remix-ui/terminal/src/lib/remix-ui-terminal.css create mode 100644 libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx create mode 100644 libs/remix-ui/terminal/tsconfig.json create mode 100644 libs/remix-ui/terminal/tsconfig.lib.json diff --git a/libs/remix-ui/terminal/.babelrc b/libs/remix-ui/terminal/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/terminal/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/terminal/.eslintrc b/libs/remix-ui/terminal/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/terminal/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/terminal/README.md b/libs/remix-ui/terminal/README.md new file mode 100644 index 0000000000..4638096417 --- /dev/null +++ b/libs/remix-ui/terminal/README.md @@ -0,0 +1,7 @@ +# remix-ui-terminal + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-terminal` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/terminal/package.json b/libs/remix-ui/terminal/package.json new file mode 100644 index 0000000000..623cf89c25 --- /dev/null +++ b/libs/remix-ui/terminal/package.json @@ -0,0 +1,4 @@ +{ + "name": "remix-ui-terminal", + "version": "0.0.1" +} diff --git a/libs/remix-ui/terminal/src/index.ts b/libs/remix-ui/terminal/src/index.ts new file mode 100644 index 0000000000..1735a3cf89 --- /dev/null +++ b/libs/remix-ui/terminal/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-terminal'; diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx new file mode 100644 index 0000000000..337bb2e1bb --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +import './remix-ui-terminal.css' + +/* eslint-disable-next-line */ +export interface RemixUiTerminalProps {} + +export const RemixUiTerminal = (props: RemixUiTerminalProps) => { + return ( +
+

Welcome to remix-ui-terminal!

+
+ ) +} + +export default RemixUiTerminal; diff --git a/libs/remix-ui/terminal/tsconfig.json b/libs/remix-ui/terminal/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/terminal/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/terminal/tsconfig.lib.json b/libs/remix-ui/terminal/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/terminal/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx.json b/nx.json index a63c015d64..4220432156 100644 --- a/nx.json +++ b/nx.json @@ -101,6 +101,9 @@ }, "remix-ui-checkbox": { "tags": [] + }, + "remix-ui-terminal": { + "tags": [] } } } diff --git a/tsconfig.json b/tsconfig.json index 75db5bc6ff..3325513e53 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -40,7 +40,8 @@ "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], - "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"] + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"], + "@remix-ui/terminal": ["libs/remix-ui/terminal/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 5d2bf912c0..14cfc136d9 100644 --- a/workspace.json +++ b/workspace.json @@ -760,6 +760,41 @@ } } } + }, + "remix-ui-terminal": { + "root": "libs/remix-ui/terminal", + "sourceRoot": "libs/remix-ui/terminal/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/terminal/tsconfig.lib.json"], + "exclude": ["**/node_modules/**", "!libs/remix-ui/terminal/**/*"] + } + }, + "build": { + "builder": "@nrwl/web:package", + "options": { + "outputPath": "dist/libs/remix-ui/terminal", + "tsConfig": "libs/remix-ui/terminal/tsconfig.lib.json", + "project": "libs/remix-ui/terminal/package.json", + "entryFile": "libs/remix-ui/terminal/src/index.ts", + "external": ["react", "react-dom"], + "babelConfig": "@nrwl/react/plugins/bundle-babel", + "rollupConfig": "@nrwl/react/plugins/bundle-rollup", + "assets": [ + { + "glob": "README.md", + "input": ".", + "output": "." + } + ] + } + } + } } }, "cli": { From 70e146ae5d7983ba1aa771c5d64d2b9e484329d0 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 29 Jun 2021 13:16:48 +0100 Subject: [PATCH 02/48] updating terminal.js --- apps/remix-ide/src/app/panels/terminal.js | 851 +++++++++--------- .../terminal/src/lib/remix-ui-terminal.tsx | 4 +- 2 files changed, 434 insertions(+), 421 deletions(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index bd474b41fb..a75f87187c 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -1,7 +1,10 @@ /* global Node, requestAnimationFrame */ + +import ReactDOM from 'react-dom' import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' import * as remixBleach from '../../lib/remixBleach' +import { RemixUiTerminal } from '@remix-ui/terminal' var yo = require('yo-yo') var javascriptserialize = require('javascript-serialize') @@ -36,6 +39,8 @@ const profile = { class Terminal extends Plugin { constructor (opts, api) { super(profile) + this.element = document.createElement('div') + this.element.setAttribute('id', 'terminalView ') var self = this self.event = new EventManager() self.blockchain = opts.blockchain @@ -149,427 +154,435 @@ class Terminal extends Plugin { if (this._view.input) this._view.input.focus() } - render () { - var self = this - if (self._view.el) return self._view.el - self._view.journal = yo`
` - self._view.input = yo` - { this.focus() }} onpaste=${paste} onkeydown=${change}> - ` - self._view.input.setAttribute('spellcheck', 'false') - self._view.input.setAttribute('contenteditable', 'true') - self._view.input.setAttribute('id', 'terminalCliInput') - self._view.input.setAttribute('data-id', 'terminalCliInput') - - self._view.input.innerText = '\n' - self._view.cli = yo` -
- ${'>'} - ${self._view.input} -
- ` - - self._view.icon = yo` - ` - self._view.dragbar = yo` -
` - - self._view.pendingTxCount = yo`
0
` - self._view.inputSearch = yo` - ` - self._view.bar = yo` -
- ${self._view.dragbar} -
- ${self._view.icon} -
- -
- ${self._view.pendingTxCount} -
-
- - -
-
- - ${self._view.inputSearch} -
-
-
- ` - self._view.term = yo` -
- ${self._components.autoCompletePopup.render()} -
-
- ${self._view.journal} - ${self._view.cli} -
-
- ` - self._view.el = yo` -
- ${self._view.bar} - ${self._view.term} -
- ` - setInterval(async () => { - try { - self._view.pendingTxCount.innerHTML = await self.call('udapp', 'pendingTransactionsCount') - } catch (err) {} - }, 1000) - - function listenOnNetwork (ev) { - self.event.trigger('listenOnNetWork', [ev.currentTarget.checked]) - } - function paste (event) { - const selection = window.getSelection() - if (!selection.rangeCount) return false - event.preventDefault() - event.stopPropagation() - var clipboard = (event.clipboardData || window.clipboardData) - var text = clipboard.getData('text/plain') - text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters - var temp = document.createElement('div') - temp.innerHTML = text - var textnode = document.createTextNode(temp.textContent) - selection.getRangeAt(0).insertNode(textnode) - selection.empty() - self.scroll2bottom() - placeCaretAtEnd(event.currentTarget) - } - function placeCaretAtEnd (el) { - el.focus() - var range = document.createRange() - range.selectNodeContents(el) - range.collapse(false) - var sel = window.getSelection() - sel.removeAllRanges() - sel.addRange(range) - } - function throttle (fn, wait) { - var time = Date.now() - return function debounce () { - if ((time + wait - Date.now()) < 0) { - fn.apply(this, arguments) - time = Date.now() - } - } - } - var css2 = csjs` - .anchor { - position : static; - border-top : 2px dotted blue; - height : 10px; - } - .overlay { - position : absolute; - width : 100%; - display : flex; - align-items : center; - justify-content : center; - bottom : 0; - right : 15px; - min-height : 20px; - } - .text { - z-index : 2; - color : black; - font-weight : bold; - pointer-events : none; - } - .background { - z-index : 1; - opacity : 0.8; - background-color : #a6aeba; - cursor : pointer; - } - .ul { - padding-left : 20px; - padding-bottom : 5px; - } - ` - var text = yo`
` - var background = yo`
` - var placeholder = yo`
${background}${text}
` - var inserted = false - - window.addEventListener('resize', function (event) { - self.event.trigger('resize', []) - self.event.trigger('resize', []) - }) - - function focusinput (event) { - if ( - event.altKey || - event.ctrlKey || - event.metaKey || - event.shiftKey || - event.key === 'Down' || - event.key === 'ArrowDown' || - event.key === 'Up' || - event.key === 'ArrowUp' || - event.key === 'Left' || - event.key === 'ArrowLeft' || - event.key === 'Right' || - event.key === 'ArrowRight' || - event.key === 'Esc' || - event.key === 'Escape' - ) return - - refocus() - } - - function refocus () { - self._view.input.focus() - reattach({ currentTarget: self._view.term }) - delete self.scroll2bottom - self.scroll2bottom() - } - function reattach (event) { - var el = event.currentTarget - var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 - if (isBottomed) { - if (inserted) { - text.innerText = '' - background.onclick = undefined - if (placeholder.parentElement) self._view.journal.removeChild(placeholder) - } - inserted = false - delete self.scroll2bottom - } else { - if (!inserted) self._view.journal.appendChild(placeholder) - inserted = true - check() - if (!placeholder.nextElementSibling) { - placeholder.style.display = 'none' - } else { - placeholder.style = '' - } - self.scroll2bottom = function () { - var next = placeholder.nextElementSibling - if (next) { - placeholder.style = '' - check() - var messages = 1 - while ((next = next.nextElementSibling)) messages += 1 - text.innerText = `${messages} new unread log entries` - } else { - placeholder.style.display = 'none' - } - } - } - } - function check () { - var pos1 = self._view.term.offsetHeight + self._view.term.scrollTop - (self._view.el.offsetHeight * 0.15) - var pos2 = placeholder.offsetTop - if ((pos1 - pos2) > 0) { - text.style.display = 'none' - background.style.position = 'relative' - background.style.opacity = 0.3 - background.style.right = 0 - background.style.borderBox = 'content-box' - background.style.padding = '2px' - background.style.height = (self._view.journal.offsetHeight - (placeholder.offsetTop + placeholder.offsetHeight)) + 'px' - background.onclick = undefined - background.style.cursor = 'default' - background.style.pointerEvents = 'none' - } else { - background.style = '' - text.style = '' - background.onclick = function (event) { - placeholder.scrollIntoView() - check() - } - } - } - function hover (event) { event.currentTarget.classList.toggle(css.hover) } - function minimize (event) { - event.preventDefault() - event.stopPropagation() - if (event.button === 0) { - var classList = self._view.icon.classList - classList.toggle('fa-angle-double-down') - classList.toggle('fa-angle-double-up') - self.event.trigger('resize', []) - } - } - var filtertimeout = null - function filter (event) { - if (filtertimeout) { - clearTimeout(filtertimeout) - } - filtertimeout = setTimeout(() => { - self.updateJournal({ type: 'search', value: self._view.inputSearch.value }) - self.scroll2bottom() - }, 500) - } - function clear (event) { - refocus() - self._view.journal.innerHTML = '' - } - // ----------------- resizeable ui --------------- - function mousedown (event) { - event.preventDefault() - if (event.which === 1) { - moveGhostbar(event) - document.body.appendChild(ghostbar) - document.addEventListener('mousemove', moveGhostbar) - document.addEventListener('mouseup', removeGhostbar) - document.addEventListener('keydown', cancelGhostbar) - } - } - function cancelGhostbar (event) { - if (event.keyCode === 27) { - document.body.removeChild(ghostbar) - document.removeEventListener('mousemove', moveGhostbar) - document.removeEventListener('mouseup', removeGhostbar) - document.removeEventListener('keydown', cancelGhostbar) - } - } - function moveGhostbar (event) { // @NOTE HORIZONTAL ghostbar - ghostbar.style.top = self._api.getPosition(event) + 'px' - } - function removeGhostbar (event) { - if (self._view.icon.classList.contains('fa-angle-double-up')) { - self._view.icon.classList.toggle('fa-angle-double-down') - self._view.icon.classList.toggle('fa-angle-double-up') - } - document.body.removeChild(ghostbar) - document.removeEventListener('mousemove', moveGhostbar) - document.removeEventListener('mouseup', removeGhostbar) - document.removeEventListener('keydown', cancelGhostbar) - self.event.trigger('resize', [self._api.getPosition(event)]) - } + // render () { + // var self = this + // if (self._view.el) return self._view.el + // self._view.journal = yo`
` + // self._view.input = yo` + // { this.focus() }} onpaste=${paste} onkeydown=${change}> + // ` + // self._view.input.setAttribute('spellcheck', 'false') + // self._view.input.setAttribute('contenteditable', 'true') + // self._view.input.setAttribute('id', 'terminalCliInput') + // self._view.input.setAttribute('data-id', 'terminalCliInput') + + // self._view.input.innerText = '\n' + // self._view.cli = yo` + //
+ // ${'>'} + // ${self._view.input} + //
+ // ` + + // self._view.icon = yo` + // ` + // self._view.dragbar = yo` + //
` + + // self._view.pendingTxCount = yo`
0
` + // self._view.inputSearch = yo` + // ` + // self._view.bar = yo` + //
+ // ${self._view.dragbar} + //
+ // ${self._view.icon} + //
+ // + //
+ // ${self._view.pendingTxCount} + //
+ //
+ // + // + //
+ //
+ // + // ${self._view.inputSearch} + //
+ //
+ //
+ // ` + // self._view.term = yo` + //
+ // ${self._components.autoCompletePopup.render()} + //
+ //
+ // ${self._view.journal} + // ${self._view.cli} + //
+ //
+ // ` + // self._view.el = yo` + //
+ // ${self._view.bar} + // ${self._view.term} + //
+ // ` + // setInterval(async () => { + // try { + // self._view.pendingTxCount.innerHTML = await self.call('udapp', 'pendingTransactionsCount') + // } catch (err) {} + // }, 1000) + + // function listenOnNetwork (ev) { + // self.event.trigger('listenOnNetWork', [ev.currentTarget.checked]) + // } + // function paste (event) { + // const selection = window.getSelection() + // if (!selection.rangeCount) return false + // event.preventDefault() + // event.stopPropagation() + // var clipboard = (event.clipboardData || window.clipboardData) + // var text = clipboard.getData('text/plain') + // text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters + // var temp = document.createElement('div') + // temp.innerHTML = text + // var textnode = document.createTextNode(temp.textContent) + // selection.getRangeAt(0).insertNode(textnode) + // selection.empty() + // self.scroll2bottom() + // placeCaretAtEnd(event.currentTarget) + // } + // function placeCaretAtEnd (el) { + // el.focus() + // var range = document.createRange() + // range.selectNodeContents(el) + // range.collapse(false) + // var sel = window.getSelection() + // sel.removeAllRanges() + // sel.addRange(range) + // } + // function throttle (fn, wait) { + // var time = Date.now() + // return function debounce () { + // if ((time + wait - Date.now()) < 0) { + // fn.apply(this, arguments) + // time = Date.now() + // } + // } + // } + // var css2 = csjs` + // .anchor { + // position : static; + // border-top : 2px dotted blue; + // height : 10px; + // } + // .overlay { + // position : absolute; + // width : 100%; + // display : flex; + // align-items : center; + // justify-content : center; + // bottom : 0; + // right : 15px; + // min-height : 20px; + // } + // .text { + // z-index : 2; + // color : black; + // font-weight : bold; + // pointer-events : none; + // } + // .background { + // z-index : 1; + // opacity : 0.8; + // background-color : #a6aeba; + // cursor : pointer; + // } + // .ul { + // padding-left : 20px; + // padding-bottom : 5px; + // } + // ` + // var text = yo`
` + // var background = yo`
` + // var placeholder = yo`
${background}${text}
` + // var inserted = false + + // window.addEventListener('resize', function (event) { + // self.event.trigger('resize', []) + // self.event.trigger('resize', []) + // }) + + // function focusinput (event) { + // if ( + // event.altKey || + // event.ctrlKey || + // event.metaKey || + // event.shiftKey || + // event.key === 'Down' || + // event.key === 'ArrowDown' || + // event.key === 'Up' || + // event.key === 'ArrowUp' || + // event.key === 'Left' || + // event.key === 'ArrowLeft' || + // event.key === 'Right' || + // event.key === 'ArrowRight' || + // event.key === 'Esc' || + // event.key === 'Escape' + // ) return + + // refocus() + // } + + // function refocus () { + // self._view.input.focus() + // reattach({ currentTarget: self._view.term }) + // delete self.scroll2bottom + // self.scroll2bottom() + // } + // function reattach (event) { + // var el = event.currentTarget + // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 + // if (isBottomed) { + // if (inserted) { + // text.innerText = '' + // background.onclick = undefined + // if (placeholder.parentElement) self._view.journal.removeChild(placeholder) + // } + // inserted = false + // delete self.scroll2bottom + // } else { + // if (!inserted) self._view.journal.appendChild(placeholder) + // inserted = true + // check() + // if (!placeholder.nextElementSibling) { + // placeholder.style.display = 'none' + // } else { + // placeholder.style = '' + // } + // self.scroll2bottom = function () { + // var next = placeholder.nextElementSibling + // if (next) { + // placeholder.style = '' + // check() + // var messages = 1 + // while ((next = next.nextElementSibling)) messages += 1 + // text.innerText = `${messages} new unread log entries` + // } else { + // placeholder.style.display = 'none' + // } + // } + // } + // } + // function check () { + // var pos1 = self._view.term.offsetHeight + self._view.term.scrollTop - (self._view.el.offsetHeight * 0.15) + // var pos2 = placeholder.offsetTop + // if ((pos1 - pos2) > 0) { + // text.style.display = 'none' + // background.style.position = 'relative' + // background.style.opacity = 0.3 + // background.style.right = 0 + // background.style.borderBox = 'content-box' + // background.style.padding = '2px' + // background.style.height = (self._view.journal.offsetHeight - (placeholder.offsetTop + placeholder.offsetHeight)) + 'px' + // background.onclick = undefined + // background.style.cursor = 'default' + // background.style.pointerEvents = 'none' + // } else { + // background.style = '' + // text.style = '' + // background.onclick = function (event) { + // placeholder.scrollIntoView() + // check() + // } + // } + // } + // function hover (event) { event.currentTarget.classList.toggle(css.hover) } + // function minimize (event) { + // event.preventDefault() + // event.stopPropagation() + // if (event.button === 0) { + // var classList = self._view.icon.classList + // classList.toggle('fa-angle-double-down') + // classList.toggle('fa-angle-double-up') + // self.event.trigger('resize', []) + // } + // } + // var filtertimeout = null + // function filter (event) { + // if (filtertimeout) { + // clearTimeout(filtertimeout) + // } + // filtertimeout = setTimeout(() => { + // self.updateJournal({ type: 'search', value: self._view.inputSearch.value }) + // self.scroll2bottom() + // }, 500) + // } + // function clear (event) { + // refocus() + // self._view.journal.innerHTML = '' + // } + // // ----------------- resizeable ui --------------- + // function mousedown (event) { + // event.preventDefault() + // if (event.which === 1) { + // moveGhostbar(event) + // document.body.appendChild(ghostbar) + // document.addEventListener('mousemove', moveGhostbar) + // document.addEventListener('mouseup', removeGhostbar) + // document.addEventListener('keydown', cancelGhostbar) + // } + // } + // function cancelGhostbar (event) { + // if (event.keyCode === 27) { + // document.body.removeChild(ghostbar) + // document.removeEventListener('mousemove', moveGhostbar) + // document.removeEventListener('mouseup', removeGhostbar) + // document.removeEventListener('keydown', cancelGhostbar) + // } + // } + // function moveGhostbar (event) { // @NOTE HORIZONTAL ghostbar + // ghostbar.style.top = self._api.getPosition(event) + 'px' + // } + // function removeGhostbar (event) { + // if (self._view.icon.classList.contains('fa-angle-double-up')) { + // self._view.icon.classList.toggle('fa-angle-double-down') + // self._view.icon.classList.toggle('fa-angle-double-up') + // } + // document.body.removeChild(ghostbar) + // document.removeEventListener('mousemove', moveGhostbar) + // document.removeEventListener('mouseup', removeGhostbar) + // document.removeEventListener('keydown', cancelGhostbar) + // self.event.trigger('resize', [self._api.getPosition(event)]) + // } + + // self._cmdHistory = [] + // self._cmdIndex = -1 + // self._cmdTemp = '' + + // var intro = yo` + //
- Welcome to Remix ${packageJson.version} -

+ //
You can use this terminal to:
+ //
    + //
  • Check transactions details and start debugging.
  • + //
  • Execute JavaScript scripts: + //
    + // - Input a script directly in the command line interface + //
    + // - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface + //
    + // - Right click on a JavaScript file in the file explorer and then click \`Run\` + //
  • + //
+ //
The following libraries are accessible:
+ // + //
+ // ` + + // self._shell('remix.help()', self.commands, () => {}) + // self.commands.html(intro) + + // self._components.txLogger = new TxLogger(this, self.blockchain) + // self._components.txLogger.event.register('debuggingRequested', async (hash) => { + // // TODO should probably be in the run module + // if (!await self._opts.appManager.isActive('debugger')) await self._opts.appManager.activatePlugin('debugger') + // this.call('menuicons', 'select', 'debugger') + // this.call('debugger', 'debug', hash) + // }) + + // return self._view.el + + // function wrapScript (script) { + // const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) + // if (isKnownScript) return script + // return ` + // try { + // const ret = ${script}; + // if (ret instanceof Promise) { + // ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) + // } else { + // console.log(ret) + // } + // } catch (e) { + // console.log(e.message) + // } + // ` + // } + // function change (event) { + // if (self._components.autoCompletePopup.handleAutoComplete( + // event, + // self._view.input.innerText)) return + // if (self._view.input.innerText.length === 0) self._view.input.innerText += '\n' + // if (event.which === 13) { + // if (event.ctrlKey) { // + // self._view.input.innerText += '\n' + // self.putCursor2End(self._view.input) + // self.scroll2bottom() + // self._components.autoCompletePopup.removeAutoComplete() + // } else { // + // self._cmdIndex = -1 + // self._cmdTemp = '' + // event.preventDefault() + // var script = self._view.input.innerText.trim() + // self._view.input.innerText = '\n' + // if (script.length) { + // self._cmdHistory.unshift(script) + // self.commands.script(wrapScript(script)) + // } + // self._components.autoCompletePopup.removeAutoComplete() + // } + // } else if (event.which === 38) { // + // var len = self._cmdHistory.length + // if (len === 0) return event.preventDefault() + // if (self._cmdHistory.length - 1 > self._cmdIndex) { + // self._cmdIndex++ + // } + // self._view.input.innerText = self._cmdHistory[self._cmdIndex] + // self.putCursor2End(self._view.input) + // self.scroll2bottom() + // } else if (event.which === 40) { // + // if (self._cmdIndex > -1) { + // self._cmdIndex-- + // } + // self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp + // self.putCursor2End(self._view.input) + // self.scroll2bottom() + // } else { + // self._cmdTemp = self._view.input.innerText + // } + // } + // } - self._cmdHistory = [] - self._cmdIndex = -1 - self._cmdTemp = '' - - var intro = yo` -
- Welcome to Remix ${packageJson.version} -

-
You can use this terminal to:
-
    -
  • Check transactions details and start debugging.
  • -
  • Execute JavaScript scripts: -
    - - Input a script directly in the command line interface -
    - - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface -
    - - Right click on a JavaScript file in the file explorer and then click \`Run\` -
  • -
-
The following libraries are accessible:
- -
- ` - - self._shell('remix.help()', self.commands, () => {}) - self.commands.html(intro) - - self._components.txLogger = new TxLogger(this, self.blockchain) - self._components.txLogger.event.register('debuggingRequested', async (hash) => { - // TODO should probably be in the run module - if (!await self._opts.appManager.isActive('debugger')) await self._opts.appManager.activatePlugin('debugger') - this.call('menuicons', 'select', 'debugger') - this.call('debugger', 'debug', hash) - }) + render () { + return this.element + } - return self._view.el - - function wrapScript (script) { - const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) - if (isKnownScript) return script - return ` - try { - const ret = ${script}; - if (ret instanceof Promise) { - ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) - } else { - console.log(ret) - } - } catch (e) { - console.log(e.message) - } - ` - } - function change (event) { - if (self._components.autoCompletePopup.handleAutoComplete( - event, - self._view.input.innerText)) return - if (self._view.input.innerText.length === 0) self._view.input.innerText += '\n' - if (event.which === 13) { - if (event.ctrlKey) { // - self._view.input.innerText += '\n' - self.putCursor2End(self._view.input) - self.scroll2bottom() - self._components.autoCompletePopup.removeAutoComplete() - } else { // - self._cmdIndex = -1 - self._cmdTemp = '' - event.preventDefault() - var script = self._view.input.innerText.trim() - self._view.input.innerText = '\n' - if (script.length) { - self._cmdHistory.unshift(script) - self.commands.script(wrapScript(script)) - } - self._components.autoCompletePopup.removeAutoComplete() - } - } else if (event.which === 38) { // - var len = self._cmdHistory.length - if (len === 0) return event.preventDefault() - if (self._cmdHistory.length - 1 > self._cmdIndex) { - self._cmdIndex++ - } - self._view.input.innerText = self._cmdHistory[self._cmdIndex] - self.putCursor2End(self._view.input) - self.scroll2bottom() - } else if (event.which === 40) { // - if (self._cmdIndex > -1) { - self._cmdIndex-- - } - self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp - self.putCursor2End(self._view.input) - self.scroll2bottom() - } else { - self._cmdTemp = self._view.input.innerText - } - } + renderComponent () { + ReactDOM.render(, this.element) } putCursor2End (editable) { 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 337bb2e1bb..f8418db3f2 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -8,9 +8,9 @@ export interface RemixUiTerminalProps {} export const RemixUiTerminal = (props: RemixUiTerminalProps) => { return (
-

Welcome to remix-ui-terminal!

+ Welcome to remix-ui-terminal
) } -export default RemixUiTerminal; +export default RemixUiTerminal From 54d4c9677b652188d5321d8281b58807fb607eff Mon Sep 17 00:00:00 2001 From: tizah Date: Thu, 1 Jul 2021 12:55:08 +0100 Subject: [PATCH 03/48] showing ToggleMenuBar --- apps/remix-ide/src/app/panels/terminal.js | 1088 +++++++++-------- .../terminal/src/lib/remix-ui-terminal.css | 133 ++ .../terminal/src/lib/remix-ui-terminal.tsx | 66 +- 3 files changed, 742 insertions(+), 545 deletions(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index a75f87187c..64404fe87f 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -1,10 +1,10 @@ /* global Node, requestAnimationFrame */ - +import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' +import { RemixUiTerminal } from '@remix-ui/terminal' import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' import * as remixBleach from '../../lib/remixBleach' -import { RemixUiTerminal } from '@remix-ui/terminal' var yo = require('yo-yo') var javascriptserialize = require('javascript-serialize') @@ -40,7 +40,7 @@ class Terminal extends Plugin { constructor (opts, api) { super(profile) this.element = document.createElement('div') - this.element.setAttribute('id', 'terminalView ') + this.element.setAttribute('id', 'terminalView') var self = this self.event = new EventManager() self.blockchain = opts.blockchain @@ -98,561 +98,565 @@ class Terminal extends Plugin { } onActivation () { - this.on('scriptRunner', 'log', (msg) => { - this.commands.log.apply(this.commands, msg.data) - }) - this.on('scriptRunner', 'info', (msg) => { - this.commands.info.apply(this.commands, msg.data) - }) - this.on('scriptRunner', 'warn', (msg) => { - this.commands.warn.apply(this.commands, msg.data) - }) - this.on('scriptRunner', 'error', (msg) => { - this.commands.error.apply(this.commands, msg.data) - }) - } - - onDeactivation () { - this.off('scriptRunner', 'log') - this.off('scriptRunner', 'info') - this.off('scriptRunner', 'warn') - this.off('scriptRunner', 'error') - } - - log (message) { - var command = this.commands[message.type] - if (typeof command === 'function') { - if (typeof message.value === 'string' && message.type === 'html') { - var el = document.createElement('div') - el.innerHTML = remixBleach.sanitize(message.value, { - list: [ - 'a', - 'b', - 'p', - 'em', - 'strong', - 'div', - 'span', - 'ul', - 'li', - 'ol', - 'hr' - ] - }) - message.value = el - } - command(message.value) - }; - } - - logHtml (html) { - var command = this.commands.html - if (typeof command === 'function') command(html) + this.renderComponent() } - focus () { - if (this._view.input) this._view.input.focus() - } - - // render () { - // var self = this - // if (self._view.el) return self._view.el - // self._view.journal = yo`
` - // self._view.input = yo` - // { this.focus() }} onpaste=${paste} onkeydown=${change}> - // ` - // self._view.input.setAttribute('spellcheck', 'false') - // self._view.input.setAttribute('contenteditable', 'true') - // self._view.input.setAttribute('id', 'terminalCliInput') - // self._view.input.setAttribute('data-id', 'terminalCliInput') - - // self._view.input.innerText = '\n' - // self._view.cli = yo` - //
- // ${'>'} - // ${self._view.input} - //
- // ` - - // self._view.icon = yo` - // ` - // self._view.dragbar = yo` - //
` - - // self._view.pendingTxCount = yo`
0
` - // self._view.inputSearch = yo` - // ` - // self._view.bar = yo` - //
- // ${self._view.dragbar} - //
- // ${self._view.icon} - //
- // - //
- // ${self._view.pendingTxCount} - //
- //
- // - // - //
- //
- // - // ${self._view.inputSearch} - //
- //
- //
- // ` - // self._view.term = yo` - //
- // ${self._components.autoCompletePopup.render()} - //
- //
- // ${self._view.journal} - // ${self._view.cli} - //
- //
- // ` - // self._view.el = yo` - //
- // ${self._view.bar} - // ${self._view.term} - //
- // ` - // setInterval(async () => { - // try { - // self._view.pendingTxCount.innerHTML = await self.call('udapp', 'pendingTransactionsCount') - // } catch (err) {} - // }, 1000) - - // function listenOnNetwork (ev) { - // self.event.trigger('listenOnNetWork', [ev.currentTarget.checked]) - // } - // function paste (event) { - // const selection = window.getSelection() - // if (!selection.rangeCount) return false - // event.preventDefault() - // event.stopPropagation() - // var clipboard = (event.clipboardData || window.clipboardData) - // var text = clipboard.getData('text/plain') - // text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters - // var temp = document.createElement('div') - // temp.innerHTML = text - // var textnode = document.createTextNode(temp.textContent) - // selection.getRangeAt(0).insertNode(textnode) - // selection.empty() - // self.scroll2bottom() - // placeCaretAtEnd(event.currentTarget) - // } - // function placeCaretAtEnd (el) { - // el.focus() - // var range = document.createRange() - // range.selectNodeContents(el) - // range.collapse(false) - // var sel = window.getSelection() - // sel.removeAllRanges() - // sel.addRange(range) - // } - // function throttle (fn, wait) { - // var time = Date.now() - // return function debounce () { - // if ((time + wait - Date.now()) < 0) { - // fn.apply(this, arguments) - // time = Date.now() - // } - // } - // } - // var css2 = csjs` - // .anchor { - // position : static; - // border-top : 2px dotted blue; - // height : 10px; - // } - // .overlay { - // position : absolute; - // width : 100%; - // display : flex; - // align-items : center; - // justify-content : center; - // bottom : 0; - // right : 15px; - // min-height : 20px; - // } - // .text { - // z-index : 2; - // color : black; - // font-weight : bold; - // pointer-events : none; - // } - // .background { - // z-index : 1; - // opacity : 0.8; - // background-color : #a6aeba; - // cursor : pointer; - // } - // .ul { - // padding-left : 20px; - // padding-bottom : 5px; - // } - // ` - // var text = yo`
` - // var background = yo`
` - // var placeholder = yo`
${background}${text}
` - // var inserted = false - - // window.addEventListener('resize', function (event) { - // self.event.trigger('resize', []) - // self.event.trigger('resize', []) + // onActivation () { + // this.on('scriptRunner', 'log', (msg) => { + // this.commands.log.apply(this.commands, msg.data) + // }) + // this.on('scriptRunner', 'info', (msg) => { + // this.commands.info.apply(this.commands, msg.data) + // }) + // this.on('scriptRunner', 'warn', (msg) => { + // this.commands.warn.apply(this.commands, msg.data) + // }) + // this.on('scriptRunner', 'error', (msg) => { + // this.commands.error.apply(this.commands, msg.data) // }) + // } - // function focusinput (event) { - // if ( - // event.altKey || - // event.ctrlKey || - // event.metaKey || - // event.shiftKey || - // event.key === 'Down' || - // event.key === 'ArrowDown' || - // event.key === 'Up' || - // event.key === 'ArrowUp' || - // event.key === 'Left' || - // event.key === 'ArrowLeft' || - // event.key === 'Right' || - // event.key === 'ArrowRight' || - // event.key === 'Esc' || - // event.key === 'Escape' - // ) return - - // refocus() - // } + // onDeactivation () { + // this.off('scriptRunner', 'log') + // this.off('scriptRunner', 'info') + // this.off('scriptRunner', 'warn') + // this.off('scriptRunner', 'error') + // } - // function refocus () { - // self._view.input.focus() - // reattach({ currentTarget: self._view.term }) - // delete self.scroll2bottom - // self.scroll2bottom() - // } - // function reattach (event) { - // var el = event.currentTarget - // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 - // if (isBottomed) { - // if (inserted) { - // text.innerText = '' - // background.onclick = undefined - // if (placeholder.parentElement) self._view.journal.removeChild(placeholder) - // } - // inserted = false - // delete self.scroll2bottom - // } else { - // if (!inserted) self._view.journal.appendChild(placeholder) - // inserted = true - // check() - // if (!placeholder.nextElementSibling) { - // placeholder.style.display = 'none' - // } else { - // placeholder.style = '' - // } - // self.scroll2bottom = function () { - // var next = placeholder.nextElementSibling - // if (next) { - // placeholder.style = '' - // check() - // var messages = 1 - // while ((next = next.nextElementSibling)) messages += 1 - // text.innerText = `${messages} new unread log entries` - // } else { - // placeholder.style.display = 'none' - // } - // } - // } - // } - // function check () { - // var pos1 = self._view.term.offsetHeight + self._view.term.scrollTop - (self._view.el.offsetHeight * 0.15) - // var pos2 = placeholder.offsetTop - // if ((pos1 - pos2) > 0) { - // text.style.display = 'none' - // background.style.position = 'relative' - // background.style.opacity = 0.3 - // background.style.right = 0 - // background.style.borderBox = 'content-box' - // background.style.padding = '2px' - // background.style.height = (self._view.journal.offsetHeight - (placeholder.offsetTop + placeholder.offsetHeight)) + 'px' - // background.onclick = undefined - // background.style.cursor = 'default' - // background.style.pointerEvents = 'none' - // } else { - // background.style = '' - // text.style = '' - // background.onclick = function (event) { - // placeholder.scrollIntoView() - // check() - // } - // } - // } - // function hover (event) { event.currentTarget.classList.toggle(css.hover) } - // function minimize (event) { - // event.preventDefault() - // event.stopPropagation() - // if (event.button === 0) { - // var classList = self._view.icon.classList - // classList.toggle('fa-angle-double-down') - // classList.toggle('fa-angle-double-up') - // self.event.trigger('resize', []) - // } - // } - // var filtertimeout = null - // function filter (event) { - // if (filtertimeout) { - // clearTimeout(filtertimeout) - // } - // filtertimeout = setTimeout(() => { - // self.updateJournal({ type: 'search', value: self._view.inputSearch.value }) - // self.scroll2bottom() - // }, 500) - // } - // function clear (event) { - // refocus() - // self._view.journal.innerHTML = '' - // } - // // ----------------- resizeable ui --------------- - // function mousedown (event) { - // event.preventDefault() - // if (event.which === 1) { - // moveGhostbar(event) - // document.body.appendChild(ghostbar) - // document.addEventListener('mousemove', moveGhostbar) - // document.addEventListener('mouseup', removeGhostbar) - // document.addEventListener('keydown', cancelGhostbar) - // } - // } - // function cancelGhostbar (event) { - // if (event.keyCode === 27) { - // document.body.removeChild(ghostbar) - // document.removeEventListener('mousemove', moveGhostbar) - // document.removeEventListener('mouseup', removeGhostbar) - // document.removeEventListener('keydown', cancelGhostbar) - // } - // } - // function moveGhostbar (event) { // @NOTE HORIZONTAL ghostbar - // ghostbar.style.top = self._api.getPosition(event) + 'px' - // } - // function removeGhostbar (event) { - // if (self._view.icon.classList.contains('fa-angle-double-up')) { - // self._view.icon.classList.toggle('fa-angle-double-down') - // self._view.icon.classList.toggle('fa-angle-double-up') + // log (message) { + // var command = this.commands[message.type] + // if (typeof command === 'function') { + // if (typeof message.value === 'string' && message.type === 'html') { + // var el = document.createElement('div') + // el.innerHTML = remixBleach.sanitize(message.value, { + // list: [ + // 'a', + // 'b', + // 'p', + // 'em', + // 'strong', + // 'div', + // 'span', + // 'ul', + // 'li', + // 'ol', + // 'hr' + // ] + // }) + // message.value = el // } - // document.body.removeChild(ghostbar) - // document.removeEventListener('mousemove', moveGhostbar) - // document.removeEventListener('mouseup', removeGhostbar) - // document.removeEventListener('keydown', cancelGhostbar) - // self.event.trigger('resize', [self._api.getPosition(event)]) - // } + // command(message.value) + // }; + // } - // self._cmdHistory = [] - // self._cmdIndex = -1 - // self._cmdTemp = '' - - // var intro = yo` - //
- Welcome to Remix ${packageJson.version} -

- //
You can use this terminal to:
- //
    - //
  • Check transactions details and start debugging.
  • - //
  • Execute JavaScript scripts: - //
    - // - Input a script directly in the command line interface - //
    - // - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface - //
    - // - Right click on a JavaScript file in the file explorer and then click \`Run\` - //
  • - //
- //
The following libraries are accessible:
- // - //
- // ` - - // self._shell('remix.help()', self.commands, () => {}) - // self.commands.html(intro) - - // self._components.txLogger = new TxLogger(this, self.blockchain) - // self._components.txLogger.event.register('debuggingRequested', async (hash) => { - // // TODO should probably be in the run module - // if (!await self._opts.appManager.isActive('debugger')) await self._opts.appManager.activatePlugin('debugger') - // this.call('menuicons', 'select', 'debugger') - // this.call('debugger', 'debug', hash) - // }) + // logHtml (html) { + // var command = this.commands.html + // if (typeof command === 'function') command(html) + // } - // return self._view.el - - // function wrapScript (script) { - // const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) - // if (isKnownScript) return script - // return ` - // try { - // const ret = ${script}; - // if (ret instanceof Promise) { - // ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) - // } else { - // console.log(ret) - // } - // } catch (e) { - // console.log(e.message) - // } - // ` - // } - // function change (event) { - // if (self._components.autoCompletePopup.handleAutoComplete( - // event, - // self._view.input.innerText)) return - // if (self._view.input.innerText.length === 0) self._view.input.innerText += '\n' - // if (event.which === 13) { - // if (event.ctrlKey) { // - // self._view.input.innerText += '\n' - // self.putCursor2End(self._view.input) - // self.scroll2bottom() - // self._components.autoCompletePopup.removeAutoComplete() - // } else { // - // self._cmdIndex = -1 - // self._cmdTemp = '' - // event.preventDefault() - // var script = self._view.input.innerText.trim() - // self._view.input.innerText = '\n' - // if (script.length) { - // self._cmdHistory.unshift(script) - // self.commands.script(wrapScript(script)) - // } - // self._components.autoCompletePopup.removeAutoComplete() - // } - // } else if (event.which === 38) { // - // var len = self._cmdHistory.length - // if (len === 0) return event.preventDefault() - // if (self._cmdHistory.length - 1 > self._cmdIndex) { - // self._cmdIndex++ - // } - // self._view.input.innerText = self._cmdHistory[self._cmdIndex] - // self.putCursor2End(self._view.input) - // self.scroll2bottom() - // } else if (event.which === 40) { // - // if (self._cmdIndex > -1) { - // self._cmdIndex-- - // } - // self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp - // self.putCursor2End(self._view.input) - // self.scroll2bottom() - // } else { - // self._cmdTemp = self._view.input.innerText - // } - // } + // focus () { + // if (this._view.input) this._view.input.focus() // } render () { + // var self = this + // if (self._view.el) return self._view.el + //self._view.journal = yo`
` + // self._view.input = yo` + // { this.focus() }} onpaste=${paste} onkeydown=${change}> + // ` + // self._view.input.setAttribute('spellcheck', 'false') + // self._view.input.setAttribute('contenteditable', 'true') + // self._view.input.setAttribute('id', 'terminalCliInput') + // self._view.input.setAttribute('data-id', 'terminalCliInput') + + // self._view.input.innerText = '\n' + // self._view.cli = yo` + //
+ // ${'>'} + // ${self._view.input} + //
+ // ` + + // self._view.icon = yo` + // ` + // self._view.dragbar = yo` + //
` + + // self._view.pendingTxCount = yo`
0
` + // self._view.inputSearch = yo` + // ` + // self._view.bar = yo` + //
+ // ${self._view.dragbar} + //
+ // ${self._view.icon} + //
+ // + //
+ // ${self._view.pendingTxCount} + //
+ //
+ // + // + //
+ //
+ // + // ${self._view.inputSearch} + //
+ //
+ //
+ // ` + // self._view.term = yo` + //
+ // ${self._components.autoCompletePopup.render()} + //
+ //
+ // ${self._view.journal} + // ${self._view.cli} + //
+ //
+ // ` + // self._view.el = yo` + //
+ // ${self._view.bar} + // ${self._view.term} + //
+ // ` + // setInterval(async () => { + // try { + // self._view.pendingTxCount.innerHTML = await self.call('udapp', 'pendingTransactionsCount') + // } catch (err) {} + // }, 1000) + + // function listenOnNetwork (ev) { + // self.event.trigger('listenOnNetWork', [ev.currentTarget.checked]) + // } + //function paste (event) { + // const selection = window.getSelection() + // if (!selection.rangeCount) return false + // event.preventDefault() + // event.stopPropagation() + // var clipboard = (event.clipboardData || window.clipboardData) + // var text = clipboard.getData('text/plain') + // text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters + // var temp = document.createElement('div') + // temp.innerHTML = text + // var textnode = document.createTextNode(temp.textContent) + // selection.getRangeAt(0).insertNode(textnode) + // selection.empty() + // self.scroll2bottom() + // placeCaretAtEnd(event.currentTarget) + //} + //function placeCaretAtEnd (el) { + // el.focus() + // var range = document.createRange() + // range.selectNodeContents(el) + // range.collapse(false) + // var sel = window.getSelection() + // sel.removeAllRanges() + // sel.addRange(range) + // } + // function throttle (fn, wait) { + // var time = Date.now() + // return function debounce () { + // if ((time + wait - Date.now()) < 0) { + // fn.apply(this, arguments) + // time = Date.now() + // } + // } + // } + // var css2 = csjs` + // .anchor { + // position : static; + // border-top : 2px dotted blue; + // height : 10px; + // } + // .overlay { + // position : absolute; + // width : 100%; + // display : flex; + // align-items : center; + // justify-content : center; + // bottom : 0; + // right : 15px; + // min-height : 20px; + // } + // .text { + // z-index : 2; + // color : black; + // font-weight : bold; + // pointer-events : none; + // } + // .background { + // z-index : 1; + // opacity : 0.8; + // background-color : #a6aeba; + // cursor : pointer; + // } + // .ul { + // padding-left : 20px; + // padding-bottom : 5px; + // } + // ` + // var text = yo`
` + // var background = yo`
` + // var placeholder = yo`
${background}${text}
` + // var inserted = false + + // window.addEventListener('resize', function (event) { + // self.event.trigger('resize', []) + // self.event.trigger('resize', []) + // }) + + //function focusinput (event) { + // if ( + // event.altKey || + // event.ctrlKey || + // event.metaKey || + // event.shiftKey || + // event.key === 'Down' || + // event.key === 'ArrowDown' || + // event.key === 'Up' || + // event.key === 'ArrowUp' || + // event.key === 'Left' || + // event.key === 'ArrowLeft' || + // event.key === 'Right' || + // event.key === 'ArrowRight' || + // event.key === 'Esc' || + // event.key === 'Escape' + // ) return + + // refocus() + //} + + // function refocus () { + // self._view.input.focus() + // reattach({ currentTarget: self._view.term }) + // delete self.scroll2bottom + // self.scroll2bottom() + // } + //function reattach (event) { + // var el = event.currentTarget + // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 + // if (isBottomed) { + // if (inserted) { + // text.innerText = '' + // background.onclick = undefined + // if (placeholder.parentElement) self._view.journal.removeChild(placeholder) + // } + // inserted = false + // delete self.scroll2bottom + // } else { + // if (!inserted) self._view.journal.appendChild(placeholder) + // inserted = true + // check() + // if (!placeholder.nextElementSibling) { + // placeholder.style.display = 'none' + // } else { + // placeholder.style = '' + // } + // self.scroll2bottom = function () { + // var next = placeholder.nextElementSibling + // if (next) { + // placeholder.style = '' + // check() + // var messages = 1 + // while ((next = next.nextElementSibling)) messages += 1 + // text.innerText = `${messages} new unread log entries` + // } else { + // placeholder.style.display = 'none' + // } + // } + // } + //} + //function check () { + // var pos1 = self._view.term.offsetHeight + self._view.term.scrollTop - (self._view.el.offsetHeight * 0.15) + // var pos2 = placeholder.offsetTop + // if ((pos1 - pos2) > 0) { + // text.style.display = 'none' + // background.style.position = 'relative' + // background.style.opacity = 0.3 + // background.style.right = 0 + // background.style.borderBox = 'content-box' + // background.style.padding = '2px' + // background.style.height = (self._view.journal.offsetHeight - (placeholder.offsetTop + placeholder.offsetHeight)) + 'px' + // background.onclick = undefined + // background.style.cursor = 'default' + // background.style.pointerEvents = 'none' + // } else { + // background.style = '' + // text.style = '' + // background.onclick = function (event) { + // placeholder.scrollIntoView() + // check() + // } + // } + //} + //function hover (event) { event.currentTarget.classList.toggle(css.hover) } + //function minimize (event) { + // event.preventDefault() + // event.stopPropagation() + // if (event.button === 0) { + // var classList = self._view.icon.classList + // classList.toggle('fa-angle-double-down') + // classList.toggle('fa-angle-double-up') + // self.event.trigger('resize', []) + // } + //} + // var filtertimeout = null + //function filter (event) { + // if (filtertimeout) { + // clearTimeout(filtertimeout) + // } + // filtertimeout = setTimeout(() => { + // self.updateJournal({ type: 'search', value: self._view.inputSearch.value }) + // self.scroll2bottom() + // }, 500) + // } + // function clear (event) { + // refocus() + // self._view.journal.innerHTML = '' + // } + // ----------------- resizeable ui --------------- + //function mousedown (event) { + // event.preventDefault() + // if (event.which === 1) { + // moveGhostbar(event) + // document.body.appendChild(ghostbar) + // document.addEventListener('mousemove', moveGhostbar) + // document.addEventListener('mouseup', removeGhostbar) + // document.addEventListener('keydown', cancelGhostbar) + // } + //} + //function cancelGhostbar (event) { + // if (event.keyCode === 27) { + // document.body.removeChild(ghostbar) + // document.removeEventListener('mousemove', moveGhostbar) + // document.removeEventListener('mouseup', removeGhostbar) + // document.removeEventListener('keydown', cancelGhostbar) + // } + // } + // function moveGhostbar (event) { // @NOTE HORIZONTAL ghostbar + // ghostbar.style.top = self._api.getPosition(event) + 'px' + // } + // function removeGhostbar (event) { + // if (self._view.icon.classList.contains('fa-angle-double-up')) { + // self._view.icon.classList.toggle('fa-angle-double-down') + // self._view.icon.classList.toggle('fa-angle-double-up') + // } + // document.body.removeChild(ghostbar) + // document.removeEventListener('mousemove', moveGhostbar) + // document.removeEventListener('mouseup', removeGhostbar) + // document.removeEventListener('keydown', cancelGhostbar) + // self.event.trigger('resize', [self._api.getPosition(event)]) + // } + + // self._cmdHistory = [] + // self._cmdIndex = -1 + // self._cmdTemp = '' + + // var intro = yo` + //
- Welcome to Remix ${packageJson.version} -

+ //
You can use this terminal to:
+ //
    + //
  • Check transactions details and start debugging.
  • + //
  • Execute JavaScript scripts: + //
    + // - Input a script directly in the command line interface + //
    + // - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface + //
    + // - Right click on a JavaScript file in the file explorer and then click \`Run\` + //
  • + //
+ //
The following libraries are accessible:
+ // + //
+ // ` + + //self._shell('remix.help()', self.commands, () => {}) + //self.commands.html(intro) + + //self._components.txLogger = new TxLogger(this, self.blockchain) + // self._components.txLogger.event.register('debuggingRequested', async (hash) => { + // // TODO should probably be in the run module + // if (!await self._opts.appManager.isActive('debugger')) await self._opts.appManager.activatePlugin('debugger') + // this.call('menuicons', 'select', 'debugger') + // this.call('debugger', 'debug', hash) + // }) + + // return self._view.el return this.element + // function wrapScript (script) { + // const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) + // if (isKnownScript) return script + // return ` + // try { + // const ret = ${script}; + // if (ret instanceof Promise) { + // ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) + // } else { + // console.log(ret) + // } + // } catch (e) { + // console.log(e.message) + // } + // ` + // } + //function change (event) { + // if (self._components.autoCompletePopup.handleAutoComplete( + // event, + // self._view.input.innerText)) return + // if (self._view.input.innerText.length === 0) self._view.input.innerText += '\n' + // if (event.which === 13) { + // if (event.ctrlKey) { // + // self._view.input.innerText += '\n' + // self.putCursor2End(self._view.input) + // self.scroll2bottom() + // self._components.autoCompletePopup.removeAutoComplete() + // } else { // + // self._cmdIndex = -1 + // self._cmdTemp = '' + // event.preventDefault() + // var script = self._view.input.innerText.trim() + // self._view.input.innerText = '\n' + // if (script.length) { + // self._cmdHistory.unshift(script) + // self.commands.script(wrapScript(script)) + // } + // self._components.autoCompletePopup.removeAutoComplete() + // } + // } else if (event.which === 38) { // + // var len = self._cmdHistory.length + // if (len === 0) return event.preventDefault() + // if (self._cmdHistory.length - 1 > self._cmdIndex) { + // self._cmdIndex++ + // } + // self._view.input.innerText = self._cmdHistory[self._cmdIndex] + // self.putCursor2End(self._view.input) + // self.scroll2bottom() + // } else if (event.which === 40) { // + // if (self._cmdIndex > -1) { + // self._cmdIndex-- + // } + // self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp + // self.putCursor2End(self._view.input) + // self.scroll2bottom() + // } else { + // self._cmdTemp = self._view.input.innerText + // } + //} } renderComponent () { - ReactDOM.render(, this.element) + ReactDOM.render( + , + this.element + ) } - putCursor2End (editable) { - var range = document.createRange() - range.selectNode(editable) - var child = editable - var chars - - while (child) { - if (child.lastChild) child = child.lastChild - else break - if (child.nodeType === Node.TEXT_NODE) { - chars = child.textContent.length - } else { - chars = child.innerHTML.length - } - } + // putCursor2End (editable) { + // var range = document.createRange() + // range.selectNode(editable) + // var child = editable + // var chars + + // while (child) { + // if (child.lastChild) child = child.lastChild + // else break + // if (child.nodeType === Node.TEXT_NODE) { + // chars = child.textContent.length + // } else { + // chars = child.innerHTML.length + // } + // } - range.setEnd(child, chars) - var toStart = true - var toEnd = !toStart - range.collapse(toEnd) + // range.setEnd(child, chars) + // var toStart = true + // var toEnd = !toStart + // range.collapse(toEnd) - var sel = window.getSelection() - sel.removeAllRanges() - sel.addRange(range) + // var sel = window.getSelection() + // sel.removeAllRanges() + // sel.addRange(range) - editable.focus() - } + // editable.focus() + // } - updateJournal (filterEvent) { - var self = this - var commands = self.data.activeFilters.commands - var value = filterEvent.value - if (filterEvent.type === 'select') { - commands[value] = true - if (!self._INDEX.commandsMain[value]) return - self._INDEX.commandsMain[value].forEach(item => { - item.root.steps.forEach(item => { self._JOURNAL[item.gidx] = item }) - self._JOURNAL[item.gidx] = item - }) - } else if (filterEvent.type === 'deselect') { - commands[value] = false - if (!self._INDEX.commandsMain[value]) return - self._INDEX.commandsMain[value].forEach(item => { - item.root.steps.forEach(item => { self._JOURNAL[item.gidx].hide = true }) - self._JOURNAL[item.gidx].hide = true - }) - } else if (filterEvent.type === 'search') { - if (value !== self.data.activeFilters.input) { - var query = self.data.activeFilters.input = value - var items = self._JOURNAL - for (var gidx = 0, len = items.length; gidx < len; gidx++) { - var item = items[gidx] - if (item && self.data.filterFns[item.cmd]) { - var show = query.length ? self.data.filterFns[item.cmd](item.args, query) : true - item.hide = !show - } - } - } - } - var df = document.createDocumentFragment() - self._JOURNAL.forEach(item => { - if (item && item.el && !item.hide) df.appendChild(item.el) - }) - self._view.journal.innerHTML = '' - requestAnimationFrame(function updateDOM () { - self._view.journal.appendChild(df) - }) - } + //updateJournal (filterEvent) { + // var self = this + // var commands = self.data.activeFilters.commands + // var value = filterEvent.value + // if (filterEvent.type === 'select') { + // commands[value] = true + // if (!self._INDEX.commandsMain[value]) return + // self._INDEX.commandsMain[value].forEach(item => { + // item.root.steps.forEach(item => { self._JOURNAL[item.gidx] = item }) + // self._JOURNAL[item.gidx] = item + // }) + // } + // else if (filterEvent.type === 'deselect') { + // commands[value] = false + // if (!self._INDEX.commandsMain[value]) return + // self._INDEX.commandsMain[value].forEach(item => { + // item.root.steps.forEach(item => { self._JOURNAL[item.gidx].hide = true }) + // self._JOURNAL[item.gidx].hide = true + // }) + // } else if (filterEvent.type === 'search') { + // if (value !== self.data.activeFilters.input) { + // var query = self.data.activeFilters.input = value + // var items = self._JOURNAL + // for (var gidx = 0, len = items.length; gidx < len; gidx++) { + // var item = items[gidx] + // if (item && self.data.filterFns[item.cmd]) { + // var show = query.length ? self.data.filterFns[item.cmd](item.args, query) : true + // item.hide = !show + // } + // } + // } + // } + // var df = document.createDocumentFragment() + // self._JOURNAL.forEach(item => { + // if (item && item.el && !item.hide) df.appendChild(item.el) + // }) + // self._view.journal.innerHTML = '' + // requestAnimationFrame(function updateDOM () { + // self._view.journal.appendChild(df) + // }) + //} _appendItem (item) { var self = this @@ -805,11 +809,11 @@ class Terminal extends Plugin { } } -function domTerminalFeatures (self, scopedCommands, blockchain) { - return { - remix: self._components.cmdInterpreter - } -} +// function domTerminalFeatures (self, scopedCommands, blockchain) { +// return { +// remix: self._components.cmdInterpreter +// } +// } function blockify (el) { return yo`
${el}
` } 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 e69de29bb2..a8870af675 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -0,0 +1,133 @@ +.panel { + position : relative; + display : flex; + flex-direction : column; + font-size : 12px; + min-height : 3em; + } + .bar { + display : flex; + z-index : 2; + } + .menu { + position : relative; + display : flex; + align-items : center; + width : 100%; + max-height : 35px; + min-height : 35px; + } + .toggleTerminal { + cursor : pointer; + } + .toggleTerminal:hover { + color : var(--secondary); + } + .terminal_container { + display : flex; + flex-direction : column; + height : 100%; + overflow-y : auto; + font-family : monospace; + margin : 0px; + background-repeat : no-repeat; + background-position : center 15%; + background-size : auto calc(75% - 1.7em); + } + .terminal { + position : relative; + display : flex; + flex-direction : column; + height : 100%; + } + .journal { + margin-top : auto; + font-family : monospace; + } + .block { + word-break : break-word; + white-space : pre-wrap; + line-height : 2ch; + padding : 1ch; + margin-top : 2ch; + } + .block > pre { + max-height : 200px; + } + .cli { + line-height : 1.7em; + font-family : monospace; + padding : .4em; + color : var(--primary); + border-top : solid 2px var(--secondary); + } + .prompt { + margin-right : 0.5em; + font-family : monospace; + font-weight : bold; + font-size : 14px; + } + .input { + word-break : break-word; + outline : none; + font-family : monospace; + } + .search { + display : flex; + align-items : center; + width : 330px; + padding-left : 20px; + height : 100%; + padding-top : 1px; + padding-bottom : 1px; + } + .filter { + height : 80%; + white-space : nowrap; + overflow : hidden; + text-overflow : ellipsis; + } + .searchIcon { + width : 25px; + border-top-left-radius : 3px; + border-bottom-left-radius : 3px; + display : flex; + align-items : center; + justify-content : center; + margin-right : 5px; + } + .listen { + margin-right : 30px; + min-width : 40px; + height : 13px; + display : flex; + align-items : center; + } + .listenLabel { + min-width: 50px; + } + .verticalLine { + border-left : 1px solid var(--secondary); + height : 65%; + } + .dragbarHorizontal { + position : absolute; + top : 0; + height : 0.5em; + right : 0; + left : 0; + cursor : ns-resize; + z-index : 999; + } + .listenOnNetwork { + min-height: auto; + } + .ghostbar { + position : absolute; + height : 6px; + opacity : 0.5; + cursor : row-resize; + z-index : 9999; + left : 0; + right : 0; + } \ No newline at end of file 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 f8418db3f2..106f5812a9 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,14 +1,74 @@ -import React from 'react' +import React, { useState } from 'react' // eslint-disable-line import './remix-ui-terminal.css' /* eslint-disable-next-line */ -export interface RemixUiTerminalProps {} +export interface RemixUiTerminalProps { + propterties: any +} export const RemixUiTerminal = (props: RemixUiTerminalProps) => { + + const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') + + const handleMinimizeTerminal = (event) => { + console.log('clikced') + if (toggleDownUp === 'fa-angle-double-down') { + console.log('clikced down') + setToggleDownUp('fa-angle-double-up') + } else { + console.log('clikced up') + // event.trigger('resize', []) + setToggleDownUp('fa-angle-double-down') + } + } return (
- Welcome to remix-ui-terminal + {console.log({ toggleDownUp })} +
+ {/* ${self._view.dragbar} */} +
+
+ {/* ${self._view.icon} */} + +
+ +
+ {/* ${self._view.pendingTxCount} */} +
0
+
+
+ + +
+
+ + {/* ${self._view.inputSearch} */} + +
+
+
+ Welcome to remix-ui-terminal {console.log(props.propterties, ' properties david')}
) } From 5b132033d3cd2c49d80140168b11f5cb7c276ce2 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 5 Jul 2021 10:34:33 +0100 Subject: [PATCH 04/48] removing unused code in terminal.js and adding props to remix-ui-terminal.ts --- apps/remix-ide/src/app/panels/terminal.js | 653 ++---------------- .../src/lib/actions/terminalAction.ts | 0 .../src/lib/reducers/terminalReducer.ts | 0 .../terminal/src/lib/remix-ui-terminal.tsx | 44 +- 4 files changed, 94 insertions(+), 603 deletions(-) create mode 100644 libs/remix-ui/terminal/src/lib/actions/terminalAction.ts create mode 100644 libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 64404fe87f..2d17230b72 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -1,10 +1,9 @@ -/* global Node, requestAnimationFrame */ +/* global Node, requestAnimationFrame */ // eslint-disable-line import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' -import { RemixUiTerminal } from '@remix-ui/terminal' +import { RemixUiTerminal } from '@remix-ui/terminal' // eslint-disable-line import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' -import * as remixBleach from '../../lib/remixBleach' var yo = require('yo-yo') var javascriptserialize = require('javascript-serialize') @@ -15,9 +14,6 @@ var EventManager = require('../../lib/events') var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI') var AutoCompletePopup = require('../ui/auto-complete-popup') -var TxLogger = require('../../app/ui/txLogger') - -var csjs = require('csjs-inject') var css = require('./styles/terminal-styles') @@ -25,8 +21,6 @@ var KONSOLES = [] function register (api) { KONSOLES.push(api) } -var ghostbar = yo`
` - const profile = { displayName: 'Terminal', name: 'terminal', @@ -41,623 +35,84 @@ class Terminal extends Plugin { super(profile) this.element = document.createElement('div') this.element.setAttribute('id', 'terminalView') - var self = this - self.event = new EventManager() - self.blockchain = opts.blockchain - self._api = api - self._opts = opts - self.data = { + this.event = new EventManager() + this.blockchain = opts.blockchain + this._api = api + this._opts = opts + this.data = { lineLength: opts.lineLength || 80, // ???? session: [], activeFilters: { commands: {}, input: '' }, filterFns: {} } - self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null } - self._components = {} - self._components.cmdInterpreter = new CommandInterpreterAPI(this, null, self.blockchain) - self._components.autoCompletePopup = new AutoCompletePopup(self._opts) - self._components.autoCompletePopup.event.register('handleSelect', function (input) { - const textList = self._view.input.innerText.split(' ') + this._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null } + this._components = {} + this._components.cmdInterpreter = new CommandInterpreterAPI(this, null, this.blockchain) + this._components.autoCompletePopup = new AutoCompletePopup(this._opts) + this._components.autoCompletePopup.event.register('handleSelect', function (input) { + const textList = this._view.input.innerText.split(' ') textList.pop() textList.push(input) - self._view.input.innerText = textList - self._view.input.focus() - self.putCursor2End(self._view.input) + this._view.input.innerText = textList + this._view.input.focus() + this.putCursor2End(this._view.input) }) - self._commands = {} - self.commands = {} - self._JOURNAL = [] - self._jobs = [] - self._INDEX = {} - self._INDEX.all = [] - self._INDEX.allMain = [] - self._INDEX.commands = {} - self._INDEX.commandsMain = {} - self.registerCommand('html', self._blocksRenderer('html'), { activate: true }) - self.registerCommand('log', self._blocksRenderer('log'), { activate: true }) - self.registerCommand('info', self._blocksRenderer('info'), { activate: true }) - self.registerCommand('warn', self._blocksRenderer('warn'), { activate: true }) - self.registerCommand('error', self._blocksRenderer('error'), { activate: true }) - self.registerCommand('script', function execute (args, scopedCommands, append) { + this._commands = {} + this.commands = {} + this._JOURNAL = [] + this._jobs = [] + this._INDEX = {} + this._INDEX.all = [] + this._INDEX.allMain = [] + this._INDEX.commands = {} + this._INDEX.commandsMain = {} + this.registerCommand('html', this._blocksRenderer('html'), { activate: true }) + this.registerCommand('log', this._blocksRenderer('log'), { activate: true }) + this.registerCommand('info', this._blocksRenderer('info'), { activate: true }) + this.registerCommand('warn', this._blocksRenderer('warn'), { activate: true }) + this.registerCommand('error', this._blocksRenderer('error'), { activate: true }) + this.registerCommand('script', function execute (args, scopedCommands, append) { var script = String(args[0]) - self._shell(script, scopedCommands, function (error, output) { + this._shell(script, scopedCommands, function (error, output) { if (error) scopedCommands.error(error) else if (output) scopedCommands.log(output) }) }, { activate: true }) function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } } - self.registerFilter('log', basicFilter) - self.registerFilter('info', basicFilter) - self.registerFilter('warn', basicFilter) - self.registerFilter('error', basicFilter) - self.registerFilter('script', basicFilter) + this.registerFilter('log', basicFilter) + this.registerFilter('info', basicFilter) + this.registerFilter('warn', basicFilter) + this.registerFilter('error', basicFilter) + this.registerFilter('script', basicFilter) - if (opts.shell) self._shell = opts.shell // ??? - register(self) + if (opts.shell) this._shell = opts.shell // ??? + register(this) } onActivation () { this.renderComponent() } - // onActivation () { - // this.on('scriptRunner', 'log', (msg) => { - // this.commands.log.apply(this.commands, msg.data) - // }) - // this.on('scriptRunner', 'info', (msg) => { - // this.commands.info.apply(this.commands, msg.data) - // }) - // this.on('scriptRunner', 'warn', (msg) => { - // this.commands.warn.apply(this.commands, msg.data) - // }) - // this.on('scriptRunner', 'error', (msg) => { - // this.commands.error.apply(this.commands, msg.data) - // }) - // } - - // onDeactivation () { - // this.off('scriptRunner', 'log') - // this.off('scriptRunner', 'info') - // this.off('scriptRunner', 'warn') - // this.off('scriptRunner', 'error') - // } - - // log (message) { - // var command = this.commands[message.type] - // if (typeof command === 'function') { - // if (typeof message.value === 'string' && message.type === 'html') { - // var el = document.createElement('div') - // el.innerHTML = remixBleach.sanitize(message.value, { - // list: [ - // 'a', - // 'b', - // 'p', - // 'em', - // 'strong', - // 'div', - // 'span', - // 'ul', - // 'li', - // 'ol', - // 'hr' - // ] - // }) - // message.value = el - // } - // command(message.value) - // }; - // } - - // logHtml (html) { - // var command = this.commands.html - // if (typeof command === 'function') command(html) - // } - - // focus () { - // if (this._view.input) this._view.input.focus() - // } - render () { - // var self = this - // if (self._view.el) return self._view.el - //self._view.journal = yo`
` - // self._view.input = yo` - // { this.focus() }} onpaste=${paste} onkeydown=${change}> - // ` - // self._view.input.setAttribute('spellcheck', 'false') - // self._view.input.setAttribute('contenteditable', 'true') - // self._view.input.setAttribute('id', 'terminalCliInput') - // self._view.input.setAttribute('data-id', 'terminalCliInput') - - // self._view.input.innerText = '\n' - // self._view.cli = yo` - //
- // ${'>'} - // ${self._view.input} - //
- // ` - - // self._view.icon = yo` - // ` - // self._view.dragbar = yo` - //
` - - // self._view.pendingTxCount = yo`
0
` - // self._view.inputSearch = yo` - // ` - // self._view.bar = yo` - //
- // ${self._view.dragbar} - //
- // ${self._view.icon} - //
- // - //
- // ${self._view.pendingTxCount} - //
- //
- // - // - //
- //
- // - // ${self._view.inputSearch} - //
- //
- //
- // ` - // self._view.term = yo` - //
- // ${self._components.autoCompletePopup.render()} - //
- //
- // ${self._view.journal} - // ${self._view.cli} - //
- //
- // ` - // self._view.el = yo` - //
- // ${self._view.bar} - // ${self._view.term} - //
- // ` - // setInterval(async () => { - // try { - // self._view.pendingTxCount.innerHTML = await self.call('udapp', 'pendingTransactionsCount') - // } catch (err) {} - // }, 1000) - - // function listenOnNetwork (ev) { - // self.event.trigger('listenOnNetWork', [ev.currentTarget.checked]) - // } - //function paste (event) { - // const selection = window.getSelection() - // if (!selection.rangeCount) return false - // event.preventDefault() - // event.stopPropagation() - // var clipboard = (event.clipboardData || window.clipboardData) - // var text = clipboard.getData('text/plain') - // text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters - // var temp = document.createElement('div') - // temp.innerHTML = text - // var textnode = document.createTextNode(temp.textContent) - // selection.getRangeAt(0).insertNode(textnode) - // selection.empty() - // self.scroll2bottom() - // placeCaretAtEnd(event.currentTarget) - //} - //function placeCaretAtEnd (el) { - // el.focus() - // var range = document.createRange() - // range.selectNodeContents(el) - // range.collapse(false) - // var sel = window.getSelection() - // sel.removeAllRanges() - // sel.addRange(range) - // } - // function throttle (fn, wait) { - // var time = Date.now() - // return function debounce () { - // if ((time + wait - Date.now()) < 0) { - // fn.apply(this, arguments) - // time = Date.now() - // } - // } - // } - // var css2 = csjs` - // .anchor { - // position : static; - // border-top : 2px dotted blue; - // height : 10px; - // } - // .overlay { - // position : absolute; - // width : 100%; - // display : flex; - // align-items : center; - // justify-content : center; - // bottom : 0; - // right : 15px; - // min-height : 20px; - // } - // .text { - // z-index : 2; - // color : black; - // font-weight : bold; - // pointer-events : none; - // } - // .background { - // z-index : 1; - // opacity : 0.8; - // background-color : #a6aeba; - // cursor : pointer; - // } - // .ul { - // padding-left : 20px; - // padding-bottom : 5px; - // } - // ` - // var text = yo`
` - // var background = yo`
` - // var placeholder = yo`
${background}${text}
` - // var inserted = false - - // window.addEventListener('resize', function (event) { - // self.event.trigger('resize', []) - // self.event.trigger('resize', []) - // }) - - //function focusinput (event) { - // if ( - // event.altKey || - // event.ctrlKey || - // event.metaKey || - // event.shiftKey || - // event.key === 'Down' || - // event.key === 'ArrowDown' || - // event.key === 'Up' || - // event.key === 'ArrowUp' || - // event.key === 'Left' || - // event.key === 'ArrowLeft' || - // event.key === 'Right' || - // event.key === 'ArrowRight' || - // event.key === 'Esc' || - // event.key === 'Escape' - // ) return - - // refocus() - //} - - // function refocus () { - // self._view.input.focus() - // reattach({ currentTarget: self._view.term }) - // delete self.scroll2bottom - // self.scroll2bottom() - // } - //function reattach (event) { - // var el = event.currentTarget - // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 - // if (isBottomed) { - // if (inserted) { - // text.innerText = '' - // background.onclick = undefined - // if (placeholder.parentElement) self._view.journal.removeChild(placeholder) - // } - // inserted = false - // delete self.scroll2bottom - // } else { - // if (!inserted) self._view.journal.appendChild(placeholder) - // inserted = true - // check() - // if (!placeholder.nextElementSibling) { - // placeholder.style.display = 'none' - // } else { - // placeholder.style = '' - // } - // self.scroll2bottom = function () { - // var next = placeholder.nextElementSibling - // if (next) { - // placeholder.style = '' - // check() - // var messages = 1 - // while ((next = next.nextElementSibling)) messages += 1 - // text.innerText = `${messages} new unread log entries` - // } else { - // placeholder.style.display = 'none' - // } - // } - // } - //} - //function check () { - // var pos1 = self._view.term.offsetHeight + self._view.term.scrollTop - (self._view.el.offsetHeight * 0.15) - // var pos2 = placeholder.offsetTop - // if ((pos1 - pos2) > 0) { - // text.style.display = 'none' - // background.style.position = 'relative' - // background.style.opacity = 0.3 - // background.style.right = 0 - // background.style.borderBox = 'content-box' - // background.style.padding = '2px' - // background.style.height = (self._view.journal.offsetHeight - (placeholder.offsetTop + placeholder.offsetHeight)) + 'px' - // background.onclick = undefined - // background.style.cursor = 'default' - // background.style.pointerEvents = 'none' - // } else { - // background.style = '' - // text.style = '' - // background.onclick = function (event) { - // placeholder.scrollIntoView() - // check() - // } - // } - //} - //function hover (event) { event.currentTarget.classList.toggle(css.hover) } - //function minimize (event) { - // event.preventDefault() - // event.stopPropagation() - // if (event.button === 0) { - // var classList = self._view.icon.classList - // classList.toggle('fa-angle-double-down') - // classList.toggle('fa-angle-double-up') - // self.event.trigger('resize', []) - // } - //} - // var filtertimeout = null - //function filter (event) { - // if (filtertimeout) { - // clearTimeout(filtertimeout) - // } - // filtertimeout = setTimeout(() => { - // self.updateJournal({ type: 'search', value: self._view.inputSearch.value }) - // self.scroll2bottom() - // }, 500) - // } - // function clear (event) { - // refocus() - // self._view.journal.innerHTML = '' - // } - // ----------------- resizeable ui --------------- - //function mousedown (event) { - // event.preventDefault() - // if (event.which === 1) { - // moveGhostbar(event) - // document.body.appendChild(ghostbar) - // document.addEventListener('mousemove', moveGhostbar) - // document.addEventListener('mouseup', removeGhostbar) - // document.addEventListener('keydown', cancelGhostbar) - // } - //} - //function cancelGhostbar (event) { - // if (event.keyCode === 27) { - // document.body.removeChild(ghostbar) - // document.removeEventListener('mousemove', moveGhostbar) - // document.removeEventListener('mouseup', removeGhostbar) - // document.removeEventListener('keydown', cancelGhostbar) - // } - // } - // function moveGhostbar (event) { // @NOTE HORIZONTAL ghostbar - // ghostbar.style.top = self._api.getPosition(event) + 'px' - // } - // function removeGhostbar (event) { - // if (self._view.icon.classList.contains('fa-angle-double-up')) { - // self._view.icon.classList.toggle('fa-angle-double-down') - // self._view.icon.classList.toggle('fa-angle-double-up') - // } - // document.body.removeChild(ghostbar) - // document.removeEventListener('mousemove', moveGhostbar) - // document.removeEventListener('mouseup', removeGhostbar) - // document.removeEventListener('keydown', cancelGhostbar) - // self.event.trigger('resize', [self._api.getPosition(event)]) - // } - - // self._cmdHistory = [] - // self._cmdIndex = -1 - // self._cmdTemp = '' - - // var intro = yo` - //
- Welcome to Remix ${packageJson.version} -

- //
You can use this terminal to:
- //
    - //
  • Check transactions details and start debugging.
  • - //
  • Execute JavaScript scripts: - //
    - // - Input a script directly in the command line interface - //
    - // - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface - //
    - // - Right click on a JavaScript file in the file explorer and then click \`Run\` - //
  • - //
- //
The following libraries are accessible:
- // - //
- // ` - - //self._shell('remix.help()', self.commands, () => {}) - //self.commands.html(intro) - - //self._components.txLogger = new TxLogger(this, self.blockchain) - // self._components.txLogger.event.register('debuggingRequested', async (hash) => { - // // TODO should probably be in the run module - // if (!await self._opts.appManager.isActive('debugger')) await self._opts.appManager.activatePlugin('debugger') - // this.call('menuicons', 'select', 'debugger') - // this.call('debugger', 'debug', hash) - // }) - - // return self._view.el return this.element - // function wrapScript (script) { - // const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) - // if (isKnownScript) return script - // return ` - // try { - // const ret = ${script}; - // if (ret instanceof Promise) { - // ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) - // } else { - // console.log(ret) - // } - // } catch (e) { - // console.log(e.message) - // } - // ` - // } - //function change (event) { - // if (self._components.autoCompletePopup.handleAutoComplete( - // event, - // self._view.input.innerText)) return - // if (self._view.input.innerText.length === 0) self._view.input.innerText += '\n' - // if (event.which === 13) { - // if (event.ctrlKey) { // - // self._view.input.innerText += '\n' - // self.putCursor2End(self._view.input) - // self.scroll2bottom() - // self._components.autoCompletePopup.removeAutoComplete() - // } else { // - // self._cmdIndex = -1 - // self._cmdTemp = '' - // event.preventDefault() - // var script = self._view.input.innerText.trim() - // self._view.input.innerText = '\n' - // if (script.length) { - // self._cmdHistory.unshift(script) - // self.commands.script(wrapScript(script)) - // } - // self._components.autoCompletePopup.removeAutoComplete() - // } - // } else if (event.which === 38) { // - // var len = self._cmdHistory.length - // if (len === 0) return event.preventDefault() - // if (self._cmdHistory.length - 1 > self._cmdIndex) { - // self._cmdIndex++ - // } - // self._view.input.innerText = self._cmdHistory[self._cmdIndex] - // self.putCursor2End(self._view.input) - // self.scroll2bottom() - // } else if (event.which === 40) { // - // if (self._cmdIndex > -1) { - // self._cmdIndex-- - // } - // self._view.input.innerText = self._cmdIndex >= 0 ? self._cmdHistory[self._cmdIndex] : self._cmdTemp - // self.putCursor2End(self._view.input) - // self.scroll2bottom() - // } else { - // self._cmdTemp = self._view.input.innerText - // } - //} } renderComponent () { ReactDOM.render( - , + , this.element ) } - // putCursor2End (editable) { - // var range = document.createRange() - // range.selectNode(editable) - // var child = editable - // var chars - - // while (child) { - // if (child.lastChild) child = child.lastChild - // else break - // if (child.nodeType === Node.TEXT_NODE) { - // chars = child.textContent.length - // } else { - // chars = child.innerHTML.length - // } - // } - - // range.setEnd(child, chars) - // var toStart = true - // var toEnd = !toStart - // range.collapse(toEnd) - - // var sel = window.getSelection() - // sel.removeAllRanges() - // sel.addRange(range) - - // editable.focus() - // } - - //updateJournal (filterEvent) { - // var self = this - // var commands = self.data.activeFilters.commands - // var value = filterEvent.value - // if (filterEvent.type === 'select') { - // commands[value] = true - // if (!self._INDEX.commandsMain[value]) return - // self._INDEX.commandsMain[value].forEach(item => { - // item.root.steps.forEach(item => { self._JOURNAL[item.gidx] = item }) - // self._JOURNAL[item.gidx] = item - // }) - // } - // else if (filterEvent.type === 'deselect') { - // commands[value] = false - // if (!self._INDEX.commandsMain[value]) return - // self._INDEX.commandsMain[value].forEach(item => { - // item.root.steps.forEach(item => { self._JOURNAL[item.gidx].hide = true }) - // self._JOURNAL[item.gidx].hide = true - // }) - // } else if (filterEvent.type === 'search') { - // if (value !== self.data.activeFilters.input) { - // var query = self.data.activeFilters.input = value - // var items = self._JOURNAL - // for (var gidx = 0, len = items.length; gidx < len; gidx++) { - // var item = items[gidx] - // if (item && self.data.filterFns[item.cmd]) { - // var show = query.length ? self.data.filterFns[item.cmd](item.args, query) : true - // item.hide = !show - // } - // } - // } - // } - // var df = document.createDocumentFragment() - // self._JOURNAL.forEach(item => { - // if (item && item.el && !item.hide) df.appendChild(item.el) - // }) - // self._view.journal.innerHTML = '' - // requestAnimationFrame(function updateDOM () { - // self._view.journal.appendChild(df) - // }) - //} - _appendItem (item) { var self = this var { el, gidx } = item @@ -785,7 +240,7 @@ class Terminal extends Plugin { if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - var context = domTerminalFeatures(self, scopedCommands, self.blockchain) + var context = domTerminalFeatures(scopedCommands, self.blockchain) try { var cmds = vm.createContext(context) var result = vm.runInContext(script, cmds) @@ -809,11 +264,11 @@ class Terminal extends Plugin { } } -// function domTerminalFeatures (self, scopedCommands, blockchain) { -// return { -// remix: self._components.cmdInterpreter -// } -// } +function domTerminalFeatures (scopedCommands, blockchain) { + return { + remix: this._components.cmdInterpreter + } +} function blockify (el) { return yo`
${el}
` } diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts new file mode 100644 index 0000000000..e69de29bb2 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 106f5812a9..85351939d2 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,30 +1,53 @@ -import React, { useState } from 'react' // eslint-disable-line +import React, { useState, useEffect } from 'react' // eslint-disable-line import './remix-ui-terminal.css' /* eslint-disable-next-line */ export interface RemixUiTerminalProps { propterties: any + event: any + autoCompletePopupEvent: any + autoCompletePopup: any + blockchain: any + api: any + options: any + data: any + cmdInterpreter: any } export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') + // events + useEffect(() => { + // window.addEventListener('resize', function () { + // props.event.trigger('resize', []) + // props.event.trigger('resize', []) + // }) + // return () => { + // window.removeEventListener('resize', function () { + // props.event.trigger('resize', []) + // props.event.trigger('resize', []) + // }) + // } + }, []) + const handleMinimizeTerminal = (event) => { - console.log('clikced') + console.log('clikced', props.event) if (toggleDownUp === 'fa-angle-double-down') { console.log('clikced down') setToggleDownUp('fa-angle-double-up') + props.event.trigger.resize('resize', []) } else { console.log('clikced up') // event.trigger('resize', []) setToggleDownUp('fa-angle-double-down') } + console.log(props.event, 'event.trigger') } return (
- {console.log({ toggleDownUp })}
{/* ${self._view.dragbar} */}
@@ -68,7 +91,20 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
- Welcome to remix-ui-terminal {console.log(props.propterties, ' properties david')} +
+ {/* onScroll=${throttle(reattach, 10)} onkeydown=${focusinput} */} + {/* {props.autoCompletePopup.render()} */} + {console.log({ props })} +
+
+
+
) } From e0b80f44f629c40db0cd310f3d30eab60abd0d58 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 5 Jul 2021 12:44:44 +0100 Subject: [PATCH 05/48] adding method to the terminal.ts --- .../terminal/src/lib/remix-ui-terminal.tsx | 16 ++++++++++++++-- package.json | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) 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 85351939d2..60249b4193 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -18,7 +18,7 @@ export interface RemixUiTerminalProps { export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') - + const [inserted, setInserted] = useState(false) // events useEffect(() => { // window.addEventListener('resize', function () { @@ -46,6 +46,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } console.log(props.event, 'event.trigger') } + + const reattached = (event) => { + let el = event.currentTarget + var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 + if (isBottomed) { + + } + } + + return (
@@ -91,7 +101,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
-
+
{/* onScroll=${throttle(reattach, 10)} onkeydown=${focusinput} */} {/* {props.autoCompletePopup.render()} */} {console.log({ props })} @@ -103,6 +113,8 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { zIndex: -1 }}>
+
+
diff --git a/package.json b/package.json index 895639bd6c..10a169c65f 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs", @@ -87,7 +87,7 @@ "onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint", "remixd": "nx build remixd && nx serve remixd --folder=./apps/remix-ide/contracts --remixide=http://127.0.0.1:8080", "selenium": "selenium-standalone start", - "selenium-install": "selenium-standalone install", + "selenium-install": "selenium-standalone install", "sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js", "test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest", "watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc", From 69029a97a72b72bf61738bb9e5e418b5a4a018a1 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 9 Jul 2021 08:17:08 +0100 Subject: [PATCH 06/48] remix id terminal update --- apps/remix-ide/src/app/panels/terminal.js | 16 ++- .../terminal/src/lib/remix-ui-terminal.tsx | 127 +++++++++++++++++- .../terminal/src/lib/types/terminalTypes.ts | 7 + 3 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 libs/remix-ui/terminal/src/lib/types/terminalTypes.ts diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 2d17230b72..0029802c1e 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -91,6 +91,18 @@ class Terminal extends Plugin { } onActivation () { + this.on('scriptRunner', 'log', (msg) => { + this.commands.log.apply(this.commands, msg.data) + }) + this.on('scriptRunner', 'info', (msg) => { + this.commands.info.apply(this.commands, msg.data) + }) + this.on('scriptRunner', 'warn', (msg) => { + this.commands.warn.apply(this.commands, msg.data) + }) + this.on('scriptRunner', 'error', (msg) => { + this.commands.error.apply(this.commands, msg.data) + }) this.renderComponent() } @@ -108,7 +120,9 @@ class Terminal extends Plugin { options = {this.opts} data = {this.data} cmdInterpreter = {this._components.cmdInterpreter} - autoCompletePopup = {this._components.autoCompletePopup}/>, + autoCompletePopup = {this._components.autoCompletePopup} + registerCommand = {this.registerCommand} + />, this.element ) } 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 60249b4193..282bc073b4 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react' // eslint-disable-line +import React, { useState, useEffect, useRef, SyntheticEvent } from 'react' // eslint-disable-line import './remix-ui-terminal.css' @@ -13,12 +13,38 @@ export interface RemixUiTerminalProps { options: any data: any cmdInterpreter: any + registerCommand: any +} + +export interface ClipboardEvent extends SyntheticEvent { + clipboardData: DataTransfer; } export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') const [inserted, setInserted] = useState(false) + + const [state, setState] = useState({ + data: { + // lineLength: props.options.lineLength || 80, + session: [], + activeFilters: { commands: {}, input: '' }, + filterFns: {} + }, + _commands: {}, + commands: {}, + _JOURNAL: [], + _jobs: [], + _INDEX: {}, + _INDEXall: [], + _INDEXallMain: [], + _INDEXcommands: {}, + _INDEXcommandsMain: {} + }) + + // terminal inputRef + const inputEl = useRef(null) // events useEffect(() => { // window.addEventListener('resize', function () { @@ -33,6 +59,25 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // } }, []) + // handle events + const handlePaste = (event: ClipboardEvent) => { + // Do something + const selection = window.getSelection() + if (!selection.rangeCount) return false + event.preventDefault() + event.stopPropagation() + var clipboard = (event.clipboardData) // || window.clipboardData + var text = clipboard.getData('text/plain') + text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters + var temp = document.createElement('div') + temp.innerHTML = text + var textnode = document.createTextNode(temp.textContent) + selection.getRangeAt(0).insertNode(textnode) + selection.empty() + // self.scroll2bottom() + // placeCaretAtEnd(event.currentTarget) + } + const handleMinimizeTerminal = (event) => { console.log('clikced', props.event) if (toggleDownUp === 'fa-angle-double-down') { @@ -47,14 +92,76 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { console.log(props.event, 'event.trigger') } - const reattached = (event) => { - let el = event.currentTarget - var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 - if (isBottomed) { + // const reattached = (event) => { + // let el = event.currentTarget + // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 + // if (isBottomed) { + + // } else { + // // if (!inserted) + // } + // } + + const registerCommand = (name, command, opts) => { + const { _commands, _INDEXcommands, _INDEXallMain, _INDEXcommandsMain, _INDEXall, commands } = state + // TODO if no _commands[name] throw an error + + // TODO if typeof command !== 'function' throw error + _commands[name] = command + _INDEXcommands[name] = [] + _INDEXallMain[name] = [] + + // TODO _command function goes here + commands[name] = function _command () { + const steps = [] + const args = [...arguments] + const gidx = 0 + const idx = 0 + const step = 0 + const root = { steps, cmd: name, gidx, idx } + const ITEM = { root, cmd: name, el: {} } + root.gidx = _INDEXallMain.push(ITEM) - 1 + root.idx = _INDEXcommandsMain[name].push(ITEM) - 1 + function append (cmd, params, el) { + let item = { el, cmd, root, gidx, idx, step, args: [...arguments] } + if (cmd) { + item = { el, cmd, root, gidx, idx, step, args } + } else { + // item = ITEM + item.el = el + cmd = name + } + item.gidx = _INDEXall.push(item) - 1 + item.idx = _INDEXcommands[cmd].push(item) - 1 + item.step = steps.push(item) - 1 + item.args = params + _appendItem(item) + } } + + return commands[name] } + const _appendItem = (item: any) => { + let { _JOURNAL, _jobs, data } = state + const self = props + const { el, gidx } = item + _JOURNAL[gidx] = item + if (!_jobs.length) { + // requestAnimationFrame(function updateTerminal () { + // self._jobs.forEach(el => self._view.journal.appendChild(el)) + // self.scroll2bottom() + _jobs = [] + } + if (data.activeFilters.commands[item.cmd]) _jobs.push(el) + } + + const focusinput = () => { + inputEl.current.focus() + } + + return (
@@ -114,6 +221,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { }}>
+
+ {/* ${background} */} +
+ {/* ${text} */} +
+
+
+
+ {'>'} +
diff --git a/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts b/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts new file mode 100644 index 0000000000..e4846cfb10 --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts @@ -0,0 +1,7 @@ + +export interface ROOTS { + steps: any, + cmd: string, + gidx: number, + idx: number +} From c49d9a351fd9946ec4904fee4a5ec46668a482e9 Mon Sep 17 00:00:00 2001 From: tizah Date: Thu, 15 Jul 2021 08:17:51 +0100 Subject: [PATCH 07/48] implemented minimize terminal window and added custom hook --- apps/remix-ide/src/app/panels/terminal.js | 6 +- .../src/lib/custom-hooks/useKeyPress.tsx | 29 +++ .../terminal/src/lib/remix-ui-terminal.css | 4 + .../terminal/src/lib/remix-ui-terminal.tsx | 242 ++++++++++++++++-- package-lock.json | 19 ++ package.json | 5 +- 6 files changed, 279 insertions(+), 26 deletions(-) create mode 100644 libs/remix-ui/terminal/src/lib/custom-hooks/useKeyPress.tsx diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 0029802c1e..f7e1e9d137 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -34,11 +34,13 @@ class Terminal extends Plugin { constructor (opts, api) { super(profile) this.element = document.createElement('div') - this.element.setAttribute('id', 'terminalView') + this.element.setAttribute('class', 'panel_2A0YE0') + this.element.setAttribute('id', 'terminal-view') this.event = new EventManager() this.blockchain = opts.blockchain this._api = api this._opts = opts + this.version = packageJson.version this.data = { lineLength: opts.lineLength || 80, // ???? session: [], @@ -122,6 +124,8 @@ class Terminal extends Plugin { cmdInterpreter = {this._components.cmdInterpreter} autoCompletePopup = {this._components.autoCompletePopup} registerCommand = {this.registerCommand} + command = {this.commands} + version = {this.version} />, this.element ) diff --git a/libs/remix-ui/terminal/src/lib/custom-hooks/useKeyPress.tsx b/libs/remix-ui/terminal/src/lib/custom-hooks/useKeyPress.tsx new file mode 100644 index 0000000000..12bbc1cefc --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/custom-hooks/useKeyPress.tsx @@ -0,0 +1,29 @@ +import React, {useEffect, useState} from "react" // eslint-disable-line + +export const useKeyPress = (targetKey: string): boolean => { +// State for keeping track of whether key is pressed + const [keyPressed, setKeyPressed] = useState(false) + // If pressed key is our target key then set to true + function downHandler ({ key }): void { + if (key === targetKey) { + setKeyPressed(true) + } + } + // If released key is our target key then set to false + const upHandler = ({ key }): void => { + if (key === targetKey) { + setKeyPressed(false) + } + } + // Add event listeners + useEffect(() => { + window.addEventListener('keydown', downHandler) + window.addEventListener('keyup', upHandler) + // Remove event listeners on cleanup + return () => { + window.removeEventListener('keydown', downHandler) + window.removeEventListener('keyup', upHandler) + } + }, []) // Empty array ensures that effect is only run on mount and unmount + return keyPressed +} 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 a8870af675..818fd1bb4a 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -1,3 +1,7 @@ + +element.style { + height: 323px !important; +} .panel { position : relative; display : flex; 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 282bc073b4..e4acaa6caf 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,4 +1,6 @@ import React, { useState, useEffect, useRef, SyntheticEvent } from 'react' // eslint-disable-line +import { useKeyPress } from './custom-hooks/useKeyPress' +import { useWindowResize } from 'beautiful-react-hooks' import './remix-ui-terminal.css' @@ -14,6 +16,14 @@ export interface RemixUiTerminalProps { data: any cmdInterpreter: any registerCommand: any + command: any + version: any + + // blockRenderHtml: any + // blockRenderLog: any + // blockRenderInfo: any + // blockRenderWarn: any + // blockRenderError: any } export interface ClipboardEvent extends SyntheticEvent { @@ -24,8 +34,40 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') const [inserted, setInserted] = useState(false) + const [_cmdIndex, setCmdIndex] = useState(-1) + const [_cmdTemp, setCmdTemp] = useState('') + const [_cmdHistory, setCmdHistory] = useState([]) + const [windowHeight, setWindowHeight] = useState(window.innerHeight) const [state, setState] = useState({ + journalBlocks: { + intro: ( +
+
- Welcome to Remix {props.version} -
+
+
You can use this terminal to:
+
    +
  • Check transactions details and start debugging.
  • +
  • Execute JavaScript scripts: +
    + - Input a script directly in the command line interface +
    + - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface +
    + - Right click on a JavaScript file in the file explorer and then click \`Run\` +
  • +
+
The following libraries are accessible:
+ +
+ ), + text: (
David
) + }, data: { // lineLength: props.options.lineLength || 80, session: [], @@ -43,6 +85,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { _INDEXcommandsMain: {} }) + const _scopedCommands = () => { + + } + + useWindowResize(() => { + setWindowHeight(window.innerHeight) + }) + + // terminal inputRef const inputEl = useRef(null) // events @@ -59,6 +110,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // } }, []) + const placeCaretAtEnd = (el) => { + el.focus() + const range = document.createRange() + range.selectNodeContents(el) + range.collapse(false) + const sel = window.getSelection() + sel.removeAllRanges() + sel.addRange(range) + } + // handle events const handlePaste = (event: ClipboardEvent) => { // Do something @@ -66,27 +127,28 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (!selection.rangeCount) return false event.preventDefault() event.stopPropagation() - var clipboard = (event.clipboardData) // || window.clipboardData - var text = clipboard.getData('text/plain') + const clipboard = (event.clipboardData) // || window.clipboardData + let text = clipboard.getData('text/plain') text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters - var temp = document.createElement('div') + const temp = document.createElement('div') temp.innerHTML = text - var textnode = document.createTextNode(temp.textContent) + const textnode = document.createTextNode(temp.textContent) selection.getRangeAt(0).insertNode(textnode) selection.empty() // self.scroll2bottom() - // placeCaretAtEnd(event.currentTarget) + placeCaretAtEnd(event.currentTarget) } const handleMinimizeTerminal = (event) => { - console.log('clikced', props.event) + event.preventDefault() + event.stopPropagation() if (toggleDownUp === 'fa-angle-double-down') { console.log('clikced down') setToggleDownUp('fa-angle-double-up') - props.event.trigger.resize('resize', []) + props.event.trigger('resize', []) } else { console.log('clikced up') - // event.trigger('resize', []) + props.event.trigger('resize', [118]) setToggleDownUp('fa-angle-double-down') } console.log(props.event, 'event.trigger') @@ -161,24 +223,151 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { inputEl.current.focus() } + const putCursor2End = (editable) => { + var range = document.createRange() + console.log({ range }) + range.selectNode(editable) + var child = editable + var chars + console.log({ child }) + while (child) { + if (child.lastChild) child = child.lastChild + else break + if (child.nodeType === Node.TEXT_NODE) { + chars = child.textContent.length + } else { + chars = child.innerHTML.length + } + } + + range.setEnd(child, chars) + var toStart = true + var toEnd = !toStart + range.collapse(toEnd) + + var sel = window.getSelection() + sel.removeAllRanges() + sel.addRange(range) + editable.focus() + } + + const wrapScript = (script) => { + const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) + if (isKnownScript) return script + return ` + try { + const ret = ${script}; + if (ret instanceof Promise) { + ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) + } else { + console.log(ret) + } + } catch (e) { + console.log(e.message) + }` + } + + const handleKeyDown = (event) => { + if (props.autoCompletePopup.handleAutoComplete( + event, + inputEl.current.innerText)) { return } + if (inputEl.current.innerText.length === 0) { + inputEl.current.innerText += '\n' + } + if (event.which === 13) { + if (event.ctrlKey) { // + // on enter, append the value in the cli input to the journal + // setState(prevState => ({...prevState.journalBlocks, prevState: inputEl}) + inputEl.current.innerText += '\n' + inputEl.current.focus() + // putCursor2End(inputEl.current) + // scroll2botton () function not implemented + props.autoCompletePopup.removeAutoComplete() + } else { + setCmdIndex(-1) + setCmdTemp('') + const script = inputEl.current.innerText.trim() + console.log({ script }) + inputEl.current.innerText += '\n' + if (script.length) { + // self._cmdHistory.unshift(script) + props.command.script(wrapScript(script)) + } + props.autoCompletePopup.removeAutoComplete() + } + } else if (event.which === 38) { // + const len = _cmdHistory.length + if (len === 0) event.preventDefault() + if (_cmdHistory.length - 1 > _cmdIndex) { + setCmdIndex(prevState => prevState++) + } + inputEl.current.innerText = _cmdHistory[_cmdIndex] + inputEl.current.focus() + // putCursor2End(inputEl.current) + // self.scroll2bottom() + } + else if (event.which === 40) { + if (_cmdIndex > -1) { + setCmdIndex(prevState => prevState--) + } + inputEl.current.innerText = _cmdIndex >= 0 ? _cmdHistory[_cmdIndex] : _cmdTemp + inputEl.current.focus() + // putCursor2End(inputEl.current) + // self.scroll2bottom() + } else { + setCmdTemp(inputEl.current.innerText) + } + console.log({ _cmdHistory }) + console.log({ _cmdIndex }) + console.log({ _cmdTemp }) + } + + const moveGhostbar = (event) => { + return props.api.getPosition(event) + 'px' + } + + const removeGhostbar = (event) => { + if (toggleDownUp === 'fa-angle-double-up') { + console.log('remove event') + setToggleDownUp('fa-angle-double-down') + } + props.event.trigger('resize', [props.api.getPostion(event)]) + } + + const mousedown = (event) => { + console.log({ windowHeight }) + console.log(event.which === 1, 'event.which === 1') + event.preventDefault() + moveGhostbar(event) + if (event.which === 1) { + console.log('event .which code 1') + moveGhostbar(event) + } + } + + const cancelGhostbar = (event) => { + if (event.keyCode === 27) { + console.log('event .key code 27') + } + } return ( -
-
+
+
{/* ${self._view.dragbar} */} -
-
+
+
{/* ${self._view.icon} */} - +
{/* ${self._view.pendingTxCount} */}
0
-
-
+
+
{ listen on network
-
- +
+ {/* ${self._view.inputSearch} */} {
-
+
{/* onScroll=${throttle(reattach, 10)} onkeydown=${focusinput} */} {/* {props.autoCompletePopup.render()} */} {console.log({ props })} @@ -219,8 +408,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { opacity: '0.1', zIndex: -1 }}>
-
-
+
+
+
+ {Object.entries(state.journalBlocks).map((x, index) => ( +
+ {x} +
+ ))} +
{/* ${background} */}
@@ -228,9 +424,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
-
+
{'>'} - +
diff --git a/package-lock.json b/package-lock.json index 9e028132b2..c942a158c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10514,6 +10514,15 @@ "tweetnacl": "^0.14.3" } }, + "beautiful-react-hooks": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/beautiful-react-hooks/-/beautiful-react-hooks-0.35.0.tgz", + "integrity": "sha512-EDjpQWskuK7ob+rfH/Xt6UpFA+vC+ARM1TYAWRgYWcjcaDCGFuc3q5Ko4WJQUcFP2cq9ps3GihUSqN+KfUwQdg==", + "requires": { + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1" + } + }, "bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", @@ -24137,6 +24146,11 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, "lodash.defaultsdeep": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", @@ -24238,6 +24252,11 @@ "lodash._reinterpolate": "^3.0.0" } }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", diff --git a/package.json b/package.json index a66874796c..a01e2a6346 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint", "remixd": "nx build remixd && nx serve remixd --folder=./apps/remix-ide/contracts --remixide=http://127.0.0.1:8080", "selenium": "selenium-standalone start", - "selenium-install": "selenium-standalone install", + "selenium-install": "selenium-standalone install", "sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js", "test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest", "watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc", @@ -144,6 +144,7 @@ "ansi-gray": "^0.1.1", "async": "^2.6.2", "axios": ">=0.21.1", + "beautiful-react-hooks": "^0.35.0", "brace": "^0.8.0", "change-case": "^4.1.1", "chokidar": "^2.1.8", @@ -177,7 +178,7 @@ "web3": "1.2.4", "winston": "^3.3.3", "ws": "^7.3.0" - }, + }, "devDependencies": { "@babel/core": "^7.4.5", "@babel/plugin-transform-modules-amd": "^7.10.4", From c51741a24e2eeaffcd14f87c399d9a282900cf1c Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Mon, 19 Jul 2021 03:52:45 +0100 Subject: [PATCH 08/48] fixed resizing of the terminal --- apps/remix-ide/src/app.js | 3 +- .../src/app/components/main-panel.js | 2 +- apps/remix-ide/src/app/panels/terminal.js | 5 +- .../src/lib/remix-ui-static-analyser.tsx | 2 +- .../terminal/src/lib/remix-ui-terminal.css | 16 ++- .../terminal/src/lib/remix-ui-terminal.tsx | 119 ++++++++++++++---- 6 files changed, 114 insertions(+), 33 deletions(-) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 8beeae8849..77f2a868e2 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -296,7 +296,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org newpos = (newpos < height - limitDown) ? newpos : height - limitDown return height - newpos } - } + }, + { config: registry.get('config').api } ) makeUdapp(blockchain, compilersArtefacts, (domEl) => terminal.logHtml(domEl)) diff --git a/apps/remix-ide/src/app/components/main-panel.js b/apps/remix-ide/src/app/components/main-panel.js index 62d76cf4c3..66e6a50245 100644 --- a/apps/remix-ide/src/app/components/main-panel.js +++ b/apps/remix-ide/src/app/components/main-panel.js @@ -31,7 +31,7 @@ export class MainPanel extends AbstractPanel { render () { return yo` -
+
${this.view}
` } diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index f7e1e9d137..95bca9da9a 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -31,7 +31,7 @@ const profile = { } class Terminal extends Plugin { - constructor (opts, api) { + constructor (opts, api, config) { super(profile) this.element = document.createElement('div') this.element.setAttribute('class', 'panel_2A0YE0') @@ -40,6 +40,7 @@ class Terminal extends Plugin { this.blockchain = opts.blockchain this._api = api this._opts = opts + this.config = config this.version = packageJson.version this.data = { lineLength: opts.lineLength || 80, // ???? @@ -113,6 +114,7 @@ class Terminal extends Plugin { } renderComponent () { + ReactDOM.render( , this.element ) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index bdf361e8c9..be7e405499 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -130,7 +130,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { row = location.start.line column = location.start.column locationString = row + 1 + ':' + column + ':' - fileName = Object.keys(lastCompilationResult.sources)[file] + fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ const msg = message(item.name, item.warning, item.more, fileName, locationString) 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 818fd1bb4a..7bd2a9f90d 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -120,7 +120,7 @@ element.style { height : 0.5em; right : 0; left : 0; - cursor : ns-resize; + cursor : row-resize; z-index : 999; } .listenOnNetwork { @@ -134,4 +134,16 @@ element.style { z-index : 9999; left : 0; right : 0; - } \ No newline at end of file + } + + + .divider-hitbox { + color: white; + cursor: row-resize; + align-self: stretch; + display: flex; + align-items: center; + padding: 0 1rem; + } + + .ul {margin-left: 0; padding-left: 20px;} \ No newline at end of file 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 e4acaa6caf..185ab2843f 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,5 +1,5 @@ -import React, { useState, useEffect, useRef, SyntheticEvent } from 'react' // eslint-disable-line -import { useKeyPress } from './custom-hooks/useKeyPress' +import React, { useState, useEffect, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line +import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' import './remix-ui-terminal.css' @@ -18,6 +18,7 @@ export interface RemixUiTerminalProps { registerCommand: any command: any version: any + config: any // blockRenderHtml: any // blockRenderLog: any @@ -38,6 +39,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [_cmdTemp, setCmdTemp] = useState('') const [_cmdHistory, setCmdHistory] = useState([]) const [windowHeight, setWindowHeight] = useState(window.innerHeight) + // dragable state + const [leftHeight, setLeftHeight] = useState(undefined) + const [separatorYPosition, setSeparatorYPosition] = useState(undefined) + const [dragging, setDragging] = useState(false) const [state, setState] = useState({ journalBlocks: { @@ -93,7 +98,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { setWindowHeight(window.innerHeight) }) - // terminal inputRef const inputEl = useRef(null) // events @@ -147,11 +151,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { setToggleDownUp('fa-angle-double-up') props.event.trigger('resize', []) } else { - console.log('clikced up') - props.event.trigger('resize', [118]) + const terminalTopOffset = props.config.config.get('terminal-top-offset') + props.event.trigger('resize', [terminalTopOffset]) setToggleDownUp('fa-angle-double-down') } - console.log(props.event, 'event.trigger') } // const reattached = (event) => { @@ -277,6 +280,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } if (event.which === 13) { if (event.ctrlKey) { // + console.log(event.which === 32, ' enter key') // on enter, append the value in the cli input to the journal // setState(prevState => ({...prevState.journalBlocks, prevState: inputEl}) inputEl.current.innerText += '\n' @@ -284,17 +288,17 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // putCursor2End(inputEl.current) // scroll2botton () function not implemented props.autoCompletePopup.removeAutoComplete() - } else { + } else { // setCmdIndex(-1) setCmdTemp('') const script = inputEl.current.innerText.trim() - console.log({ script }) - inputEl.current.innerText += '\n' - if (script.length) { - // self._cmdHistory.unshift(script) - props.command.script(wrapScript(script)) - } - props.autoCompletePopup.removeAutoComplete() + console.log({ script }, ' script ') + // inputEl.current.innerText += '\n' + // if (script.length) { + // // self._cmdHistory.unshift(script) + // props.command.script(wrapScript(script)) + // } + // props.autoCompletePopup.removeAutoComplete() } } else if (event.which === 38) { // const len = _cmdHistory.length @@ -332,31 +336,93 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { console.log('remove event') setToggleDownUp('fa-angle-double-down') } - props.event.trigger('resize', [props.api.getPostion(event)]) + const value = props.event.get('resize') + console.log({ value }) + props.event.trigger('resize', [value]) } - const mousedown = (event) => { - console.log({ windowHeight }) - console.log(event.which === 1, 'event.which === 1') - event.preventDefault() - moveGhostbar(event) - if (event.which === 1) { - console.log('event .which code 1') - moveGhostbar(event) + /* start of mouse events */ + + const mousedown = (event: MouseEvent) => { + setSeparatorYPosition(event.clientY) + setDragging(true) + // console.log({ windowHeight }) + // console.log(event.which === 1, 'event.which === 1') + // event.preventDefault() + // moveGhostbar(event) + // if (event.which === 1) { + // console.log('event .which code 1') + // moveGhostbar(event) + // } + } + + const onMouseMove: any = (e: MouseEvent) => { + e.preventDefault() + if (dragging && leftHeight && separatorYPosition) { + const newEditorHeight = leftHeight - e.clientY + separatorYPosition + const newLeftHeight = leftHeight + separatorYPosition - e.clientY + setSeparatorYPosition(e.clientY) + + // if (newLeftHeight < MIN_HEIGHT) { + // setLeftHeight(MIN_HEIGHT) + // return + // } + // if (splitPaneRef.current) { + // const splitPaneHeight = splitPaneRef.current.clientHeight + + // if (newLeftHeight > splitPaneHeight - MIN_HEIGHT) { + // setLeftHeight(splitPaneHeight - MIN_HEIGHT) + // return + // } + // } + setLeftHeight(newLeftHeight) + props.event.trigger('resize', [newLeftHeight + 32]) + console.log({ newLeftHeight }) } } + const onMouseUp = () => { + setDragging(false) + } + + + /* end of mouse event */ + const cancelGhostbar = (event) => { if (event.keyCode === 27) { console.log('event .key code 27') } } + useEffect(() => { + document.addEventListener('mousemove', onMouseMove) + document.addEventListener('mouseup', onMouseUp) + + return () => { + document.removeEventListener('mousemove', onMouseMove) + document.removeEventListener('mouseup', onMouseUp) + } + }) + + React.useEffect(() => { + const leftRef = document.getElementById('terminal-view') + const editorRef = document.getElementById('mainPanelPluginsContainer-id') + if (leftRef) { + if (!leftHeight) { + setLeftHeight(leftRef.offsetHeight) + return + } + + leftRef.style.height = `${leftHeight}px` + } + }, [leftHeight, setLeftHeight]) + return (
+ {console.log({ props })}
{/* ${self._view.dragbar} */} -
+
{/* ${self._view.icon} */} @@ -400,7 +466,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{/* onScroll=${throttle(reattach, 10)} onkeydown=${focusinput} */} {/* {props.autoCompletePopup.render()} */} - {console.log({ props })}
{
- {'>'} - + {'>'} +
From b2e29ef35f46cfd6013c24e4ae60d3f567e6bcc7 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 21 Jul 2021 19:09:50 +0100 Subject: [PATCH 09/48] fixing scripRunner error --- .gitignore | 1 + apps/remix-ide/src/app/panels/terminal.js | 31 +--- .../src/lib/actions/terminalAction.ts | 103 +++++++++++ .../src/lib/reducers/terminalReducer.ts | 120 ++++++++++++ .../terminal/src/lib/remix-ui-terminal.tsx | 171 ++++++++++-------- 5 files changed, 332 insertions(+), 94 deletions(-) diff --git a/.gitignore b/.gitignore index 4f0a8bafd7..0da94f8b75 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ soljson.js *.launch .settings/ *.sublime-workspace +.vscode/ # IDE - VSCode .vscode/* diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 95bca9da9a..eb67e15e55 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -69,26 +69,6 @@ class Terminal extends Plugin { this._INDEX.allMain = [] this._INDEX.commands = {} this._INDEX.commandsMain = {} - this.registerCommand('html', this._blocksRenderer('html'), { activate: true }) - this.registerCommand('log', this._blocksRenderer('log'), { activate: true }) - this.registerCommand('info', this._blocksRenderer('info'), { activate: true }) - this.registerCommand('warn', this._blocksRenderer('warn'), { activate: true }) - this.registerCommand('error', this._blocksRenderer('error'), { activate: true }) - this.registerCommand('script', function execute (args, scopedCommands, append) { - var script = String(args[0]) - this._shell(script, scopedCommands, function (error, output) { - if (error) scopedCommands.error(error) - else if (output) scopedCommands.log(output) - }) - }, { activate: true }) - function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } } - - this.registerFilter('log', basicFilter) - this.registerFilter('info', basicFilter) - this.registerFilter('warn', basicFilter) - this.registerFilter('error', basicFilter) - this.registerFilter('script', basicFilter) - if (opts.shell) this._shell = opts.shell // ??? register(this) } @@ -109,12 +89,18 @@ class Terminal extends Plugin { this.renderComponent() } + onDeactivation () { + this.off('scriptRunner', 'log') + this.off('scriptRunner', 'info') + this.off('scriptRunner', 'warn') + this.off('scriptRunner', 'error') + } + render () { return this.element } renderComponent () { - ReactDOM.render( , this.element ) @@ -213,6 +200,8 @@ class Terminal extends Plugin { if (self._commands[name]) throw new Error(`command "${name}" exists already`) if (typeof command !== 'function') throw new Error(`invalid command: ${command}`) self._commands[name] = command + console.log({ command }) + console.log(self._commands) self._INDEX.commands[name] = [] self._INDEX.commandsMain[name] = [] self.commands[name] = function _command () { diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index e69de29bb2..4e14ac46c8 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -0,0 +1,103 @@ + +export const registerCommandAction = (name, command, activate, dispatch) => { + const commands: any = {} + const _commands: any = {} + _commands[name] = command + const data: any = { + // lineLength: props.options.lineLength || 80, + session: [], + activeFilters: { commands: {}, input: '' }, + filterFns: {} + } + const _INDEX = { + all: [], + allMain: [], + commands: {}, + commandsMain: {} + } + + const registerFilter = (commandName, filterFn) => { + data.filterFns[commandName] = filterFn + } + + // const _appendItem = (item) => { + // var { el, gidx } = item + // _JOURNAL[gidx] = item + // if (!_jobs.length) { + // requestAnimationFrame(function updateTerminal () { + // _jobs.forEach(el => _view.journal.appendChild(el)) + // .scroll2bottom() + // ._jobs = [] + // }) + // } + // if (data.activeFilters.commands[item.cmd]) _jobs.push(el) + // } + + commands[name] = function () { + const args = [...arguments] + const steps = [] + const root = { steps, cmd: name, gidx: 0, idx: 0 } + const ITEM = { root, cmd: name } + root.gidx = _INDEX.allMain.push(ITEM) - 1 + // root.idx = _INDEX.commandsMain[name].push(ITEM) - 1 + let item + function append (cmd, params, el) { + if (cmd) { // subcommand + item = { el, cmd, root } + } else { // command + item = ITEM + item.el = el + cmd = name + } + item.gidx = _INDEX.all.push(item) - 1 + item.idx = _INDEX.commands[cmd].push(item) - 1 + item.step = steps.push(item) - 1 + item.args = params + // _appendItem(item) + console.log({ item }, 'append items') + // self._appendItem(item) + } + var scopedCommands = _scopeCommands(append) + command(args, scopedCommands, el => append(null, args, blockify(el))) + console.log({ args }) + } + const help = typeof command.help === 'string' ? command.help : [ + '// no help available for:', `terminal.command.${name}` + ].join('\n') + commands[name].toString = () => { return help } + commands[name].help = help + data.activeFilters.commands[name] = activate && activate.activate + if (activate.filterFn) { + registerFilter(name, activate.filterFn) + } + dispatch({ type: name, payload: { commands: commands, _commands: _commands, data: data } }) + + const blockify = (el) => { + return `
${el}
` + } + + const _scopeCommands = (append) => { + const scopedCommands = {} + Object.keys(commands).forEach(function makeScopedCommand (cmd) { + var command = _commands[cmd] + scopedCommands[cmd] = function _command () { + var args = [...arguments] + console.log({ cmd }, { args }, { blockify }) + command(args, scopedCommands, el => append(cmd, args, blockify(el))) + } + }) + console.log({ scopedCommands }) + return scopedCommands + } + +} + +export const filterFnAction = (name, filterFn, dispatch) => { + const data: any = { + // session: [], + // activeFilters: { commands: {}, input: '' }, + filterFns: {} + } + data.filterFns[name] = filterFn + dispatch({ type: name, payload: { data: data } }) +} diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index e69de29bb2..43fae4b344 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -0,0 +1,120 @@ +export const initialState = { + journalBlocks: { + }, + data: { + // lineLength: props.options.lineLength || 80, + session: [], + activeFilters: { commands: {}, input: '' }, + filterFns: {} + }, + _commandHistory: [], + _commands: {}, + commands: {}, + _JOURNAL: [], + _jobs: [], + _INDEX: { + }, + _INDEXall: [], + _INDEXallMain: [], + _INDEXcommands: {}, + _INDEXcommandsMain: {} +} + +export const registerCommandReducer = (state, action) => { + switch (action.type) { + case 'html' : + return { + ...state, + _commands: Object.assign(initialState._commands, action.payload._commands), + commands: Object.assign(initialState.commands, action.payload.commands), + data: Object.assign(initialState.data, { ...action.payload.data }) + } + case 'log': + return { + ...state, + _commands: Object.assign(initialState._commands, action.payload._commands), + commands: Object.assign(initialState.commands, action.payload.commands), + data: Object.assign(initialState.data, { ...action.payload.data }) + + } + case 'info': + return { + ...state, + _commands: Object.assign(initialState._commands, action.payload._commands), + commands: Object.assign(initialState.commands, action.payload.commands), + data: Object.assign(initialState.data, action.payload.data) + } + case 'warn': + return { + ...state, + _commands: Object.assign(initialState._commands, action.payload._commands), + commands: Object.assign(initialState.commands, action.payload.commands), + data: Object.assign(initialState.data, action.payload.data) + } + case 'error': + return { + ...state, + _commands: Object.assign(initialState._commands, action.payload._commands), + commands: Object.assign(initialState.commands, action.payload.commands), + data: Object.assign(initialState.data, action.payload.data) + } + case 'script': + return { + ...state, + _commands: Object.assign(initialState._commands, action.payload._commands), + commands: Object.assign(initialState.commands, action.payload.commands), + data: Object.assign(initialState.data, action.payload.data) + } + default : + return { state } + } +} + +export const registerFilterReducer = (state, action) => { + switch (action.type) { + case 'log': + console.log({ action }, { state }, 'register Filter') + return { + ...state, + data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) + + } + case 'info': + console.log({ action }, 'registerFilter') + return { + ...state, + data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) + } + case 'warn': + return { + ...state, + data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) + } + case 'error': + return { + ...state, + data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) + } + case 'script': + return { + ...state, + data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) + } + default : + return { state } + } +} + +export const addCommandHistoryReducer = (state, action) => { + switch (action.type) { + case 'cmdHistory': + console.log({ action }, { state }, 'cmd history') + return { + ...state, + _commandHistory: initialState._commandHistory.unshift(action.payload.script) + + } + default : + return { state } + } +} 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 185ab2843f..9f2f421b09 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,6 +1,10 @@ -import React, { useState, useEffect, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line +import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' +import { registerCommandAction, filterFnAction } from './actions/terminalAction' +import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer } from './reducers/terminalReducer' +import javascriptserialize from 'javascript-serialize' +import jsbeautify from 'js-beautify' import './remix-ui-terminal.css' @@ -15,10 +19,10 @@ export interface RemixUiTerminalProps { options: any data: any cmdInterpreter: any - registerCommand: any command: any version: any config: any + thisState: any // blockRenderHtml: any // blockRenderLog: any @@ -44,6 +48,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [separatorYPosition, setSeparatorYPosition] = useState(undefined) const [dragging, setDragging] = useState(false) + const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) + const [filterState, filterDispatch] = useReducer(registerFilterReducer, initialState) + const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) + const [state, setState] = useState({ journalBlocks: { intro: ( @@ -102,16 +110,27 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const inputEl = useRef(null) // events useEffect(() => { - // window.addEventListener('resize', function () { - // props.event.trigger('resize', []) - // props.event.trigger('resize', []) - // }) - // return () => { - // window.removeEventListener('resize', function () { - // props.event.trigger('resize', []) - // props.event.trigger('resize', []) - // }) - // } + registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch) + registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch) + registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch) + registerCommandAction('warn', _blocksRenderer('warn'), { activate: true }, dispatch) + registerCommandAction('error', _blocksRenderer('error'), { activate: true }, dispatch) + registerCommandAction('script', function execute (args, scopedCommands, append) { + var script = String(args[0]) + props.thisState._shell(script, scopedCommands, function (error, output) { + if (error) scopedCommands.error(error) + else if (output) scopedCommands.log(output) + }) + }, { activate: true }, dispatch) + filterFnAction('log', basicFilter, filterDispatch) + filterFnAction('info', basicFilter, filterDispatch) + filterFnAction('warn', basicFilter, filterDispatch) + filterFnAction('error', basicFilter, filterDispatch) + filterFnAction('script', basicFilter, filterDispatch) + // console.log({ htmlresullt }, { logresult }) + // dispatch({ type: 'html', payload: { commands: htmlresullt.commands } }) + // dispatch({ type: 'log', payload: { _commands: logresult._commands } }) + // registerCommand('log', _blocksRenderer('log'), { activate: true }) }, []) const placeCaretAtEnd = (el) => { @@ -157,56 +176,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - // const reattached = (event) => { - // let el = event.currentTarget - // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 - // if (isBottomed) { - - // } else { - // // if (!inserted) - // } - // } - - const registerCommand = (name, command, opts) => { - const { _commands, _INDEXcommands, _INDEXallMain, _INDEXcommandsMain, _INDEXall, commands } = state - // TODO if no _commands[name] throw an error - - // TODO if typeof command !== 'function' throw error - - _commands[name] = command - _INDEXcommands[name] = [] - _INDEXallMain[name] = [] - - // TODO _command function goes here - commands[name] = function _command () { - const steps = [] - const args = [...arguments] - const gidx = 0 - const idx = 0 - const step = 0 - const root = { steps, cmd: name, gidx, idx } - const ITEM = { root, cmd: name, el: {} } - root.gidx = _INDEXallMain.push(ITEM) - 1 - root.idx = _INDEXcommandsMain[name].push(ITEM) - 1 - function append (cmd, params, el) { - let item = { el, cmd, root, gidx, idx, step, args: [...arguments] } - if (cmd) { - item = { el, cmd, root, gidx, idx, step, args } - } else { - // item = ITEM - item.el = el - cmd = name - } - item.gidx = _INDEXall.push(item) - 1 - item.idx = _INDEXcommands[cmd].push(item) - 1 - item.step = steps.push(item) - 1 - item.args = params - _appendItem(item) - } - } - - return commands[name] - } const _appendItem = (item: any) => { let { _JOURNAL, _jobs, data } = state @@ -259,16 +228,17 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) if (isKnownScript) return script return ` - try { - const ret = ${script}; - if (ret instanceof Promise) { - ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) - } else { - console.log(ret) - } - } catch (e) { - console.log(e.message) - }` + try { + const ret = ${script}; + if (ret instanceof Promise) { + ret.then((result) => { console.log(result) }).catch((error) => { console.log(error) }) + } else { + console.log(ret) + } + } catch (e) { + console.log(e.message) + } + ` } const handleKeyDown = (event) => { @@ -289,10 +259,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // scroll2botton () function not implemented props.autoCompletePopup.removeAutoComplete() } else { // + console.log('hit enter') setCmdIndex(-1) setCmdTemp('') const script = inputEl.current.innerText.trim() console.log({ script }, ' script ') + if (script.length) { + cmdHistoryDispatch({ type: 'cmdHistory', payload: { script } }) + const result = newstate.commands.script(wrapScript(script)) + console.log({ result }) + } // inputEl.current.innerText += '\n' // if (script.length) { // // self._cmdHistory.unshift(script) @@ -417,9 +393,58 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } }, [leftHeight, setLeftHeight]) + /* block contents that gets rendered from scriptRunner */ + + const _blocksRenderer = (mode) => { + if (mode === 'html') { + return function logger (args) { + console.log({ args }) + if (args.length) { + return args[0] + } + } + } + mode = { + log: 'text-info', + info: 'text-info', + warn: 'text-warning', + error: 'text-danger' + }[mode] // defaults + + if (mode) { + const filterUndefined = (el) => el !== undefined && el !== null + return function logger (args) { + var types = args.filter(filterUndefined).map(type => type) + var values = javascriptserialize.apply(null, args.filter(filterUndefined)).map(function (val, idx) { + if (typeof args[idx] === 'string') { + const el = document.createElement('div') + el.innerHTML = args[idx].replace(/(\r\n|\n|\r)/gm, '
') + val = el.children.length === 0 ? el.firstChild : el + } + if (types[idx] === 'element') val = jsbeautify.html(val) + return val + }) + if (values.length) { + console.log({ values }) + return `${values}` + } + } + } else { + throw new Error('mode is not supported') + } + } + + function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } } + + const registerCommand = (name, command, opts) => { + // setState((prevState) => ({ ...prevState, _commands[name]: command })) + } + + /* end of block content that gets rendered from script Runner */ + return (
- {console.log({ props })} + {console.log({ newstate })}
{/* ${self._view.dragbar} */}
From 28bdc89c356d1f03ab0a776e5da10aa0ce0b4dd9 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 23 Jul 2021 17:21:00 +0100 Subject: [PATCH 10/48] getting response from scriptRunnser --- apps/remix-ide/src/app/panels/terminal.js | 56 +++++++++--- .../src/lib/actions/terminalAction.ts | 28 ++++++ .../src/lib/reducers/terminalReducer.ts | 13 ++- .../terminal/src/lib/remix-ui-terminal.css | 5 ++ .../terminal/src/lib/remix-ui-terminal.tsx | 88 ++++++++++++------- 5 files changed, 145 insertions(+), 45 deletions(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index eb67e15e55..39c5c844b1 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -4,6 +4,7 @@ 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 * as remixBleach from '../../lib/remixBleach' var yo = require('yo-yo') var javascriptserialize = require('javascript-serialize') @@ -74,18 +75,18 @@ class Terminal extends Plugin { } onActivation () { - this.on('scriptRunner', 'log', (msg) => { - this.commands.log.apply(this.commands, msg.data) - }) - this.on('scriptRunner', 'info', (msg) => { - this.commands.info.apply(this.commands, msg.data) - }) - this.on('scriptRunner', 'warn', (msg) => { - this.commands.warn.apply(this.commands, msg.data) - }) - this.on('scriptRunner', 'error', (msg) => { - this.commands.error.apply(this.commands, msg.data) - }) + // this.on('scriptRunner', 'log', (msg) => { + // this.commands.log.apply(this.commands, msg.data) + // }) + // this.on('scriptRunner', 'info', (msg) => { + // this.commands.info.apply(this.commands, msg.data) + // }) + // this.on('scriptRunner', 'warn', (msg) => { + // this.commands.warn.apply(this.commands, msg.data) + // }) + // this.on('scriptRunner', 'error', (msg) => { + // this.commands.error.apply(this.commands, msg.data) + // }) this.renderComponent() } @@ -96,6 +97,37 @@ class Terminal extends Plugin { this.off('scriptRunner', 'error') } + log (message) { + var command = this.commands[message.type] + if (typeof command === 'function') { + if (typeof message.value === 'string' && message.type === 'html') { + var el = document.createElement('div') + el.innerHTML = remixBleach.sanitize(message.value, { + list: [ + 'a', + 'b', + 'p', + 'em', + 'strong', + 'div', + 'span', + 'ul', + 'li', + 'ol', + 'hr' + ] + }) + message.value = el + } + command(message.value) + }; + } + + logHtml (html) { + var command = this.commands.html + if (typeof command === 'function') command(html) + } + render () { return this.element } diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index 4e14ac46c8..a986dd8ddc 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -101,3 +101,31 @@ export const filterFnAction = (name, filterFn, dispatch) => { data.filterFns[name] = filterFn dispatch({ type: name, payload: { data: data } }) } + +export const registerLogScriptRunnerAction = (event, commandName, commandFn, dispatch) => { + event.on('scriptRunner', commandName, (msg) => { + commandFn.log.apply(commandFn, msg.data) + dispatch({ type: commandName, payload: { commandFn, message: msg.data } }) + }) +} + +export const registerInfoScriptRunnerAction = (event, commandName, commandFn, dispatch) => { + event.on('scriptRunner', commandName, (msg) => { + commandFn.info.apply(commandFn, msg.data) + dispatch({ type: commandName, payload: { commandFn, message: msg.data } }) + }) +} + +export const registerWarnScriptRunnerAction = (event, commandName, commandFn, dispatch) => { + event.on('scriptRunner', commandName, (msg) => { + commandFn.warn.apply(commandFn, msg.data) + dispatch({ type: commandName, payload: { commandFn, message: msg.data } }) + }) +} + +export const registerErrorScriptRunnerAction = (event, commandName, commandFn, dispatch) => { + event.on('scriptRunner', commandName, (msg) => { + commandFn.error.apply(commandFn, msg.data) + dispatch({ type: commandName, payload: { commandFn, message: msg.data } }) + }) +} diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index 43fae4b344..5c422ead5e 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -17,7 +17,8 @@ export const initialState = { _INDEXall: [], _INDEXallMain: [], _INDEXcommands: {}, - _INDEXcommandsMain: {} + _INDEXcommandsMain: {}, + message: [] } export const registerCommandReducer = (state, action) => { @@ -118,3 +119,13 @@ export const addCommandHistoryReducer = (state, action) => { return { state } } } + +export const registerScriptRunnerReducer = (state, action) => { + console.log({ state }, { action }, 'register script runner reducer') + switch (action.type) { + case 'log': + return { + ...state + } + } +} 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 7bd2a9f90d..99a0a3927c 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -123,6 +123,11 @@ element.style { cursor : row-resize; z-index : 999; } + + .dragbarHorizontal:hover { + background-color: #007AA6; + border:2px solid #007AA6; + } .listenOnNetwork { min-height: auto; } 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 9f2f421b09..2316173ede 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,8 +1,8 @@ import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' -import { registerCommandAction, filterFnAction } from './actions/terminalAction' -import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer } from './reducers/terminalReducer' +import { registerCommandAction, filterFnAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction } from './actions/terminalAction' +import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer } from './reducers/terminalReducer' import javascriptserialize from 'javascript-serialize' import jsbeautify from 'js-beautify' @@ -51,6 +51,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) const [filterState, filterDispatch] = useReducer(registerFilterReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) + const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) const [state, setState] = useState({ journalBlocks: { @@ -110,6 +111,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const inputEl = useRef(null) // events useEffect(() => { + registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) + registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) + registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) + registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch) registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch) registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch) @@ -127,6 +132,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { filterFnAction('warn', basicFilter, filterDispatch) filterFnAction('error', basicFilter, filterDispatch) filterFnAction('script', basicFilter, filterDispatch) + registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) + registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) + registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) + registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) // console.log({ htmlresullt }, { logresult }) // dispatch({ type: 'html', payload: { commands: htmlresullt.commands } }) // dispatch({ type: 'log', payload: { _commands: logresult._commands } }) @@ -195,34 +204,34 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { inputEl.current.focus() } - const putCursor2End = (editable) => { - var range = document.createRange() - console.log({ range }) - range.selectNode(editable) - var child = editable - var chars - console.log({ child }) - while (child) { - if (child.lastChild) child = child.lastChild - else break - if (child.nodeType === Node.TEXT_NODE) { - chars = child.textContent.length - } else { - chars = child.innerHTML.length - } - } - - range.setEnd(child, chars) - var toStart = true - var toEnd = !toStart - range.collapse(toEnd) - - var sel = window.getSelection() - sel.removeAllRanges() - sel.addRange(range) - - editable.focus() - } + // const putCursor2End = (editable) => { + // var range = document.createRange() + // console.log({ range }) + // range.selectNode(editable) + // var child = editable + // var chars + // console.log({ child }) + // while (child) { + // if (child.lastChild) child = child.lastChild + // else break + // if (child.nodeType === Node.TEXT_NODE) { + // chars = child.textContent.length + // } else { + // chars = child.innerHTML.length + // } + // } + + // range.setEnd(child, chars) + // var toStart = true + // var toEnd = !toStart + // range.collapse(toEnd) + + // var sel = window.getSelection() + // sel.removeAllRanges() + // sel.addRange(range) + + // editable.focus() + // } const wrapScript = (script) => { const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) @@ -371,10 +380,26 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } useEffect(() => { + // document.addEventListener('mousemove', changeBg) + // function changeBg () { + // document.getElementById('dragId').style.backgroundColor = 'skyblue' + // } + // document.addEventListener('mouseup', changeBg2) + // function changeBg2 () { + // document.getElementById('dragId').style.backgroundColor = '' + // } document.addEventListener('mousemove', onMouseMove) document.addEventListener('mouseup', onMouseUp) return () => { + // document.addEventListener('mousemove', changeBg) + // function changeBg () { + // document.getElementById('dragId').style.backgroundColor = 'skyblue' + // } + // document.addEventListener('mouseup', changeBg2) + // function changeBg2 () { + // document.getElementById('dragId').style.backgroundColor = '' + // } document.removeEventListener('mousemove', onMouseMove) document.removeEventListener('mouseup', onMouseUp) } @@ -388,7 +413,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { setLeftHeight(leftRef.offsetHeight) return } - leftRef.style.height = `${leftHeight}px` } }, [leftHeight, setLeftHeight]) @@ -447,7 +471,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { {console.log({ newstate })}
{/* ${self._view.dragbar} */} -
+
{/* ${self._view.icon} */} From d41d10ad109daa986b9ceeca6176751490012065 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 23 Jul 2021 17:21:15 +0100 Subject: [PATCH 11/48] getting response from scriptRunnser --- libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index 5c422ead5e..c4a849a1b8 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -1,5 +1,6 @@ export const initialState = { journalBlocks: { + }, data: { // lineLength: props.options.lineLength || 80, @@ -126,6 +127,7 @@ export const registerScriptRunnerReducer = (state, action) => { case 'log': return { ...state + } } } From 8c4fe582bcd1d1c8a78d918f11482b9c6f8c96ad Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Sat, 24 Jul 2021 22:04:45 +0100 Subject: [PATCH 12/48] implementing command execution script in react --- apps/remix-ide/src/app/panels/terminal.js | 14 +- .../src/lib/actions/terminalAction.ts | 4 + libs/remix-ui/terminal/src/lib/commands.ts | 52 ++++ .../terminal/src/lib/reducers/remixWelcom.ts | 25 ++ .../src/lib/reducers/terminalReducer.ts | 40 ++- .../terminal/src/lib/remix-ui-terminal.css | 85 ++++++- .../terminal/src/lib/remix-ui-terminal.tsx | 240 +++++++++++------- libs/remix-ui/terminal/src/lib/utils/utils.ts | 8 + 8 files changed, 355 insertions(+), 113 deletions(-) create mode 100644 libs/remix-ui/terminal/src/lib/commands.ts create mode 100644 libs/remix-ui/terminal/src/lib/reducers/remixWelcom.ts create mode 100644 libs/remix-ui/terminal/src/lib/utils/utils.ts diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 39c5c844b1..9facd299ef 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -39,6 +39,7 @@ class Terminal extends Plugin { this.element.setAttribute('id', 'terminal-view') this.event = new EventManager() this.blockchain = opts.blockchain + this.vm = vm this._api = api this._opts = opts this.config = config @@ -75,18 +76,6 @@ class Terminal extends Plugin { } onActivation () { - // this.on('scriptRunner', 'log', (msg) => { - // this.commands.log.apply(this.commands, msg.data) - // }) - // this.on('scriptRunner', 'info', (msg) => { - // this.commands.info.apply(this.commands, msg.data) - // }) - // this.on('scriptRunner', 'warn', (msg) => { - // this.commands.warn.apply(this.commands, msg.data) - // }) - // this.on('scriptRunner', 'error', (msg) => { - // this.commands.error.apply(this.commands, msg.data) - // }) this.renderComponent() } @@ -148,6 +137,7 @@ class Terminal extends Plugin { version = {this.version} config = {this.config} thisState = {this} + vm = {this.vm} />, this.element ) diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index a986dd8ddc..38c58f3555 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -129,3 +129,7 @@ export const registerErrorScriptRunnerAction = (event, commandName, commandFn, d dispatch({ type: commandName, payload: { commandFn, message: msg.data } }) }) } + +export const registerRemixWelcomeTextAction = (welcomeText, dispatch) => { + dispatch({ type: 'welcomeText', payload: { welcomeText } }) +} diff --git a/libs/remix-ui/terminal/src/lib/commands.ts b/libs/remix-ui/terminal/src/lib/commands.ts new file mode 100644 index 0000000000..14a3cbb97b --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/commands.ts @@ -0,0 +1,52 @@ +export 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/.' } +] + +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.' }, + + { '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' } +] diff --git a/libs/remix-ui/terminal/src/lib/reducers/remixWelcom.ts b/libs/remix-ui/terminal/src/lib/reducers/remixWelcom.ts new file mode 100644 index 0000000000..2b3e392aab --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/reducers/remixWelcom.ts @@ -0,0 +1,25 @@ +export const remixWelcome = () => { + return `
+
- Welcome to Remix {props.version} -
+
+
You can use this terminal to:
+
    +
  • Check transactions details and start debugging.
  • +
  • Execute JavaScript scripts: +
    + - Input a script directly in the command line interface +
    + - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface +
    + - Right click on a JavaScript file in the file explorer and then click \`Run\` +
  • +
+
The following libraries are accessible:
+ +
` +} \ No newline at end of file diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index c4a849a1b8..18d8a0a0d8 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -1,7 +1,7 @@ -export const initialState = { - journalBlocks: { - }, +export const initialState = { + journalBlocks: [ + ], data: { // lineLength: props.options.lineLength || 80, session: [], @@ -121,13 +121,43 @@ export const addCommandHistoryReducer = (state, action) => { } } +export const remixWelcomeTextReducer = (state, action) => { + switch (action.type) { + case 'welcomeText' : + return { + ...state, + journalBlocks: initialState.journalBlocks.push(action.payload.welcomeText) + } + } +} + export const registerScriptRunnerReducer = (state, action) => { console.log({ state }, { action }, 'register script runner reducer') switch (action.type) { case 'log': return { - ...state - + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-info' }) + } + case 'info': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-info' }) + } + case 'warn': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-warning' }) + } + case 'error': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-danger' }) + } + case 'script': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log' }) } } } 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 99a0a3927c..0091042df2 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -1,6 +1,21 @@ element.style { height: 323px !important; +} +#terminalCliInput{ + width: 95%; + background-color: #222336; + color: #a2a3bd; + border-top-style: hidden; + border-right-style: hidden; + border-left-style: hidden; + border-bottom-style: hidden; +} +#terminalCliInput:focus { + outline: none; +} +input #terminalCliInput { + } .panel { position : relative; @@ -151,4 +166,72 @@ element.style { padding: 0 1rem; } - .ul {margin-left: 0; padding-left: 20px;} \ No newline at end of file + .ul {margin-left: 0; padding-left: 20px;} + + .popup { + position : absolute; + text-align : left; + display : none; + width : 95%; + font-family : monospace; + background-color : var(--secondary); + overflow : auto; + padding-bottom : 13px; + z-index : 80; + bottom : 1em; + border-width : 4px; + left : 2em; + } + + .autoCompleteItem { + padding : 4px; + border-radius : 2px; + } + + .popup a { + cursor : pointer; + } + + .listHandlerShow { + display : block; + } + + .listHandlerHide { + display : none; + } + + .listHandlerButtonShow { + position : fixed; + width : 46%; + } + + .pageNumberAlignment { + font-size : 10px; + float : right; + } + + .modalContent { + position : absolute; + margin-left : 20%; + margin-bottom : 32px; + bottom : 0px; + padding : 0; + line-height : 18px; + font-size : 12px; + width : 40%; + box-shadow : 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19); + -webkit-animation-name: animatebottom; + -webkit-animation-duration: 0.4s; + animation-name : animatetop; + animation-duration: 0.4s + } + + @-webkit-keyframes animatetop { + from {bottom: -300px; opacity: 0} + to {bottom: 0; opacity: 1} + } + + @keyframes animatetop { + from {bottom: -300px; opacity: 0} + to {bottom: 0; opacity: 1} + } \ No newline at end of file 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 2316173ede..cb2d91393a 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,8 +1,11 @@ import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' -import { registerCommandAction, filterFnAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction } from './actions/terminalAction' -import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer } from './reducers/terminalReducer' +import { registerCommandAction, filterFnAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, registerRemixWelcomeTextAction } from './actions/terminalAction' +import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer, remixWelcomeTextReducer } from './reducers/terminalReducer' +import { remixWelcome } from './reducers/remixWelcom' +import {getKeyOf, getValueOf} from './utils/utils' +import {allCommands, allPrograms} from './commands' // eslint-disable-line import javascriptserialize from 'javascript-serialize' import jsbeautify from 'js-beautify' @@ -23,12 +26,7 @@ export interface RemixUiTerminalProps { version: any config: any thisState: any - - // blockRenderHtml: any - // blockRenderLog: any - // blockRenderInfo: any - // blockRenderWarn: any - // blockRenderError: any + vm: any } export interface ClipboardEvent extends SyntheticEvent { @@ -52,6 +50,22 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [filterState, filterDispatch] = useReducer(registerFilterReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) + const [welcomeTextState, welcomTextDispath] = useReducer(remixWelcomeTextReducer, initialState) + const [autoCompletState, setAutoCompleteState] = useState({ + activeSuggestion: 0, + data: { + _options: [] + }, + _startingElement: 0, + _elementToShow: 4, + _selectedElement: 0, + filteredCommands: [], + filteredPrograms: [], + showSuggestions: false, + text: '', + userInput: '', + extraCommands: [] + }) const [state, setState] = useState({ journalBlocks: { @@ -111,6 +125,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const inputEl = useRef(null) // events useEffect(() => { + registerRemixWelcomeTextAction(remixWelcome, welcomTextDispath) registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) @@ -122,9 +137,11 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerCommandAction('error', _blocksRenderer('error'), { activate: true }, dispatch) registerCommandAction('script', function execute (args, scopedCommands, append) { var script = String(args[0]) - props.thisState._shell(script, scopedCommands, function (error, output) { - if (error) scopedCommands.error(error) - else if (output) scopedCommands.log(output) + _shell(script, scopedCommands, function (error, output) { + console.log({ error }, 'registerCommand scrpt') + console.log({ output }, 'registerCommand scrpt 2') + if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } }) + else if (output) scriptRunnerDispatch({ type: 'error', payload: { message: output } }) }) }, { activate: true }, dispatch) filterFnAction('log', basicFilter, filterDispatch) @@ -140,7 +157,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // dispatch({ type: 'html', payload: { commands: htmlresullt.commands } }) // dispatch({ type: 'log', payload: { _commands: logresult._commands } }) // registerCommand('log', _blocksRenderer('log'), { activate: true }) - }, []) + }, [newstate.journalBlocks, props.thisState.autoCompletePopup, autoCompletState.text]) const placeCaretAtEnd = (el) => { el.focus() @@ -152,6 +169,35 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { sel.addRange(range) } + const _shell = async (script, scopedCommands, done) => { // default shell + if (script.indexOf('remix:') === 0) { + return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') + } + + if (script.indexOf('remix.') === 0) { + // we keep the old feature. This will basically only be called when the command is querying the "remix" object. + // for all the other case, we use the Code Executor plugin + var context = props.cmdInterpreter + try { + var cmds = props.vm.createContext(context) + var result = props.vm.runInContext(script, cmds) + return done(null, result) + } catch (error) { + return done(error.message) + } + } + try { + if (script.trim().startsWith('git')) { + // result = await this.call('git', 'execute', script) + } else { + result = await props.thisState.call('scriptRunner', 'execute', script) + } + done() + } catch (error) { + done(error.message || error) + } + } + // handle events const handlePaste = (event: ClipboardEvent) => { // Do something @@ -204,35 +250,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { inputEl.current.focus() } - // const putCursor2End = (editable) => { - // var range = document.createRange() - // console.log({ range }) - // range.selectNode(editable) - // var child = editable - // var chars - // console.log({ child }) - // while (child) { - // if (child.lastChild) child = child.lastChild - // else break - // if (child.nodeType === Node.TEXT_NODE) { - // chars = child.textContent.length - // } else { - // chars = child.innerHTML.length - // } - // } - - // range.setEnd(child, chars) - // var toStart = true - // var toEnd = !toStart - // range.collapse(toEnd) - - // var sel = window.getSelection() - // sel.removeAllRanges() - // sel.addRange(range) - - // editable.focus() - // } - const wrapScript = (script) => { const isKnownScript = ['remix.', 'git'].some(prefix => script.trim().startsWith(prefix)) if (isKnownScript) return script @@ -251,39 +268,24 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const handleKeyDown = (event) => { - if (props.autoCompletePopup.handleAutoComplete( - event, - inputEl.current.innerText)) { return } - if (inputEl.current.innerText.length === 0) { - inputEl.current.innerText += '\n' - } if (event.which === 13) { if (event.ctrlKey) { // - console.log(event.which === 32, ' enter key') // on enter, append the value in the cli input to the journal - // setState(prevState => ({...prevState.journalBlocks, prevState: inputEl}) - inputEl.current.innerText += '\n' inputEl.current.focus() - // putCursor2End(inputEl.current) - // scroll2botton () function not implemented - props.autoCompletePopup.removeAutoComplete() } else { // + event.preventDefault() console.log('hit enter') setCmdIndex(-1) setCmdTemp('') - const script = inputEl.current.innerText.trim() - console.log({ script }, ' script ') + const script = autoCompletState.userInput.trim() // inputEl.current.innerText.trim() if (script.length) { cmdHistoryDispatch({ type: 'cmdHistory', payload: { script } }) - const result = newstate.commands.script(wrapScript(script)) - console.log({ result }) + newstate.commands.script(wrapScript(script)) } - // inputEl.current.innerText += '\n' - // if (script.length) { - // // self._cmdHistory.unshift(script) - // props.command.script(wrapScript(script)) - // } - // props.autoCompletePopup.removeAutoComplete() + setAutoCompleteState(prevState => ({ ...prevState, userInput: '' })) + inputEl.current.innerText = '' + inputEl.current.focus() + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false })) } } else if (event.which === 38) { // const len = _cmdHistory.length @@ -293,8 +295,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } inputEl.current.innerText = _cmdHistory[_cmdIndex] inputEl.current.focus() - // putCursor2End(inputEl.current) - // self.scroll2bottom() } else if (event.which === 40) { if (_cmdIndex > -1) { @@ -302,14 +302,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } inputEl.current.innerText = _cmdIndex >= 0 ? _cmdHistory[_cmdIndex] : _cmdTemp inputEl.current.focus() - // putCursor2End(inputEl.current) - // self.scroll2bottom() } else { setCmdTemp(inputEl.current.innerText) } - console.log({ _cmdHistory }) - console.log({ _cmdIndex }) - console.log({ _cmdTemp }) } const moveGhostbar = (event) => { @@ -347,19 +342,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const newEditorHeight = leftHeight - e.clientY + separatorYPosition const newLeftHeight = leftHeight + separatorYPosition - e.clientY setSeparatorYPosition(e.clientY) - - // if (newLeftHeight < MIN_HEIGHT) { - // setLeftHeight(MIN_HEIGHT) - // return - // } - // if (splitPaneRef.current) { - // const splitPaneHeight = splitPaneRef.current.clientHeight - - // if (newLeftHeight > splitPaneHeight - MIN_HEIGHT) { - // setLeftHeight(splitPaneHeight - MIN_HEIGHT) - // return - // } - // } setLeftHeight(newLeftHeight) props.event.trigger('resize', [newLeftHeight + 32]) console.log({ newLeftHeight }) @@ -415,7 +397,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } leftRef.style.height = `${leftHeight}px` } - }, [leftHeight, setLeftHeight]) + }, [leftHeight, setLeftHeight, inputEl]) /* block contents that gets rendered from scriptRunner */ @@ -429,7 +411,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } mode = { - log: 'text-info', + log: 'text-log', info: 'text-info', warn: 'text-warning', error: 'text-danger' @@ -466,9 +448,78 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { /* end of block content that gets rendered from script Runner */ + /* start of autoComplete */ + const handleSelect = (text) => { + props.thisState.event.trigger('handleSelect', [text]) + } + + const onChange = (event: any) => { + event.preventDefault() + const inputString = event.target.value + console.log(event) + console.log({ inputString }) + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: true, userInput: inputString })) + const textList = inputString.split(' ') + const autoCompleteInput = textList.length > 1 ? textList[textList.length - 1] : textList[0] + allPrograms.forEach(item => { + const program = getKeyOf(item) + console.log({ program }) + if (program.substring(0, program.length - 1).includes(autoCompleteInput.trim())) { + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [item] } })) + } else if (autoCompleteInput.trim().includes(program) || (program === autoCompleteInput.trim())) { + allCommands.forEach(item => { + console.log({ item }) + const command = getKeyOf(item) + if (command.includes(autoCompleteInput.trim())) { + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [item] } })) + } + }) + } + }) + autoCompletState.extraCommands.forEach(item => { + const command = getKeyOf(item) + if (command.includes(autoCompleteInput.trim())) { + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [item] } })) + } + }) + if (autoCompletState.data._options.length === 1 && event.which === 9) { + // if only one option and tab is pressed, we resolve it + event.preventDefault() + textList.pop() + textList.push(getKeyOf(autoCompletState.data._options[0])) + handleSelect(`${textList}`.replace(/,/g, ' ')) + } + } + + const handleAutoComplete = () => ( +
+
+ ${autoCompletState.data._options.map((item, index) => { + return ( +
auto complete here
+ //
+ //
{ handleSelect(event.srcElement.innerText) }}> + // {getKeyOf(item)} + //
+ //
+ // {getValueOf(item)} + //
+ //
+ ) + })} +
+ {/*
+
Page ${(self._startingElement / self._elementsToShow) + 1} of ${Math.ceil(data._options.length / self._elementsToShow)}
+
*/} +
+ ) + /* end of autoComplete */ + return (
{console.log({ newstate })} + {console.log({ props })} + {console.log({ autoCompletState })}
{/* ${self._view.dragbar} */}
@@ -513,8 +564,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
- {/* onScroll=${throttle(reattach, 10)} onkeydown=${focusinput} */} - {/* {props.autoCompletePopup.render()} */} + { + (autoCompletState.showSuggestions && autoCompletState.userInput) && handleAutoComplete() + }
{ }}>
-
- {Object.entries(state.journalBlocks).map((x, index) => ( -
- {x} -
- ))} -
+ {(newstate.journalBlocks).map((x, index) => ( +
+ {x.message} +
+ ))}
{/* ${background} */}
@@ -540,7 +590,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{'>'} - + onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput}>
diff --git a/libs/remix-ui/terminal/src/lib/utils/utils.ts b/libs/remix-ui/terminal/src/lib/utils/utils.ts new file mode 100644 index 0000000000..46ca37fa89 --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/utils/utils.ts @@ -0,0 +1,8 @@ + +export const getKeyOf = (item) => { + return Object.keys(item)[0] +} + +export const getValueOf = (item) => { + return Object.values(item)[0] +} From b56c1c804de2b43fea7c9248c7773b387724fc05 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 11 Aug 2021 06:15:40 +0100 Subject: [PATCH 13/48] feat: clear-console, terminal-search, fix-input terminal input to buttom --- apps/remix-ide/src/app.js | 7 +- apps/remix-ide/src/app/panels/terminal.js | 483 +++++++----- .../src/lib/actions/terminalAction.ts | 106 ++- .../src/lib/reducers/terminalReducer.ts | 37 +- .../terminal/src/lib/remix-ui-terminal.css | 123 +++- .../terminal/src/lib/remix-ui-terminal.tsx | 690 ++++++++++++++---- .../remix-ui/terminal/src/lib/utils/helper.ts | 176 +++++ libs/remix-ui/terminal/src/lib/utils/utils.ts | 34 + 8 files changed, 1310 insertions(+), 346 deletions(-) create mode 100644 libs/remix-ui/terminal/src/lib/utils/helper.ts diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 2347737a20..518d93c64c 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -288,6 +288,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org // -------------------Terminal---------------------------------------- + // move this up for *** level so as to access it in the terminal + makeUdapp(blockchain, compilersArtefacts, (domEl) => terminal.logHtml(domEl)) const terminal = new Terminal( { appManager, blockchain }, { @@ -300,10 +302,11 @@ Please make a backup of your contracts and start using http://remix.ethereum.org return height - newpos } }, - { config: registry.get('config').api } + { config: registry.get('config').api }, + registry ) - makeUdapp(blockchain, compilersArtefacts, (domEl) => terminal.logHtml(domEl)) + // previous *** level for makeUdapp method const contextualListener = new ContextualListener({ editor }) engine.register([ diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 9facd299ef..fb3bc4a130 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -18,6 +18,11 @@ var AutoCompletePopup = require('../ui/auto-complete-popup') var css = require('./styles/terminal-styles') +import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line +var globalRegistry = require('../../global/registry') +var SourceHighlighter = require('../../app/editor/sourceHighlighter') +var GistHandler = require('../../lib/gist-handler') + var KONSOLES = [] function register (api) { KONSOLES.push(api) } @@ -32,12 +37,32 @@ const profile = { } class Terminal extends Plugin { - constructor (opts, api, config) { + constructor (opts, api, config, registry) { super(profile) + this.fileImport = new CompilerImports() + this.gistHandler = new GistHandler() + this.event = new EventManager() + this.registry = registry + this.globalRegistry = globalRegistry this.element = document.createElement('div') this.element.setAttribute('class', 'panel_2A0YE0') this.element.setAttribute('id', 'terminal-view') - this.event = new EventManager() + this.eventsDecoder = this.globalRegistry.get('eventsDecoder').api + this.txListener = this.globalRegistry.get('txlistener').api + this.sourceHighlighter = new SourceHighlighter() + this._deps = { + fileManager: this.registry.get('filemanager').api, + editor: this.registry.get('editor').api, + compilersArtefacts: this.registry.get('compilersartefacts').api, + offsetToLineColumnConverter: this.registry.get('offsettolinecolumnconverter').api + } + this.commandHelp = { + '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, ipfs or raw http', + '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' + } this.blockchain = opts.blockchain this.vm = vm this._api = api @@ -54,14 +79,14 @@ class Terminal extends Plugin { this._components = {} this._components.cmdInterpreter = new CommandInterpreterAPI(this, null, this.blockchain) this._components.autoCompletePopup = new AutoCompletePopup(this._opts) - this._components.autoCompletePopup.event.register('handleSelect', function (input) { - const textList = this._view.input.innerText.split(' ') - textList.pop() - textList.push(input) - this._view.input.innerText = textList - this._view.input.focus() - this.putCursor2End(this._view.input) - }) + // this._components.autoCompletePopup.event.register('handleSelect', function (input) { + // const textList = this._view.input.innerText.split(' ') + // textList.pop() + // textList.push(input) + // this._view.input.innerText = textList + // this._view.input.focus() + // this.putCursor2End(this._view.input) + // }) this._commands = {} this.commands = {} this._JOURNAL = [] @@ -86,31 +111,10 @@ class Terminal extends Plugin { this.off('scriptRunner', 'error') } - log (message) { - var command = this.commands[message.type] - if (typeof command === 'function') { - if (typeof message.value === 'string' && message.type === 'html') { - var el = document.createElement('div') - el.innerHTML = remixBleach.sanitize(message.value, { - list: [ - 'a', - 'b', - 'p', - 'em', - 'strong', - 'div', - 'span', - 'ul', - 'li', - 'ol', - 'hr' - ] - }) - message.value = el - } - command(message.value) - }; - } + // logHtml (html) { + // var command = this.commands.html + // if (typeof command === 'function') command(html) + // } logHtml (html) { var command = this.commands.html @@ -128,7 +132,7 @@ class Terminal extends Plugin { autoCompletePopupEvent = {this._components.autoCompletePopup.event} blockchain = {this.blockchain} api = {this._api} - options = {this.opts} + options = {this._opts} data = {this.data} cmdInterpreter = {this._components.cmdInterpreter} autoCompletePopup = {this._components.autoCompletePopup} @@ -138,170 +142,285 @@ class Terminal extends Plugin { config = {this.config} thisState = {this} vm = {this.vm} + blockchain = {this.blockchain} + commandHelp = {this.commandHelp} + event = {this.event} + _deps = {this._deps} + fileImport = {this.fileImport} + sourceHighlighter = {this.sourceHighlighter} + gistHandler ={this.gistHandler} + registry = {this.registry} + commands = {this.commands} + txListener = {this.txListener} + eventsDecoder = {this.eventsDecoder} />, this.element ) } - _appendItem (item) { - var self = this - var { el, gidx } = item - self._JOURNAL[gidx] = item - if (!self._jobs.length) { - requestAnimationFrame(function updateTerminal () { - self._jobs.forEach(el => self._view.journal.appendChild(el)) - self.scroll2bottom() - self._jobs = [] - }) - } - if (self.data.activeFilters.commands[item.cmd]) self._jobs.push(el) - } + // _appendItem (item) { + // var self = this + // var { el, gidx } = item + // self._JOURNAL[gidx] = item + // if (!self._jobs.length) { + // requestAnimationFrame(function updateTerminal () { + // self._jobs.forEach(el => self._view.journal.appendChild(el)) + // self.scroll2bottom() + // self._jobs = [] + // }) + // } + // if (self.data.activeFilters.commands[item.cmd]) self._jobs.push(el) + // } scroll2bottom () { var self = this setTimeout(function () { - self._view.term.scrollTop = self._view.term.scrollHeight + // self._view.term.scrollTop = self._view.term.scrollHeight }, 0) } - _blocksRenderer (mode) { - if (mode === 'html') { - return function logger (args, scopedCommands, append) { - if (args.length) append(args[0]) - } - } - mode = { - log: 'text-info', - info: 'text-info', - warn: 'text-warning', - error: 'text-danger' - }[mode] // defaults - - if (mode) { - const filterUndefined = (el) => el !== undefined && el !== null - return function logger (args, scopedCommands, append) { - var types = args.filter(filterUndefined).map(type) - var values = javascriptserialize.apply(null, args.filter(filterUndefined)).map(function (val, idx) { - if (typeof args[idx] === 'string') { - const el = document.createElement('div') - el.innerHTML = args[idx].replace(/(\r\n|\n|\r)/gm, '
') - val = el.children.length === 0 ? el.firstChild : el - } - if (types[idx] === 'element') val = jsbeautify.html(val) - return val - }) - if (values.length) { - append(yo`${values}`) - } - } - } else { - throw new Error('mode is not supported') - } - } + // _blocksRenderer (mode) { + // if (mode === 'html') { + // return function logger (args, scopedCommands, append) { + // if (args.length) append(args[0]) + // } + // } + // mode = { + // log: 'text-info', + // info: 'text-info', + // warn: 'text-warning', + // error: 'text-danger' + // }[mode] // defaults - _scopeCommands (append) { - var self = this - var scopedCommands = {} - Object.keys(self.commands).forEach(function makeScopedCommand (cmd) { - var command = self._commands[cmd] - scopedCommands[cmd] = function _command () { - var args = [...arguments] - command(args, scopedCommands, el => append(cmd, args, blockify(el))) - } - }) - return scopedCommands - } + // if (mode) { + // const filterUndefined = (el) => el !== undefined && el !== null + // return function logger (args, scopedCommands, append) { + // var types = args.filter(filterUndefined).map(type) + // var values = javascriptserialize.apply(null, args.filter(filterUndefined)).map(function (val, idx) { + // if (typeof args[idx] === 'string') { + // const el = document.createElement('div') + // el.innerHTML = args[idx].replace(/(\r\n|\n|\r)/gm, '
') + // val = el.children.length === 0 ? el.firstChild : el + // } + // if (types[idx] === 'element') val = jsbeautify.html(val) + // return val + // }) + // if (values.length) { + // append(yo`${values}`) + // } + // } + // } else { + // throw new Error('mode is not supported') + // } + // } - registerFilter (commandName, filterFn) { - this.data.filterFns[commandName] = filterFn - } + // _scopeCommands (append) { + // var self = this + // var scopedCommands = {} + // Object.keys(self.commands).forEach(function makeScopedCommand (cmd) { + // var command = self._commands[cmd] + // scopedCommands[cmd] = function _command () { + // var args = [...arguments] + // command(args, scopedCommands, el => append(cmd, args, blockify(el))) + // } + // }) + // return scopedCommands + // } - registerCommand (name, command, opts) { - var self = this - name = String(name) - if (self._commands[name]) throw new Error(`command "${name}" exists already`) - if (typeof command !== 'function') throw new Error(`invalid command: ${command}`) - self._commands[name] = command - console.log({ command }) - console.log(self._commands) - self._INDEX.commands[name] = [] - self._INDEX.commandsMain[name] = [] - self.commands[name] = function _command () { - var args = [...arguments] - var steps = [] - var root = { steps, cmd: name } - var ITEM = { root, cmd: name } - root.gidx = self._INDEX.allMain.push(ITEM) - 1 - root.idx = self._INDEX.commandsMain[name].push(ITEM) - 1 - function append (cmd, params, el) { - var item - if (cmd) { // subcommand - item = { el, cmd, root } - } else { // command - item = ITEM - item.el = el - cmd = name - } - item.gidx = self._INDEX.all.push(item) - 1 - item.idx = self._INDEX.commands[cmd].push(item) - 1 - item.step = steps.push(item) - 1 - item.args = params - self._appendItem(item) - } - var scopedCommands = self._scopeCommands(append) - command(args, scopedCommands, el => append(null, args, blockify(el))) - } - var help = typeof command.help === 'string' ? command.help : [ - '// no help available for:', - `terminal.commands.${name}(...)` - ].join('\n') - self.commands[name].toString = _ => { return help } - self.commands[name].help = help - self.data.activeFilters.commands[name] = opts && opts.activate - if (opts.filterFn) { - self.registerFilter(name, opts.filterFn) - } - return self.commands[name] - } + // registerFilter (commandName, filterFn) { + // this.data.filterFns[commandName] = filterFn + // } - async _shell (script, scopedCommands, done) { // default shell - if (script.indexOf('remix:') === 0) { - return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') - } - var self = this - if (script.indexOf('remix.') === 0) { - // we keep the old feature. This will basically only be called when the command is querying the "remix" object. - // for all the other case, we use the Code Executor plugin - var context = domTerminalFeatures(scopedCommands, self.blockchain) - try { - var cmds = vm.createContext(context) - var result = vm.runInContext(script, cmds) - return done(null, result) - } catch (error) { - return done(error.message) - } - } - try { - let result - if (script.trim().startsWith('git')) { - // result = await this.call('git', 'execute', script) - } else { - result = await this.call('scriptRunner', 'execute', script) - } - if (result) self.commands.html(yo`
${result}
`) - done() - } catch (error) { - done(error.message || error) - } - } -} + // registerCommand (name, command, opts) { + // var self = this + // name = String(name) + // if (this._commands[name]) throw new Error(`command "${name}" exists already`) + // if (typeof command !== 'function') throw new Error(`invalid command: ${command}`) + // this._commands[name] = command + // console.log({ command }) + // console.log(self._commands) + // this._INDEX.commands[name] = [] + // this._INDEX.commandsMain[name] = [] + // this.commands[name] = function _command () { + // var args = [...arguments] + // var steps = [] + // var root = { steps, cmd: name } + // var ITEM = { root, cmd: name } + // root.gidx = self._INDEX.allMain.push(ITEM) - 1 + // root.idx = self._INDEX.commandsMain[name].push(ITEM) - 1 + // function append (cmd, params, el) { + // var item + // if (cmd) { // subcommand + // item = { el, cmd, root } + // } else { // command + // item = ITEM + // item.el = el + // cmd = name + // } + // item.gidx = self._INDEX.all.push(item) - 1 + // item.idx = self._INDEX.commands[cmd].push(item) - 1 + // item.step = steps.push(item) - 1 + // item.args = params + // // self._appendItem(item) + // } + // var scopedCommands = self._scopeCommands(append) + // command(args, scopedCommands, el => append(null, args, blockify(el))) + // } + // var help = typeof command.help === 'string' ? command.help : [ + // '// no help available for:', + // `terminal.commands.${name}(...)` + // ].join('\n') + // this.commands[name].toString = _ => { return help } + // this.commands[name].help = help + // this.data.activeFilters.commands[name] = opts && opts.activate + // if (opts.filterFn) { + // this.registerFilter(name, opts.filterFn) + // } + // return this.commands[name] + // } -function domTerminalFeatures (scopedCommands, blockchain) { - return { - remix: this._components.cmdInterpreter - } -} + // async _shell (script, scopedCommands, done) { // default shell + // if (script.indexOf('remix:') === 0) { + // return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') + // } + // var self = this + // if (script.indexOf('remix.') === 0) { + // // we keep the old feature. This will basically only be called when the command is querying the "remix" object. + // // for all the other case, we use the Code Executor plugin + // var context = domTerminalFeatures(scopedCommands, self.blockchain) + // try { + // var cmds = vm.createContext(context) + // var result = vm.runInContext(script, cmds) + // return done(null, result) + // } catch (error) { + // return done(error.message) + // } + // } + // try { + // let result + // if (script.trim().startsWith('git')) { + // // result = await this.call('git', 'execute', script) + // } else { + // result = await this.call('scriptRunner', 'execute', script) + // } + // if (result) self.commands.html(yo`
${result}
`) + // done() + // } catch (error) { + // done(error.message || error) + // } + // } + // } + + // function domTerminalFeatures (scopedCommands, blockchain) { + // return { + // remix: { + // blockchain: this.blockchain, + // commandHelp: this.commandHelp, + // event: this.event, + // _deps: this._deps + // } + // } + // } + + // function loadgist (id, cb) { + // const self = this + // self._components.gistHandler.loadFromGist({ gist: id }, this._deps.fileManager) + // if (cb) cb() + // } + + // function loadurl (url, cb) { + // const self = this + // self._components.fileImport.import(url, + // (loadingMsg) => { toolTip(loadingMsg) }, + // (err, content, cleanUrl, type, url) => { + // if (err) { + // toolTip(`Unable to load ${url}: ${err}`) + // if (cb) cb(err) + // } else { + // self._deps.fileManager.writeFile(type + '/' + cleanUrl, content) + // try { + // content = JSON.parse(content) + // async.eachOfSeries(content.sources, (value, file, callbackSource) => { + // var url = value.urls[0] // @TODO retrieve all other contents ? + // self._components.fileImport.import(url, + // (loadingMsg) => { toolTip(loadingMsg) }, + // async (error, content, cleanUrl, type, url) => { + // if (error) { + // toolTip(`Cannot retrieve the content of ${url}: ${error}`) + // return callbackSource(`Cannot retrieve the content of ${url}: ${error}`) + // } else { + // try { + // await self._deps.fileManager.writeFile(type + '/' + cleanUrl, content) + // callbackSource() + // } catch (e) { + // callbackSource(e.message) + // } + // } + // }) + // }, (error) => { + // if (cb) cb(error) + // }) + // } catch (e) {} + // if (cb) cb() + // } + // }) + // } + // function exeCurrent (cb) { + // return this.execute(undefined, cb) + // } + + // function execute (file, cb) { + // const self = this + + // function _execute (content, cb) { + // if (!content) { + // toolTip('no content to execute') + // if (cb) cb() + // return + // } + + // self._components.terminal.commands.script(content) + // } + + // if (typeof file === 'undefined') { + // var content = self._deps.editor.currentContent() + // _execute(content, cb) + // return + // } + + // var provider = self._deps.fileManager.fileProviderOf(file) + + // if (!provider) { + // toolTip(`provider for path ${file} not found`) + // if (cb) cb() + // return + // } + + // provider.get(file, (error, content) => { + // if (error) { + // // toolTip(error) + // // TODO: pop up + // if (cb) cb() + // return + // } + + // _execute(content, cb) + // }) + // } + +// function help (cb) { +// const self = this +// var help = yo`
` +// for (var k in self.commandHelp) { +// help.appendChild(yo`
${k}: ${self.commandHelp[k]}
`) +// help.appendChild(yo`
`) +// } +// self._components.terminal.commands.html(help) +// if (cb) cb() +// return '' +// } +} function blockify (el) { return yo`
${el}
` } module.exports = Terminal diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index 38c58f3555..d032daafc5 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -70,8 +70,9 @@ export const registerCommandAction = (name, command, activate, dispatch) => { if (activate.filterFn) { registerFilter(name, activate.filterFn) } - dispatch({ type: name, payload: { commands: commands, _commands: _commands, data: data } }) - + if (name !== ('knownTransaction' || 'unkownTransaction' || 'emptyBlock')) { + dispatch({ type: name, payload: { commands: commands, _commands: _commands, data: data } }) + } const blockify = (el) => { return `
${el}
` } @@ -89,7 +90,6 @@ export const registerCommandAction = (name, command, activate, dispatch) => { console.log({ scopedCommands }) return scopedCommands } - } export const filterFnAction = (name, filterFn, dispatch) => { @@ -133,3 +133,103 @@ export const registerErrorScriptRunnerAction = (event, commandName, commandFn, d export const registerRemixWelcomeTextAction = (welcomeText, dispatch) => { dispatch({ type: 'welcomeText', payload: { welcomeText } }) } + +export const listenOnNetworkAction = async (props, isListening) => { + props.event.trigger('listenOnNetWork', [isListening]) +} + +export const initListeningOnNetwork = (props, dispatch) => { + props.txListener.event.register('newBlock', (block) => { + if (!block.transactions || (block.transactions && !block.transactions.length)) { + dispatch({ type: 'emptyBlock', payload: { message: 0 } }) + console.log({ block }, ' david') + // registerCommandAction('emptyBlock', (args, cmds, append) => { + // const data = args[0] + // console.log({ data }, ' useEffect props') + // // // var el = renderEmptyBlock(this, data) + // // // append(el) + // }, { activate: true }, dispatch) + } else { + registerCommandAction('knownTransaction', function (args, cmds, append) { + var data = args[0] + console.log({ data }) + // let el + // if (data.tx.isCall) { + // console.log({ data }) + // // el = renderCall(this, data) + // } else { + // // el = renderKnownTransaction(this, data, blockchain) + // } + // this.seen[data.tx.hash] = el + // append(el) + }, { activate: true }, dispatch) + } + }) + props.txListener.event.register('newCall', (tx) => { + console.log('new call action') + // log(this, tx, null) + }) + props.txListener.event.register('newTransaction', (tx, receipt) => { + log(props, tx, receipt, dispatch) + registerCommandAction('knownTransaction', function (args, cmds, append) { + var data = args[0] + console.log({ data }) + // let el + // if (data.tx.isCall) { + // console.log({ data }) + // // el = renderCall(this, data) + // } else { + // // el = renderKnownTransaction(this, data, blockchain) + // } + // this.seen[data.tx.hash] = el + // append(el) + }, { activate: true }, dispatch) + // const result = Object.assign([], tx) + // console.log({ result }) + // scriptRunnerDispatch({ type: 'knownTransaction', payload: { message: result } }) + }) + + const log = async (props, tx, receipt, dispatch) => { + const resolvedTransaction = await props.txListener.resolvedTransaction(tx.hash) + if (resolvedTransaction) { + var compiledContracts = null + if (props._deps.compilersArtefacts.__last) { + compiledContracts = await props._deps.compilersArtefacts.__last.getContracts() + } + console.log({ compiledContracts }) + await props.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => { + if (!error) { + console.log({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }) + console.log('knownTransaction') + // logKnownTX({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }) + registerCommandAction('knownTransaction', function (args, cmds, append) { + var data = args[0] + console.log({ data }, 'knownTransaction') + // let el + // if (data.tx.isCall) { + // console.log({ data }) + // // el = renderCall(this, data) + // } else { + // // el = renderKnownTransaction(this, data, blockchain) + // } + // this.seen[data.tx.hash] = el + // append(el) + }, { activate: true }, dispatch) + } + }) + } else { + console.log('unknownTransaction') + // contract unknown - just displaying raw tx. + // logUnknownTX({ tx: tx, receipt: receipt }) + await dispatch({ type: 'unknownTransaction', payload: { message: [{ tx: tx, receipt: receipt }] } }) + } + } + + props.txListener.event.register('debuggingRequested', async (hash) => { + // TODO should probably be in the run module + console.log({ hash }, 'register Call') + if (!await props.options.appManager.isActive('debugger')) await props.options.appManager.activatePlugin('debugger') + props.thisState.call('menuicons', 'select', 'debugger') + props.thisState.call('debugger', 'debug', hash) + }) +} diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index 18d8a0a0d8..7b9043f6c5 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -67,6 +67,17 @@ export const registerCommandReducer = (state, action) => { commands: Object.assign(initialState.commands, action.payload.commands), data: Object.assign(initialState.data, action.payload.data) } + case 'clearconsole': + return { + ...state, + ...state.journalBlocks.splice(0) + } + case 'listenOnNetWork': + console.log({ action: action.payload }) + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-info' }) + } default : return { state } } @@ -75,14 +86,12 @@ export const registerCommandReducer = (state, action) => { export const registerFilterReducer = (state, action) => { switch (action.type) { case 'log': - console.log({ action }, { state }, 'register Filter') return { ...state, data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) } case 'info': - console.log({ action }, 'registerFilter') return { ...state, data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) @@ -132,7 +141,8 @@ export const remixWelcomeTextReducer = (state, action) => { } export const registerScriptRunnerReducer = (state, action) => { - console.log({ state }, { action }, 'register script runner reducer') + const result = Object.assign([], action.payload.message) + console.log({ result }) switch (action.type) { case 'log': return { @@ -159,5 +169,26 @@ export const registerScriptRunnerReducer = (state, action) => { ...state, journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log' }) } + case 'knownTransaction': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'knownTransaction' }) + } + case 'unknownTransaction': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'knownTransaction' }) + } + case 'emptyBlock': + console.log({ action: action.payload.message }, ' emptyBLock reducer') + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'emptyBlock' }) + } + case 'newTransaction': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '' }) + } } } 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 0091042df2..890460b43c 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -17,6 +17,18 @@ element.style { input #terminalCliInput { } + +.border-primary { + border-color: #007aa6!important; +} +.border { + border: 1px solid #3f4455!important; +} + +.selectedOptions { + background-color: #222336; +} + .panel { position : relative; display : flex; @@ -138,6 +150,10 @@ input #terminalCliInput { cursor : row-resize; z-index : 999; } + + .console { + cursor : pointer; + } .dragbarHorizontal:hover { background-color: #007AA6; @@ -171,7 +187,6 @@ input #terminalCliInput { .popup { position : absolute; text-align : left; - display : none; width : 95%; font-family : monospace; background-color : var(--secondary); @@ -234,4 +249,108 @@ input #terminalCliInput { @keyframes animatetop { from {bottom: -300px; opacity: 0} to {bottom: 0; opacity: 1} - } \ No newline at end of file + } + + + + + /* tx logger css*/ + + .log { + display: flex; + cursor: pointer; + align-items: center; + cursor: pointer; + } + .log:hover { + opacity: 0.8; + } + .arrow { + color: var(--text-info); + font-size: 20px; + cursor: pointer; + display: flex; + margin-left: 10px; + } + .arrow:hover { + color: var(--secondary); + } + .txLog { + } + .txStatus { + display: flex; + font-size: 20px; + margin-right: 20px; + float: left; + } + .succeeded { + color: var(--success); + } + .failed { + color: var(--danger); + } + .notavailable { + } + .call { + font-size: 7px; + border-radius: 50%; + min-width: 20px; + min-height: 20px; + display: flex; + justify-content: center; + align-items: center; + color: var(--text-info); + text-transform: uppercase; + font-weight: bold; + } + .txItem { + color: var(--text-info); + margin-right: 5px; + float: left; + } + .txItemTitle { + font-weight: bold; + } + .tx { + color: var(--text-info); + font-weight: bold; + float: left; + margin-right: 10px; + } + .txTable, + .tr, + .td { + border-collapse: collapse; + font-size: 10px; + color: var(--text-info); + border: 1px solid var(--text-info); + } + #txTable { + margin-top: 1%; + margin-bottom: 5%; + align-self: center; + width: 85%; + } + .tr, .td { + padding: 4px; + vertical-align: baseline; + } + .td:first-child { + min-width: 30%; + width: 30%; + align-items: baseline; + font-weight: bold; + } + .tableTitle { + width: 25%; + } + .buttons { + display: flex; + margin-left: auto; + } + .debug { + white-space: nowrap; + } + .debug:hover { + opacity: 0.8; + } 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 cb2d91393a..94c45e2b90 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,15 +1,26 @@ import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' -import { registerCommandAction, filterFnAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, registerRemixWelcomeTextAction } from './actions/terminalAction' +import { registerCommandAction, filterFnAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, registerRemixWelcomeTextAction, listenOnNetworkAction, initListeningOnNetwork } from './actions/terminalAction' import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer, remixWelcomeTextReducer } from './reducers/terminalReducer' import { remixWelcome } from './reducers/remixWelcom' -import {getKeyOf, getValueOf} from './utils/utils' +import { getKeyOf, getValueOf, Objectfilter, matched, find } from './utils/utils' import {allCommands, allPrograms} from './commands' // eslint-disable-line +import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line +import { ModalDialog } from '@remix-ui/modal-dialog' +// const TxLogger from '../../../apps/' +import vm from 'vm' import javascriptserialize from 'javascript-serialize' import jsbeautify from 'js-beautify' +import helper from '../../../../../apps/remix-ide/src/lib/helper' +import parse from 'html-react-parser' import './remix-ui-terminal.css' +import { debug } from 'console' +import { eventNames } from 'process' + +const remixLib = require('@remix-project/remix-lib') +var typeConversion = remixLib.execution.typeConversion /* eslint-disable-next-line */ export interface RemixUiTerminalProps { @@ -27,6 +38,15 @@ export interface RemixUiTerminalProps { config: any thisState: any vm: any + commandHelp: any, + _deps: any, + fileImport: any, + gistHandler: any, + sourceHighlighter: any, + registry: any, + commands: any, + txListener: any, + eventsDecoder: any } export interface ClipboardEvent extends SyntheticEvent { @@ -34,7 +54,6 @@ export interface ClipboardEvent extends SyntheticEvent { } export const RemixUiTerminal = (props: RemixUiTerminalProps) => { - const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') const [inserted, setInserted] = useState(false) const [_cmdIndex, setCmdIndex] = useState(-1) @@ -51,12 +70,14 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) const [welcomeTextState, welcomTextDispath] = useReducer(remixWelcomeTextReducer, initialState) + const [isListeningOnNetwork, setIsListeningOnNetwork] = useState(false) const [autoCompletState, setAutoCompleteState] = useState({ activeSuggestion: 0, data: { _options: [] }, _startingElement: 0, + autoCompleteSelectedItem: {}, _elementToShow: 4, _selectedElement: 0, filteredCommands: [], @@ -64,58 +85,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { showSuggestions: false, text: '', userInput: '', - extraCommands: [] - }) - - const [state, setState] = useState({ - journalBlocks: { - intro: ( -
-
- Welcome to Remix {props.version} -
-
-
You can use this terminal to:
-
    -
  • Check transactions details and start debugging.
  • -
  • Execute JavaScript scripts: -
    - - Input a script directly in the command line interface -
    - - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface -
    - - Right click on a JavaScript file in the file explorer and then click \`Run\` -
  • -
-
The following libraries are accessible:
- -
- ), - text: (
David
) - }, - data: { - // lineLength: props.options.lineLength || 80, - session: [], - activeFilters: { commands: {}, input: '' }, - filterFns: {} - }, - _commands: {}, - commands: {}, - _JOURNAL: [], - _jobs: [], - _INDEX: {}, - _INDEXall: [], - _INDEXallMain: [], - _INDEXcommands: {}, - _INDEXcommandsMain: {} + extraCommands: [], + commandHistoryIndex: 0 }) - const _scopedCommands = () => { - - } + const [searchInput, setSearchInput] = useState('') + // const [showTableDetails, setShowTableDetails] = useState([]) + const [showTableDetails, setShowTableDetails] = useState(null) useWindowResize(() => { setWindowHeight(window.innerHeight) @@ -125,7 +101,8 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const inputEl = useRef(null) // events useEffect(() => { - registerRemixWelcomeTextAction(remixWelcome, welcomTextDispath) + initListeningOnNetwork(props, scriptRunnerDispatch) + // registerRemixWelcomeTextAction(remixWelcome, welcomTextDispath) registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) @@ -135,15 +112,18 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch) registerCommandAction('warn', _blocksRenderer('warn'), { activate: true }, dispatch) registerCommandAction('error', _blocksRenderer('error'), { activate: true }, dispatch) + registerCommandAction('script', function execute (args, scopedCommands, append) { var script = String(args[0]) + console.log({ script }) + console.log({ scopedCommands }) + _shell(script, scopedCommands, function (error, output) { - console.log({ error }, 'registerCommand scrpt') - console.log({ output }, 'registerCommand scrpt 2') if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } }) - else if (output) scriptRunnerDispatch({ type: 'error', payload: { message: output } }) + if (output) scriptRunnerDispatch({ type: 'script', payload: { message: '5' } }) }) }, { activate: true }, dispatch) + filterFnAction('log', basicFilter, filterDispatch) filterFnAction('info', basicFilter, filterDispatch) filterFnAction('warn', basicFilter, filterDispatch) @@ -157,7 +137,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // dispatch({ type: 'html', payload: { commands: htmlresullt.commands } }) // dispatch({ type: 'log', payload: { _commands: logresult._commands } }) // registerCommand('log', _blocksRenderer('log'), { activate: true }) - }, [newstate.journalBlocks, props.thisState.autoCompletePopup, autoCompletState.text]) + }, [props.thisState.autoCompletePopup, autoCompletState.text]) const placeCaretAtEnd = (el) => { el.focus() @@ -169,6 +149,53 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { sel.addRange(range) } + const domTerminalFeatures = () => { + return { + remix: props.cmdInterpreter + } + } + + function exeCurrent (cb) { + return execute(undefined, cb) + } + + function execute (file, cb) { + function _execute (content, cb) { + if (!content) { + // toolTip('no content to execute') + if (cb) cb() + return + } + + newstate.commands.script(content) + } + + if (typeof file === 'undefined') { + var content = props._deps.editor.currentContent() + _execute(content, cb) + return + } + + var provider = props._deps.fileManager.fileProviderOf(file) + + if (!provider) { + // toolTip(`provider for path ${file} not found`) + if (cb) cb() + return + } + + provider.get(file, (error, content) => { + if (error) { + // toolTip(error) + // TODO: pop up + if (cb) cb() + return + } + + _execute(content, cb) + }) + } + const _shell = async (script, scopedCommands, done) => { // default shell if (script.indexOf('remix:') === 0) { return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') @@ -177,21 +204,36 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - var context = props.cmdInterpreter + var context = domTerminalFeatures() try { - var cmds = props.vm.createContext(context) - var result = props.vm.runInContext(script, cmds) - return done(null, result) + const cmds = vm.createContext(context) + // const result + let result = vm.runInContext(script, cmds) + if (script === 'remix.exeCurrent()') { + result = exeCurrent(undefined) + } else { + if (result === {}) { + for (const k in result) { + result = +`
{k}: ${result[k]}

` + } + } + } + + console.log(result === {}, ' is result === object') + console.log({ result }) + return done(null, '') } catch (error) { return done(error.message) } } try { + let result: any if (script.trim().startsWith('git')) { // result = await this.call('git', 'execute', script) } else { result = await props.thisState.call('scriptRunner', 'execute', script) } + console.log({ result }) done() } catch (error) { done(error.message || error) @@ -231,7 +273,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - const _appendItem = (item: any) => { let { _JOURNAL, _jobs, data } = state const self = props @@ -268,7 +309,20 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const handleKeyDown = (event) => { - if (event.which === 13) { + const suggestionCount = autoCompletState.activeSuggestion + if (autoCompletState.userInput !== '' && (event.which === 27 || event.which === 8 || event.which === 46)) { + console.log(' enter esc and delete') + // backspace or any key that should remove the autocompletion + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false })) + } + if (autoCompletState.showSuggestions && (event.which === 13 || event.which === 9)) { + if (autoCompletState.userInput.length === 1) { + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: Object.keys(autoCompletState.data._options[0]).toString() })) + } else { + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: autoCompletState.userInput })) + } + } + if (event.which === 13 && !autoCompletState.showSuggestions) { if (event.ctrlKey) { // // on enter, append the value in the cli input to the journal inputEl.current.focus() @@ -287,7 +341,50 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { inputEl.current.focus() setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false })) } - } else if (event.which === 38) { // + } else if (newstate._commandHistory.length && event.which === 38 && !autoCompletState.showSuggestions && (autoCompletState.userInput === '')) { + console.log('previous command up') + // if (autoCompletState.commandHistoryIndex < 1) { + event.preventDefault() + console.log(newstate._commandHistory[0], ' up value') + setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate._commandHistory[0] })) + + // } + // else if (newstate._commandHistory.length < autoCompletState.commandHistoryIndex) { + // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: --autoCompletState.commandHistoryIndex })) + // console.log(newstate._commandHistory[newstate._commandHistory.length > 1 ? autoCompletState.commandHistoryIndex-- : newstate._commandHistory.length + 1], ' up value') + // } else if (newstate._commandHistory.length === autoCompletState.commandHistoryIndex) { + // console.log(newstate._commandHistory.length === autoCompletState.commandHistoryIndex, ' up value middle') + // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: autoCompletState.commandHistoryIndex - 2, userInput: newstate._commandHistory[autoCompletState.commandHistoryIndex] })) + // } else { + // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: autoCompletState.commandHistoryIndex - 1, userInput: newstate._commandHistory[autoCompletState.commandHistoryIndex] })) + // console.log(newstate._commandHistory[newstate._commandHistory.length - 1], ' up value last') + // } + // if (newstate._commandHistory.length === 0) { + // setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate[0] })) + // } + // setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate[autoCompletState.commandHistoryIndex] })) + // TODO: giving error => need to work on the logic + // // } else if (newstate._commandHistory.length && event.which === 40 && !autoCompletState.showSuggestions && (autoCompletState.userInput !== '')) { + // // console.log('previous command down') + // // if (autoCompletState.commandHistoryIndex < newstate._commandHistory.length) { + // // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: autoCompletState.commandHistoryIndex + 1, userInput: newstate._commandHistory[autoCompletState.commandHistoryIndex + 1] })) + // // console.log(newstate._commandHistory[newstate._commandHistory.length > 1 ? autoCompletState.commandHistoryIndex++ : newstate._commandHistory.length - 1], ' down ++ value') + // // } else { + // // console.log(newstate._commandHistory[newstate._commandHistory.length - 1], ' down value last') + // // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: newstate._commandHistory.length - 1, userInput: newstate._commandHistory[newstate._commandHistory.length - 1] })) + // // } + // // // if (autoCompletState.commandHistoryIndex === newstate._commandHistory.length) { + // // // return + // // // } + // setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate[autoCompletState.commandHistoryIndex] + 1 })) + } else if (event.which === 38 && autoCompletState.showSuggestions) { + event.preventDefault() + if (autoCompletState.activeSuggestion === 0) { + return + } + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount - 1, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion - 1]).toString() })) + console.log('disable up an down key in input box') + } else if (event.which === 38 && !autoCompletState.showSuggestions) { // const len = _cmdHistory.length if (len === 0) event.preventDefault() if (_cmdHistory.length - 1 > _cmdIndex) { @@ -295,8 +392,14 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } inputEl.current.innerText = _cmdHistory[_cmdIndex] inputEl.current.focus() - } - else if (event.which === 40) { + } else if (event.which === 40 && autoCompletState.showSuggestions) { + event.preventDefault() + if ((autoCompletState.activeSuggestion + 1) === autoCompletState.data._options.length) { + return + } + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount + 1, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion + 1]).toString() })) + console.log('disable up an down key in input box') + } else if (event.which === 40 && !autoCompletState.showSuggestions) { if (_cmdIndex > -1) { setCmdIndex(prevState => prevState--) } @@ -305,6 +408,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } else { setCmdTemp(inputEl.current.innerText) } + console.log({ autoCompletState }) } const moveGhostbar = (event) => { @@ -326,14 +430,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const mousedown = (event: MouseEvent) => { setSeparatorYPosition(event.clientY) setDragging(true) - // console.log({ windowHeight }) - // console.log(event.which === 1, 'event.which === 1') - // event.preventDefault() - // moveGhostbar(event) - // if (event.which === 1) { - // console.log('event .which code 1') - // moveGhostbar(event) - // } } const onMouseMove: any = (e: MouseEvent) => { @@ -352,36 +448,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { setDragging(false) } - /* end of mouse event */ - const cancelGhostbar = (event) => { - if (event.keyCode === 27) { - console.log('event .key code 27') - } - } - useEffect(() => { - // document.addEventListener('mousemove', changeBg) - // function changeBg () { - // document.getElementById('dragId').style.backgroundColor = 'skyblue' - // } - // document.addEventListener('mouseup', changeBg2) - // function changeBg2 () { - // document.getElementById('dragId').style.backgroundColor = '' - // } document.addEventListener('mousemove', onMouseMove) document.addEventListener('mouseup', onMouseUp) return () => { - // document.addEventListener('mousemove', changeBg) - // function changeBg () { - // document.getElementById('dragId').style.backgroundColor = 'skyblue' - // } - // document.addEventListener('mouseup', changeBg2) - // function changeBg2 () { - // document.getElementById('dragId').style.backgroundColor = '' - // } document.removeEventListener('mousemove', onMouseMove) document.removeEventListener('mouseup', onMouseUp) } @@ -448,85 +521,378 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { /* end of block content that gets rendered from script Runner */ + const handleClearConsole = () => { + dispatch({ type: 'clearconsole', payload: [] }) + inputEl.current.focus() + } /* start of autoComplete */ - const handleSelect = (text) => { - props.thisState.event.trigger('handleSelect', [text]) + + const listenOnNetwork = (event: any) => { + const isListening = event.target.checked + setIsListeningOnNetwork(isListening) + listenOnNetworkAction(props, isListening) } const onChange = (event: any) => { event.preventDefault() const inputString = event.target.value - console.log(event) - console.log({ inputString }) - setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: true, userInput: inputString })) - const textList = inputString.split(' ') - const autoCompleteInput = textList.length > 1 ? textList[textList.length - 1] : textList[0] - allPrograms.forEach(item => { - const program = getKeyOf(item) - console.log({ program }) - if (program.substring(0, program.length - 1).includes(autoCompleteInput.trim())) { - setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [item] } })) - } else if (autoCompleteInput.trim().includes(program) || (program === autoCompleteInput.trim())) { - allCommands.forEach(item => { - console.log({ item }) - const command = getKeyOf(item) - if (command.includes(autoCompleteInput.trim())) { - setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [item] } })) - } - }) + if (matched(allPrograms, inputString) || inputString.includes('.')) { + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: true, userInput: inputString })) + const textList = inputString.split('.') + if (textList.length === 1) { + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [] } })) + const result = Objectfilter(allPrograms, autoCompletState.userInput) + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: result } })) + } else { + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [] } })) + const result = Objectfilter(allCommands, autoCompletState.userInput) + setAutoCompleteState(prevState => ({ ...prevState, data: { _options: result } })) } - }) - autoCompletState.extraCommands.forEach(item => { - const command = getKeyOf(item) - if (command.includes(autoCompleteInput.trim())) { - setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [item] } })) + } else { + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: inputString })) + } + } + + const handleSelect = (event) => { + const suggestionCount = autoCompletState.activeSuggestion + if (event.keyCode === 38) { + if (autoCompletState.activeSuggestion === 0) { + return + } + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount - 1 })) + } else if (event.keyCode === 40) { + if (autoCompletState.activeSuggestion - 1 === autoCompletState.data._options.length) { + return + } + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount + 1 })) + } + // props.thisState.event.trigger('handleSelect', [text]) + } + + const checkTxStatus = (tx, type) => { + if (tx.status === '0x1' || tx.status === true) { + return () + } + if (type === 'call' || type === 'unknownCall' || type === 'unknown') { + return (call) + } else if (tx.status === '0x0' || tx.status === false) { + return () + } else { + return () + } + } + + const context = (opts, blockchain) => { + const data = opts.tx || '' + const from = opts.from ? helper.shortenHexData(opts.from) : '' + let to = opts.to + if (data.to) to = to + ' ' + helper.shortenHexData(data.to) + const val = data.value + let hash = data.hash ? helper.shortenHexData(data.hash) : '' + const input = data.input ? helper.shortenHexData(data.input) : '' + const logs = data.logs && data.logs.decoded && data.logs.decoded.length ? data.logs.decoded.length : 0 + const block = data.receipt ? data.receipt.blockNumber : data.blockNumber || '' + const i = data ? data.transactionIndex : data.transactionIndex + const value = val ? typeConversion.toInt(val) : 0 + + if (blockchain.getProvider() === 'vm') { + return ( +
+ + [{vm}] +
from: {from}
+
to: {to}
+
value: {value} wei
+
data: {input}
+
logs: {logs}
+
hash: {hash}
+
+
) + } else if (blockchain.getProvider() !== 'vm' && data.resolvedData) { + return ( +
+ + [block:${block} txIndex:${i}] +
from: {from}
+
to: {to}
+
value: {value} wei
+
data: {input}
+
logs: {logs}
+
hash: {hash}
+
+
) + } else { + to = helper.shortenHexData(to) + hash = helper.shortenHexData(data.blockHash) + return ( +
+ + [block:${block} txIndex:${i}] +
from: {from}
+
to: {to}
+
value: {value} wei
+
+
) + } + } + + const txDetails = (event, tx, obj) => { + if (showTableDetails === null) { + setShowTableDetails(true) + } else { + setShowTableDetails(null) + } + // if (showTableDetails.length === 0) { + // setShowTableDetails([{ hash: tx.hash, show: true }]) + // } + // const id = showTableDetails.filter(x => x.hash !== tx.hash) + // if ((showTableDetails.length !== 0) && (id[0] === tx.hash)) { + // setShowTableDetails(currentState => ([...currentState, { hash: tx.hash, show: false }])) + // } + // console.log((showTableDetails.length !== 0) && (id[0] === tx.hash)) + // console.log({ showTableDetails }, ' clicked button') + } + + const showTable = (opts) => { + let msg = '' + let toHash + const data = opts.data // opts.data = data.tx + if (data.to) { + toHash = opts.to + ' ' + data.to + } else { + toHash = opts.to + } + let callWarning = '' + if (opts.isCall) { + callWarning = '(Cost only applies when called by a contract)' + } + if (!opts.isCall) { + if (opts.status !== undefined && opts.status !== null) { + if (opts.status === '0x0' || opts.status === false) { + msg = ' Transaction mined but execution failed' + } else if (opts.status === '0x1' || opts.status === true) { + msg = ' Transaction mined and execution succeed' + } + } else { + msg = ' Status not available at the moment' } - }) - if (autoCompletState.data._options.length === 1 && event.which === 9) { - // if only one option and tab is pressed, we resolve it - event.preventDefault() - textList.pop() - textList.push(getKeyOf(autoCompletState.data._options[0])) - handleSelect(`${textList}`.replace(/,/g, ' ')) + } + + let stringified = ' - ' + if (opts.logs && opts.logs.decoded) { + stringified = typeConversion.stringify(opts.logs.decoded) + } + const val = opts.val != null ? typeConversion.toInt(opts.val) : 0 + return ( + + + + + + + + + + { + opts.contractAddress && ( + + + + + ) + } + { + opts.from && ( + + + + + ) + } + { + opts.to && ( + + + + + ) + } + { + opts.gas && ( + + + + + ) + } + { + opts.transactionCost && ( + + + + + ) + } + { + opts.executionCost && ( + + + + + ) + } + {opts.hash && ( + + + + + )} + {opts.input && ( + + + + + )} + {opts['decoded input'] && ( + + + + + )} + {opts['decoded output'] && ( + + + + + )} + {opts.logs && ( + + + + + )} + {opts.val && ( + + + + + )} +
status {opts.status}{msg}
transaction hash {opts.hash} + +
contract address {opts.contractAddress} + +
from {opts.from} + +
to {toHash} + +
gas {opts.gas} gas + +
transaction cost {opts.transactionCost} gas {callWarning} + +
execution cost {opts.executionCost} gas {callWarning} + +
hash {opts.hash} + +
input {helper.shortenHexData(opts.input)} + +
decode input {opts['decoded input']} + +
decode output {opts['decoded output']} + +
logs + {JSON.stringify(stringified, null, '\t')} + + +
val {val} wei + +
+ ) + } + + const debug = (event, tx) => { + event.stopPropagation() + if (tx.isCall && tx.envMode !== 'vm') { + console.log('start debugging') + return ( {} } + message="Cannot debug this call. Debugging calls is only possible in JavaScript VM mode." + />) + } else { + props.event.trigger('debuggingRequested', [tx.hash]) + console.log('trigger ', { tx: props.event.trigger }) } } + const renderKnownTransactions = (tx, receipt, index) => { + const from = tx.from + const to = tx.to + const obj = { from, to } + const showDetails = showTableDetails === tx.from + const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx') + return ( + +
txDetails(event, tx, obj)}> + {/* onClick={e => txDetails(e, tx, data, obj)} */} + {checkTxStatus(receipt || tx, txType)} + {context({ from, to, tx }, props.blockchain)} +
+
debug(event, tx)}>Debug
+
+ +
+ {showTableDetails ? showTable({ + hash: tx.hash, + status: receipt !== null ? receipt.status : null, + isCall: tx.isCall, + contractAddress: tx.contractAddress, + data: tx, + from, + to, + gas: tx.gas, + input: tx.input, + 'decoded input': tx.resolvedData && tx.resolvedData.params ? JSON.stringify(typeConversion.stringify(tx.resoparams), null, '\t') : ' - ', + 'decoded output': tx.resolvedData && tx.resolvedData.decodedReturnValue ? JSON.stringify(typeConversion.stringify(tx.resolvedData.decodedReturnValue), null, '\t') : ' - ', + logs: tx.logs, + val: tx.value, + transactionCost: tx.transactionCost, + executionCost: tx.executionCost + }) : null} +
+ ) + } + const handleAutoComplete = () => ( -
+
- ${autoCompletState.data._options.map((item, index) => { + {autoCompletState.data._options.map((item, index) => { return ( -
auto complete here
- //
- //
{ handleSelect(event.srcElement.innerText) }}> - // {getKeyOf(item)} - //
- //
- // {getValueOf(item)} - //
- //
+
+
+ {getKeyOf(item)} +
+
+ {getValueOf(item)} +
+
) })}
- {/*
-
Page ${(self._startingElement / self._elementsToShow) + 1} of ${Math.ceil(data._options.length / self._elementsToShow)}
-
*/}
) /* end of autoComplete */ return ( -
+
{console.log({ newstate })} {console.log({ props })} - {console.log({ autoCompletState })}
{/* ${self._view.dragbar} */}
{/* ${self._view.icon} */} -
+
@@ -537,7 +903,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { @@ -554,6 +920,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { {/* ${self._view.inputSearch} */} setSearchInput(event.target.value) } type="text" className="border filter_2A0YE0 form-control" id="searchInput" @@ -565,7 +932,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{ - (autoCompletState.showSuggestions && autoCompletState.userInput) && handleAutoComplete() + handleAutoComplete() }
{ }}>
- {(newstate.journalBlocks).map((x, index) => ( -
- {x.message} -
- ))} + {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { + if (x.name === 'emptyBlock') { + return ( +
+ +
[block:{x.message} - 0 {'transactions'} ]
+
+ ) + } else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { + return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || x.tx.to.includes(searchInput)).map((trans) => { + return (
{renderKnownTransactions(trans.tx, trans.receipt, index)}
) + }) + } else { + return ( +
+ {x.message} +
+ ) + } + })}
{/* ${background} */}
diff --git a/libs/remix-ui/terminal/src/lib/utils/helper.ts b/libs/remix-ui/terminal/src/lib/utils/helper.ts new file mode 100644 index 0000000000..56b50a4377 --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/utils/helper.ts @@ -0,0 +1,176 @@ +// var async = require('async') +// const ethJSUtil = require('ethereumjs-util') + +// export const shortenAddress = (address, etherBalance) => { +// var len = address.length +// return address.slice(0, 5) + '...' + address.slice(len - 5, len) + (etherBalance ? ' (' + etherBalance.toString() + ' ether)' : '') +// } + +// export const addressToString = (address) => { +// if (!address) return null +// if (typeof address !== 'string') { +// address = address.toString('hex') +// } +// if (address.indexOf('0x') === -1) { +// address = '0x' + address +// } +// return ethJSUtil.toChecksumAddress(address) +// } + +// export const shortenHexData = (data) => { +// if (!data) return '' +// if (data.length < 5) return data +// var len = data.length +// return data.slice(0, 5) + '...' + data.slice(len - 5, len) +// } + +// export const createNonClashingNameWithPrefix = (name, fileProvider, prefix, cb) => { +// if (!name) name = 'Undefined' +// var counter = '' +// var ext = 'sol' +// var reg = /(.*)\.([^.]+)/g +// var split = reg.exec(name) +// if (split) { +// name = split[1] +// ext = split[2] +// } +// var exist = true +// async.whilst( +// () => { return exist }, +// (callback) => { +// fileProvider.exists(name + counter + prefix + '.' + ext).then(currentExist => { +// exist = currentExist +// if (exist) counter = (counter | 0) + 1 +// callback() +// }).catch(error => { +// if (error) console.log(error) +// }) +// }, +// (error) => { cb(error, name + counter + prefix + '.' + ext) } +// ) +// } + +// export const createNonClashingName = (name, fileProvider, cb) => { +// this.createNonClashingNameWithPrefix(name, fileProvider, '', cb) +// }, +// export const createNonClashingNameAsync = async (name, fileManager, prefix = '') => { +// if (!name) name = 'Undefined' +// let counter = '' +// let ext = 'sol' +// const reg = /(.*)\.([^.]+)/g +// const split = reg.exec(name) +// if (split) { +// name = split[1] +// ext = split[2] +// } +// let exist = true + +// do { +// const isDuplicate = await fileManager.exists(name + counter + prefix + '.' + ext) + +// if (isDuplicate) counter = (counter | 0) + 1 +// else exist = false +// } while (exist) + +// return name + counter + prefix + '.' + ext +// } + +// export const createNonClashingDirNameAsync = async (name, fileManager) => { +// if (!name) name = 'Undefined' +// let counter = '' +// let exist = true + +// do { +// const isDuplicate = await fileManager.exists(name + counter) + +// if (isDuplicate) counter = (counter | 0) + 1 +// else exist = false +// } while (exist) + +// return name + counter +// } + +// export const checkSpecialChars = (name) => { +// return name.match(/[:*?"<>\\'|]/) != null +// } + +// export const checkSlash = (name) => { +// return name.match(/\//) != null +// } + +// export const isHexadecimal = (value) => { +// return /^[0-9a-fA-F]+$/.test(value) && (value.length % 2 === 0) +// } + +// export const is0XPrefixed = (value) => { +// return value.substr(0, 2) === '0x' +// } + +// export const isNumeric = (value) => { +// return /^\+?(0|[1-9]\d*)$/.test(value) +// } + +// export const isValidHash = (hash) => { // 0x prefixed, hexadecimal, 64digit +// const hexValue = hash.slice(2, hash.length) +// return this.is0XPrefixed(hash) && /^[0-9a-fA-F]{64}$/.test(hexValue) +// } + +// export const removeTrailingSlashes = (text) { +// // Remove single or consecutive trailing slashes +// return text.replace(/\/+$/g, '') +// }, +// removeMultipleSlashes (text) { +// // Replace consecutive slashes with '/' +// return text.replace(/\/+/g, '/') +// }, +// find: find, +// getPathIcon (path) { +// return path.endsWith('.txt') +// ? 'far fa-file-alt' : path.endsWith('.md') +// ? 'far fa-file-alt' : path.endsWith('.sol') +// ? 'fak fa-solidity-mono' : path.endsWith('.js') +// ? 'fab fa-js' : path.endsWith('.json') +// ? 'fas fa-brackets-curly' : path.endsWith('.vy') +// ? 'fak fa-vyper-mono' : path.endsWith('.lex') +// ? 'fak fa-lexon' : path.endsWith('.contract') +// ? 'fab fa-ethereum' : 'far fa-file' +// }, +// joinPath (...paths) { +// paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) +// if (paths.length === 1) return paths[0] +// return paths.join('/') +// }, +// extractNameFromKey (key) { +// const keyPath = key.split('/') + +// return keyPath[keyPath.length - 1] +// } + +// const findDeep = (object, fn, found = { break: false, value: undefined }) => { +// if (typeof object !== 'object' || object === null) return +// for (var i in object) { +// if (found.break) break +// var el = object[i] +// if (el && el.innerText !== undefined && el.innerText !== null) el = el.innerText +// if (fn(el, i, object)) { +// found.value = el +// found.break = true +// break +// } else { +// findDeep(el, fn, found) +// } +// } +// return found.value +// } + +// const find = (args, query) => { +// query = query.trim() +// var isMatch = !!findDeep(args, function check (value, key) { +// if (value === undefined || value === null) return false +// if (typeof value === 'function') return false +// if (typeof value === 'object') return false +// var contains = String(value).indexOf(query.trim()) !== -1 +// return contains +// }) +// return isMatch +// } diff --git a/libs/remix-ui/terminal/src/lib/utils/utils.ts b/libs/remix-ui/terminal/src/lib/utils/utils.ts index 46ca37fa89..c5732f1b53 100644 --- a/libs/remix-ui/terminal/src/lib/utils/utils.ts +++ b/libs/remix-ui/terminal/src/lib/utils/utils.ts @@ -6,3 +6,37 @@ export const getKeyOf = (item) => { export const getValueOf = (item) => { return Object.values(item)[0] } + +export const Objectfilter = (obj: any, filterValue: any) => + obj.filter((item: any) => Object.keys(item)[0].indexOf(filterValue) > -1) + +export const matched = (arr, value) => arr.map(x => Object.keys(x).some(x => x.startsWith(value))).some(x => x === true) + +const findDeep = (object, fn, found = { break: false, value: undefined }) => { + if (typeof object !== 'object' || object === null) return + for (var i in object) { + if (found.break) break + var el = object[i] + if (el && el.innerText !== undefined && el.innerText !== null) el = el.innerText + if (fn(el, i, object)) { + found.value = el + found.break = true + break + } else { + findDeep(el, fn, found) + } + } + return found.value +} + +export const find = (args, query) => { + query = query.trim() + var isMatch = !!findDeep(args, function check (value) { + if (value === undefined || value === null) return false + if (typeof value === 'function') return false + if (typeof value === 'object') return false + var contains = String(value).indexOf(query.trim()) !== -1 + return contains + }) + return isMatch +} From 3998fb267e369b27d9196eedb2cd4255e11a543e Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 11 Aug 2021 06:53:38 +0100 Subject: [PATCH 14/48] fix linting issues --- apps/remix-ide/src/app/panels/terminal.js | 280 ------------------ .../terminal/src/lib/remix-ui-terminal.css | 60 ++++ 2 files changed, 60 insertions(+), 280 deletions(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index fb3bc4a130..76b632a649 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -4,20 +4,12 @@ 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 * as remixBleach from '../../lib/remixBleach' - -var yo = require('yo-yo') -var javascriptserialize = require('javascript-serialize') -var jsbeautify = require('js-beautify') -var type = require('component-type') var vm = require('vm') var EventManager = require('../../lib/events') var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI') var AutoCompletePopup = require('../ui/auto-complete-popup') -var css = require('./styles/terminal-styles') - import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line var globalRegistry = require('../../global/registry') var SourceHighlighter = require('../../app/editor/sourceHighlighter') @@ -79,14 +71,6 @@ class Terminal extends Plugin { this._components = {} this._components.cmdInterpreter = new CommandInterpreterAPI(this, null, this.blockchain) this._components.autoCompletePopup = new AutoCompletePopup(this._opts) - // this._components.autoCompletePopup.event.register('handleSelect', function (input) { - // const textList = this._view.input.innerText.split(' ') - // textList.pop() - // textList.push(input) - // this._view.input.innerText = textList - // this._view.input.focus() - // this.putCursor2End(this._view.input) - // }) this._commands = {} this.commands = {} this._JOURNAL = [] @@ -111,11 +95,6 @@ class Terminal extends Plugin { this.off('scriptRunner', 'error') } - // logHtml (html) { - // var command = this.commands.html - // if (typeof command === 'function') command(html) - // } - logHtml (html) { var command = this.commands.html if (typeof command === 'function') command(html) @@ -158,269 +137,10 @@ class Terminal extends Plugin { ) } - // _appendItem (item) { - // var self = this - // var { el, gidx } = item - // self._JOURNAL[gidx] = item - // if (!self._jobs.length) { - // requestAnimationFrame(function updateTerminal () { - // self._jobs.forEach(el => self._view.journal.appendChild(el)) - // self.scroll2bottom() - // self._jobs = [] - // }) - // } - // if (self.data.activeFilters.commands[item.cmd]) self._jobs.push(el) - // } - scroll2bottom () { - var self = this setTimeout(function () { - // self._view.term.scrollTop = self._view.term.scrollHeight }, 0) } - - // _blocksRenderer (mode) { - // if (mode === 'html') { - // return function logger (args, scopedCommands, append) { - // if (args.length) append(args[0]) - // } - // } - // mode = { - // log: 'text-info', - // info: 'text-info', - // warn: 'text-warning', - // error: 'text-danger' - // }[mode] // defaults - - // if (mode) { - // const filterUndefined = (el) => el !== undefined && el !== null - // return function logger (args, scopedCommands, append) { - // var types = args.filter(filterUndefined).map(type) - // var values = javascriptserialize.apply(null, args.filter(filterUndefined)).map(function (val, idx) { - // if (typeof args[idx] === 'string') { - // const el = document.createElement('div') - // el.innerHTML = args[idx].replace(/(\r\n|\n|\r)/gm, '
') - // val = el.children.length === 0 ? el.firstChild : el - // } - // if (types[idx] === 'element') val = jsbeautify.html(val) - // return val - // }) - // if (values.length) { - // append(yo`${values}`) - // } - // } - // } else { - // throw new Error('mode is not supported') - // } - // } - - // _scopeCommands (append) { - // var self = this - // var scopedCommands = {} - // Object.keys(self.commands).forEach(function makeScopedCommand (cmd) { - // var command = self._commands[cmd] - // scopedCommands[cmd] = function _command () { - // var args = [...arguments] - // command(args, scopedCommands, el => append(cmd, args, blockify(el))) - // } - // }) - // return scopedCommands - // } - - // registerFilter (commandName, filterFn) { - // this.data.filterFns[commandName] = filterFn - // } - - // registerCommand (name, command, opts) { - // var self = this - // name = String(name) - // if (this._commands[name]) throw new Error(`command "${name}" exists already`) - // if (typeof command !== 'function') throw new Error(`invalid command: ${command}`) - // this._commands[name] = command - // console.log({ command }) - // console.log(self._commands) - // this._INDEX.commands[name] = [] - // this._INDEX.commandsMain[name] = [] - // this.commands[name] = function _command () { - // var args = [...arguments] - // var steps = [] - // var root = { steps, cmd: name } - // var ITEM = { root, cmd: name } - // root.gidx = self._INDEX.allMain.push(ITEM) - 1 - // root.idx = self._INDEX.commandsMain[name].push(ITEM) - 1 - // function append (cmd, params, el) { - // var item - // if (cmd) { // subcommand - // item = { el, cmd, root } - // } else { // command - // item = ITEM - // item.el = el - // cmd = name - // } - // item.gidx = self._INDEX.all.push(item) - 1 - // item.idx = self._INDEX.commands[cmd].push(item) - 1 - // item.step = steps.push(item) - 1 - // item.args = params - // // self._appendItem(item) - // } - // var scopedCommands = self._scopeCommands(append) - // command(args, scopedCommands, el => append(null, args, blockify(el))) - // } - // var help = typeof command.help === 'string' ? command.help : [ - // '// no help available for:', - // `terminal.commands.${name}(...)` - // ].join('\n') - // this.commands[name].toString = _ => { return help } - // this.commands[name].help = help - // this.data.activeFilters.commands[name] = opts && opts.activate - // if (opts.filterFn) { - // this.registerFilter(name, opts.filterFn) - // } - // return this.commands[name] - // } - - // async _shell (script, scopedCommands, done) { // default shell - // if (script.indexOf('remix:') === 0) { - // return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') - // } - // var self = this - // if (script.indexOf('remix.') === 0) { - // // we keep the old feature. This will basically only be called when the command is querying the "remix" object. - // // for all the other case, we use the Code Executor plugin - // var context = domTerminalFeatures(scopedCommands, self.blockchain) - // try { - // var cmds = vm.createContext(context) - // var result = vm.runInContext(script, cmds) - // return done(null, result) - // } catch (error) { - // return done(error.message) - // } - // } - // try { - // let result - // if (script.trim().startsWith('git')) { - // // result = await this.call('git', 'execute', script) - // } else { - // result = await this.call('scriptRunner', 'execute', script) - // } - // if (result) self.commands.html(yo`
${result}
`) - // done() - // } catch (error) { - // done(error.message || error) - // } - // } - // } - - // function domTerminalFeatures (scopedCommands, blockchain) { - // return { - // remix: { - // blockchain: this.blockchain, - // commandHelp: this.commandHelp, - // event: this.event, - // _deps: this._deps - // } - // } - // } - - // function loadgist (id, cb) { - // const self = this - // self._components.gistHandler.loadFromGist({ gist: id }, this._deps.fileManager) - // if (cb) cb() - // } - - // function loadurl (url, cb) { - // const self = this - // self._components.fileImport.import(url, - // (loadingMsg) => { toolTip(loadingMsg) }, - // (err, content, cleanUrl, type, url) => { - // if (err) { - // toolTip(`Unable to load ${url}: ${err}`) - // if (cb) cb(err) - // } else { - // self._deps.fileManager.writeFile(type + '/' + cleanUrl, content) - // try { - // content = JSON.parse(content) - // async.eachOfSeries(content.sources, (value, file, callbackSource) => { - // var url = value.urls[0] // @TODO retrieve all other contents ? - // self._components.fileImport.import(url, - // (loadingMsg) => { toolTip(loadingMsg) }, - // async (error, content, cleanUrl, type, url) => { - // if (error) { - // toolTip(`Cannot retrieve the content of ${url}: ${error}`) - // return callbackSource(`Cannot retrieve the content of ${url}: ${error}`) - // } else { - // try { - // await self._deps.fileManager.writeFile(type + '/' + cleanUrl, content) - // callbackSource() - // } catch (e) { - // callbackSource(e.message) - // } - // } - // }) - // }, (error) => { - // if (cb) cb(error) - // }) - // } catch (e) {} - // if (cb) cb() - // } - // }) - // } - - // function exeCurrent (cb) { - // return this.execute(undefined, cb) - // } - - // function execute (file, cb) { - // const self = this - - // function _execute (content, cb) { - // if (!content) { - // toolTip('no content to execute') - // if (cb) cb() - // return - // } - - // self._components.terminal.commands.script(content) - // } - - // if (typeof file === 'undefined') { - // var content = self._deps.editor.currentContent() - // _execute(content, cb) - // return - // } - - // var provider = self._deps.fileManager.fileProviderOf(file) - - // if (!provider) { - // toolTip(`provider for path ${file} not found`) - // if (cb) cb() - // return - // } - - // provider.get(file, (error, content) => { - // if (error) { - // // toolTip(error) - // // TODO: pop up - // if (cb) cb() - // return - // } - - // _execute(content, cb) - // }) - // } - -// function help (cb) { -// const self = this -// var help = yo`
` -// for (var k in self.commandHelp) { -// help.appendChild(yo`
${k}: ${self.commandHelp[k]}
`) -// help.appendChild(yo`
`) -// } -// self._components.terminal.commands.html(help) -// if (cb) cb() -// return '' -// } } -function blockify (el) { return yo`
${el}
` } module.exports = Terminal 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 890460b43c..abd5c36476 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -354,3 +354,63 @@ input #terminalCliInput { .debug:hover { opacity: 0.8; } + + + /* Style the accordion section */ +.accordion__section { + display: flex; + flex-direction: column; +} + +/* Style the buttons that are used to open and close the accordion panel */ +.accordion { + background-color: #eee; + color: #444; + cursor: pointer; + padding: 18px; + display: flex; + align-items: center; + border: none; + outline: none; + transition: background-color 0.6s ease; +} + +/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */ +.accordion:hover, +.active { + background-color: #ccc; +} + +/* Style the accordion content title */ +.accordion__title { + font-family: "Open Sans", sans-serif; + font-weight: 600; + font-size: 14px; +} + +/* Style the accordion chevron icon */ +.accordion__icon { + margin-left: auto; + transition: transform 0.6s ease; +} + +/* Style to rotate icon when state is active */ +.rotate { + transform: rotate(90deg); +} + +/* Style the accordion content panel. Note: hidden by default */ +.accordion__content { + background-color: white; + overflow: hidden; + transition: max-height 0.6s ease; +} + +/* Style the accordion content text */ +.accordion__text { + font-family: "Open Sans", sans-serif; + font-weight: 400; + font-size: 14px; + padding: 18px; +} + From 19163c72f1bac975c4fdf57a669f8ce2c99454e3 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 11 Aug 2021 07:20:09 +0100 Subject: [PATCH 15/48] fixing conflicts --- .../src/commands/verifyContracts.ts | 3 + apps/remix-ide-e2e/src/tests/ballot.test.ts | 2 +- .../src/tests/ballot_0_4_11.spec.ts | 2 +- apps/remix-ide-e2e/src/tests/debugger.spec.ts | 4 +- apps/remix-ide/src/app.js | 6 +- apps/remix-ide/src/app/files/file-explorer.js | 702 --------------- apps/remix-ide/src/app/files/remixd-handle.js | 16 +- apps/remix-ide/src/app/panels/terminal.js | 280 ------ apps/remix-ide/src/app/tabs/compile-tab.js | 1 - .../src/app/tabs/compileTab/compileTab.js | 135 --- .../app/tabs/compileTab/compilerContainer.js | 580 ------------- .../src/app/tabs/compileTab/contractParser.js | 122 --- .../src/app/tabs/hardhat-provider.js | 2 +- .../src/app/tabs/runTab/contractDropdown.js | 7 +- .../remix-ide/src/app/tabs/runTab/recorder.js | 7 +- .../remix-ide/src/app/tabs/runTab/settings.js | 8 +- apps/remix-ide/src/app/ui/confirmDialog.js | 88 +- .../src/app/ui/landing-page/landing-page.js | 28 +- apps/remix-ide/src/app/ui/sendTxCallbacks.js | 7 +- .../src/assets/img/optimismLogo.webp | Bin 0 -> 15868 bytes .../src/assets/js/editor/darkTheme.js | 8 +- .../src/blockchain/execution-context.js | 10 +- libs/remix-analyzer/package.json | 14 +- libs/remix-astwalker/package.json | 14 +- .../src/lib/compiler-content-imports.ts | 11 +- libs/remix-debug/package.json | 14 +- libs/remix-debug/src/code/codeUtils.ts | 2 +- libs/remix-debug/src/trace/traceManager.ts | 2 +- libs/remix-debug/test/decoder/vmCall.ts | 2 +- libs/remix-debug/test/vmCall.ts | 2 +- libs/remix-lib/package.json | 10 +- libs/remix-lib/src/execution/forkAt.ts | 6 +- libs/remix-lib/src/execution/txRunnerVM.ts | 2 +- libs/remix-lib/src/execution/txRunnerWeb3.ts | 18 +- libs/remix-simulator/package.json | 14 +- libs/remix-simulator/src/vm-context.ts | 2 +- libs/remix-solidity/package.json | 14 +- libs/remix-tests/package.json | 18 +- .../copy-to-clipboard/copy-to-clipboard.tsx | 1 + .../src/lib/file-explorer-context-menu.tsx | 12 + .../src/lib/remix-ui-modal-dialog.tsx | 26 +- .../src/lib/actions/compiler.ts | 2 +- .../src/lib/compiler-container.tsx | 51 +- .../src/lib/contract-selection.tsx | 30 +- .../src/lib/logic/compiler-abstract.ts | 51 -- .../src/lib/logic/compiler-helpers.ts | 19 - .../src/lib/logic/compiler-utils.ts | 46 - .../solidity-compiler/src/lib/logic/index.ts | 3 - .../src/lib/remix-ui-static-analyser.tsx | 58 +- .../terminal/src/lib/remix-ui-terminal.css | 1 + .../terminal/src/lib/remix-ui-terminal.tsx | 1 + libs/remix-url-resolver/package.json | 4 +- libs/remixd/package.json | 2 +- libs/remixd/src/services/slitherClient.ts | 6 +- package-lock.json | 816 ++++++++++-------- package.json | 12 +- release-process.md | 11 +- 57 files changed, 841 insertions(+), 2474 deletions(-) delete mode 100644 apps/remix-ide/src/app/files/file-explorer.js delete mode 100644 apps/remix-ide/src/app/tabs/compileTab/compileTab.js delete mode 100644 apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js delete mode 100644 apps/remix-ide/src/app/tabs/compileTab/contractParser.js create mode 100644 apps/remix-ide/src/assets/img/optimismLogo.webp delete mode 100644 libs/remix-ui/solidity-compiler/src/lib/logic/compiler-abstract.ts delete mode 100644 libs/remix-ui/solidity-compiler/src/lib/logic/compiler-helpers.ts delete mode 100644 libs/remix-ui/solidity-compiler/src/lib/logic/compiler-utils.ts diff --git a/apps/remix-ide-e2e/src/commands/verifyContracts.ts b/apps/remix-ide-e2e/src/commands/verifyContracts.ts index 027f71dd05..e7dbf4a591 100644 --- a/apps/remix-ide-e2e/src/commands/verifyContracts.ts +++ b/apps/remix-ide-e2e/src/commands/verifyContracts.ts @@ -22,6 +22,9 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str if (opts.version) { browser .click('*[data-id="compilation-details"]') + .waitForElementVisible('*[data-id="remixui_treeviewitem_metadata"]') + .pause(2000) + .click('*[data-id="remixui_treeviewitem_metadata"]') .waitForElementVisible('*[data-id="treeViewDivtreeViewItemcompiler"]') .pause(2000) .click('*[data-id="treeViewDivtreeViewItemcompiler"]') diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index aa6d507120..866ce3149b 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -49,7 +49,7 @@ module.exports = { 'Debug Ballot / delegate': function (browser: NightwatchBrowser) { browser.pause(500) - .click('*[data-id="txLoggerDebugButton0xf88bc0ac0761f78d8c883b32550c68dadcdb095595c30e1a1b7c583e5e958dcb"]') + .debugTransaction(1) .waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') .click('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') .pause(2000) diff --git a/apps/remix-ide-e2e/src/tests/ballot_0_4_11.spec.ts b/apps/remix-ide-e2e/src/tests/ballot_0_4_11.spec.ts index a3bf500ec0..5c768859f8 100644 --- a/apps/remix-ide-e2e/src/tests/ballot_0_4_11.spec.ts +++ b/apps/remix-ide-e2e/src/tests/ballot_0_4_11.spec.ts @@ -45,7 +45,7 @@ module.exports = { 'Debug Ballot / delegate': function (browser: NightwatchBrowser) { browser.pause(500) - .click('*[data-id="txLoggerDebugButton0xf88bc0ac0761f78d8c883b32550c68dadcdb095595c30e1a1b7c583e5e958dcb"]') + .debugTransaction(1) .pause(2000) .waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') .click('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') diff --git a/apps/remix-ide-e2e/src/tests/debugger.spec.ts b/apps/remix-ide-e2e/src/tests/debugger.spec.ts index 0baeee65b3..63bda87e9c 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.spec.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.spec.ts @@ -423,7 +423,7 @@ const localVariable_step717_ABIEncoder = { // eslint-disable-line const jsGetTrace = `(async () => { try { - const result = await remix.call('debugger', 'getTrace', '0xa38bff6f06e7c4fc91df1db6aa31a69ab5d5882faa953b1e7a88bfa523268ed7') + const result = await remix.call('debugger', 'getTrace', '0x9341be49e911afe99bf1abc67cbcf36739d2e6470a08a69511c205a0737d7332') console.log('result ', result) } catch (e) { console.log(e.message) @@ -432,7 +432,7 @@ const jsGetTrace = `(async () => { const jsDebug = `(async () => { try { - const result = await remix.call('debugger', 'debug', '0xa38bff6f06e7c4fc91df1db6aa31a69ab5d5882faa953b1e7a88bfa523268ed7') + const result = await remix.call('debugger', 'debug', '0x9341be49e911afe99bf1abc67cbcf36739d2e6470a08a69511c205a0737d7332') console.log('result ', result) } catch (e) { console.log(e.message) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 518d93c64c..fca8897ec8 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -342,7 +342,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org const hiddenPanel = new HiddenPanel() const pluginManagerComponent = new PluginManagerComponent(appManager, engine) const filePanel = new FilePanel(appManager) - const landingPage = new LandingPage(appManager, menuicons, fileManager, filePanel) + const landingPage = new LandingPage(appManager, menuicons, fileManager, filePanel, contentImport) const settings = new SettingsTab( registry.get('config').api, editor, @@ -423,6 +423,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org fn: null } ) + } else { + startWalkthroughService() } // CONTENT VIEWS & DEFAULT PLUGINS @@ -518,6 +520,4 @@ Please make a backup of your contracts and start using http://remix.ethereum.org if (params.embed) framingService.embed() framingService.start(params) - - startWalkthroughService() } diff --git a/apps/remix-ide/src/app/files/file-explorer.js b/apps/remix-ide/src/app/files/file-explorer.js deleted file mode 100644 index cef877b68b..0000000000 --- a/apps/remix-ide/src/app/files/file-explorer.js +++ /dev/null @@ -1,702 +0,0 @@ -/* global FileReader */ -/* global fetch */ -const async = require('async') -const Gists = require('gists') -const modalDialogCustom = require('../ui/modal-dialog-custom') -const tooltip = require('../ui/tooltip') -const QueryParams = require('../../lib/query-params') -const helper = require('../../lib/helper') -const yo = require('yo-yo') -const Treeview = require('../ui/TreeView') -const modalDialog = require('../ui/modaldialog') -const EventManager = require('events') -const contextMenu = require('../ui/contextMenu') -const css = require('./styles/file-explorer-styles') -const globalRegistry = require('../../global/registry') -const queryParams = new QueryParams() -let MENU_HANDLE - -function fileExplorer (localRegistry, files, menuItems, plugin) { - var self = this - this.events = new EventManager() - // file provider backend - this.files = files - // element currently focused on - this.focusElement = null - // path currently focused on - this.focusPath = null - const allItems = - [ - { - action: 'createNewFile', - title: 'Create New File', - icon: 'fas fa-plus-circle' - }, - { - action: 'publishToGist', - title: 'Publish all [browser] explorer files to a github gist', - icon: 'fab fa-github' - }, - { - action: 'uploadFile', - title: 'Add Local file to the Browser Storage Explorer', - icon: 'far fa-folder-open' - }, - { - action: 'updateGist', - title: 'Update the current [gist] explorer', - icon: 'fab fa-github' - } - ] - // menu items - this.menuItems = allItems.filter( - (item) => { - if (menuItems) return menuItems.find((name) => { return name === item.action }) - } - ) - - self._components = {} - self._components.registry = localRegistry || globalRegistry - self._deps = { - config: self._components.registry.get('config').api, - editor: self._components.registry.get('editor').api, - fileManager: self._components.registry.get('filemanager').api - } - - self.events.register('focus', function (path) { - self._deps.fileManager.open(path) - }) - - self._components.registry.put({ api: self, name: `fileexplorer/${self.files.type}` }) - - // warn if file changed outside of Remix - function remixdDialog () { - return yo`
This file has been changed outside of Remix IDE.
` - } - - this.files.event.register('fileExternallyChanged', (path, file) => { - if (self._deps.config.get('currentFile') === path && self._deps.editor.currentContent() && self._deps.editor.currentContent() !== file.content) { - if (this.files.isReadOnly(path)) return self._deps.editor.setText(file.content) - - modalDialog(path + ' changed', remixdDialog(), - { - label: 'Replace by the new content', - fn: () => { - self._deps.editor.setText(file.content) - } - }, - { - label: 'Keep the content displayed in Remix', - fn: () => {} - } - ) - } - }) - - // register to event of the file provider - files.event.on('fileRemoved', fileRemoved) - files.event.on('fileRenamed', fileRenamed) - files.event.on('fileRenamedError', fileRenamedError) - files.event.on('fileAdded', fileAdded) - files.event.on('folderAdded', folderAdded) - - function fileRenamedError (error) { - modalDialogCustom.alert(error) - } - - function fileAdded (filepath) { - self.ensureRoot(() => { - const folderpath = filepath.split('/').slice(0, -1).join('/') - const currentTree = self.treeView.nodeAt(folderpath) - if (!self.treeView.isExpanded(folderpath)) self.treeView.expand(folderpath) - if (currentTree) { - self.files.resolveDirectory(folderpath, (error, fileTree) => { - if (error) console.error(error) - if (!fileTree) return - fileTree = normalize(folderpath, fileTree) - self.treeView.updateNodeFromJSON(folderpath, fileTree, true) - self.focusElement = self.treeView.labelAt(self.focusPath) - // TODO: here we update the selected file (it applicable) - // cause we are refreshing the interface of the whole directory when there's a new file. - if (self.focusElement && !self.focusElement.classList.contains('bg-secondary')) { - self.focusElement.classList.add('bg-secondary') - } - }) - } - }) - } - - function extractNameFromKey (key) { - const keyPath = key.split('/') - - return keyPath[keyPath.length - 1] - } - - function folderAdded (folderpath) { - self.ensureRoot(() => { - folderpath = folderpath.split('/').slice(0, -1).join('/') - self.files.resolveDirectory(folderpath, (error, fileTree) => { - if (error) console.error(error) - if (!fileTree) return - fileTree = normalize(folderpath, fileTree) - self.treeView.updateNodeFromJSON(folderpath, fileTree, true) - if (!self.treeView.isExpanded(folderpath)) self.treeView.expand(folderpath) - }) - }) - } - - function fileRemoved (filepath) { - const label = self.treeView.labelAt(filepath) - filepath = filepath.split('/').slice(0, -1).join('/') - - if (label && label.parentElement) { - label.parentElement.removeChild(label) - } - - self.updatePath(filepath) - } - - function fileRenamed (oldName, newName, isFolder) { - fileRemoved(oldName) - fileAdded(newName) - } - - // make interface and register to nodeClick, leafClick - self.treeView = new Treeview({ - extractData: function extractData (value, tree, key) { - var newValue = {} - // var isReadOnly = false - var isFile = false - Object.keys(value).filter(function keep (x) { - if (x === '/content') isFile = true - if (x[0] !== '/') return true - }).forEach(function (x) { newValue[x] = value[x] }) - return { - path: (tree || {}).path ? tree.path + '/' + key : key, - children: isFile ? undefined - : value instanceof Array ? value.map((item, index) => ({ - key: index, value: item - })) : value instanceof Object ? Object.keys(value).map(subkey => ({ - key: subkey, value: value[subkey] - })) : undefined - } - }, - formatSelf: function formatSelf (key, data, li) { - const isRoot = data.path === self.files.type - const isFolder = !!data.children - return yo` -
- - ${key.split('/').pop()} - - ${isRoot ? self.renderMenuItems() : ''} -
- ` - } - }) - - /** - * Extracts first two folders as a subpath from the path. - **/ - function extractExternalFolder (path) { - const firstSlIndex = path.indexOf('/', 1) - if (firstSlIndex === -1) return '' - const secondSlIndex = path.indexOf('/', firstSlIndex + 1) - if (secondSlIndex === -1) return '' - return path.substring(0, secondSlIndex) - } - - self.treeView.event.register('nodeRightClick', function (key, data, label, event) { - if (self.files.readonly) return - if (key === self.files.type) return - MENU_HANDLE && MENU_HANDLE.hide(null, true) - const actions = {} - const provider = self._deps.fileManager.fileProviderOf(key) - actions['Create File'] = () => self.createNewFile(key) - actions['Create Folder'] = () => self.createNewFolder(key) - // @todo(#2386) not fully implemented. Readd later when fixed - if (provider.isExternalFolder(key)) { - /* actions['Discard changes'] = () => { - modalDialogCustom.confirm( - 'Discard changes', - 'Are you sure you want to discard all your changes?', - () => { self.files.discardChanges(key) }, - () => {} - ) - } */ - } else { - const folderPath = extractExternalFolder(key) - actions.Rename = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot rename folder. ' + self.files.type + ' is a read only explorer') } - var name = label.querySelector('span[data-path="' + key + '"]') - if (name) editModeOn(name) - } - actions.Delete = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') } - const currentFoldername = extractNameFromKey(key) - - modalDialogCustom.confirm('Confirm to delete folder', `Are you sure you want to delete ${currentFoldername} folder?`, - async () => { - const fileManager = self._deps.fileManager - const removeFolder = await fileManager.remove(key) - - if (!removeFolder) { - tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) - } - }, () => {}) - } - if (folderPath === 'browser/gists') { - actions['Push changes to gist'] = () => { - const id = key.substr(key.lastIndexOf('/') + 1, key.length - 1) - modalDialogCustom.confirm( - 'Push back to Gist', - 'Are you sure you want to push all your changes back to Gist?', - () => { self.toGist(id) }, - () => {} - ) - } - } - } - MENU_HANDLE = contextMenu(event, actions) - }) - - self.treeView.event.register('leafRightClick', function (key, data, label, event) { - if (key === self.files.type) return - MENU_HANDLE && MENU_HANDLE.hide(null, true) - const actions = {} - const provider = self._deps.fileManager.fileProviderOf(key) - if (!provider.isExternalFolder(key)) { - actions['Create Folder'] = () => self.createNewFolder(self._deps.fileManager.extractPathOf(key)) - actions.Rename = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot rename file. ' + self.files.type + ' is a read only explorer') } - var name = label.querySelector('span[data-path="' + key + '"]') - if (name) editModeOn(name) - } - actions.Delete = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot delete file. ' + self.files.type + ' is a read only explorer') } - const currentFilename = extractNameFromKey(key) - - modalDialogCustom.confirm( - 'Delete file', `Are you sure you want to delete ${currentFilename} file?`, - async () => { - const fileManager = self._deps.fileManager - const removeFile = await fileManager.remove(key) - - if (!removeFile) { - tooltip(`Failed to remove file ${key}.`) - } - }, - () => {} - ) - } - if (key.endsWith('.js')) { - actions.Run = async () => { - provider.get(key, (error, content) => { - if (error) return console.log(error) - plugin.call('scriptRunner', 'execute', content) - }) - } - } - } - MENU_HANDLE = contextMenu(event, actions) - }) - - self.treeView.event.register('leafClick', function (key, data, label) { - self.events.trigger('focus', [key]) - }) - - self.treeView.event.register('nodeClick', function (path, childrenContainer) { - if (!childrenContainer) return - if (childrenContainer.style.display === 'none') return - self.updatePath(path) - }) - - // register to main app, trigger when the current file in the editor changed - self._deps.fileManager.events.on('currentFileChanged', (newFile) => { - const provider = self._deps.fileManager.fileProviderOf(newFile) - if (self.focusElement && self.focusPath !== newFile) { - self.focusElement.classList.remove('bg-secondary') - self.focusElement = null - self.focusPath = null - } - if (provider && (provider.type === files.type)) { - self.focusElement = self.treeView.labelAt(newFile) - if (self.focusElement) { - self.focusElement.classList.add('bg-secondary') - self.focusPath = newFile - } - } - }) - - self._deps.fileManager.events.on('noFileSelected', () => { - if (self.focusElement) { - self.focusElement.classList.remove('bg-secondary') - self.focusElement = null - self.focusPath = null - } - }) - - var textUnderEdit = null - - function selectElementContents (el) { - var range = document.createRange() - range.selectNodeContents(el) - var sel = window.getSelection() - sel.removeAllRanges() - sel.addRange(range) - } - - function editModeOn (label) { - textUnderEdit = label.innerText - label.setAttribute('contenteditable', true) - label.classList.add('bg-light') - label.focus() - selectElementContents(label) - } - - function editModeOff (event) { - const label = this - - const isFolder = label.className.indexOf('folder') !== -1 - function rename () { - var newPath = label.dataset.path - newPath = newPath.split('/') - newPath[newPath.length - 1] = label.innerText - newPath = newPath.join('/') - if (label.innerText === '') { - modalDialogCustom.alert('File name cannot be empty') - label.innerText = textUnderEdit - } else if (helper.checkSpecialChars(label.innerText)) { - modalDialogCustom.alert('Special characters are not allowed') - label.innerText = textUnderEdit - } else { - files.exists(newPath, (error, exist) => { - if (error) return modalDialogCustom.alert('Unexpected error while renaming: ' + error) - if (!exist) { - files.rename(label.dataset.path, newPath, isFolder) - } else { - modalDialogCustom.alert('File already exists.') - label.innerText = textUnderEdit - } - }) - } - } - - if (event.which === 13) event.preventDefault() - if ((event.type === 'blur' || event.which === 13) && label.getAttribute('contenteditable')) { - var save = textUnderEdit !== label.innerText - if (save) { - modalDialogCustom.confirm( - 'Confirm to rename a ' + (isFolder ? 'folder' : 'file'), - 'Are you sure you want to rename ' + textUnderEdit + '?', - () => { rename() }, - () => { label.innerText = textUnderEdit } - ) - } - label.removeAttribute('contenteditable') - label.classList.remove('bg-light') - } - } -} - -fileExplorer.prototype.updatePath = function (path) { - this.files.resolveDirectory(path, (error, fileTree) => { - if (error) console.error(error) - if (!fileTree) return - var newTree = normalize(path, fileTree) - this.treeView.updateNodeFromJSON(path, newTree, true) - }) -} - -fileExplorer.prototype.hide = function () { - if (this.container) this.container.style.display = 'none' -} - -fileExplorer.prototype.show = function () { - if (this.container) this.container.style.display = 'block' -} - -fileExplorer.prototype.init = function () { - this.container = yo`
` - return this.container -} - -fileExplorer.prototype.publishToGist = function () { - modalDialogCustom.confirm( - 'Create a public gist', - 'Are you sure you want to publish all your files in browser directory anonymously as a public gist on github.com? Note: this will not include directories.', - () => { this.toGist() } - ) -} - -fileExplorer.prototype.uploadFile = function (event) { - // TODO The file explorer is merely a view on the current state of - // the files module. Please ask the user here if they want to overwrite - // a file and then just use `files.add`. The file explorer will - // pick that up via the 'fileAdded' event from the files module. - - const self = this - - ;[...event.target.files].forEach((file) => { - const files = this.files - function loadFile () { - var fileReader = new FileReader() - fileReader.onload = async function (event) { - if (helper.checkSpecialChars(file.name)) { - modalDialogCustom.alert('Special characters are not allowed') - return - } - var success = await files.set(name, event.target.result) - if (!success) { - modalDialogCustom.alert('Failed to create file ' + name) - } else { - self.events.trigger('focus', [name]) - } - } - fileReader.readAsText(file) - } - var name = files.type + '/' + file.name - files.exists(name, (error, exist) => { - if (error) console.log(error) - if (!exist) { - loadFile() - } else { - modalDialogCustom.confirm('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() }) - } - }) - }) -} - -fileExplorer.prototype.toGist = function (id) { - const proccedResult = function (error, data) { - if (error) { - modalDialogCustom.alert('Failed to manage gist: ' + error) - console.log('Failed to manage gist: ' + error) - } else { - if (data.html_url) { - modalDialogCustom.confirm('Gist is ready', `The gist is at ${data.html_url}. Would you like to open it in a new window?`, () => { - window.open(data.html_url, '_blank') - }) - } else { - modalDialogCustom.alert(data.message + ' ' + data.documentation_url + ' ' + JSON.stringify(data.errors, null, '\t')) - } - } - } - - /** - * This function is to get the original content of given gist - * @params id is the gist id to fetch - */ - async function getOriginalFiles (id) { - if (!id) { - return [] - } - - const url = `https://api.github.com/gists/${id}` - const res = await fetch(url) - const data = await res.json() - return data.files || [] - } - - // If 'id' is not defined, it is not a gist update but a creation so we have to take the files from the browser explorer. - const folder = id ? '/gists/' + id : '/' - this.packageFiles(this.files, folder, (error, packaged) => { - if (error) { - console.log(error) - modalDialogCustom.alert('Failed to create gist: ' + error.message) - } else { - // check for token - var tokenAccess = this._deps.config.get('settings/gist-access-token') - if (!tokenAccess) { - modalDialogCustom.alert( - 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab to create one.' - ) - } else { - const description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + - queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&runs=' + queryParams.get().runs + '&gist=' - const gists = new Gists({ token: tokenAccess }) - - if (id) { - const originalFileList = getOriginalFiles(id) - // Telling the GIST API to remove files - const updatedFileList = Object.keys(packaged) - const allItems = Object.keys(originalFileList) - .filter(fileName => updatedFileList.indexOf(fileName) === -1) - .reduce((acc, deleteFileName) => ({ - ...acc, - [deleteFileName]: null - }), originalFileList) - // adding new files - updatedFileList.forEach((file) => { - const _items = file.split('/') - const _fileName = _items[_items.length - 1] - allItems[_fileName] = packaged[file] - }) - - tooltip('Saving gist (' + id + ') ...') - gists.edit({ - description: description, - public: true, - files: allItems, - id: id - }, (error, result) => { - proccedResult(error, result) - if (!error) { - for (const key in allItems) { - if (allItems[key] === null) delete allItems[key] - } - } - }) - } else { - // id is not existing, need to create a new gist - tooltip('Creating a new gist ...') - gists.create({ - description: description, - public: true, - files: packaged - }, (error, result) => { - proccedResult(error, result) - }) - } - } - } - }) -} - -// return all the files, except the temporary/readonly ones.. -fileExplorer.prototype.packageFiles = function (filesProvider, directory, callback) { - const ret = {} - filesProvider.resolveDirectory(directory, (error, files) => { - if (error) callback(error) - else { - async.eachSeries(Object.keys(files), (path, cb) => { - if (filesProvider.isDirectory(path)) { - cb() - } else { - filesProvider.get(path, (error, content) => { - if (error) return cb(error) - if (/^\s+$/.test(content) || !content.length) { - content = '// this line is added to create a gist. Empty file is not allowed.' - } - ret[path] = { content } - cb() - }) - } - }, (error) => { - callback(error, ret) - }) - } - }) -} - -fileExplorer.prototype.createNewFile = function (parentFolder = '/') { - const self = this - modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { - if (!input) input = 'New file' - helper.createNonClashingName(parentFolder + '/' + input, self.files, async (error, newName) => { - if (error) return tooltip('Failed to create file ' + newName + ' ' + error) - const fileManager = self._deps.fileManager - const createFile = await fileManager.writeFile(newName, '') - - if (!createFile) { - tooltip('Failed to create file ' + newName) - } else { - await fileManager.open(newName) - if (newName.includes('_test.sol')) { - self.events.trigger('newTestFileCreated', [newName]) - } - } - }) - }, null, true) -} - -fileExplorer.prototype.createNewFolder = function (parentFolder) { - const self = this - modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => { - if (!input) { - return tooltip('Failed to create folder. The name can not be empty') - } - - const currentPath = !parentFolder ? self._deps.fileManager.currentPath() : parentFolder - let newName = currentPath ? currentPath + '/' + input : self.files.type + '/' + input - - newName = newName + '/' - self.files.exists(newName, (error, exist) => { - if (error) return tooltip('Unexpected error while creating folder: ' + error) - if (!exist) { - self.files.set(newName, '') - } else { - tooltip('Folder already exists.', () => {}) - } - }) - }, null, true) -} - -fileExplorer.prototype.renderMenuItems = function () { - let items = '' - if (this.menuItems) { - items = this.menuItems.map(({ action, title, icon }) => { - if (action === 'uploadFile') { - return yo` - - ` - } else { - return yo` - { event.stopPropagation(); this[action]() }} - class="newFile ${icon} ${css.newFile}" - title=${title} - > - - ` - } - }) - } - return yo`${items}` -} - -fileExplorer.prototype.ensureRoot = function (cb) { - cb = cb || (() => {}) - var self = this - if (self.element) return cb() - const root = {} - root[this.files.type] = {} - var element = self.treeView.render(root, false) - element.classList.add(css.fileexplorer) - element.events = self.events - element.api = self.api - self.container.appendChild(element) - self.element = element - if (cb) cb() - self.treeView.expand(self.files.type) -} - -function normalize (path, filesList) { - var prefix = path.split('/')[0] - var newList = {} - Object.keys(filesList).forEach(key => { - newList[prefix + '/' + key] = filesList[key].isDirectory ? {} : { '/content': true } - }) - return newList -} - -module.exports = fileExplorer diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/files/remixd-handle.js index 6f06d8773b..be6997574d 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/files/remixd-handle.js @@ -136,23 +136,25 @@ export class RemixdHandle extends WebsocketPlugin { } function remixdDialog () { - const commandText = 'remixd -s path-to-the-shared-folder --remix-ide remix-ide-instance-URL' + const commandText = 'remixd -s -u ' return yo`
Access your local file system from Remix IDE using Remixd NPM package.

Remixd needs to be running in the background to load the files in localhost workspace. For more info, please check the Remixd tutorial.
-
If you are just looking for the remixd command, here it is: +
+ If you are just looking for the remixd command, here it is:

${commandText} ${copyToClipboard(() => commandText)}
-
When connected, a session will be started between ${window.location.origin} and your local file system at ws://127.0.0.1:65520 - and the shared folder will be in the File Explorers workspace named "localhost". -
Note, if the shared folder is a Hardhat project, an additional Hardhat websocket plugin will be listening at ws://127.0.0.1:65522 +
+ When connected, a session will be started between ${window.location.origin} and your local file system at ws://127.0.0.1:65520. + The shared folder will be in the "File Explorers" workspace named "localhost". +
Read more about other Remixd ports usage
-
Please make sure your system is secured enough and ports 65520, 65522 are not opened nor forwarded. - This feature is still in Alpha, so we recommend to keep a copy of the shared folder. +
+ This feature is still in Alpha. We recommend to keep a backup of the shared folder.
diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index fb3bc4a130..76b632a649 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -4,20 +4,12 @@ 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 * as remixBleach from '../../lib/remixBleach' - -var yo = require('yo-yo') -var javascriptserialize = require('javascript-serialize') -var jsbeautify = require('js-beautify') -var type = require('component-type') var vm = require('vm') var EventManager = require('../../lib/events') var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI') var AutoCompletePopup = require('../ui/auto-complete-popup') -var css = require('./styles/terminal-styles') - import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line var globalRegistry = require('../../global/registry') var SourceHighlighter = require('../../app/editor/sourceHighlighter') @@ -79,14 +71,6 @@ class Terminal extends Plugin { this._components = {} this._components.cmdInterpreter = new CommandInterpreterAPI(this, null, this.blockchain) this._components.autoCompletePopup = new AutoCompletePopup(this._opts) - // this._components.autoCompletePopup.event.register('handleSelect', function (input) { - // const textList = this._view.input.innerText.split(' ') - // textList.pop() - // textList.push(input) - // this._view.input.innerText = textList - // this._view.input.focus() - // this.putCursor2End(this._view.input) - // }) this._commands = {} this.commands = {} this._JOURNAL = [] @@ -111,11 +95,6 @@ class Terminal extends Plugin { this.off('scriptRunner', 'error') } - // logHtml (html) { - // var command = this.commands.html - // if (typeof command === 'function') command(html) - // } - logHtml (html) { var command = this.commands.html if (typeof command === 'function') command(html) @@ -158,269 +137,10 @@ class Terminal extends Plugin { ) } - // _appendItem (item) { - // var self = this - // var { el, gidx } = item - // self._JOURNAL[gidx] = item - // if (!self._jobs.length) { - // requestAnimationFrame(function updateTerminal () { - // self._jobs.forEach(el => self._view.journal.appendChild(el)) - // self.scroll2bottom() - // self._jobs = [] - // }) - // } - // if (self.data.activeFilters.commands[item.cmd]) self._jobs.push(el) - // } - scroll2bottom () { - var self = this setTimeout(function () { - // self._view.term.scrollTop = self._view.term.scrollHeight }, 0) } - - // _blocksRenderer (mode) { - // if (mode === 'html') { - // return function logger (args, scopedCommands, append) { - // if (args.length) append(args[0]) - // } - // } - // mode = { - // log: 'text-info', - // info: 'text-info', - // warn: 'text-warning', - // error: 'text-danger' - // }[mode] // defaults - - // if (mode) { - // const filterUndefined = (el) => el !== undefined && el !== null - // return function logger (args, scopedCommands, append) { - // var types = args.filter(filterUndefined).map(type) - // var values = javascriptserialize.apply(null, args.filter(filterUndefined)).map(function (val, idx) { - // if (typeof args[idx] === 'string') { - // const el = document.createElement('div') - // el.innerHTML = args[idx].replace(/(\r\n|\n|\r)/gm, '
') - // val = el.children.length === 0 ? el.firstChild : el - // } - // if (types[idx] === 'element') val = jsbeautify.html(val) - // return val - // }) - // if (values.length) { - // append(yo`${values}`) - // } - // } - // } else { - // throw new Error('mode is not supported') - // } - // } - - // _scopeCommands (append) { - // var self = this - // var scopedCommands = {} - // Object.keys(self.commands).forEach(function makeScopedCommand (cmd) { - // var command = self._commands[cmd] - // scopedCommands[cmd] = function _command () { - // var args = [...arguments] - // command(args, scopedCommands, el => append(cmd, args, blockify(el))) - // } - // }) - // return scopedCommands - // } - - // registerFilter (commandName, filterFn) { - // this.data.filterFns[commandName] = filterFn - // } - - // registerCommand (name, command, opts) { - // var self = this - // name = String(name) - // if (this._commands[name]) throw new Error(`command "${name}" exists already`) - // if (typeof command !== 'function') throw new Error(`invalid command: ${command}`) - // this._commands[name] = command - // console.log({ command }) - // console.log(self._commands) - // this._INDEX.commands[name] = [] - // this._INDEX.commandsMain[name] = [] - // this.commands[name] = function _command () { - // var args = [...arguments] - // var steps = [] - // var root = { steps, cmd: name } - // var ITEM = { root, cmd: name } - // root.gidx = self._INDEX.allMain.push(ITEM) - 1 - // root.idx = self._INDEX.commandsMain[name].push(ITEM) - 1 - // function append (cmd, params, el) { - // var item - // if (cmd) { // subcommand - // item = { el, cmd, root } - // } else { // command - // item = ITEM - // item.el = el - // cmd = name - // } - // item.gidx = self._INDEX.all.push(item) - 1 - // item.idx = self._INDEX.commands[cmd].push(item) - 1 - // item.step = steps.push(item) - 1 - // item.args = params - // // self._appendItem(item) - // } - // var scopedCommands = self._scopeCommands(append) - // command(args, scopedCommands, el => append(null, args, blockify(el))) - // } - // var help = typeof command.help === 'string' ? command.help : [ - // '// no help available for:', - // `terminal.commands.${name}(...)` - // ].join('\n') - // this.commands[name].toString = _ => { return help } - // this.commands[name].help = help - // this.data.activeFilters.commands[name] = opts && opts.activate - // if (opts.filterFn) { - // this.registerFilter(name, opts.filterFn) - // } - // return this.commands[name] - // } - - // async _shell (script, scopedCommands, done) { // default shell - // if (script.indexOf('remix:') === 0) { - // return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') - // } - // var self = this - // if (script.indexOf('remix.') === 0) { - // // we keep the old feature. This will basically only be called when the command is querying the "remix" object. - // // for all the other case, we use the Code Executor plugin - // var context = domTerminalFeatures(scopedCommands, self.blockchain) - // try { - // var cmds = vm.createContext(context) - // var result = vm.runInContext(script, cmds) - // return done(null, result) - // } catch (error) { - // return done(error.message) - // } - // } - // try { - // let result - // if (script.trim().startsWith('git')) { - // // result = await this.call('git', 'execute', script) - // } else { - // result = await this.call('scriptRunner', 'execute', script) - // } - // if (result) self.commands.html(yo`
${result}
`) - // done() - // } catch (error) { - // done(error.message || error) - // } - // } - // } - - // function domTerminalFeatures (scopedCommands, blockchain) { - // return { - // remix: { - // blockchain: this.blockchain, - // commandHelp: this.commandHelp, - // event: this.event, - // _deps: this._deps - // } - // } - // } - - // function loadgist (id, cb) { - // const self = this - // self._components.gistHandler.loadFromGist({ gist: id }, this._deps.fileManager) - // if (cb) cb() - // } - - // function loadurl (url, cb) { - // const self = this - // self._components.fileImport.import(url, - // (loadingMsg) => { toolTip(loadingMsg) }, - // (err, content, cleanUrl, type, url) => { - // if (err) { - // toolTip(`Unable to load ${url}: ${err}`) - // if (cb) cb(err) - // } else { - // self._deps.fileManager.writeFile(type + '/' + cleanUrl, content) - // try { - // content = JSON.parse(content) - // async.eachOfSeries(content.sources, (value, file, callbackSource) => { - // var url = value.urls[0] // @TODO retrieve all other contents ? - // self._components.fileImport.import(url, - // (loadingMsg) => { toolTip(loadingMsg) }, - // async (error, content, cleanUrl, type, url) => { - // if (error) { - // toolTip(`Cannot retrieve the content of ${url}: ${error}`) - // return callbackSource(`Cannot retrieve the content of ${url}: ${error}`) - // } else { - // try { - // await self._deps.fileManager.writeFile(type + '/' + cleanUrl, content) - // callbackSource() - // } catch (e) { - // callbackSource(e.message) - // } - // } - // }) - // }, (error) => { - // if (cb) cb(error) - // }) - // } catch (e) {} - // if (cb) cb() - // } - // }) - // } - - // function exeCurrent (cb) { - // return this.execute(undefined, cb) - // } - - // function execute (file, cb) { - // const self = this - - // function _execute (content, cb) { - // if (!content) { - // toolTip('no content to execute') - // if (cb) cb() - // return - // } - - // self._components.terminal.commands.script(content) - // } - - // if (typeof file === 'undefined') { - // var content = self._deps.editor.currentContent() - // _execute(content, cb) - // return - // } - - // var provider = self._deps.fileManager.fileProviderOf(file) - - // if (!provider) { - // toolTip(`provider for path ${file} not found`) - // if (cb) cb() - // return - // } - - // provider.get(file, (error, content) => { - // if (error) { - // // toolTip(error) - // // TODO: pop up - // if (cb) cb() - // return - // } - - // _execute(content, cb) - // }) - // } - -// function help (cb) { -// const self = this -// var help = yo`
` -// for (var k in self.commandHelp) { -// help.appendChild(yo`
${k}: ${self.commandHelp[k]}
`) -// help.appendChild(yo`
`) -// } -// self._components.terminal.commands.html(help) -// if (cb) cb() -// return '' -// } } -function blockify (el) { return yo`
${el}
` } module.exports = Terminal diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 285ecb5363..6d84a9721f 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -24,7 +24,6 @@ const profile = { documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html', version: packageJson.version, methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile'] - } // EditorApi: diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js deleted file mode 100644 index a9c17192cc..0000000000 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ /dev/null @@ -1,135 +0,0 @@ -import * as packageJson from '../../../../../../package.json' -import { Plugin } from '@remixproject/engine' -const EventEmitter = require('events') -var Compiler = require('@remix-project/remix-solidity').Compiler - -const profile = { - name: 'solidity-logic', - displayName: 'Solidity compiler logic', - description: 'Compile solidity contracts - Logic', - methods: ['getCompilerState'], - version: packageJson.version -} - -class CompileTab extends Plugin { - constructor (queryParams, fileManager, editor, config, fileProvider, contentImport) { - super(profile) - this.event = new EventEmitter() - this.queryParams = queryParams - this.compilerImport = contentImport - this.compiler = new Compiler((url, cb) => this.compilerImport.resolveAndSave(url).then((result) => cb(null, result)).catch((error) => cb(error.message))) - this.fileManager = fileManager - this.editor = editor - this.config = config - this.fileProvider = fileProvider - } - - init () { - this.optimize = this.queryParams.get().optimize - this.optimize = this.optimize === 'true' - this.queryParams.update({ optimize: this.optimize }) - this.compiler.set('optimize', this.optimize) - - this.runs = this.queryParams.get().runs - this.runs = this.runs || 200 - this.queryParams.update({ runs: this.runs }) - this.compiler.set('runs', this.runs) - - this.evmVersion = this.queryParams.get().evmVersion - if (this.evmVersion === 'undefined' || this.evmVersion === 'null' || !this.evmVersion) { - this.evmVersion = null - } - this.queryParams.update({ evmVersion: this.evmVersion }) - this.compiler.set('evmVersion', this.evmVersion) - } - - setOptimize (newOptimizeValue) { - this.optimize = newOptimizeValue - this.queryParams.update({ optimize: this.optimize }) - this.compiler.set('optimize', this.optimize) - } - - setRuns (runs) { - this.runs = runs - this.queryParams.update({ runs: this.runs }) - this.compiler.set('runs', this.runs) - } - - setEvmVersion (newEvmVersion) { - this.evmVersion = newEvmVersion - this.queryParams.update({ evmVersion: this.evmVersion }) - this.compiler.set('evmVersion', this.evmVersion) - } - - /** - * Set the compiler to using Solidity or Yul (default to Solidity) - * @params lang {'Solidity' | 'Yul'} ... - */ - setLanguage (lang) { - this.compiler.set('language', lang) - } - - getCompilerState () { - return this.compiler.state - } - - /** - * Compile a specific file of the file manager - * @param {string} target the path to the file to compile - */ - compileFile (target) { - if (!target) throw new Error('No target provided for compiliation') - const provider = this.fileManager.fileProviderOf(target) - if (!provider) throw new Error(`cannot compile ${target}. Does not belong to any explorer`) - return new Promise((resolve, reject) => { - provider.get(target, (error, content) => { - if (error) return reject(error) - const sources = { [target]: { content } } - this.event.emit('startingCompilation') - // setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation') - setTimeout(() => { this.compiler.compile(sources, target); resolve() }, 100) - }) - }) - } - - async isHardhatProject () { - if (this.fileManager.mode === 'localhost') { - return await this.fileManager.exists('hardhat.config.js') - } else return false - } - - runCompiler (hhCompilation) { - try { - if (this.fileManager.mode === 'localhost' && hhCompilation) { - const { currentVersion, optimize, runs } = this.compiler.state - if (currentVersion) { - const fileContent = `module.exports = { - solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}', - settings: { - optimizer: { - enabled: ${optimize}, - runs: ${runs} - } - } - } - ` - const configFilePath = 'remix-compiler.config.js' - this.fileManager.setFileContent(configFilePath, fileContent) - this.call('hardhat', 'compile', configFilePath).then((result) => { - this.call('terminal', 'log', { type: 'info', value: result }) - }).catch((error) => { - this.call('terminal', 'log', { type: 'error', value: error }) - }) - } - } - this.fileManager.saveCurrentFile() - this.event.emit('removeAnnotations') - var currentFile = this.config.get('currentFile') - return this.compileFile(currentFile) - } catch (err) { - console.error(err) - } - } -} - -module.exports = CompileTab diff --git a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js deleted file mode 100644 index a7214c3b3a..0000000000 --- a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js +++ /dev/null @@ -1,580 +0,0 @@ - -import toaster from '../../ui/tooltip' -import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '@remix-project/remix-solidity' -const yo = require('yo-yo') -const helper = require('../../../lib/helper') -const addTooltip = require('../../ui/tooltip') -const semver = require('semver') -const modalDialogCustom = require('../../ui/modal-dialog-custom') -const css = require('../styles/compile-tab-styles') -const _paq = window._paq = window._paq || [] - -class CompilerContainer { - constructor (compileTabLogic, editor, config, queryParams) { - this._view = {} - this.compileTabLogic = compileTabLogic - this.editor = editor - this.config = config - this.queryParams = queryParams - this.hhCompilation = false - - this.data = { - hideWarnings: config.get('hideWarnings') || false, - autoCompile: config.get('autoCompile'), - compileTimeout: null, - timeout: 300, - allversions: null, - selectedVersion: null, - defaultVersion: 'soljson-v0.8.4+commit.c7e474f2.js' // this default version is defined: in makeMockCompiler (for browser test) - } - } - - /** - * Update the compilation button with the name of the current file - */ - set currentFile (name = '') { - if (name && name !== '') { - this._setCompilerVersionFromPragma(name) - } - if (!this._view.compilationButton) return - const button = this.compilationButton(name.split('/').pop()) - this._disableCompileBtn(!name || (name && !this.isSolFileSelected(name))) - yo.update(this._view.compilationButton, button) - } - - isSolFileSelected (currentFile = '') { - if (!currentFile) currentFile = this.config.get('currentFile') - if (!currentFile) return false - const extention = currentFile.substr(currentFile.length - 3, currentFile.length) - return extention.toLowerCase() === 'sol' || extention.toLowerCase() === 'yul' - } - - deactivate () { - // deactivate editor listeners - this.editor.event.unregister('contentChanged') - this.editor.event.unregister('sessionSwitched') - } - - activate () { - this.currentFile = this.config.get('currentFile') - this.listenToEvents() - } - - listenToEvents () { - this.editor.event.register('sessionSwitched', () => { - if (!this._view.compileIcon) return - this.scheduleCompilation() - }) - - this.compileTabLogic.event.on('startingCompilation', () => { - if (!this._view.compileIcon) return - this._view.compileIcon.setAttribute('title', 'compiling...') - this._view.compileIcon.classList.remove(`${css.bouncingIcon}`) - this._view.compileIcon.classList.add(`${css.spinningIcon}`) - }) - - this.compileTabLogic.compiler.event.register('compilationDuration', (speed) => { - if (!this._view.warnCompilationSlow) return - if (speed > 1000) { - const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.` - this._view.warnCompilationSlow.setAttribute('title', msg) - this._view.warnCompilationSlow.style.visibility = 'visible' - } else { - this._view.warnCompilationSlow.style.visibility = 'hidden' - } - }) - - this.editor.event.register('contentChanged', () => { - if (!this._view.compileIcon) return - this.scheduleCompilation() - this._view.compileIcon.classList.add(`${css.bouncingIcon}`) // @TODO: compileView tab - }) - - this.compileTabLogic.compiler.event.register('loadingCompiler', () => { - if (!this._view.compileIcon) return - this._disableCompileBtn(true) - this._view.compileIcon.setAttribute('title', 'compiler is loading, please wait a few moments.') - this._view.compileIcon.classList.add(`${css.spinningIcon}`) - this._view.warnCompilationSlow.style.visibility = 'hidden' - this._updateLanguageSelector() - }) - - this.compileTabLogic.compiler.event.register('compilerLoaded', () => { - if (!this._view.compileIcon) return - this._disableCompileBtn(false) - this._view.compileIcon.setAttribute('title', '') - this._view.compileIcon.classList.remove(`${css.spinningIcon}`) - if (this.data.autoCompile) this.compileIfAutoCompileOn() - }) - - this.compileTabLogic.compiler.event.register('compilationFinished', (success, data, source) => { - if (!this._view.compileIcon) return - this._view.compileIcon.setAttribute('title', 'idle') - this._view.compileIcon.classList.remove(`${css.spinningIcon}`) - this._view.compileIcon.classList.remove(`${css.bouncingIcon}`) - _paq.push(['trackEvent', 'compiler', 'compiled_with_version', this._retrieveVersion()]) - }) - } - - /************** - * SUBCOMPONENT - */ - compilationButton (name = '') { - const displayed = name || '' - const disabled = name && this.isSolFileSelected() ? '' : 'disabled' - return yo` - - ` - } - - _disableCompileBtn (shouldDisable) { - const btn = document.getElementById('compileBtn') - if (!btn) return - if (shouldDisable) { - btn.classList.add('disabled') - } else if (this.isSolFileSelected()) { - btn.classList.remove('disabled') - } - } - - // Load solc compiler version according to pragma in contract file - _setCompilerVersionFromPragma (filename) { - if (!this.data.allversions) return - this.compileTabLogic.fileManager.readFile(filename).then(data => { - const pragmaArr = data.match(/(pragma solidity (.+?);)/g) - if (pragmaArr && pragmaArr.length === 1) { - const pragmaStr = pragmaArr[0].replace('pragma solidity', '').trim() - const pragma = pragmaStr.substring(0, pragmaStr.length - 1) - const releasedVersions = this.data.allversions.filter(obj => !obj.prerelease).map(obj => obj.version) - const allVersions = this.data.allversions.map(obj => this._retrieveVersion(obj.version)) - const currentCompilerName = this._retrieveVersion(this._view.versionSelector.selectedOptions[0].label) - // contains only numbers part, for example '0.4.22' - const pureVersion = this._retrieveVersion() - // is nightly build newer than the last release - const isNewestNightly = currentCompilerName.includes('nightly') && semver.gt(pureVersion, releasedVersions[0]) - // checking if the selected version is in the pragma range - const isInRange = semver.satisfies(pureVersion, pragma) - // checking if the selected version is from official compilers list(excluding custom versions) and in range or greater - const isOfficial = allVersions.includes(currentCompilerName) - if (isOfficial && (!isInRange && !isNewestNightly)) { - const compilerToLoad = semver.maxSatisfying(releasedVersions, pragma) - const compilerPath = this.data.allversions.filter(obj => !obj.prerelease && obj.version === compilerToLoad)[0].path - if (this.data.selectedVersion !== compilerPath) { - this.data.selectedVersion = compilerPath - this._updateVersionSelector() - } - } - } - }) - } - - _retrieveVersion (version) { - if (!version) version = this._view.versionSelector.value - if (version === 'builtin') version = this.data.defaultVersion - return semver.coerce(version) ? semver.coerce(version).version : '' - } - - render () { - this.compileTabLogic.compiler.event.register('compilerLoaded', (version) => this.setVersionText(version)) - this.fetchAllVersion((allversions, selectedVersion, isURL) => { - this.data.allversions = allversions - if (isURL) this._updateVersionSelector(selectedVersion) - else { - this.data.selectedVersion = selectedVersion - if (this._view.versionSelector) this._updateVersionSelector() - } - }) - - this.hardhatCompilation = yo`` - this._view.warnCompilationSlow = yo`` - this._view.compileIcon = yo`` - this._view.autoCompile = yo` this.updateAutoCompile()} data-id="compilerContainerAutoCompile" id="autoCompile" type="checkbox" title="Auto compile">` - this._view.hideWarningsBox = yo` this.hideWarnings()} id="hideWarningsBox" type="checkbox" title="Hide warnings">` - if (this.data.autoCompile) this._view.autoCompile.setAttribute('checked', '') - if (this.data.hideWarnings) this._view.hideWarningsBox.setAttribute('checked', '') - - this._view.optimize = yo` this.onchangeOptimize()} class="custom-control-input" id="optimize" type="checkbox">` - if (this.compileTabLogic.optimize) this._view.optimize.setAttribute('checked', '') - - this._view.runs = yo` this.onchangeRuns()} - >` - if (this.compileTabLogic.optimize) { - this._view.runs.removeAttribute('disabled') - this._view.runs.value = this.compileTabLogic.runs - } else { - this._view.runs.setAttribute('disabled', '') - } - - this._view.versionSelector = yo` - ` - this._view.languageSelector = yo` - ` - this._view.version = yo`` - - this._view.evmVersionSelector = yo` - ` - if (this.compileTabLogic.evmVersion) { - const s = this._view.evmVersionSelector - let i - for (i = 0; i < s.options.length; i++) { - if (s.options[i].value === this.compileTabLogic.evmVersion) { - break - } - } - if (i === s.options.length) { // invalid evmVersion from queryParams - s.selectedIndex = 0 // compiler default - this.onchangeEvmVersion() - } else { - s.selectedIndex = i - this.onchangeEvmVersion() - } - } - - this._view.compilationButton = this.compilationButton() - - this._view.includeNightlies = yo` - this._updateVersionSelector()}> - ` - this._view.compileContainer = yo` -
- -
-
-
- - ${this._view.versionSelector} -
-
- ${this._view.includeNightlies} - -
-
- - ${this._view.languageSelector} -
-
- - ${this._view.evmVersionSelector} -
-
-

Compiler Configuration

-
- ${this._view.autoCompile} - -
-
-
- ${this._view.optimize} - - ${this._view.runs} -
-
-
- ${this._view.hideWarningsBox} - -
-
- ${this.hardhatCompilation} - ${this._view.compilationButton} -
-
- -
` - - return this._view.compileContainer - } - - promtCompiler () { - modalDialogCustom.prompt( - 'Add a custom compiler', - 'URL', - '', - (url) => this.addCustomCompiler(url) - ) - } - - addCustomCompiler (url) { - this.data.selectedVersion = this._view.versionSelector.value - this._updateVersionSelector(url) - } - - updateAutoCompile (event) { - this.config.set('autoCompile', this._view.autoCompile.checked) - } - - updatehhCompilation (event) { - this.hhCompilation = event.target.checked - } - - compile (event) { - const currentFile = this.config.get('currentFile') - if (!this.isSolFileSelected()) return - - this._setCompilerVersionFromPragma(currentFile) - this.compileTabLogic.runCompiler(this.hhCompilation) - } - - compileIfAutoCompileOn () { - if (this.config.get('autoCompile')) { - this.compile() - } - } - - hideWarnings (event) { - this.config.set('hideWarnings', this._view.hideWarningsBox.checked) - this.compileIfAutoCompileOn() - } - - /* - The following functions are handlers for internal events. - */ - - onchangeOptimize () { - this.compileTabLogic.setOptimize(!!this._view.optimize.checked) - if (this.compileTabLogic.optimize) { - this._view.runs.removeAttribute('disabled') - this.compileTabLogic.setRuns(parseInt(this._view.runs.value)) - } else { - this.compileTabLogic.setRuns(200) - this._view.runs.setAttribute('disabled', '') - } - this.compileIfAutoCompileOn() - } - - onchangeRuns () { - this.compileTabLogic.setRuns(parseInt(this._view.runs.value)) - this.compileIfAutoCompileOn() - } - - onchangeLanguage () { - this.compileTabLogic.setLanguage(this._view.languageSelector.value) - this.compileIfAutoCompileOn() - } - - onchangeEvmVersion () { - const s = this._view.evmVersionSelector - let v = s.value - if (v === 'default') { - v = null - } - this.compileTabLogic.setEvmVersion(v) - for (let i = 0; i < s.options.length; i++) { - if (i === s.selectedIndex) { - s.options[s.selectedIndex].setAttribute('selected', 'selected') - } else { - s.options[i].removeAttribute('selected') - } - } - - this.compileIfAutoCompileOn() - } - - onchangeLoadVersion () { - this.data.selectedVersion = this._view.versionSelector.value - this._updateVersionSelector() - this._updateLanguageSelector() - } - - /* - The following functions map with the above event handlers. - They are an external API for modifying the compiler configuration. - */ - setConfiguration (settings) { - this.setLanguage(settings.language) - this.setEvmVersion(settings.evmVersion) - this.setOptimize(settings.optimize) - this.setRuns(settings.runs) - this.setVersion(settings.version) - } - - setOptimize (enabled) { - this._view.optimize.checked = enabled - this.onchangeOptimize() - } - - setRuns (value) { - if (value) { - this._view.runs.value = value - this.onchangeRuns() - } - } - - setLanguage (lang) { - this._view.languageSelector.value = lang - this.onchangeLanguage() - } - - setEvmVersion (version) { - this._view.evmVersionSelector.value = version || 'default' - this.onchangeEvmVersion() - } - - setVersion (version) { - this._view.versionSelector.value = `soljson-v${version}.js` - this.onchangeLoadVersion() - } - - _shouldBeAdded (version) { - return !version.includes('nightly') || - (version.includes('nightly') && this._view.includeNightlies.checked) - } - - _updateVersionSelector (customUrl = '') { - // update selectedversion if previous one got filtered out - if (!this.data.selectedVersion || !this._shouldBeAdded(this.data.selectedVersion)) { - this.data.selectedVersion = this.data.defaultVersion - } - this._view.versionSelector.innerHTML = '' - this._view.versionSelector.removeAttribute('disabled') - this.queryParams.update({ version: this.data.selectedVersion }) - let url - if (customUrl !== '') { - this.data.selectedVersion = customUrl - this._view.versionSelector.appendChild(yo``) - url = customUrl - this.queryParams.update({ version: this.data.selectedVersion }) - } else if (this.data.selectedVersion === 'builtin') { - let location = window.document.location - let path = location.pathname - if (!path.startsWith('/')) path = '/' + path - location = `${location.protocol}//${location.host}${path}assets/js` - if (location.endsWith('index.html')) location = location.substring(0, location.length - 10) - if (!location.endsWith('/')) location += '/' - url = location + 'soljson.js' - } else { - if (this.data.selectedVersion.indexOf('soljson') !== 0 || helper.checkSpecialChars(this.data.selectedVersion)) { - return console.log('loading ' + this.data.selectedVersion + ' not allowed') - } - url = `${urlFromVersion(this.data.selectedVersion)}` - } - - this.data.allversions.forEach(build => { - const option = build.path === this.data.selectedVersion - ? yo`` - : yo`` - - if (this._shouldBeAdded(option.innerText)) { - this._view.versionSelector.appendChild(option) - } - }) - if (this.data.selectedVersion !== 'builtin' && semver.lt(this._retrieveVersion(), 'v0.4.12+commit.194ff033.js')) { - toaster(yo` -
- Old compiler usage detected. -

You are using a compiler older than v0.4.12.

-

Some functionality may not work.

-
` - ) - } - - // Workers cannot load js on "file:"-URLs and we get a - // "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium, - // resort to non-worker version in that case. - if (canUseWorker(this._retrieveVersion())) { - this.compileTabLogic.compiler.loadVersion(true, url) - this.setVersionText('(loading using worker)') - } else { - this.compileTabLogic.compiler.loadVersion(false, url) - this.setVersionText('(loading)') - } - } - - _updateLanguageSelector () { - // This is the first version when Yul is available - if (!semver.valid(this._retrieveVersion()) || semver.lt(this._retrieveVersion(), 'v0.5.7+commit.6da8b019.js')) { - this._view.languageSelector.setAttribute('disabled', '') - this._view.languageSelector.value = 'Solidity' - this.compileTabLogic.setLanguage('Solidity') - } else { - this._view.languageSelector.removeAttribute('disabled') - } - } - - setVersionText (text) { - if (this._view.version) this._view.version.innerText = text - } - - // fetching both normal and wasm builds and creating a [version, baseUrl] map - async fetchAllVersion (callback) { - let selectedVersion, allVersionsWasm, isURL - let allVersions = [{ path: 'builtin', longVersion: 'Stable local version - 0.8.4' }] - // fetch normal builds - const binRes = await promisedMiniXhr(`${baseURLBin}/list.json`) - // fetch wasm builds - const wasmRes = await promisedMiniXhr(`${baseURLWasm}/list.json`) - if (binRes.event.type === 'error' && wasmRes.event.type === 'error') { - selectedVersion = 'builtin' - return callback(allVersions, selectedVersion) - } - try { - const versions = JSON.parse(binRes.json).builds.slice().reverse() - allVersions = [...allVersions, ...versions] - selectedVersion = this.data.defaultVersion - if (this.queryParams.get().version) selectedVersion = this.queryParams.get().version - // Check if version is a URL and corresponding filename starts with 'soljson' - if (selectedVersion.startsWith('https://')) { - const urlArr = selectedVersion.split('/') - if (urlArr[urlArr.length - 1].startsWith('soljson')) isURL = true - } - if (wasmRes.event.type !== 'error') { - allVersionsWasm = JSON.parse(wasmRes.json).builds.slice().reverse() - } - } catch (e) { - addTooltip('Cannot load compiler version list. It might have been blocked by an advertisement blocker. Please try deactivating any of them from this page and reload. Error: ' + e) - } - // replace in allVersions those compiler builds which exist in allVersionsWasm with new once - if (allVersionsWasm && allVersions) { - allVersions.forEach((compiler, index) => { - const wasmIndex = allVersionsWasm.findIndex(wasmCompiler => { return wasmCompiler.longVersion === compiler.longVersion }) - if (wasmIndex !== -1) { - allVersions[index] = allVersionsWasm[wasmIndex] - pathToURL[compiler.path] = baseURLWasm - } else { - pathToURL[compiler.path] = baseURLBin - } - }) - } - callback(allVersions, selectedVersion, isURL) - } - - scheduleCompilation () { - if (!this.config.get('autoCompile')) return - if (this.data.compileTimeout) window.clearTimeout(this.data.compileTimeout) - this.data.compileTimeout = window.setTimeout(() => this.compileIfAutoCompileOn(), this.data.timeout) - } -} - -module.exports = CompilerContainer diff --git a/apps/remix-ide/src/app/tabs/compileTab/contractParser.js b/apps/remix-ide/src/app/tabs/compileTab/contractParser.js deleted file mode 100644 index cd603c859a..0000000000 --- a/apps/remix-ide/src/app/tabs/compileTab/contractParser.js +++ /dev/null @@ -1,122 +0,0 @@ -'use strict' - -var solcTranslate = require('solc/translate') -var remixLib = require('@remix-project/remix-lib') -var txHelper = remixLib.execution.txHelper - -module.exports = (contractName, contract, compiledSource) => { - return getDetails(contractName, contract, compiledSource) -} - -var getDetails = function (contractName, contract, source) { - var detail = {} - detail.name = contractName - detail.metadata = contract.metadata - if (contract.evm.bytecode.object) { - detail.bytecode = contract.evm.bytecode.object - } - - detail.abi = contract.abi - - if (contract.evm.bytecode.object) { - detail.bytecode = contract.evm.bytecode - detail.web3Deploy = gethDeploy(contractName.toLowerCase(), contract.abi, contract.evm.bytecode.object) - - detail.metadataHash = retrieveMetadataHash(contract.evm.bytecode.object) - if (detail.metadataHash) { - detail.swarmLocation = 'bzzr://' + detail.metadataHash - } - } - - detail.functionHashes = {} - for (var fun in contract.evm.methodIdentifiers) { - detail.functionHashes[contract.evm.methodIdentifiers[fun]] = fun - } - - detail.gasEstimates = formatGasEstimates(contract.evm.gasEstimates) - - detail.devdoc = contract.devdoc - detail.userdoc = contract.userdoc - - if (contract.evm.deployedBytecode && contract.evm.deployedBytecode.object.length > 0) { - detail['Runtime Bytecode'] = contract.evm.deployedBytecode - } - - if (source && contract.assembly !== null) { - detail.Assembly = solcTranslate.prettyPrintLegacyAssemblyJSON(contract.evm.legacyAssembly, source.content) - } - - return detail -} - -var retrieveMetadataHash = function (bytecode) { - var match = /a165627a7a72305820([0-9a-f]{64})0029$/.exec(bytecode) - if (!match) { - match = /a265627a7a72305820([0-9a-f]{64})6c6578706572696d656e74616cf50037$/.exec(bytecode) - } - if (match) { - return match[1] - } -} - -var gethDeploy = function (contractName, jsonInterface, bytecode) { - var code = '' - var funABI = txHelper.getConstructorInterface(jsonInterface) - - funABI.inputs.forEach(function (inp) { - code += 'var ' + inp.name + ' = /* var of type ' + inp.type + ' here */ ;\n' - }) - - contractName = contractName.replace(/[:./]/g, '_') - code += 'var ' + contractName + 'Contract = new web3.eth.Contract(' + JSON.stringify(jsonInterface).replace('\n', '') + ');' + - '\nvar ' + contractName + ' = ' + contractName + 'Contract.deploy({' + - "\n data: '0x" + bytecode + "', " + - '\n arguments: [' - - funABI.inputs.forEach(function (inp) { - code += '\n ' + inp.name + ',' - }) - - code += '\n ]' + - '\n}).send({' + - '\n from: web3.eth.accounts[0], ' + - "\n gas: '4700000'" + - '\n }, function (e, contract){' + - '\n console.log(e, contract);' + - "\n if (typeof contract.address !== 'undefined') {" + - "\n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" + - '\n }' + - '\n })' - - return code -} - -var formatGasEstimates = function (data) { - if (!data) return {} - if (data.creation === undefined && data.external === undefined && data.internal === undefined) return {} - - var gasToText = function (g) { - return g === null ? 'unknown' : g - } - - var ret = {} - var fun - if ('creation' in data) { - ret.Creation = data.creation - } - - if ('external' in data) { - ret.External = {} - for (fun in data.external) { - ret.External[fun] = gasToText(data.external[fun]) - } - } - - if ('internal' in data) { - ret.Internal = {} - for (fun in data.internal) { - ret.Internal[fun] = gasToText(data.internal[fun]) - } - } - return ret -} diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.js b/apps/remix-ide/src/app/tabs/hardhat-provider.js index 8152d61332..75c20a90cd 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.js +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.js @@ -65,7 +65,7 @@ export default class HardhatProvider extends Plugin { if (error) { this.blocked = true modalDialogCustom.alert('Hardhat Provider', `Error while connecting to the hardhat provider: ${error.message}`) - await this.call('udapp', 'setEnvironmentMode', { context: 'vm', fork: 'berlin' }) + await this.call('udapp', 'setEnvironmentMode', { context: 'vm', fork: 'london' }) this.provider = null setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm return reject(error) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index 0d3da9f1a2..8328e04bcb 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -361,7 +361,7 @@ class ContractDropdownUI { return continueTxExecution(null) } const amount = this.blockchain.fromWei(tx.value, true, 'ether') - const content = confirmDialog(tx, amount, gasEstimation, null, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) + const content = confirmDialog(tx, network, amount, gasEstimation, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) modalDialog('Confirm transaction', content, { @@ -370,10 +370,9 @@ class ContractDropdownUI { this.blockchain.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked) // TODO: check if this is check is still valid given the refactor if (!content.gasPriceStatus) { - cancelCb('Given gas price is not correct') + cancelCb('Given transaction fee is not correct') } else { - var gasPrice = this.blockchain.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) + continueTxExecution(content.txFee) } } }, { diff --git a/apps/remix-ide/src/app/tabs/runTab/recorder.js b/apps/remix-ide/src/app/tabs/runTab/recorder.js index 47f6ff440b..52d5367464 100644 --- a/apps/remix-ide/src/app/tabs/runTab/recorder.js +++ b/apps/remix-ide/src/app/tabs/runTab/recorder.js @@ -104,7 +104,7 @@ class RecorderUI extends Plugin { return continueTxExecution(null) } const amount = this.blockchain.fromWei(tx.value, true, 'ether') - const content = confirmDialog(tx, amount, gasEstimation, null, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) + const content = confirmDialog(tx, network, amount, gasEstimation, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) modalDialog('Confirm transaction', content, { @@ -113,10 +113,9 @@ class RecorderUI extends Plugin { this.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked) // TODO: check if this is check is still valid given the refactor if (!content.gasPriceStatus) { - cancelCb('Given gas price is not correct') + cancelCb('Given transaction fee is not correct') } else { - var gasPrice = this.blockchain.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) + continueTxExecution(content.txFee) } } }, { diff --git a/apps/remix-ide/src/app/tabs/runTab/settings.js b/apps/remix-ide/src/app/tabs/runTab/settings.js index f99a2bc461..d71ca500f7 100644 --- a/apps/remix-ide/src/app/tabs/runTab/settings.js +++ b/apps/remix-ide/src/app/tabs/runTab/settings.js @@ -98,14 +98,14 @@ class SettingsUI {
+ Gwei +
+
+
+
+ Max fee (Not less than base fee ${Web3.utils.fromWei(Web3.utils.toBN(parseInt(network.lastBlock.baseFeePerGas, 16)), 'Gwei')} Gwei): + + Gwei + +
+
` + : yo`
+ Gas price: + + Gwei (visit ethgasstation.info for current gas price info.) +
` + } +
Max transaction fee: - -
-
- Gas price: - - Gwei (visit ethgasstation.info for current gas price info.) -
-
- Data: -
${tx.data && tx.data.length > 50 ? tx.data.substring(0, 49) + '...' : tx.data} ${copyToClipboard(() => { return tx.data })}
+
@@ -74,10 +120,14 @@ function confirmDialog (tx, amount, gasEstimation, self, newGasPriceCb, initialP if (txFeeText) { el.querySelector('#txfee').innerHTML = txFeeText } - if (gasPriceValue) { + if (el.querySelector('#gasprice') && gasPriceValue) { el.querySelector('#gasprice').value = gasPriceValue onGasPriceChange() } + if (el.querySelector('#maxfee') && network && network.lastBlock && network.lastBlock.baseFeePerGas) { + el.querySelector('#maxfee').value = Web3.utils.fromWei(Web3.utils.toBN(parseInt(network.lastBlock.baseFeePerGas, 16)), 'Gwei') + onMaxFeeChange() + } if (gasPriceStatus !== undefined) { el.gasPriceStatus = gasPriceStatus } 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 8652017b2a..60d762472f 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,7 +1,6 @@ import * as packageJson from '../../../../../../package.json' import { ViewPlugin } from '@remixproject/engine-web' import { migrateToWorkspace } from '../../../migrateFileSystem' -import { CompilerImports } from '@remix-project/core-plugin' import JSZip from 'jszip' const yo = require('yo-yo') @@ -119,11 +118,12 @@ const profile = { } export class LandingPage extends ViewPlugin { - constructor (appManager, verticalIcons, fileManager, filePanel) { + constructor (appManager, verticalIcons, fileManager, filePanel, contentImport) { super(profile) this.profile = profile this.fileManager = fileManager this.filePanel = filePanel + this.contentImport = contentImport this.appManager = appManager this.verticalIcons = verticalIcons this.gistHandler = new GistHandler() @@ -216,7 +216,7 @@ export class LandingPage extends ViewPlugin { const invertNum = (themeQuality === 'dark') ? 1 : 0 if (this.solEnv.getElementsByTagName('img')[0]) this.solEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` - if (this.debuggerEnv.getElementsByTagName('img')[0]) this.debuggerEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` + if (this.optimismEnv.getElementsByTagName('img')[0]) this.optimismEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` if (this.solhintEnv.getElementsByTagName('img')[0]) this.solhintEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` if (this.learnEthEnv.getElementsByTagName('img')[0]) this.learnEthEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` if (this.sourcifyEnv.getElementsByTagName('img')[0]) this.sourcifyEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` @@ -240,7 +240,7 @@ export class LandingPage extends ViewPlugin { render () { const load = (service, item, examples, info) => { - const compilerImport = new CompilerImports() + const contentImport = this.contentImport const fileProviders = globalRegistry.get('fileproviders').api const msg = yo`
@@ -252,7 +252,7 @@ export class LandingPage extends ViewPlugin { const title = `Import from ${service}` modalDialogCustom.prompt(title, msg, null, (target) => { if (target !== '') { - compilerImport.import( + contentImport.import( target, (loadingMsg) => { tooltip(loadingMsg) }, (error, content, cleanUrl, type, url) => { @@ -277,10 +277,10 @@ export class LandingPage extends ViewPlugin { this.verticalIcons.select('solidity') _paq.push(['trackEvent', 'pluginManager', 'userActivate', 'solidity']) } - const startDebugger = async () => { - await this.appManager.activatePlugin('debugger') - this.verticalIcons.select('debugger') - _paq.push(['trackEvent', 'pluginManager', 'userActivate', 'debugger']) + const startOptimism = async () => { + await this.appManager.activatePlugin('optimism-compiler') + this.verticalIcons.select('optimism-compiler') + _paq.push(['trackEvent', 'pluginManager', 'userActivate', 'optimism-compiler']) } const startSolhint = async () => { await this.appManager.activatePlugin(['solidity', 'solhint']) @@ -385,8 +385,8 @@ export class LandingPage extends ViewPlugin { // main this.solEnv = createLargeButton('assets/img/solidityLogo.webp', 'solidityLogo', 'Solidity', startSolidity) // Featured - this.debuggerEnv = createLargeButton('assets/img/debuggerLogo.webp', 'debuggerLogo', 'Debugger', startDebugger) - this.solhintEnv = createLargeButton('assets/img/solhintLogo.png', 'solhintLogo', 'solhint linter', startSolhint) + this.optimismEnv = createLargeButton('assets/img/optimismLogo.webp', 'optimismLogo', 'Optimism', startOptimism) + this.solhintEnv = createLargeButton('assets/img/solhintLogo.png', 'solhintLogo', 'Solhint linter', startSolhint) this.learnEthEnv = createLargeButton('assets/img/learnEthLogo.webp', 'learnEthLogo', 'LearnEth', startLearnEth) this.sourcifyEnv = createLargeButton('assets/img/sourcifyLogo.webp', 'sourcifyLogo', 'Sourcify', startSourceVerify) this.moreEnv = createLargeButton('assets/img/moreLogo.webp', 'moreLogo', 'More', startPluginManager) @@ -395,7 +395,7 @@ export class LandingPage extends ViewPlugin { const themeQuality = globalRegistry.get('themeModule').api.currentTheme().quality const invertNum = (themeQuality === 'dark') ? 1 : 0 this.solEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` - this.debuggerEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` + this.optimismEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` this.solhintEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` this.learnEthEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` this.sourcifyEnv.getElementsByTagName('img')[0].style.filter = `invert(${invertNum})` @@ -505,10 +505,10 @@ export class LandingPage extends ViewPlugin {

Featured Plugins

${this.solEnv} + ${this.optimismEnv} ${this.learnEthEnv} ${this.solhintEnv} - ${this.sourcifyEnv} - ${this.debuggerEnv} + ${this.sourcifyEnv} ${this.moreEnv}
diff --git a/apps/remix-ide/src/app/ui/sendTxCallbacks.js b/apps/remix-ide/src/app/ui/sendTxCallbacks.js index f2785482b2..3f5c7c7506 100644 --- a/apps/remix-ide/src/app/ui/sendTxCallbacks.js +++ b/apps/remix-ide/src/app/ui/sendTxCallbacks.js @@ -51,7 +51,7 @@ const confirmationCb = function (network, tx, gasEstimation, continueTxExecution return continueTxExecution(null) } var amount = Web3.utils.fromWei(typeConversion.toInt(tx.value), 'ether') - var content = confirmDialog(tx, amount, gasEstimation, self.udappUI, + var content = confirmDialog(tx, network, amount, gasEstimation, (gasPrice, cb) => { let txFeeText, priceStatus // TODO: this try catch feels like an anti pattern, can/should be @@ -93,10 +93,9 @@ const confirmationCb = function (network, tx, gasEstimation, continueTxExecution ) // TODO: check if this is check is still valid given the refactor if (!content.gasPriceStatus) { - cancelCb('Given gas price is not correct') + cancelCb('Given transaction fee is not correct') } else { - var gasPrice = Web3.utils.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) + continueTxExecution(content.txFee) } } }, diff --git a/apps/remix-ide/src/assets/img/optimismLogo.webp b/apps/remix-ide/src/assets/img/optimismLogo.webp new file mode 100644 index 0000000000000000000000000000000000000000..d7569da3f1f8dc53d16ff064e4c1c9986f3ec620 GIT binary patch literal 15868 zcmYLwbyOSg^EK{PT#FQ!;98tw4HDb}#oe_ODei8;2@7WcNe7lJ#*rBI6XQz-CD z_`c`79RAp3cjuY8bLYnY1__K3fsGz$rF4Q?*_y=WRjEA}3N_&#-@m8;R3jsd|B zPG@1^8WvVu6nXgsx7F66g_YLi&u*(zt!`af{`{pF>KUx+zd7A=gVBms3<9r{aI)_o z*Hls-GA%Y9@o$QHT48yQ{2?W(1H6;Gla$NQsjNl~+hx&TY04HEp?v1MopC1lqO9`; z8?PvpkKE#n^LaBix<(>!+FRWC^icgrLt`?~d#uwfY zti@L|m$%z0(6=Wj=)=mkkMW$ShH|-1SHxSAp~&YG`TnRv6XzG7Xp=ZQJIfe%T@hQL zD_uW5eXL*6^exyvJ0pU`?0(qPI&|C|=zjd8>#-;mR6qWP&dn?_Yb}3QdGDo1HpkS=pt0Hjx|Nky6&*t3Ow_DWk)(`ALFa-}-i z)AgR(WMs_-xL*_oehvg&(3ihuP8AM3`(0>nLmrG&zWYeVml_Q3U;@MKLg==}Ne zGQ_JeIpXz#?$UB>z#oB!K^itXHrE}AKZja|SV=FY@N12~RlDGfDEPakV$FjINm7JW zWnY^BHI-y~#KLYWULK#$F&~9p-bOhun3kDlR-!b&tUKv+PWC7qjA(5ATmfHU>GG{N z<2p|F?hG{kryF&=YLDyUCOhDF^f%K;tLi6iyO$w8_tI%b%hR1kF1) zlSx`$lP<+2;u@GuPBpVDhpJT#tGqUv4BLZ;j4f4)Zk|(@0mZwXm7ghn@^<>&?(KDA z!jeqK9%fOBt*TY^s@5wffvs!$+3ORW@38T8N49H?9Rd;Wqso?EEBwjRs&Jk13{<$p z$>2&~lcHl$X@_qET@S`+7Eo`kRnS@7{Vl~fO!Zj!72zUkvII}Bql01C0&68mOWQZ6 zHYV5mNDRwSzUa)qa>6W@6XNcmiRy=H2XL!%&bBX%-Zof0!-W!5x1A9%<5e^EmIipe z>=%YUtYq>bJ{M)H0M;MWTZp_SV5e-SpblR%@hxi5_uk6b>I*lM zGVyj&QbC{Fw9W+vVH|~-&O?INNTFe!dt_zk&QA1S+~6e8Fe&j=5(bdA^k1+Z8J7II zl1Ji~*QQl>1TWTkypA?p3|tt$fTbjBBFA7H9N}okIxfMAzVi21HCMApQ`Sz@h%<=q zgV;(CW_Z32!Ro{Ecge@WD<1O6S-@4)YYNalJdLP&-hBrykLowc@d|qmt;x#?8n)t> zW7^Mi3^N^a19ytco0sPRtJGJ%dL8+$4#0vi=dx4;Au7J|^{?n4 zSa{XrISs!`cM;~UEr1;q87O?Uox3}J!+0w=)pv*#JJnSxcppijToa-A9POez7lS*i z=;*Gt#$dBmK?4^T>FvJje7om+@HnDs2N(}KfRG%NYMQCeO}{mEfLI?OulXU08!|N% z*xr7%{=)N!-4sgi-{Jcj-8lo?`G=0~gLe8j>=^?HSd$Dy$DGULZQ3tVN(3&_Ermw4 zn)>_Az(1z1Oc z4)H$4cc-^1#_%$R6ACa}sEE{IeJMki4isP3xfHSN@VyVqXM{9d4`GFLdpnhdnbNv~ zX*r=&d|{Qur9-d+v^mE;_$$=wKb7#d(HQ)Ss>&W4t29$7lQckHyRT2!JF+@(J|{G1 zuZCZoA+0#y@G}TJ#-8Df%*%C;u0YL$l!#74GEf|^S{3?%#8{$MK@BVgq3jLgf~eqC z&)YvG@Y_v1CzNt}E`Wm$fH2~}5aIkEn<2Q-pJ$-c8IK4uRbReu z&AP9G-{>?tn66!X_X_wH?RfA_v`JN0T)PNJ{yru8*jFA2KySwol2nbhPxlY@`Efl5 z6j4Ddr2!ox2%_(ayf>mjc)HM<)`Lofqz{M5^yJG}LgZnhEVC4p68e-z2fp(dU5#+y z>KS(?Gt@$b6++}LKbZy$IIVFC+eMOvicrMwyDeVz?-6A7PY_rkvTv98%?kA7QKRw< zUOcf}tz$7ziPqVaC#BO_=$4m8&bRSLgveZTIHmgWyEG1n%D}|ucFWtS!?4>M`VQY% zdm<7r?F{O51cZDB1LePi0vDFo(PZJOlm!Ryw3z&Tp~TTQR-TB0xwYV`)$j6H(rJBK z*ex-U;8hX-y|5BsokAEJ4M2Dl_Ace=)Zo%_tsTNDCsfvDMid;Agmh>n$LaSxm(2D^ z+|xCFiRsNuyYRGJ$>J~6cD3z^s7OG5nHFL&@leurRMIBLt78`6^dUxde| z&bRCUb8;wAAy7#Q+B-A^3q)k4=l8;qR)r+5Du6IPZ-*gq`ADEctZkd~eeU>S$r+#nV zLe2{T^hAsHJryjrM~jzJaoD?Y5bkl-a}lJ^B?2^RJ|o~xOL+z!WEF*&(ST`D{#}}9 z_MLcnIYB1rllI|ih&bNuz}YsI!mgrfD5NEiYvV^)=AVd4ETXV-r(g)CeI`7-ZJ~bb z`?8_CHxNJw*PGqXjA zezK=~R@jM;QaQ(6!7I4(49_7kzVbbN3o_{BAgU0AcJhS@wIji4V%P1r6ZCeHL-9ix zn?Y?M&_0zkkw*=CAKF*Zh(ipy$<2Eq^dyRH<6Cf)t&(5)U<@ie$j0{pSP1HzQS=~; znE_PiTD#Bw34s*1$-0k~mlMkQcXZ9>xj;qg<&7cOJ?fmG7gBQM5U4@J-W97Kgrs{p zrK0$~dRlX0@d@Tr;>=X}zHPV`>harlWYO5IAQ``oqMcE68Tq|= z*5?LOj6N8%pildTG$JOM>2exxr_=&TmLJGEvE%$76L2$UWqv#{_itjvjUsMUKMeJ& z+~!)KX@v4O7@L3(#y40xnsfHkV&>PP=AzHVAXrB=P8^fV6Vl-XkbTC-?slUUsdc<4 zWT{OW^REsO9eEiWuN|=IaaCpDcUU}{v)$7F0?1P@ zX-khNN_Ya0QLywSIHPhwp_CP>=T2*DoIMQ}k5_rW${*(`C*>2&< zfSd+4+D$6(iw&|tzjIKJ2Ndjqvx;9pVg@E=1o$QhQ;@pZ+_V2oSN!k8r(AQnvu#UHPD<@ zADhgN87NfcPcQxy3h!M<+iSIE+?(zl|iy z7n@bW50)q`W=Ng6{uQzhC-MNVD@-2O2FiIW{jZAg^y-g(wSR*xaz_Bs!`^RPWV`#l zzGg96eM+$4Dg7xmga{WDGyt2Y0S%8L878hN#}WM%#!M*cR>-yVi%krnjZW20281WI zGfYp)lv!yltbHC2yu_GGbdg#xpo6JSKS{xNVLtWfON2Y1S$8cx;XN&KhCHrFXRvNz1AbM zoh`Vth|k-vNagcDFc&cm4PRYXvUFT6Ac_ZpTRDJxO&sgFj}x+6i6r+lebr1Va@&Sm zp&j>ii0I1Kvpl7`OKS0yj1-yPV0f1M{wn^s1|1}Y90Zv_5??{|J8b@OuGt$|6d}8l zVt`39&}L!f+p#=OPNAY5MScbA{r{FkIKFzb#MdQ%h3&ZisMSSYTtC;@A>t~hXx8uB z*6j#j;D^ehGei7;fF`P^o@g1lvS{G5SLn;H6irZ#zl)qTqSArG1l8j^$YY=5efU!G z^nxHpcMS-@AO@`*hRH~f3pZLl#X2i+{xY^hgw;O9i;d*=-Ux`~huJs+B97$`sEC-QW1)pi^wOsn*`P6u9E?T-`z zUr0fVUH+F0fzJaBfXOwz*^B)r6v!mo^{I1-i|FOKPY(7IIrLBQr4llrjpRO6 z1%F>=Ev4-${VD z8KS)$6wEnurLlh#M29R4@*x`RPt=uuVwj8Z{C)N44rs&E$=unL=&5rvsRAY|@?KyA z2)~C(F+PoVg#2iZ$KW57BnZ)Y$&Z%9O||RY;E8~vk$Hbl%gd?t{5zqKlN$CM5HZQ9 zaEsPQo2=_KZo#1_e&tU#2iWaAouOQg=9alYJ zbE>N}W!!&&M@0p7Pe7{w82?jUp3(a6cl9C5UR&rqzb%CW+53G6dpfacrHS?sqpd*X z#~;~~MLb~pu+C6`COPOa0}n#k76d+tVRGWnKqB<^fhDTuqTyeMh?=%04_!>J5fd_( zpBLp_r;^xHlq3W;S-tPo9do^<3yu{ZC)|*`IgxV+?>;@rDK) zHPasZ|2ojcIxEfx=1e8)BclAAictA#MKI&pcq0>yHiEc0`Sb zsQ!;z$SLFYqkemH`})qi1r)cpcF(}HIKrxM3cpRAE)1|SzhNlogL1xAQKJR?Ct> zx4wh>`N_$+2c+nNJ4kH#2dmi*fAUMw{b^3~7h=SEGHU7S=+&D-%8l$3P65ngyL;|5 z_3=eJhl_Mq24C(63U(%wHpIdGOoQwM(2WnGv)kB$U+f!S|C%XMntTfglKrt_{NjZO z5!h1NtVz_x|4J$Nku(=S;d)&&7cnFAf?g~or zt7sJ(HJ{k?`!Xc0OGG}6er^9~Hij|dkYVO978`Wq5@F3b>&EitrBN|A|M`|~oF^@v z(d0*%{U7~M^6KRF%5<;!0fi8}Y_9vS4y>8AAH)Ca857VQx%Yhn_mpMDhWs|Px04mdsoAQSP>i1;YxRR zxyYhbikI!RUi(|q#s~eT;$ZA$SkWwVj^Lj1-DCbdGw8-jfVnNHP9-%e-^9bk0C#Ip zl4k!C)V753WRX1L#DA&dOC39rVaM1v^UOkXjfDsep^lFkBY#+o>jX+~NzBYF^l6PT zdki#4-;lnkESxmh3paAGrpQdV;_a+}->TJ)|Ejn82_RB%hvo1!NxhS`SY;Q2Ri$lfYD|52bbZPVzjfK^7 zKE+?6ALlwf%YFvPX^m4~bLk6bq!&fwHnR3e#ns6p{4lNcS ze~-w2Vw>Hs_l$@o0tTQcll;?w4V#rHk)UpuWyJ%!#v_eK+3S5Jsb_Ko zoG5I@j&Voni9#a`pU3|M1)0DTv?n?=8XwH>J`~$7Mh!VJqcITWl17%uXdD#>rDGD>+XxWuF{O8xo0&|~jnd}j3WJI&R_^`C} z`>pP~6KB%2UAg9?PYr026^hsE7dlW&dm_Esx;G(8djGE1j;c8QX9demws=keMg1Ml zI7BDX_u*WLiVu5sXz#bU1t)&gs*C>%4y)6}*BX_I4s>MTzbzLjU8JY-)P8qlyC3Y# z|D)YT?;Wq3&j+Azg2?c}NK&SFW~msOYFkabl4;99csm80Xv1yB_+agvB9%LCj zt?Q3IsINKtxg`9banMbAnvV#F*Zc?EQU}t%QfPcWm*;Z>lIn7nZ3D$WYDoWl{Fxpn zsg6H*qI>p@`^Gfv?$Qs zSu5h6y1yYDL@2?V+&<4H(~VRyGu5_2K7PULWhM*$_^@RA@ae^f;4SJMcrxZ+|sHx{I@EPDI6TBXT(I{f`K z^Djr0pna12Fy;EsGfX^=%-g>hB>mI{67)gV3CYXj)?Dz#ajg&Sf9cB@KY1kiJHbQl z8jNjQqFy>UmcHfE%{1Y1WEq|*Alp44xDOMJpAnSElEjN)T_D%t&mFYwX%5nr_X2IVZqJUIkPh+--Jo;MTt-IhG{k^%tz^?uGJ3 zISZWQ+=7%NjHVQe>R;Yh_NQ7b6n?0b|hZJh;PxH$U#Ob~4Q*2!-?gt5fGld9xXIt0zG)n_Rw zwD^={+Y)E%9obfwd*#h-nM2&Xvd?U%;MX8iNjxq?7wiR}lj~Gk9tgH5mlfn{-!4ha$)~b09esFN ztUmar#L2(Gs%!2R%Iu*6kfHtg;%LlIs6QRQ(J&p)w)=d((Ta)d#q1un z<=vgx=}p7aF|AIR)VY z8C;W*UDVYpWeyzd?5NpeXvqWVtB^0=qJPLm_l()cHi57tuT|RRZ>QP>*4v{{E|L@t z+P5_#Z&rVK@Hbqd1`Wv9aGbeVZo_q*em$r(8twT6wlDR%oNpY^G{+RjG&CNJol6JbyT8aRyQKfF5yGm?P;oGut;bV5UUsm03r?7uIz3>x~#3uWm zV>+U{81Sa_@&?}aXH%*3;v7^Ht>G84=_pmsXvVc?sruZIw?&KFDl6prZ9KorLE9Xa z{%=o%nwAXF*XE*_MC$M5r>Uq0l{~$N4um=}L@kO%2BZ4ECh)CXy?Pl^Gy@w@nf;2M z%|oCrBzU@2c6Mt?~JoXWMFb<%uW%T;Q-Io&2=S}hWkEQrqhi|8~ zHKMa1o0k`9Jk#m5?5yXHu+*Z{t{!2q8_rN`T!Ls;wk<>M zdRuCgXKc$zm29TJ^}qPtx{{R!Zggk1t~ppK{KztLg|$ntD+iWE8IOsg-Cc4TdCt ze`24eFnHmt-G)y+&$nP;Z}VI_dIHs8r>ILC^7WFbM#sX@%zY#M!EqbLoO=lC z@Vz8#vdfA-3FZyd4?*-32K=u^H=7g%Yflyz-`2{=dEH_83YZ-*5Ztx#&ab`)nZ%TyrfJz zy{{|b!eI9B`>V8DDqC7b`5F`IGOpqA?10PZ?x(Gl)x`90-x^VkxN?yTdEz>?xy?ps+^C@$}s62LD zv2{PBKDdP?p?8jTv-#t`&uT1W2#n1NnCR_Y#VH(v*U#~B#QaGzS^RltjUJxeLzdD2 z6~8E++%62cbLDp*SbSU5z=47?VYr`8^CiPr)@bO}#s>kJGH%Ow4OS)s9fp#d1ap}3 z;oz#iUFOJj_7G?MTJYCUs=QZG`4Lv^F#-pWa`Wm|G4De{Kw)&5{)_EMp0ZKPTbs3g zbi-EA`20n0U_#k!Fz$PS-ozVQ6T943(wr-YWP9F%R9`E6cQB+oeB7;gy1iSA#TUKC z1`d6i%i*z3E-zGNEL}A8HRI$OLn^JD_h&ZLaV2VY**LOS0UZJk*0ZO`f1UNrrjhHjAT5(ll8mH{|MhH|+T%>*=V2L(Ig5l`xR|O zsMt1>^)xgGwdC6=e!k}C0`iK4im!u`)dInd=BRFNyJ;@LdUGTCaYjiz5*9S_LuO%< z*hwBVpZE2NBdEU)@kt%w<9)v_7ZZLUqzkCQCa~GXM=Q0tiD|C{NpBaMuydU$h~<-K zfql_R8fXP)otrB|vu!R1H8RVFOJW^7?~+w2G+fRZOBM;Q&eOx7%Jt~RdYosp%dfm@ ze~(Mk9YBZ9&A*~fEvP&+<#^OujtLS9X_D9ShtcOn%o_;*ja1$@rMbeCt)zcy2&P+(Vr^ks2=-|o&VtVWVJhM&e_tAu!aJ?Qhn-N@Yfsh;l5XFXz8hbm}PVRyVcB1E$RG%y(ZPxi$_!ixldoWsyLe>R{nz;q%jdx@I)c~|up_rT&a&u?+63gRIOvmFi2>olemj7k5p zEw973SzZv!FI@u<30_w6Dh=&+bjkZMId=;;21PUzJ|CDf5FViAcw1LFzfVjlPD@jB z13le;zm-Rv8z&l;dqfhF;F_~59&qAwo#JSYj#cR0+NnW6AYZtK5;#^R(tiKGQENu- zj3JyIWV5>~c9=;ct;b3EdExyb?=fog3yzWycZFMyA9=*aE@f4cm_ee47$`h@lwxY% zA@awyd50+h+4Z3{gKQTKv*#nWeXdCe-5*0O&e4@I9TO7nN5*WHlrWR_(TBRVmfxN~g4yW3t#|DJ zVagVm2l=IJ?)w&?5vqTiY#975q+&3BV+kV@OJHceD$7UNE9v;)@H|_BI`9{%!gSN; zTtAdq#Xst4ezw`QGw&06p8*y#!g^1E3#2kN?%Vkpb~-ZA^=Wdl1WP1(8+)nkg<{{S zTVvX0>I8vR$;++gKVIWD6T#-UbOdz=hDZ=)z&DrauI#Q*7cS@m0^^zFZbk&k*k&Z*m? zjZFcAuErnC!uD_1n_&t$-zh8^&yKW-T;l3gE&KIS-gB)GEZzwDn_;cAU9nY|k^QCl z>djv!%=qd36#F-Uxy{U`FZyw4?RG&!utY7R$w{3Ef!;{sa1U8LsIq0xM|HBIzhRna z`-g&0zL&#arW6PhK_I}33<)6HR4#tlpZ1!%_so<|MU^BU~>Bk<5 zh67&46rr~iu1geC(E^9&VR+r7`)e5u)|xGjFJyLP5YNzh1(P;zv%ENHWHS zKUZ#x)qzwBL6-#I82%|7Tw41KfLX+sc$b4>tUoRLu$?k!f&N-+e`$9NR+j9J$h=Yt zp~*{sNLXn%8Gct9xA01SZi>@I(DRky5+WNBW+tnuEk3tK978bjGA93z5|->ylvo|V zzOp?gX3Pb_d|$dIXnmZdE7Jh2bcWXOM~Ys}-RfkacxrJ0a6^x%%6QGOjVQ~V`1=LN zHaRtnWbzljp#@Qt@k$f<%bQZ~CLKi~etRp%4xuHsdx4XxlUqFG`UxH0$3%sV_w`e^ zdB}nDtXO3BV=lUpPJSP@B_5P5=u0&{W0g)J9>h;uZyV&mqkW?+X$^Ro3$tHL5>o%u4e%p_| zMY6<(e@n{vf+|;M#zv?2`FkS6(Pntb4D@kA(}PU9AUi*)rBJ>hFg1M{FKG zGBP*4`>_zLkx2U~j`Se3x4fWg-NW3F)Ld&nEBI7MP}G!62cJN(#rBt{)_QT0?7b4z zXF#Lcer2X@Y=IcNV|{$90_mn9hJ?M(E44@)jn1>x+!kqPw1R(y5tlls z`kQMt-*S+iep2-aXLbaKJVf_cmfI*z{CSwp6@rcJC81hFT-ac%&Me(2;|`ZA$GHgJ zV(G-Gy-({yPNgGmiL>0UO1Lc}p{+fJFe;bm6)Mw{)S)O+S?Zd4*vc+D(K<03iFqZ)WA)vFFmTam+Di>RGC z{9Rtv4f<_fw!nHI*m|sgb@!`s-|o%hBUvl4!L!HfhY-yb*?2dTd3E=VHy?YrC(JPr zVCL#!{$i8+yO&ES4jrI0Iz7|v&g`}Ey!4Skr|}3h5T%UhA?*e2xh$w)T@5LxlhIp^Q$Q&N8 z+8geAFJRrjL|n2d#YuEe#t`^zc4%(zAJ=N#7rQiXp*cT`){gyjMJfLk;Nl$o9?vni zW7a67i^`Robt=QmwQGUX5`HveM)GM{=VT1)G!Ru#dFIBlBM|%YC() z4T(m^ZGT-H^5_xmX3h37{i^FEvLMuz@V@)+a#{G6{N|5585OtF;|XNGk15p;rOs>P zTysZDt5uGo-SE}idVcNXsL+`*wA|$Lm{FVloWcjm*!mv32-s*UPs!huKW^re^}HF5 z&PmMx)#SQcorvku58uXBoatQNc1NoRRCRxNJJu$5vpHGUF>f2rS9;`CcE535@xAW( zt8b4lq4N?RxyR`*hv>WABBJBPj~fs6!kQlMZGWxzE`DFwm=-nJmdqb$(rbR)pun|@ ziXW}1Q!?Aml;*h8!u{v1a;ow7=kk98@lDg~0VON9Kd=)I)jd@5{dGnA#cXLrhyvsF zh82SVj9$EdoS6&guvZzzaBxrI^E$0C3|Byg&8K^2Md~HkBV25ZHBo;`v`Ar=D7}om zVKsE_-nuXU>LZ;3H%RZ>cix4f%Do|%5st;ocZ_>Pt)_cei7{DH~JJP$8e7E zf~H#0N-vj3y7UUMN?}c>JL?uQP3CPBkOGbx(No824 zqDK}meC=`N`Ne zlLewh9<4)A9sOoJ6{m_>2~admgvz-O_tS4lNds~uqlKq#Y1A2wB7WA)qoz1Oac^m@ z%qK>i`S_1*h#&I2j%TrcI2Bm6^&O@6zII4i`d}C~OR{jd2d^xh5yYJ9&wU*`eFs%( zc1ymNeFv6em?7wtVO76&SHpb?DB`64;-%tmrj(0z%&n)C&FmQzx(-|bPloTnk3>zs zdlei>=m=oW0jv^obeD1fBA%^ypS+Glc;cg>r#o;*Ts`@9tJ*WwQ!GERMqSWcyKm<< zK{L2B-D-+Ekp`mG@!VbLTr`Vq@a3twETu z=OBFptjo>DAQ`#~KYhQWkz@$q!vP|^O3lL^!?M&QZX;ay<>+1U{z#pt<^dFC2V+?v_npR!z^wia(JVXDO}SJ_dL0p*lF)a8^SPkUA$Ipn zh&j;ilSZ6e`2b8lNc7Ly9w|1!_Y~RpN+wMYMjxDAw;FPvZ&W)LQ;mz$CjB` zk>`W-g*|PP)wMbjV5y|a6G5?#tEn6Wo{YjIKva=c)+QxCLUtGT7~PIGEFOqGf*XR= zS+DjZX?2?O<_ktVk30v2!QM`@D&&Zp+^yxWtLaLGX2w%N27<;DR;?dCrhT@QLsh zu_G*cA5xHD%+ckAju8uE&S_%(N+b{K>CDa4!ixn0M9K0VuP9emuTfc2SU*?sMe0 zBzYoo&{s=~UkDu5lZz`AaDU1ai$30x#UiB<2lEg3h0xTT>ue!DII{%3Y#*-kH}fRy z-6@MURBH|_1z0A)+QC9lJtMuvm4zgUP6O31d**kn^lahyhbHuW_;1k~Zyd)d#Mhb6 zR+w4)MGmZ80C)gCi5&tI5eH;$I77??yDnEFfM1!~n|G6hX+C!N&Y0mzmaeHaMWlCb zvQEqv=Aj+4lvAXbz$76LN{5_?twtV4MF!!YHGm?K3T#A{6nih#pDUhEF3`#(pHB6G#Q^ugji7Fc%+NPS>Xfd}Op2i-)%u^sW||wa|>p*T?d)}uTGRbjZ8Uswog&K5Of27If z3+v0@H)<;qR4$N`~WZXv%l2iB$>aeygb1mWtkD7$> z6-Z@@B7N+Mi0Ft+4ZHnK6xvA`qvPo`^OK<|9T@bV`YB!naD0LCI=J;I)scOrQ-#qm zpZY`t&8V+1m`ikY*zJz42eMkQ2Ym#wQLpL6-xIK64Z~pV2s*#=@y7$z4ZH{NK}D~z z=lWdNKPacQiv)E2ixA2JA{^!5Dw8u{1Qpy!q;f&sb=0mwzeOC3>P+zxf%raNF*Hcn zLLk-&x)#XwuLlqIT&=AQk!-vsBcHR$ZsfRFSSPJs1)IWE6eiUGr_Z5=#fxB5{moh_ zsQ+Kj7jD!f5Xz%%0y-oo-;qZ9eaY}xIt;33Mi7@7+Kw|B2t@)03%Xd)J11m(vwkA2 zt@+^X6mD{jHOE8$c=YWj0Fu*QhL;WW@&Bin4{elhZ?>g!APID$>n7W2lc zkVf1qrq4i#?Vta=V*Z<&)&uahYIwHH7M7wNLo%bc2lJ9Kwn7>}1tnlp&%jzxe$yQr zx`p>q(Wv6@?Fk6m<|8jC83H!-eTk;5HNYIaA%MOGC$%W7$=38iu;IJzTkV2ZGf$VmKk1KtjevszgzZeJ%^cpf^o|KI14yk+(Hbwmb4!pCXQ!&Wg@H+CM^&KJ66+lwu zA(A`Ja2|*>wwMGjjmJfV^h7hi7}>^8-o~+XNUg9`u?RwrtEfNbF^4 zCG~BKEbN{B83j}qNwywHLi?LLyeHZR)Fen4a3ELcZP$amV>e_+9*0JZeG1QD?^^&N za@EYYqOae=;)KkhNv+K!>+1^S0;0#WzBZLi`99#1g3$Nv&5E2Z!I<#E9hA8gZzpR0 zsSnS{XNeG--HKM=9T!goVAOxzkQ3Hf=lw`1*^2{iQ2u zRg06~lu(PcwgWeuknowNdcA>-lk@IV{O99%eG-sd&3>dwp%2(JF-f>3iF@$;g^xl`$#k@GBd;U}V4`CZ zWLz(h0zs_1SV?E2?li?+XUdfcn;yyTs_tY31Y8n|DG3QEZA94xaP(v0vbObVaAchamFO3%1 zhqzD8YGkXOe7$2X{@A7WnD4`X0`h}7XO1H-YAcJj;45~8qp(WJRgth;Vr~F9J8u6& zuX})1$m{EI39{F&YoDA@u3ze#vjFAYB2GKsD=~vj|KO=3c48Y5QKktc9KfaQ3*%W~ zPX?G;JUV4_GWQ86K)+zOoK+!QNYeP_p)3`QsUhjgfA$Khsi~%j)Gc!k4DXK!S$Xx_ zO{3BhP=7R-XW9vt@|3Ut*WDq4Q|(SV`XpO!f_T@Fd0>%)EmXf!u<3fDuVg zPUdzE5r^uqcl6=sRSxLK{9m$ESs!-6+MQJ7LLaf_CQWcjvo`pdB{+K z0!pR;U@uh#u<7qa;hN!AcY&nZ(zSLG*0Vpx^6NE9t6vfC+2AG!oKsIOi_nf20{aD^ zHxfwGvOr^23%qJ=+@YB}p>24(zWxSob&2@&dtg0cH$10BVV-cmJ7Z{f006P4GOzMP zDfNScKw51cTDu4um4o+pI5JwiZ=VC^>yQF+yUpplG8ZND8VTqov$Quq#vIL#C98T6 z7UKSrckGuHUXjRvNNT%6`wQRW*juMsO@V1+6NS;bRefR*Qxx;71u$Y$>Ux?!ptsxv zkgPNNX1_s;5b^d_lL>$@L(cD~Ad=YT92$*Z5iJj)y(^l9QoGjjJ+tY}LLeO<#A_%z z*>B^JX#D}G)W$!X5X~32ogWw8fmeeIab*;cvAo34Si7g|UAE>ywMFb1rv>%r0)eX@9g@sSgk*jN z`vibDv^ABO3Etue}U|-z*`cLT#!kc9<3XA>Y?jh)Ln)X6MXr?Lh|bph)w$21mi=5AEz=D zvJdBfy_T10iZ(7-_y+rN**s-lic~*}ZKJ=yW2{LUI;eXVaL3n+-8Xzci4as*W&|KC z?VP2vn5RWdkk30Y`-$>CoD30GhDmY6m8G~Z9ZKiqJt`RbIDG(2;T*>86ExjUv-&tu z%Pc6!-~Z%s+CP1dc>h5{%(SFUMyE~U1pl!^BrV5xLSk|`R!LBgBO`ke(`~jed_iZk zLnP~L(Qnal3Io;e7-52ciq|83fzHCmN#rEY1d+LF152*&Fsm+!*=*!vM+52i1n2gx z2a5sIkdd$hIO0L^!2GF&0+`D*#o?ImtD4b*inY7|$!mjopKOq2y3SnPxF9a!k~m%b zdq_Z8(NpQ>jVuuFYktu) zMU@Tl-1KpBl&RloO-A { if (error) console.log('cant query first block') if (block && block.hash !== this.mainNetGenesisHash) name = 'Custom' - callback(err, { id, name }) + callback(err, { id, name, lastBlock: this.lastBlock, currentFork: this.currentFork }) }) } else { - callback(err, { id, name }) + callback(err, { id, name, lastBlock: this.lastBlock, currentFork: this.currentFork }) } }) } @@ -176,10 +177,11 @@ export class ExecutionContext { const block = await web3.eth.getBlock('latest') // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506 this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault + this.lastBlock = block try { this.currentFork = execution.forkAt(await web3.eth.net.getId(), block.number) } catch (e) { - this.currentFork = 'berlin' + this.currentFork = 'london' console.log(`unable to detect fork, defaulting to ${this.currentFork}..`) console.error(e) } diff --git a/libs/remix-analyzer/package.json b/libs/remix-analyzer/package.json index 0cf6c4702e..c9b875ec1c 100644 --- a/libs/remix-analyzer/package.json +++ b/libs/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-analyzer", - "version": "0.5.12", + "version": "0.5.14", "description": "Tool to perform static analysis on Solidity smart contracts", "main": "index.js", "types": ".index.d.ts", @@ -19,14 +19,14 @@ } ], "dependencies": { - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", "@remix-project/remix-astwalker": "^0.0.26", - "@remix-project/remix-lib": "^0.5.3", + "@remix-project/remix-lib": "^0.5.5", "async": "^2.6.2", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "string-similarity": "^4.0.4", "web3": "1.2.4" }, @@ -51,5 +51,5 @@ "typescript": "^3.7.5" }, "typings": "index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-astwalker/package.json b/libs/remix-astwalker/package.json index 5642455132..6054263f6f 100644 --- a/libs/remix-astwalker/package.json +++ b/libs/remix-astwalker/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-astwalker", - "version": "0.0.33", + "version": "0.0.35", "description": "Tool to walk through Solidity AST", "main": "index.js", "scripts": { @@ -34,14 +34,14 @@ ] }, "dependencies": { - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", - "@remix-project/remix-lib": "^0.5.3", + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", + "@remix-project/remix-lib": "^0.5.5", "@types/tape": "^4.2.33", "async": "^2.6.2", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "nyc": "^13.3.0", "string-similarity": "^4.0.4", "tape": "^4.10.1", @@ -53,5 +53,5 @@ "tap-spec": "^5.0.0" }, "typings": "index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts index ea4eae6958..edb512a7ed 100644 --- a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts +++ b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts @@ -21,9 +21,14 @@ export class CompilerImports extends Plugin { } async setToken () { - const protocol = typeof window !== 'undefined' && window.location.protocol - const token = await this.call('settings', 'get', 'settings/gist-access-token') - this.urlResolver.setGistToken(token, protocol) + try { + const protocol = typeof window !== 'undefined' && window.location.protocol + const token = await this.call('settings', 'get', 'settings/gist-access-token') + + this.urlResolver.setGistToken(token, protocol) + } catch (error) { + console.log(error) + } } isRelativeImport (url) { diff --git a/libs/remix-debug/package.json b/libs/remix-debug/package.json index 5a8a8bc22b..6691d37d1d 100644 --- a/libs/remix-debug/package.json +++ b/libs/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-debug", - "version": "0.5.3", + "version": "0.5.5", "description": "Tool to debug Ethereum transactions", "contributors": [ { @@ -18,17 +18,17 @@ ], "main": "src/index.js", "dependencies": { - "@ethereumjs/block": "^3.3.0", + "@ethereumjs/block": "^3.4.0", "@ethereumjs/common": "^2.2.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", "@remix-project/remix-astwalker": "^0.0.26", - "@remix-project/remix-lib": "^0.5.3", + "@remix-project/remix-lib": "^0.5.5", "async": "^2.6.2", "commander": "^2.19.0", "deep-equal": "^1.0.1", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "string-similarity": "^4.0.4", "web3": "^1.2.4" }, @@ -61,5 +61,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "typings": "src/index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-debug/src/code/codeUtils.ts b/libs/remix-debug/src/code/codeUtils.ts index b44dd2be61..da777d4b71 100644 --- a/libs/remix-debug/src/code/codeUtils.ts +++ b/libs/remix-debug/src/code/codeUtils.ts @@ -46,7 +46,7 @@ type Opcode = { * information about the opcode. */ export function parseCode (raw) { - const common = new Common({ chain: 'mainnet', hardfork: 'berlin' }) + const common = new Common({ chain: 'mainnet', hardfork: 'london' }) const opcodes = getOpcodesForHF(common) const code = [] diff --git a/libs/remix-debug/src/trace/traceManager.ts b/libs/remix-debug/src/trace/traceManager.ts index f4bf488392..49ba500889 100644 --- a/libs/remix-debug/src/trace/traceManager.ts +++ b/libs/remix-debug/src/trace/traceManager.ts @@ -40,7 +40,7 @@ export class TraceManager { const networkId = await this.web3.eth.net.getId() this.fork = execution.forkAt(networkId, tx.blockNumber) } catch (e) { - this.fork = 'berlin' + this.fork = 'london' console.log(`unable to detect fork, defaulting to ${this.fork}..`) console.error(e) } diff --git a/libs/remix-debug/test/decoder/vmCall.ts b/libs/remix-debug/test/decoder/vmCall.ts index 89417ac698..a0d2040e7c 100644 --- a/libs/remix-debug/test/decoder/vmCall.ts +++ b/libs/remix-debug/test/decoder/vmCall.ts @@ -11,7 +11,7 @@ export function sendTx (vm, from, to, value, data, cb?) { return new Promise ((resolve, reject) => { var tx = new Tx({ nonce: new BN(from.nonce++), - gasPrice: new BN(1), + // gasPrice: new BN(1), gasLimit: new BN(3000000, 10), to: to, value: new BN(value, 10), diff --git a/libs/remix-debug/test/vmCall.ts b/libs/remix-debug/test/vmCall.ts index b3cd6bccf1..a640c4d1b8 100644 --- a/libs/remix-debug/test/vmCall.ts +++ b/libs/remix-debug/test/vmCall.ts @@ -9,7 +9,7 @@ var remixLib = require('@remix-project/remix-lib') function sendTx (vm, from, to, value, data, cb) { var tx = new Tx({ nonce: new BN(from.nonce++), - gasPrice: new BN(1), + // gasPrice: new BN(1), gasLimit: new BN(3000000, 10), to: to, value: new BN(value, 10), diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index 61a31e7d3f..59a6770087 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-lib", - "version": "0.5.3", + "version": "0.5.5", "description": "Library to various Remix tools", "contributors": [ { @@ -14,9 +14,9 @@ ], "main": "src/index.js", "dependencies": { - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", "async": "^2.1.2", "ethereumjs-util": "^7.0.10", "ethers": "^4.0.40", @@ -53,5 +53,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "typings": "src/index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-lib/src/execution/forkAt.ts b/libs/remix-lib/src/execution/forkAt.ts index 5c4316f868..c5f1a1e981 100644 --- a/libs/remix-lib/src/execution/forkAt.ts +++ b/libs/remix-lib/src/execution/forkAt.ts @@ -17,7 +17,7 @@ export function forkAt (networkId, blockNumber) { } return currentForkName } - return 'berlin' + return 'london' } // see https://github.com/ethereum/go-ethereum/blob/master/params/config.go @@ -46,6 +46,10 @@ const forks = { { number: 12244000, name: 'berlin' + }, + { + number: 12965000, + name: 'london' } ], 3: [ diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts index ce079856fc..ac6e629b89 100644 --- a/libs/remix-lib/src/execution/txRunnerVM.ts +++ b/libs/remix-lib/src/execution/txRunnerVM.ts @@ -72,7 +72,7 @@ export class TxRunnerVM { } } - const EIP1559 = this.commonContext.hardfork() !== 'berlin' + const EIP1559 = this.commonContext.hardfork() !== 'berlin' // berlin is the only pre eip1559 fork that we handle. let tx if (!EIP1559) { tx = Transaction.fromTxData({ diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts index b36aaffdcc..64500d01a3 100644 --- a/libs/remix-lib/src/execution/txRunnerWeb3.ts +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -15,8 +15,18 @@ export class TxRunnerWeb3 { this._api = api } - _executeTx (tx, gasPrice, api, promptCb, callback) { - if (gasPrice) tx.gasPrice = this.getWeb3().utils.toHex(gasPrice) + _executeTx (tx, txFee, api, promptCb, callback) { + if (txFee) { + if (txFee.baseFeePerGas) { + tx.maxPriorityFee = this.getWeb3().utils.toHex(this.getWeb3().utils.toWei(txFee.maxPriorityFee, 'gwei')) + tx.maxFee = this.getWeb3().utils.toHex(this.getWeb3().utils.toWei(txFee.maxFee, 'gwei')) + tx.type = 2 + } else { + tx.gasPrice = this.getWeb3().utils.toHex(this.getWeb3().utils.toWei(txFee.gasPrice, 'gwei')) + tx.type = 1 + } + } + if (api.personalMode()) { promptCb( (value) => { @@ -100,8 +110,8 @@ export class TxRunnerWeb3 { return } - confirmCb(network, tx, tx['gas'], (gasPrice) => { - return this._executeTx(tx, gasPrice, this._api, promptCb, callback) + confirmCb(network, tx, tx['gas'], (txFee) => { + return this._executeTx(tx, txFee, this._api, promptCb, callback) }, (error) => { callback(error) }) diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index d0ab857b8c..5a99b8dd63 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-simulator", - "version": "0.2.3", + "version": "0.2.5", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -14,11 +14,11 @@ ], "main": "src/index.js", "dependencies": { - "@ethereumjs/block": "^3.3.0", + "@ethereumjs/block": "^3.4.0", "@ethereumjs/common": "^2.2.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", - "@remix-project/remix-lib": "^0.5.3", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", + "@remix-project/remix-lib": "^0.5.5", "ansi-gray": "^0.1.1", "async": "^3.1.0", "body-parser": "^1.18.2", @@ -26,7 +26,7 @@ "commander": "^2.19.0", "cors": "^2.8.5", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "express": "^4.16.3", "express-ws": "^4.0.0", "merge": "^1.2.0", @@ -66,5 +66,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "typings": "src/index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index 363e9ab50e..b9cb6a4151 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -99,7 +99,7 @@ export class VMContext { constructor (fork?) { this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault - this.currentFork = fork || 'berlin' + this.currentFork = fork || 'london' this.currentVm = this.createVm(this.currentFork) this.blocks = {} this.latestBlockNumber = 0 diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index e338edf16c..a3974fd364 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-solidity", - "version": "0.4.3", + "version": "0.4.5", "description": "Tool to load and run Solidity compiler", "main": "index.js", "types": "./index.d.ts", @@ -15,14 +15,14 @@ } ], "dependencies": { - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", - "@remix-project/remix-lib": "^0.5.3", + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", + "@remix-project/remix-lib": "^0.5.5", "async": "^2.6.2", "eslint-scope": "^5.0.0", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "solc": "^0.7.4", "string-similarity": "^4.0.4", "web3": "1.2.4", @@ -59,5 +59,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "typings": "index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index f8c5c5184b..b07486c5ad 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-tests", - "version": "0.2.3", + "version": "0.2.5", "description": "Tool to test Solidity smart contracts", "main": "src/index.js", "types": "./src/index.d.ts", @@ -35,13 +35,13 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-tests#readme", "dependencies": { - "@ethereumjs/block": "^3.3.0", + "@ethereumjs/block": "^3.4.0", "@ethereumjs/common": "^2.2.0", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", - "@remix-project/remix-lib": "^0.5.3", - "@remix-project/remix-simulator": "^0.2.3", - "@remix-project/remix-solidity": "^0.4.3", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", + "@remix-project/remix-lib": "^0.5.5", + "@remix-project/remix-simulator": "^0.2.5", + "@remix-project/remix-solidity": "^0.4.5", "ansi-gray": "^0.1.1", "async": "^2.6.0", "axios": ">=0.21.1", @@ -50,7 +50,7 @@ "colors": "^1.1.2", "commander": "^2.13.0", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "express-ws": "^4.0.0", "merge": "^1.2.0", "signale": "^1.4.0", @@ -77,5 +77,5 @@ "typescript": "^3.3.1" }, "typings": "src/index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx b/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx index cea2b0d7a1..a892831d99 100644 --- a/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx +++ b/libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx @@ -40,6 +40,7 @@ export const CopyToClipboard = (props: ICopyToClipboard) => { } return ( + // eslint-disable-next-line jsx-a11y/anchor-is-valid diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx index a8a31fd6c8..3d85829294 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx @@ -4,6 +4,13 @@ import { action, FileExplorerContextMenuProps } from './types' import './css/file-explorer-context-menu.css' import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel' +declare global { + interface Window { + _paq: any + } +} +const _paq = window._paq = window._paq || [] //eslint-disable-line + export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => { const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, pushChangesToGist, publishFileToGist, publishFolderToGist, copy, paste, runScript, emit, pageX, pageY, path, type, focus, ...otherProps } = props const contextMenuRef = useRef(null) @@ -76,15 +83,19 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => deletePath(getPath()) break case 'Push changes to gist': + _paq.push(['trackEvent', 'fileExplorer', 'pushToChangesoGist']) pushChangesToGist(path, type) break case 'Publish folder to gist': + _paq.push(['trackEvent', 'fileExplorer', 'publishFolderToGist']) publishFolderToGist(path, type) break case 'Publish file to gist': + _paq.push(['trackEvent', 'fileExplorer', 'publishFileToGist']) publishFileToGist(path, type) break case 'Run': + _paq.push(['trackEvent', 'fileExplorer', 'runScript']) runScript(path) break case 'Copy': @@ -97,6 +108,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => deletePath(getPath()) break default: + _paq.push(['trackEvent', 'fileExplorer', 'customAction', item.name]) emit && emit({ ...item, path: [path] } as customAction) break } diff --git a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx index ec016068e9..6a764a85e2 100644 --- a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx +++ b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx @@ -16,6 +16,24 @@ export const ModalDialog = (props: ModalDialogProps) => { modal.current.focus() }, [props.hide]) + useEffect(() => { + function handleBlur (e) { + if (!e.currentTarget.contains(e.relatedTarget)) { + e.stopPropagation() + if (document.activeElement !== this) { + handleHide() + } + } + } + if (modal.current) { + modal.current.addEventListener('blur', handleBlur) + + return () => { + modal.current.removeEventListener('blur', handleBlur) + } + } + }, [modal.current]) + const modalKeyEvent = (keyCode) => { if (keyCode === 27) { // Esc if (props.cancelFn) props.cancelFn() @@ -40,13 +58,6 @@ export const ModalDialog = (props: ModalDialogProps) => { handleHide() } - const handleBlur = (e) => { - if (!e.currentTarget.contains(e.relatedTarget)) { - e.stopPropagation() - handleHide() - } - } - return (
{ >
(dispatch: React.Disp }) compileTabLogic.compiler.event.register('loadingCompiler', () => { - dispatch(setCompilerMode('compilationDuration')) + dispatch(setCompilerMode('loadingCompiler')) }) compileTabLogic.compiler.event.register('compilerLoaded', () => { diff --git a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx index 0d40bd011c..84059151ca 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx @@ -5,9 +5,18 @@ import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '@remix-project/remix-solidity' import { compilerReducer, compilerInitialState } from './reducers/compiler' import { resetEditorMode, listenToEvents } from './actions/compiler' +import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line import './css/style.css' +declare global { + interface Window { + _paq: any + } +} + +const _paq = window._paq = window._paq || [] //eslint-disable-line + export const CompilerContainer = (props: CompilerContainerProps) => { const { editor, config, queryParams, compileTabLogic, tooltip, modal, compiledFileName, setHardHatCompilation, updateCurrentVersion, isHardHatProject, configurationSettings } = props // eslint-disable-line const [state, setState] = useState({ @@ -27,8 +36,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => { language: '', evmVersion: '' }) + const [disableCompileButton, setDisableCompileButton] = useState(false) const compileIcon = useRef(null) - const warningIcon = useRef(null) const promptMessageInput = useRef(null) const [hhCompilation, sethhCompilation] = useState(false) const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState) @@ -75,6 +84,9 @@ export const CompilerContainer = (props: CompilerContainerProps) => { }, [compileTabLogic]) useEffect(() => { + const isDisabled = !compiledFileName || (compiledFileName && !isSolFileSelected(compiledFileName)) + + setDisableCompileButton(isDisabled) setState(prevState => { return { ...prevState, compiledFileName } }) @@ -235,14 +247,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => { } const compilationDuration = (speed: number) => { - if (!warningIcon.current) return if (speed > 1000) { - const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.` - - warningIcon.current.setAttribute('title', msg) - warningIcon.current.style.visibility = 'visible' - } else { - warningIcon.current.style.visibility = 'hidden' + console.log(`Last compilation took ${speed}ms. We suggest to turn off autocompilation.`) } } @@ -256,8 +262,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => { if (!compileIcon.current) return compileIcon.current.setAttribute('title', 'compiler is loading, please wait a few moments.') compileIcon.current.classList.add('remixui_spinningIcon') - warningIcon.current.style.visibility = 'hidden' _updateLanguageSelector() + setDisableCompileButton(true) } const compilerLoaded = () => { @@ -265,6 +271,9 @@ export const CompilerContainer = (props: CompilerContainerProps) => { compileIcon.current.setAttribute('title', '') compileIcon.current.classList.remove('remixui_spinningIcon') if (state.autoCompile) compile() + const isDisabled = !compiledFileName || (compiledFileName && !isSolFileSelected(compiledFileName)) + + setDisableCompileButton(isDisabled) } const compilationFinished = () => { @@ -272,6 +281,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => { compileIcon.current.setAttribute('title', 'idle') compileIcon.current.classList.remove('remixui_spinningIcon') compileIcon.current.classList.remove('remixui_bouncingIcon') + _paq.push(['trackEvent', 'compiler', 'compiled_with_version', _retrieveVersion()]) } const scheduleCompilation = () => { @@ -292,7 +302,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => { if (!isSolFileSelected()) return _setCompilerVersionFromPragma(currentFile) - compileTabLogic.runCompiler() + compileTabLogic.runCompiler(hhCompilation) } const _retrieveVersion = (version?) => { @@ -440,6 +450,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => { const handleNightliesChange = (e) => { const checked = e.target.checked + if (!checked) handleLoadVersion(state.defaultVersion) config.set('includeNightlies', checked) setState(prevState => { return { ...prevState, includeNightlies: checked } @@ -522,6 +533,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => { + + + Learn how to use Hardhat Compilation + + }> + + +
} - diff --git a/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx b/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx index 0d2d6bf486..e86689f94e 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx @@ -162,17 +162,25 @@ export const ContractSelection = (props: ContractSelectionProps) => { } const contractProperties = contractsDetails[selectedContract] || {} const log =
- { - Object.keys(contractProperties).map((propertyName, index) => { - const copyDetails = - const questionMark = - - return (
-
{ propertyName } { copyDetails } { questionMark }
- { insertValue(contractProperties, propertyName) } -
) - }) - } + + { + Object.keys(contractProperties).map((propertyName, index) => { + const copyDetails = + const questionMark = + + return ( +
+ { propertyName } { copyDetails } { questionMark }
+ }> + { insertValue(contractProperties, propertyName) } + +
+ ) + }) + } +
modal(selectedContract, log, 'Close', null) diff --git a/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-abstract.ts b/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-abstract.ts deleted file mode 100644 index f0c4fc3ad1..0000000000 --- a/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-abstract.ts +++ /dev/null @@ -1,51 +0,0 @@ -'use strict' -import * as remixLib from '@remix-project/remix-lib' - -const txHelper = remixLib.execution.txHelper - -export class CompilerAbstract { - public languageversion: string - public data: Record - public source: Record - - constructor (languageversion, data, source) { - this.languageversion = languageversion - this.data = data - this.source = source // source code - } - - getContracts () { - return this.data.contracts - } - - getContract (name) { - return txHelper.getContract(name, this.data.contracts) - } - - visitContracts (calllback) { - return txHelper.visitContracts(this.data.contracts, calllback) - } - - getData () { - return this.data - } - - getAsts () { - return this.data.sources // ast - } - - getSourceName (fileIndex) { - if (this.data && this.data.sources) { - return Object.keys(this.data.sources)[fileIndex] - } else if (Object.keys(this.source.sources).length === 1) { - // if we don't have ast, we return the only one filename present. - const sourcesArray = Object.keys(this.source.sources) - return sourcesArray[0] - } - return null - } - - getSourceCode () { - return this.source - } -} diff --git a/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-helpers.ts b/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-helpers.ts deleted file mode 100644 index 64c56bd7a5..0000000000 --- a/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-helpers.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' -import { canUseWorker, urlFromVersion } from './compiler-utils' -import { Compiler } from '@remix-project/remix-solidity' -import { CompilerAbstract } from './compiler-abstract' - -export const compile = async (compilationTargets, settings, contentResolverCallback) => { - return new Promise((resolve) => { - const compiler = new Compiler(contentResolverCallback) - compiler.set('evmVersion', settings.evmVersion) - compiler.set('optimize', settings.optimize) - compiler.set('language', settings.language) - compiler.set('runs', settings.runs) - compiler.loadVersion(canUseWorker(settings.version), urlFromVersion(settings.version)) - compiler.event.register('compilationFinished', (success, compilationData, source) => { - resolve(new CompilerAbstract(settings.version, compilationData, source)) - }) - compiler.event.register('compilerLoaded', () => compiler.compile(compilationTargets, '')) - }) -} diff --git a/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-utils.ts b/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-utils.ts deleted file mode 100644 index fe26765ac1..0000000000 --- a/libs/remix-ui/solidity-compiler/src/lib/logic/compiler-utils.ts +++ /dev/null @@ -1,46 +0,0 @@ -const semver = require('semver') -const minixhr = require('minixhr') -/* global Worker */ - -export const baseURLBin = 'https://binaries.soliditylang.org/bin' -export const baseURLWasm = 'https://binaries.soliditylang.org/wasm' - -export const pathToURL = {} - -/** - * Retrieves the URL of the given compiler version - * @param version is the version of compiler with or without 'soljson-v' prefix and .js postfix - */ -export function urlFromVersion (version) { - if (!version.startsWith('soljson-v')) version = 'soljson-v' + version - if (!version.endsWith('.js')) version = version + '.js' - return `${pathToURL[version]}/${version}` -} - -/** - * Checks if the worker can be used to load a compiler. - * checks a compiler whitelist, browser support and OS. - */ -export function canUseWorker (selectedVersion) { - const version = semver.coerce(selectedVersion) - const isNightly = selectedVersion.includes('nightly') - return browserSupportWorker() && ( - // All compiler versions (including nightlies) after 0.6.3 are wasm compiled - semver.gt(version, '0.6.3') || - // Only releases are wasm compiled starting with 0.3.6 - (semver.gte(version, '0.3.6') && !isNightly) - ) -} - -function browserSupportWorker () { - return document.location.protocol !== 'file:' && Worker !== undefined -} - -// returns a promise for minixhr -export function promisedMiniXhr (url) { - return new Promise((resolve) => { - minixhr(url, (json, event) => { - resolve({ json, event }) - }) - }) -} diff --git a/libs/remix-ui/solidity-compiler/src/lib/logic/index.ts b/libs/remix-ui/solidity-compiler/src/lib/logic/index.ts index b67d648896..e2c8f6d006 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/logic/index.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/logic/index.ts @@ -1,5 +1,2 @@ export * from './compileTabLogic' -export * from './compiler-abstract' -export * from './compiler-helpers' -export * from './compiler-utils' export * from './contract-parser' diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 4434db6c26..e21fd83f97 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -7,6 +7,7 @@ import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line import { compilation } from './actions/staticAnalysisActions' import { initialState, analysisReducer } from './reducers/staticAnalysisReducer' +import { OverlayTrigger, Tooltip } from 'react-bootstrap'// eslint-disable-line const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -56,7 +57,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } const [autoRun, setAutoRun] = useState(true) const [slitherEnabled, setSlitherEnabled] = useState(false) - const [showSlither, setShowSlither] = useState('hidden') + const [showSlither, setShowSlither] = useState(false) const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) @@ -88,7 +89,24 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // Reset state dispatch({ type: '', payload: {} }) // Show 'Enable Slither Analysis' checkbox - if (currentWorkspace && currentWorkspace.isLocalhost === true) setShowSlither('visible') + if (currentWorkspace && currentWorkspace.isLocalhost === true) setShowSlither(true) + else { + setShowSlither(false) + setSlitherEnabled(false) + } + }) + props.analysisModule.on('manager', 'pluginDeactivated', (plugin) => { + // Hide 'Enable Slither Analysis' checkbox + if (plugin.name === 'remixd') { + // Reset warning state + setWarningState([]) + // Reset badge + props.event.trigger('staticAnaysisWarning', []) + // Reset state + dispatch({ type: '', payload: {} }) + setShowSlither(false) + setSlitherEnabled(false) + } }) return () => { } }, [props]) @@ -245,8 +263,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { showWarnings(warningMessage, 'warningModuleName') props.event.trigger('staticAnaysisWarning', [warningCount]) } - }).catch((error) => { - console.log('Error found:', error) // This should be removed once testing done + }).catch(() => { props.analysisModule.call('terminal', 'log', { type: 'error', value: '[Slither Analysis]: Error occured! See remixd console for details.' }) showWarnings(warningMessage, 'warningModuleName') }) @@ -398,17 +415,28 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { />
-
- {}} - visibility = {showSlither} - /> -
+ { showSlither && + + }
{Object.keys(groupedModules).map((categoryId, i) => { 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 890460b43c..24e9fc6400 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -354,3 +354,4 @@ input #terminalCliInput { .debug:hover { opacity: 0.8; } + 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 94c45e2b90..32a23f19e5 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -639,6 +639,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const txDetails = (event, tx, obj) => { if (showTableDetails === null) { setShowTableDetails(true) + console.log({tx: tx.hash}) } else { setShowTableDetails(null) } diff --git a/libs/remix-url-resolver/package.json b/libs/remix-url-resolver/package.json index 7a6c7baeca..a9b6770890 100644 --- a/libs/remix-url-resolver/package.json +++ b/libs/remix-url-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-url-resolver", - "version": "0.0.24", + "version": "0.0.26", "description": "Solidity import url resolver engine", "main": "index.js", "types": "./index.d.ts", @@ -42,5 +42,5 @@ "typescript": "^3.1.6" }, "typings": "index.d.ts", - "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea" + "gitHead": "df7abe1c219e361a947031d620f4ae6e3786a4d7" } \ No newline at end of file diff --git a/libs/remixd/package.json b/libs/remixd/package.json index 064fce325a..6f9123c651 100644 --- a/libs/remixd/package.json +++ b/libs/remixd/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remixd", - "version": "0.4.2", + "version": "0.5.0", "description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)", "main": "index.js", "types": "./index.d.ts", diff --git a/libs/remixd/src/services/slitherClient.ts b/libs/remixd/src/services/slitherClient.ts index e2d9a281bb..a0808d281f 100644 --- a/libs/remixd/src/services/slitherClient.ts +++ b/libs/remixd/src/services/slitherClient.ts @@ -120,9 +120,9 @@ export class SlitherClient extends PluginClient { allowPaths = allowPathString remaps = remapString.trim() } - const allowPathsOption: string = allowPaths ? `--allow-paths ${allowPaths}` : '' - const optimizeOption: string = optimize ? ' --optimize ' : '' - const evmOption: string = evmVersion ? ` --evm-version ${evmVersion}` : '' + const allowPathsOption: string = allowPaths ? `--allow-paths ${allowPaths} ` : '' + const optimizeOption: string = optimize ? '--optimize ' : '' + const evmOption: string = evmVersion ? `--evm-version ${evmVersion}` : '' const solcArgs: string = optimizeOption || evmOption || allowPathsOption ? `--solc-args '${allowPathsOption}${optimizeOption}${evmOption}'` : '' const solcRemaps = remaps ? `--solc-remaps "${remaps}"` : '' diff --git a/package-lock.json b/package-lock.json index 83fc0b9385..2a3685ee9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "remix-project", - "version": "0.15.0-dev", + "version": "0.17.0-dev", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2559,32 +2559,73 @@ } }, "@ethereumjs/block": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.3.0.tgz", - "integrity": "sha512-WoefY9Rs4W8vZTxG9qwntAlV61xsSv0NPoXmHO7x3SH16dwJQtU15YvahPCz4HEEXbu7GgGgNgu0pv8JY7VauA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.4.0.tgz", + "integrity": "sha512-umKAoTX32yXzErpIksPHodFc/5y8bmZMnOl6hWy5Vd8xId4+HKFUOyEiN16Y97zMwFRysRpcrR6wBejfqc6Bmg==", "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.0", - "ethereumjs-util": "^7.0.10", + "@ethereumjs/common": "^2.4.0", + "@ethereumjs/tx": "^3.3.0", + "ethereumjs-util": "^7.1.0", "merkle-patricia-tree": "^4.2.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "ethereumjs-util": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz", + "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==", + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + } } }, "@ethereumjs/blockchain": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.3.0.tgz", - "integrity": "sha512-B0Y5QDZcRDQISPilv3m8nzk97QmC98DnSE9WxzGpCxfef22Mw7xhwGipci5Iy0dVC2Np2Cr5d3F6bHAR7+yVmQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.4.0.tgz", + "integrity": "sha512-wAuKLaew6PL52kH8YPXO7PbjjKV12jivRSyHQehkESw4slSLLfYA6Jv7n5YxyT2ajD7KNMPVh7oyF/MU6HcOvg==", "requires": { - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/common": "^2.3.0", + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/common": "^2.4.0", "@ethereumjs/ethash": "^1.0.0", "debug": "^2.2.0", - "ethereumjs-util": "^7.0.10", + "ethereumjs-util": "^7.1.0", "level-mem": "^5.0.1", "lru-cache": "^5.1.1", "rlp": "^2.2.4", "semaphore-async-await": "^1.5.1" }, "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2593,6 +2634,19 @@ "ms": "2.0.0" } }, + "ethereumjs-util": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz", + "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==", + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2601,12 +2655,40 @@ } }, "@ethereumjs/common": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.3.1.tgz", - "integrity": "sha512-V8hrULExoq0H4HFs3cCmdRGbgmipmlNzak6Xg34nHYfQyqkSdrCuflvYjyWmsNpI8GtrcZhzifAbgX/1C1Cjwg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.4.0.tgz", + "integrity": "sha512-UdkhFWzWcJCZVsj1O/H8/oqj/0RVYjLc1OhPjBrQdALAkQHpCp8xXI4WLnuGTADqTdJZww0NtgwG+TRPkXt27w==", "requires": { "crc-32": "^1.2.0", - "ethereumjs-util": "^7.0.10" + "ethereumjs-util": "^7.1.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "ethereumjs-util": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz", + "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==", + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + } } }, "@ethereumjs/ethash": { @@ -2631,27 +2713,55 @@ } }, "@ethereumjs/tx": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.2.1.tgz", - "integrity": "sha512-i9V39OtKvwWos1uVNZxdVhd7zFOyzFLjgt69CoiOY0EmXugS0HjO3uxpLBSglDKFMRriuGqw6ddKEv+RP1UNEw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.0.tgz", + "integrity": "sha512-yTwEj2lVzSMgE6Hjw9Oa1DZks/nKTWM8Wn4ykDNapBPua2f4nXO3qKnni86O6lgDj5fVNRqbDsD0yy7/XNGDEA==", "requires": { - "@ethereumjs/common": "^2.3.1", - "ethereumjs-util": "^7.0.10" + "@ethereumjs/common": "^2.4.0", + "ethereumjs-util": "^7.1.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "ethereumjs-util": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz", + "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==", + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + } } }, "@ethereumjs/vm": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.4.1.tgz", - "integrity": "sha512-cpQcg5CtjzXJBn8QNiobaiWckeN/ZQwsDHLYa9df2wBEUvzuEZgFWK48YEXSpx3CnUY9fNT/lgA9CzKdq8HTzQ==", - "requires": { - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/blockchain": "^5.3.0", - "@ethereumjs/common": "^2.3.1", - "@ethereumjs/tx": "^3.2.1", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.5.2.tgz", + "integrity": "sha512-AydZ4wfvZAsBuFzs3xVSA2iU0hxhL8anXco3UW3oh9maVC34kTEytOfjHf06LTEfN0MF9LDQ4ciLa7If6ZN/sg==", + "requires": { + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/blockchain": "^5.4.0", + "@ethereumjs/common": "^2.4.0", + "@ethereumjs/tx": "^3.3.0", "async-eventemitter": "^0.2.4", "core-js-pure": "^3.0.1", "debug": "^2.2.0", - "ethereumjs-util": "^7.0.10", + "ethereumjs-util": "^7.1.0", "functional-red-black-tree": "^1.0.1", "mcl-wasm": "^0.7.1", "merkle-patricia-tree": "^4.2.0", @@ -2659,6 +2769,19 @@ "util.promisify": "^1.0.1" }, "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2667,6 +2790,19 @@ "ms": "2.0.0" } }, + "ethereumjs-util": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz", + "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==", + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.4" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2675,294 +2811,284 @@ } }, "@ethersproject/abi": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.2.tgz", - "integrity": "sha512-uMhoQVPX0UtfzTpekYQSEUcJGDgsJ25ifz+SV6PDETWaUFhcR8RNgb1QPTASP13inW8r6iy0/Xdq9D5hK2pNvA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.4.0.tgz", + "integrity": "sha512-9gU2H+/yK1j2eVMdzm6xvHSnMxk8waIHQGYCZg5uvAyH0rsAzxkModzBSpbAkAuhKFEovC2S9hM4nPuLym8IZw==", "requires": { - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" + "@ethersproject/address": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/constants": "^5.4.0", + "@ethersproject/hash": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/strings": "^5.4.0" } }, "@ethersproject/abstract-provider": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz", - "integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz", + "integrity": "sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ==", "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/networks": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/web": "^5.1.0" + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/networks": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/transactions": "^5.4.0", + "@ethersproject/web": "^5.4.0" } }, "@ethersproject/abstract-signer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz", - "integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz", + "integrity": "sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA==", "requires": { - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0" + "@ethersproject/abstract-provider": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0" } }, "@ethersproject/address": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz", - "integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.4.0.tgz", + "integrity": "sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q==", "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/rlp": "^5.1.0" + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/rlp": "^5.4.0" } }, "@ethersproject/base64": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz", - "integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.4.0.tgz", + "integrity": "sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ==", "requires": { - "@ethersproject/bytes": "^5.1.0" + "@ethersproject/bytes": "^5.4.0" } }, "@ethersproject/basex": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz", - "integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.4.0.tgz", + "integrity": "sha512-J07+QCVJ7np2bcpxydFVf/CuYo9mZ7T73Pe7KQY4c1lRlrixMeblauMxHXD0MPwFmUHZIILDNViVkykFBZylbg==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/properties": "^5.1.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/properties": "^5.4.0" } }, "@ethersproject/bignumber": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.1.tgz", - "integrity": "sha512-AVz5iqz7+70RIqoQTznsdJ6DOVBYciNlvO+AlQmPTB6ofCvoihI9bQdr6wljsX+d5W7Yc4nyvQvP4JMzg0Agig==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", + "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "bn.js": "^4.4.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "bn.js": "^4.11.9" } }, "@ethersproject/bytes": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz", - "integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", + "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", "requires": { - "@ethersproject/logger": "^5.1.0" + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/constants": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz", - "integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", + "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", "requires": { - "@ethersproject/bignumber": "^5.1.0" + "@ethersproject/bignumber": "^5.4.0" } }, "@ethersproject/contracts": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.1.tgz", - "integrity": "sha512-6WwktLJ0DFWU8pDkgH4IGttQHhQN4SnwKFu9h+QYVe48VGWtbDu4W8/q/7QA1u/HWlWMrKxqawPiZUJj0UMvOw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.4.1.tgz", + "integrity": "sha512-m+z2ZgPy4pyR15Je//dUaymRUZq5MtDajF6GwFbGAVmKz/RF+DNIPwF0k5qEcL3wPGVqUjFg2/krlCRVTU4T5w==", "requires": { - "@ethersproject/abi": "^5.1.0", - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/transactions": "^5.1.0" + "@ethersproject/abi": "^5.4.0", + "@ethersproject/abstract-provider": "^5.4.0", + "@ethersproject/abstract-signer": "^5.4.0", + "@ethersproject/address": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/constants": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/transactions": "^5.4.0" } }, "@ethersproject/hash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz", - "integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.4.0.tgz", + "integrity": "sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA==", "requires": { - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" + "@ethersproject/abstract-signer": "^5.4.0", + "@ethersproject/address": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/strings": "^5.4.0" } }, "@ethersproject/hdnode": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz", - "integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==", - "requires": { - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/basex": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/pbkdf2": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/sha2": "^5.1.0", - "@ethersproject/signing-key": "^5.1.0", - "@ethersproject/strings": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/wordlists": "^5.1.0" + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.4.0.tgz", + "integrity": "sha512-pKxdS0KAaeVGfZPp1KOiDLB0jba11tG6OP1u11QnYfb7pXn6IZx0xceqWRr6ygke8+Kw74IpOoSi7/DwANhy8Q==", + "requires": { + "@ethersproject/abstract-signer": "^5.4.0", + "@ethersproject/basex": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/pbkdf2": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/sha2": "^5.4.0", + "@ethersproject/signing-key": "^5.4.0", + "@ethersproject/strings": "^5.4.0", + "@ethersproject/transactions": "^5.4.0", + "@ethersproject/wordlists": "^5.4.0" } }, "@ethersproject/json-wallets": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz", - "integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==", - "requires": { - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/hdnode": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/pbkdf2": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/random": "^5.1.0", - "@ethersproject/strings": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.4.0.tgz", + "integrity": "sha512-igWcu3fx4aiczrzEHwG1xJZo9l1cFfQOWzTqwRw/xcvxTk58q4f9M7cjh51EKphMHvrJtcezJ1gf1q1AUOfEQQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.4.0", + "@ethersproject/address": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/hdnode": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/pbkdf2": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/random": "^5.4.0", + "@ethersproject/strings": "^5.4.0", + "@ethersproject/transactions": "^5.4.0", "aes-js": "3.0.0", "scrypt-js": "3.0.1" } }, "@ethersproject/keccak256": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz", - "integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.4.0.tgz", + "integrity": "sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A==", "requires": { - "@ethersproject/bytes": "^5.1.0", + "@ethersproject/bytes": "^5.4.0", "js-sha3": "0.5.7" } }, "@ethersproject/logger": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz", - "integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==" + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.0.tgz", + "integrity": "sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==" }, "@ethersproject/networks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz", - "integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.4.2.tgz", + "integrity": "sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw==", "requires": { - "@ethersproject/logger": "^5.1.0" + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/pbkdf2": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz", - "integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz", + "integrity": "sha512-x94aIv6tiA04g6BnazZSLoRXqyusawRyZWlUhKip2jvoLpzJuLb//KtMM6PEovE47pMbW+Qe1uw+68ameJjB7g==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/sha2": "^5.1.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/sha2": "^5.4.0" } }, "@ethersproject/properties": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz", - "integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.4.0.tgz", + "integrity": "sha512-7jczalGVRAJ+XSRvNA6D5sAwT4gavLq3OXPuV/74o3Rd2wuzSL035IMpIMgei4CYyBdialJMrTqkOnzccLHn4A==", "requires": { - "@ethersproject/logger": "^5.1.0" + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/providers": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.2.tgz", - "integrity": "sha512-GqsS8rd+eyd4eNkcNgzZ4l9IRULBPUZa7JPnv22k4MHflMobUseyhfbVnmoN5bVNNkOxjV1IPTw9i0sV1hwdpg==", - "requires": { - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/basex": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/networks": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/random": "^5.1.0", - "@ethersproject/rlp": "^5.1.0", - "@ethersproject/sha2": "^5.1.0", - "@ethersproject/strings": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/web": "^5.1.0", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.4.3.tgz", + "integrity": "sha512-VURwkaWPoUj7jq9NheNDT5Iyy64Qcyf6BOFDwVdHsmLmX/5prNjFrgSX3GHPE4z1BRrVerDxe2yayvXKFm/NNg==", + "requires": { + "@ethersproject/abstract-provider": "^5.4.0", + "@ethersproject/abstract-signer": "^5.4.0", + "@ethersproject/address": "^5.4.0", + "@ethersproject/basex": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/constants": "^5.4.0", + "@ethersproject/hash": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/networks": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/random": "^5.4.0", + "@ethersproject/rlp": "^5.4.0", + "@ethersproject/sha2": "^5.4.0", + "@ethersproject/strings": "^5.4.0", + "@ethersproject/transactions": "^5.4.0", + "@ethersproject/web": "^5.4.0", "bech32": "1.1.4", - "ws": "7.2.3" + "ws": "7.4.6" }, "dependencies": { "ws": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", - "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" } } }, "@ethersproject/random": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz", - "integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.4.0.tgz", + "integrity": "sha512-pnpWNQlf0VAZDEOVp1rsYQosmv2o0ITS/PecNw+mS2/btF8eYdspkN0vIXrCMtkX09EAh9bdk8GoXmFXM1eAKw==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/rlp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz", - "integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.4.0.tgz", + "integrity": "sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/sha2": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz", - "integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.4.0.tgz", + "integrity": "sha512-siheo36r1WD7Cy+bDdE1BJ8y0bDtqXCOxRMzPa4bV1TGt/eTUUt03BHoJNB6reWJD8A30E/pdJ8WFkq+/uz4Gg==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "hash.js": "1.1.3" - }, - "dependencies": { - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - } + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "hash.js": "1.1.7" } }, "@ethersproject/signing-key": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz", - "integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.4.0.tgz", + "integrity": "sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "bn.js": "^4.4.0", - "elliptic": "6.5.4" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" }, "dependencies": { "elliptic": { @@ -2982,97 +3108,97 @@ } }, "@ethersproject/solidity": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz", - "integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.4.0.tgz", + "integrity": "sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ==", "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/sha2": "^5.1.0", - "@ethersproject/strings": "^5.1.0" + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/sha2": "^5.4.0", + "@ethersproject/strings": "^5.4.0" } }, "@ethersproject/strings": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz", - "integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.4.0.tgz", + "integrity": "sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/logger": "^5.1.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/constants": "^5.4.0", + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/transactions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.1.tgz", - "integrity": "sha512-Nwgbp09ttIVN0OoUBatCXaHxR7grWPHbozJN8v7AXDLrl6nnOIBEMDh+yJTnosSQlFhcyjfTGGN+Mx6R8HdvMw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.4.0.tgz", + "integrity": "sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ==", "requires": { - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/rlp": "^5.1.0", - "@ethersproject/signing-key": "^5.1.0" + "@ethersproject/address": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/constants": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/rlp": "^5.4.0", + "@ethersproject/signing-key": "^5.4.0" } }, "@ethersproject/units": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz", - "integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.4.0.tgz", + "integrity": "sha512-Z88krX40KCp+JqPCP5oPv5p750g+uU6gopDYRTBGcDvOASh6qhiEYCRatuM/suC4S2XW9Zz90QI35MfSrTIaFg==", "requires": { - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/constants": "^5.1.0", - "@ethersproject/logger": "^5.1.0" + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/constants": "^5.4.0", + "@ethersproject/logger": "^5.4.0" } }, "@ethersproject/wallet": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz", - "integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@ethersproject/address": "^5.1.0", - "@ethersproject/bignumber": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/hdnode": "^5.1.0", - "@ethersproject/json-wallets": "^5.1.0", - "@ethersproject/keccak256": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/random": "^5.1.0", - "@ethersproject/signing-key": "^5.1.0", - "@ethersproject/transactions": "^5.1.0", - "@ethersproject/wordlists": "^5.1.0" + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.4.0.tgz", + "integrity": "sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.4.0", + "@ethersproject/abstract-signer": "^5.4.0", + "@ethersproject/address": "^5.4.0", + "@ethersproject/bignumber": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/hash": "^5.4.0", + "@ethersproject/hdnode": "^5.4.0", + "@ethersproject/json-wallets": "^5.4.0", + "@ethersproject/keccak256": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/random": "^5.4.0", + "@ethersproject/signing-key": "^5.4.0", + "@ethersproject/transactions": "^5.4.0", + "@ethersproject/wordlists": "^5.4.0" } }, "@ethersproject/web": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz", - "integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.4.0.tgz", + "integrity": "sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og==", "requires": { - "@ethersproject/base64": "^5.1.0", - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" + "@ethersproject/base64": "^5.4.0", + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/strings": "^5.4.0" } }, "@ethersproject/wordlists": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz", - "integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.4.0.tgz", + "integrity": "sha512-FemEkf6a+EBKEPxlzeVgUaVSodU7G0Na89jqKjmWMlDB0tomoU8RlEMgUvXyqtrg8N4cwpLh8nyRnm1Nay1isA==", "requires": { - "@ethersproject/bytes": "^5.1.0", - "@ethersproject/hash": "^5.1.0", - "@ethersproject/logger": "^5.1.0", - "@ethersproject/properties": "^5.1.0", - "@ethersproject/strings": "^5.1.0" + "@ethersproject/bytes": "^5.4.0", + "@ethersproject/hash": "^5.4.0", + "@ethersproject/logger": "^5.4.0", + "@ethersproject/properties": "^5.4.0", + "@ethersproject/strings": "^5.4.0" } }, "@evocateur/libnpmaccess": { @@ -7546,9 +7672,9 @@ "dev": true }, "@types/abstract-leveldown": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-5.0.1.tgz", - "integrity": "sha512-wYxU3kp5zItbxKmeRYCEplS2MW7DzyBnxPGj+GJVHZEUZiK/nn5Ei1sUFgURDh+X051+zsGe28iud3oHjrYWQQ==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-5.0.2.tgz", + "integrity": "sha512-+jA1XXF3jsz+Z7FcuiNqgK53hTa/luglT2TyTpKPqoYbxVY+mCPF22Rm+q3KPBrMHJwNXFrTViHszBOfU4vftQ==" }, "@types/aria-query": { "version": "4.2.0", @@ -7728,12 +7854,18 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/level-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", + "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==" + }, "@types/levelup": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.1.tgz", - "integrity": "sha512-n//PeTpbHLjMLTIgW5B/g06W/6iuTBHuvUka2nFL9APMSVMNe2r4enADfu3CIE9IyV9E+uquf9OEQQqrDeg24A==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", + "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", "requires": { "@types/abstract-leveldown": "*", + "@types/level-errors": "*", "@types/node": "*" } }, @@ -16206,40 +16338,40 @@ } }, "ethers": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.4.tgz", - "integrity": "sha512-EAPQ/fgGRu0PoR/VNFnHTMOtG/IZ0AItdW55C9T8ffmVu0rnyllZL404eBF66elJehOLz2kxnUrhXpE7TCpW7g==", - "requires": { - "@ethersproject/abi": "5.1.2", - "@ethersproject/abstract-provider": "5.1.0", - "@ethersproject/abstract-signer": "5.1.0", - "@ethersproject/address": "5.1.0", - "@ethersproject/base64": "5.1.0", - "@ethersproject/basex": "5.1.0", - "@ethersproject/bignumber": "5.1.1", - "@ethersproject/bytes": "5.1.0", - "@ethersproject/constants": "5.1.0", - "@ethersproject/contracts": "5.1.1", - "@ethersproject/hash": "5.1.0", - "@ethersproject/hdnode": "5.1.0", - "@ethersproject/json-wallets": "5.1.0", - "@ethersproject/keccak256": "5.1.0", - "@ethersproject/logger": "5.1.0", - "@ethersproject/networks": "5.1.0", - "@ethersproject/pbkdf2": "5.1.0", - "@ethersproject/properties": "5.1.0", - "@ethersproject/providers": "5.1.2", - "@ethersproject/random": "5.1.0", - "@ethersproject/rlp": "5.1.0", - "@ethersproject/sha2": "5.1.0", - "@ethersproject/signing-key": "5.1.0", - "@ethersproject/solidity": "5.1.0", - "@ethersproject/strings": "5.1.0", - "@ethersproject/transactions": "5.1.1", - "@ethersproject/units": "5.1.0", - "@ethersproject/wallet": "5.1.0", - "@ethersproject/web": "5.1.0", - "@ethersproject/wordlists": "5.1.0" + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.4.tgz", + "integrity": "sha512-zaTs8yaDjfb0Zyj8tT6a+/hEkC+kWAA350MWRp6yP5W7NdGcURRPMOpOU+6GtkfxV9wyJEShWesqhE/TjdqpMA==", + "requires": { + "@ethersproject/abi": "5.4.0", + "@ethersproject/abstract-provider": "5.4.1", + "@ethersproject/abstract-signer": "5.4.1", + "@ethersproject/address": "5.4.0", + "@ethersproject/base64": "5.4.0", + "@ethersproject/basex": "5.4.0", + "@ethersproject/bignumber": "5.4.1", + "@ethersproject/bytes": "5.4.0", + "@ethersproject/constants": "5.4.0", + "@ethersproject/contracts": "5.4.1", + "@ethersproject/hash": "5.4.0", + "@ethersproject/hdnode": "5.4.0", + "@ethersproject/json-wallets": "5.4.0", + "@ethersproject/keccak256": "5.4.0", + "@ethersproject/logger": "5.4.0", + "@ethersproject/networks": "5.4.2", + "@ethersproject/pbkdf2": "5.4.0", + "@ethersproject/properties": "5.4.0", + "@ethersproject/providers": "5.4.3", + "@ethersproject/random": "5.4.0", + "@ethersproject/rlp": "5.4.0", + "@ethersproject/sha2": "5.4.0", + "@ethersproject/signing-key": "5.4.0", + "@ethersproject/solidity": "5.4.0", + "@ethersproject/strings": "5.4.0", + "@ethersproject/transactions": "5.4.0", + "@ethersproject/units": "5.4.0", + "@ethersproject/wallet": "5.4.0", + "@ethersproject/web": "5.4.0", + "@ethersproject/wordlists": "5.4.0" } }, "ethjs-unit": { @@ -24818,9 +24950,19 @@ "dev": true }, "mcl-wasm": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.7.tgz", - "integrity": "sha512-jDGiCQA++5hX37gdH6RDZ3ZsA0raet7xyY/R5itj5cbcdf4Gvw+YyxWX/ZZ0Z2UPxJiw1ktRsCJZzpnqlQILdw==" + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.8.tgz", + "integrity": "sha512-qNHlYO6wuEtSoH5A8TcZfCEHtw8gGPqF6hLZpQn2SVd/Mck0ELIKOkmj072D98S9B9CI/jZybTUC96q1P2/ZDw==", + "requires": { + "typescript": "^4.3.4" + }, + "dependencies": { + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + } + } }, "md5.js": { "version": "1.3.5", diff --git a/package.json b/package.json index bb82c62830..511f75fffb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "remix-project", - "version": "0.15.0-dev", + "version": "0.17.0-dev", "license": "MIT", "description": "Ethereum Remix Monorepo", "keywords": [ @@ -130,10 +130,10 @@ }, "dependencies": { "@erebos/bzz-node": "^0.13.0", - "@ethereumjs/block": "^3.3.0", - "@ethereumjs/common": "^2.3.1", - "@ethereumjs/tx": "^3.2.1", - "@ethereumjs/vm": "^5.4.1", + "@ethereumjs/block": "^3.4.0", + "@ethereumjs/common": "^2.4.0", + "@ethereumjs/tx": "^3.3.0", + "@ethereumjs/vm": "^5.5.0", "@remixproject/engine": "^0.3.17", "@remixproject/engine-web": "^0.3.17", "@remixproject/plugin": "^0.3.17", @@ -153,7 +153,7 @@ "deep-equal": "^1.0.1", "document-register-element": "1.13.1", "ethereumjs-util": "^7.0.10", - "ethers": "^5.1.4", + "ethers": "^5.4.2", "express-ws": "^4.0.0", "file-saver": "^2.0.5", "form-data": "^4.0.0", diff --git a/release-process.md b/release-process.md index ceb1caccbc..67e100a5f8 100644 --- a/release-process.md +++ b/release-process.md @@ -1,13 +1,22 @@ # Release process This document includes: + - how to release the remixd - how to publish remix libs to NPM - how to update remix.ethereum.org - how to update remix-alpha.ethereum.org - how to update remix-beta.ethereum.org - how to release remix IDE +## RemixD release + - update new version number in remixd libs/remixd/package.json + - nx build remixd + - cd into ./dist/libs/remixd + - npm publish + - create bump PR to master. + ## Remix libs release +(remove dist and login to npm) - git fetch origin master - git checkout origin/master - git checkout -b bumpLibsVersion @@ -76,4 +85,4 @@ This is not strictly speaking a release. Updating the remix site is done through ## remix-alpha.ethereum.org update -remix-alpha.ethereum.org is automaticaly updated every time commits are pushed to master \ No newline at end of file +remix-alpha.ethereum.org is automaticaly updated every time commits are pushed to master From b18ac78c408a710d86b076f22f446d972ef59374 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Mon, 16 Aug 2021 11:44:36 +0100 Subject: [PATCH 16/48] cleaning up code --- apps/remix-ide/src/app/panels/terminal.js | 8 +- apps/remix-ide/src/lib/cmdInterpreterAPI.js | 2 +- libs/remix-ui/terminal/src/lib/commands.ts | 6 +- .../terminal/src/lib/remix-ui-terminal.css | 11 +- .../terminal/src/lib/remix-ui-terminal.tsx | 272 +++++------------- .../terminal/src/lib/terminalWelcome.tsx | 30 ++ .../remix-ui/terminal/src/lib/utils/helper.ts | 176 ------------ 7 files changed, 118 insertions(+), 387 deletions(-) create mode 100644 libs/remix-ui/terminal/src/lib/terminalWelcome.tsx delete mode 100644 libs/remix-ui/terminal/src/lib/utils/helper.ts diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 76b632a649..c595e952f3 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -37,7 +37,7 @@ class Terminal extends Plugin { this.registry = registry this.globalRegistry = globalRegistry this.element = document.createElement('div') - this.element.setAttribute('class', 'panel_2A0YE0') + this.element.setAttribute('class', 'panel') this.element.setAttribute('id', 'terminal-view') this.eventsDecoder = this.globalRegistry.get('eventsDecoder').api this.txListener = this.globalRegistry.get('txlistener').api @@ -82,6 +82,12 @@ class Terminal extends Plugin { this._INDEX.commandsMain = {} if (opts.shell) this._shell = opts.shell // ??? register(this) + this.event.register('debuggingRequested', async (hash) => { + // TODO should probably be in the run module + if (!await this._opts.appManager.isActive('debugger')) await this._opts.appManager.activatePlugin('debugger') + this.call('menuicons', 'select', 'debugger') + this.call('debugger', 'debug', hash) + }) } onActivation () { diff --git a/apps/remix-ide/src/lib/cmdInterpreterAPI.js b/apps/remix-ide/src/lib/cmdInterpreterAPI.js index 9c79cae25b..7468a7f334 100644 --- a/apps/remix-ide/src/lib/cmdInterpreterAPI.js +++ b/apps/remix-ide/src/lib/cmdInterpreterAPI.js @@ -93,7 +93,7 @@ class CmdInterpreterAPI { if (cb) cb() return } - + console.log({ content }, ' contents') self._components.terminal.commands.script(content) } diff --git a/libs/remix-ui/terminal/src/lib/commands.ts b/libs/remix-ui/terminal/src/lib/commands.ts index 14a3cbb97b..62eaafa0a0 100644 --- a/libs/remix-ui/terminal/src/lib/commands.ts +++ b/libs/remix-ui/terminal/src/lib/commands.ts @@ -2,13 +2,13 @@ export 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/.' } + // { swarmgw: 'This library can be used to upload/download files to Swarm via https://swarm-gateways.net/.' } ] 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.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.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 ff9c5442d4..5a4ffee292 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -14,9 +14,6 @@ element.style { #terminalCliInput:focus { outline: none; } -input #terminalCliInput { - -} .border-primary { border-color: #007aa6!important; @@ -90,13 +87,13 @@ input #terminalCliInput { font-family : monospace; padding : .4em; color : var(--primary); - border-top : solid 2px var(--secondary); } .prompt { margin-right : 0.5em; font-family : monospace; font-weight : bold; font-size : 14px; + color : lightgray; } .input { word-break : break-word; @@ -275,8 +272,6 @@ input #terminalCliInput { .arrow:hover { color: var(--secondary); } - .txLog { - } .txStatus { display: flex; font-size: 20px; @@ -322,6 +317,10 @@ input #terminalCliInput { font-size: 10px; color: var(--text-info); border: 1px solid var(--text-info); + transition: max-height 0.3s, padding 0.3s; + } + table .active { + transition: max-height 0.6s, padding 0.6s; } #txTable { margin-top: 1%; 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 32a23f19e5..9be04ca258 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,23 +1,21 @@ import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' -import { registerCommandAction, filterFnAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, registerRemixWelcomeTextAction, listenOnNetworkAction, initListeningOnNetwork } from './actions/terminalAction' +import { registerCommandAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, registerRemixWelcomeTextAction, listenOnNetworkAction, initListeningOnNetwork } from './actions/terminalAction' import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer, remixWelcomeTextReducer } from './reducers/terminalReducer' -import { remixWelcome } from './reducers/remixWelcom' -import { getKeyOf, getValueOf, Objectfilter, matched, find } from './utils/utils' +import { remixWelcome } from './reducers/remixWelcom' // eslint-disable-line +import { getKeyOf, getValueOf, Objectfilter, matched } from './utils/utils' import {allCommands, allPrograms} from './commands' // eslint-disable-line import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line -import { ModalDialog } from '@remix-ui/modal-dialog' +import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line +import TerminalWelcomeMessage from './terminalWelcome' // eslint-disable-line + +import './remix-ui-terminal.css' // const TxLogger from '../../../apps/' import vm from 'vm' import javascriptserialize from 'javascript-serialize' import jsbeautify from 'js-beautify' import helper from '../../../../../apps/remix-ide/src/lib/helper' -import parse from 'html-react-parser' - -import './remix-ui-terminal.css' -import { debug } from 'console' -import { eventNames } from 'process' const remixLib = require('@remix-project/remix-lib') var typeConversion = remixLib.execution.typeConversion @@ -55,7 +53,6 @@ export interface ClipboardEvent extends SyntheticEvent { export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') - const [inserted, setInserted] = useState(false) const [_cmdIndex, setCmdIndex] = useState(-1) const [_cmdTemp, setCmdTemp] = useState('') const [_cmdHistory, setCmdHistory] = useState([]) @@ -66,11 +63,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [dragging, setDragging] = useState(false) const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) - const [filterState, filterDispatch] = useReducer(registerFilterReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) - const [welcomeTextState, welcomTextDispath] = useReducer(remixWelcomeTextReducer, initialState) const [isListeningOnNetwork, setIsListeningOnNetwork] = useState(false) + const [clearConsole, setClearConsole] = useState(false) const [autoCompletState, setAutoCompleteState] = useState({ activeSuggestion: 0, data: { @@ -91,7 +87,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [searchInput, setSearchInput] = useState('') // const [showTableDetails, setShowTableDetails] = useState([]) - const [showTableDetails, setShowTableDetails] = useState(null) + const [showTableHash, setShowTableHash] = useState([]) useWindowResize(() => { setWindowHeight(window.innerHeight) @@ -99,14 +95,20 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // terminal inputRef const inputEl = useRef(null) + const messagesEndRef = useRef(null) + + const scrollToBottom = () => { + messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }) + } + // events useEffect(() => { initListeningOnNetwork(props, scriptRunnerDispatch) - // registerRemixWelcomeTextAction(remixWelcome, welcomTextDispath) registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) + registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch) registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch) registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch) @@ -115,51 +117,20 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerCommandAction('script', function execute (args, scopedCommands, append) { var script = String(args[0]) - console.log({ script }) - console.log({ scopedCommands }) - _shell(script, scopedCommands, function (error, output) { if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } }) if (output) scriptRunnerDispatch({ type: 'script', payload: { message: '5' } }) }) }, { activate: true }, dispatch) - - filterFnAction('log', basicFilter, filterDispatch) - filterFnAction('info', basicFilter, filterDispatch) - filterFnAction('warn', basicFilter, filterDispatch) - filterFnAction('error', basicFilter, filterDispatch) - filterFnAction('script', basicFilter, filterDispatch) - registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) - registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) - registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) - registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) - // console.log({ htmlresullt }, { logresult }) - // dispatch({ type: 'html', payload: { commands: htmlresullt.commands } }) - // dispatch({ type: 'log', payload: { _commands: logresult._commands } }) - // registerCommand('log', _blocksRenderer('log'), { activate: true }) }, [props.thisState.autoCompletePopup, autoCompletState.text]) - const placeCaretAtEnd = (el) => { - el.focus() - const range = document.createRange() - range.selectNodeContents(el) - range.collapse(false) - const sel = window.getSelection() - sel.removeAllRanges() - sel.addRange(range) - } - - const domTerminalFeatures = () => { - return { - remix: props.cmdInterpreter - } - } - - function exeCurrent (cb) { - return execute(undefined, cb) - } + useEffect(() => { + scrollToBottom() + console.log({ messagesEndRef: messagesEndRef.current }, ' onScroll') + }, [newstate.journalBlocks.length]) function execute (file, cb) { + console.log('called execute scriptRunner') function _execute (content, cb) { if (!content) { // toolTip('no content to execute') @@ -194,44 +165,36 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { _execute(content, cb) }) + return '' } const _shell = async (script, scopedCommands, done) => { // default shell if (script.indexOf('remix:') === 0) { return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') } - if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - var context = domTerminalFeatures() + const context = execute(undefined, undefined) try { const cmds = vm.createContext(context) - // const result - let result = vm.runInContext(script, cmds) - if (script === 'remix.exeCurrent()') { - result = exeCurrent(undefined) - } else { - if (result === {}) { - for (const k in result) { - result = +`
{k}: ${result[k]}

` - } - } - } - - console.log(result === {}, ' is result === object') - console.log({ result }) - return done(null, '') + const result = vm.runInContext(script, cmds) + console.log(done, ' done func') + return done(null, result) } catch (error) { return done(error.message) } } try { + console.log(' remix command by david 2') let result: any if (script.trim().startsWith('git')) { // result = await this.call('git', 'execute', script) } else { + console.log(' remix command by david 3') result = await props.thisState.call('scriptRunner', 'execute', script) + + console.log({ result }, ' me ') } console.log({ result }) done() @@ -240,25 +203,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - // handle events - const handlePaste = (event: ClipboardEvent) => { - // Do something - const selection = window.getSelection() - if (!selection.rangeCount) return false - event.preventDefault() - event.stopPropagation() - const clipboard = (event.clipboardData) // || window.clipboardData - let text = clipboard.getData('text/plain') - text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters - const temp = document.createElement('div') - temp.innerHTML = text - const textnode = document.createTextNode(temp.textContent) - selection.getRangeAt(0).insertNode(textnode) - selection.empty() - // self.scroll2bottom() - placeCaretAtEnd(event.currentTarget) - } - const handleMinimizeTerminal = (event) => { event.preventDefault() event.stopPropagation() @@ -273,20 +217,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - const _appendItem = (item: any) => { - let { _JOURNAL, _jobs, data } = state - const self = props - const { el, gidx } = item - _JOURNAL[gidx] = item - if (!_jobs.length) { - // requestAnimationFrame(function updateTerminal () { - // self._jobs.forEach(el => self._view.journal.appendChild(el)) - // self.scroll2bottom() - _jobs = [] - } - if (data.activeFilters.commands[item.cmd]) _jobs.push(el) - } - const focusinput = () => { inputEl.current.focus() } @@ -311,15 +241,19 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const handleKeyDown = (event) => { const suggestionCount = autoCompletState.activeSuggestion if (autoCompletState.userInput !== '' && (event.which === 27 || event.which === 8 || event.which === 46)) { - console.log(' enter esc and delete') // backspace or any key that should remove the autocompletion setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false })) } if (autoCompletState.showSuggestions && (event.which === 13 || event.which === 9)) { if (autoCompletState.userInput.length === 1) { - setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: Object.keys(autoCompletState.data._options[0]).toString() })) - } else { - setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: autoCompletState.userInput })) + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false, userInput: Object.keys(autoCompletState.data._options[0]).toString() })) + } + // else if (autoCompletState.activeSuggestion === 0) { + // setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false, userInput: autoCompletState.userInput })) + // } + else { + console.log(autoCompletState.activeSuggestion, 'autoCompletState.userInput.length') + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion]).toString() })) } } if (event.which === 13 && !autoCompletState.showSuggestions) { @@ -328,7 +262,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { inputEl.current.focus() } else { // event.preventDefault() - console.log('hit enter') setCmdIndex(-1) setCmdTemp('') const script = autoCompletState.userInput.trim() // inputEl.current.innerText.trim() @@ -347,43 +280,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { event.preventDefault() console.log(newstate._commandHistory[0], ' up value') setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate._commandHistory[0] })) - - // } - // else if (newstate._commandHistory.length < autoCompletState.commandHistoryIndex) { - // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: --autoCompletState.commandHistoryIndex })) - // console.log(newstate._commandHistory[newstate._commandHistory.length > 1 ? autoCompletState.commandHistoryIndex-- : newstate._commandHistory.length + 1], ' up value') - // } else if (newstate._commandHistory.length === autoCompletState.commandHistoryIndex) { - // console.log(newstate._commandHistory.length === autoCompletState.commandHistoryIndex, ' up value middle') - // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: autoCompletState.commandHistoryIndex - 2, userInput: newstate._commandHistory[autoCompletState.commandHistoryIndex] })) - // } else { - // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: autoCompletState.commandHistoryIndex - 1, userInput: newstate._commandHistory[autoCompletState.commandHistoryIndex] })) - // console.log(newstate._commandHistory[newstate._commandHistory.length - 1], ' up value last') - // } - // if (newstate._commandHistory.length === 0) { - // setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate[0] })) - // } - // setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate[autoCompletState.commandHistoryIndex] })) - // TODO: giving error => need to work on the logic - // // } else if (newstate._commandHistory.length && event.which === 40 && !autoCompletState.showSuggestions && (autoCompletState.userInput !== '')) { - // // console.log('previous command down') - // // if (autoCompletState.commandHistoryIndex < newstate._commandHistory.length) { - // // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: autoCompletState.commandHistoryIndex + 1, userInput: newstate._commandHistory[autoCompletState.commandHistoryIndex + 1] })) - // // console.log(newstate._commandHistory[newstate._commandHistory.length > 1 ? autoCompletState.commandHistoryIndex++ : newstate._commandHistory.length - 1], ' down ++ value') - // // } else { - // // console.log(newstate._commandHistory[newstate._commandHistory.length - 1], ' down value last') - // // setAutoCompleteState(prevState => ({ ...prevState, commandHistoryIndex: newstate._commandHistory.length - 1, userInput: newstate._commandHistory[newstate._commandHistory.length - 1] })) - // // } - // // // if (autoCompletState.commandHistoryIndex === newstate._commandHistory.length) { - // // // return - // // // } - // setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate[autoCompletState.commandHistoryIndex] + 1 })) } else if (event.which === 38 && autoCompletState.showSuggestions) { event.preventDefault() if (autoCompletState.activeSuggestion === 0) { return } - setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount - 1, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion - 1]).toString() })) - console.log('disable up an down key in input box') + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount - 1, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion]).toString() })) + console.log({ autoCompletState }, 'disable up an down key in input box') } else if (event.which === 38 && !autoCompletState.showSuggestions) { // const len = _cmdHistory.length if (len === 0) event.preventDefault() @@ -408,21 +311,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } else { setCmdTemp(inputEl.current.innerText) } - console.log({ autoCompletState }) - } - - const moveGhostbar = (event) => { - return props.api.getPosition(event) + 'px' - } - - const removeGhostbar = (event) => { - if (toggleDownUp === 'fa-angle-double-up') { - console.log('remove event') - setToggleDownUp('fa-angle-double-down') - } - const value = props.event.get('resize') - console.log({ value }) - props.event.trigger('resize', [value]) } /* start of mouse events */ @@ -513,15 +401,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } } - - const registerCommand = (name, command, opts) => { - // setState((prevState) => ({ ...prevState, _commands[name]: command })) - } - /* end of block content that gets rendered from script Runner */ const handleClearConsole = () => { + setClearConsole(true) dispatch({ type: 'clearconsole', payload: [] }) inputEl.current.focus() } @@ -637,21 +520,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const txDetails = (event, tx, obj) => { - if (showTableDetails === null) { - setShowTableDetails(true) - console.log({tx: tx.hash}) + if (showTableHash.includes(tx.hash)) { + const index = showTableHash.indexOf(tx.hash) + console.log({ index }) + if (index > -1) { + setShowTableHash((prevState) => prevState.filter((x) => x !== tx.hash)) + } } else { - setShowTableDetails(null) + setShowTableHash((prevState) => ([...prevState, tx.hash])) } - // if (showTableDetails.length === 0) { - // setShowTableDetails([{ hash: tx.hash, show: true }]) - // } - // const id = showTableDetails.filter(x => x.hash !== tx.hash) - // if ((showTableDetails.length !== 0) && (id[0] === tx.hash)) { - // setShowTableDetails(currentState => ([...currentState, { hash: tx.hash, show: false }])) - // } - // console.log((showTableDetails.length !== 0) && (id[0] === tx.hash)) - // console.log({ showTableDetails }, ' clicked button') } const showTable = (opts) => { @@ -685,7 +562,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const val = opts.val != null ? typeConversion.toInt(opts.val) : 0 return ( - +
@@ -829,7 +706,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const from = tx.from const to = tx.to const obj = { from, to } - const showDetails = showTableDetails === tx.from const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx') return ( @@ -840,9 +716,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
debug(event, tx)}>Debug
- + - {showTableDetails ? showTable({ + {showTableHash.includes(tx.hash) ? showTable({ hash: tx.hash, status: receipt !== null ? receipt.status : null, isCall: tx.isCall, @@ -868,7 +744,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{autoCompletState.data._options.map((item, index) => { return ( -
+
{getKeyOf(item)}
@@ -884,23 +760,23 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { /* end of autoComplete */ return ( -
+
{console.log({ newstate })} {console.log({ props })} -
+
{/* ${self._view.dragbar} */}
-
+
{/* ${self._view.icon} */} - +
{/* ${self._view.pendingTxCount} */}
0
-
-
+
+
{ listen on network
-
- +
+ {/* ${self._view.inputSearch} */} setSearchInput(event.target.value) } type="text" - className="border filter_2A0YE0 form-control" + className="border filter form-control" id="searchInput" // onkeydown=${filter} placeholder="Search with transaction hash or address" @@ -931,7 +807,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
-
+
{ handleAutoComplete() } @@ -942,38 +818,34 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { opacity: '0.1', zIndex: -1 }}>
-
-
+
+
+ {!clearConsole && } {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { if (x.name === 'emptyBlock') { return ( -
+
[block:{x.message} - 0 {'transactions'} ]
) } else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || x.tx.to.includes(searchInput)).map((trans) => { - return (
{renderKnownTransactions(trans.tx, trans.receipt, index)}
) + return (
{renderKnownTransactions(trans.tx, trans.receipt, index)}
) }) } else { return ( -
+
{x.message}
) } })} -
- {/* ${background} */} -
- {/* ${text} */} -
-
+
-
- {'>'} - onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput}> +
+ {'>'} + onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput}>
diff --git a/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx new file mode 100644 index 0000000000..7d9c1a4055 --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/terminalWelcome.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +const TerminalWelcomeMessage = ({ packageJson }) => { + return ( +
+
- Welcome to Remix {packageJson} -

+
You can use this terminal to:
+
    +
  • Check transactions details and start debugging.
  • +
  • Execute JavaScript scripts: +
    + - Input a script directly in the command line interface +
    + - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface +
    + - Right click on a JavaScript file in the file explorer and then click \`Run\` +
  • +
+
The following libraries are accessible:
+ +
+ ) +} + +export default TerminalWelcomeMessage diff --git a/libs/remix-ui/terminal/src/lib/utils/helper.ts b/libs/remix-ui/terminal/src/lib/utils/helper.ts deleted file mode 100644 index 56b50a4377..0000000000 --- a/libs/remix-ui/terminal/src/lib/utils/helper.ts +++ /dev/null @@ -1,176 +0,0 @@ -// var async = require('async') -// const ethJSUtil = require('ethereumjs-util') - -// export const shortenAddress = (address, etherBalance) => { -// var len = address.length -// return address.slice(0, 5) + '...' + address.slice(len - 5, len) + (etherBalance ? ' (' + etherBalance.toString() + ' ether)' : '') -// } - -// export const addressToString = (address) => { -// if (!address) return null -// if (typeof address !== 'string') { -// address = address.toString('hex') -// } -// if (address.indexOf('0x') === -1) { -// address = '0x' + address -// } -// return ethJSUtil.toChecksumAddress(address) -// } - -// export const shortenHexData = (data) => { -// if (!data) return '' -// if (data.length < 5) return data -// var len = data.length -// return data.slice(0, 5) + '...' + data.slice(len - 5, len) -// } - -// export const createNonClashingNameWithPrefix = (name, fileProvider, prefix, cb) => { -// if (!name) name = 'Undefined' -// var counter = '' -// var ext = 'sol' -// var reg = /(.*)\.([^.]+)/g -// var split = reg.exec(name) -// if (split) { -// name = split[1] -// ext = split[2] -// } -// var exist = true -// async.whilst( -// () => { return exist }, -// (callback) => { -// fileProvider.exists(name + counter + prefix + '.' + ext).then(currentExist => { -// exist = currentExist -// if (exist) counter = (counter | 0) + 1 -// callback() -// }).catch(error => { -// if (error) console.log(error) -// }) -// }, -// (error) => { cb(error, name + counter + prefix + '.' + ext) } -// ) -// } - -// export const createNonClashingName = (name, fileProvider, cb) => { -// this.createNonClashingNameWithPrefix(name, fileProvider, '', cb) -// }, -// export const createNonClashingNameAsync = async (name, fileManager, prefix = '') => { -// if (!name) name = 'Undefined' -// let counter = '' -// let ext = 'sol' -// const reg = /(.*)\.([^.]+)/g -// const split = reg.exec(name) -// if (split) { -// name = split[1] -// ext = split[2] -// } -// let exist = true - -// do { -// const isDuplicate = await fileManager.exists(name + counter + prefix + '.' + ext) - -// if (isDuplicate) counter = (counter | 0) + 1 -// else exist = false -// } while (exist) - -// return name + counter + prefix + '.' + ext -// } - -// export const createNonClashingDirNameAsync = async (name, fileManager) => { -// if (!name) name = 'Undefined' -// let counter = '' -// let exist = true - -// do { -// const isDuplicate = await fileManager.exists(name + counter) - -// if (isDuplicate) counter = (counter | 0) + 1 -// else exist = false -// } while (exist) - -// return name + counter -// } - -// export const checkSpecialChars = (name) => { -// return name.match(/[:*?"<>\\'|]/) != null -// } - -// export const checkSlash = (name) => { -// return name.match(/\//) != null -// } - -// export const isHexadecimal = (value) => { -// return /^[0-9a-fA-F]+$/.test(value) && (value.length % 2 === 0) -// } - -// export const is0XPrefixed = (value) => { -// return value.substr(0, 2) === '0x' -// } - -// export const isNumeric = (value) => { -// return /^\+?(0|[1-9]\d*)$/.test(value) -// } - -// export const isValidHash = (hash) => { // 0x prefixed, hexadecimal, 64digit -// const hexValue = hash.slice(2, hash.length) -// return this.is0XPrefixed(hash) && /^[0-9a-fA-F]{64}$/.test(hexValue) -// } - -// export const removeTrailingSlashes = (text) { -// // Remove single or consecutive trailing slashes -// return text.replace(/\/+$/g, '') -// }, -// removeMultipleSlashes (text) { -// // Replace consecutive slashes with '/' -// return text.replace(/\/+/g, '/') -// }, -// find: find, -// getPathIcon (path) { -// return path.endsWith('.txt') -// ? 'far fa-file-alt' : path.endsWith('.md') -// ? 'far fa-file-alt' : path.endsWith('.sol') -// ? 'fak fa-solidity-mono' : path.endsWith('.js') -// ? 'fab fa-js' : path.endsWith('.json') -// ? 'fas fa-brackets-curly' : path.endsWith('.vy') -// ? 'fak fa-vyper-mono' : path.endsWith('.lex') -// ? 'fak fa-lexon' : path.endsWith('.contract') -// ? 'fab fa-ethereum' : 'far fa-file' -// }, -// joinPath (...paths) { -// paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) -// if (paths.length === 1) return paths[0] -// return paths.join('/') -// }, -// extractNameFromKey (key) { -// const keyPath = key.split('/') - -// return keyPath[keyPath.length - 1] -// } - -// const findDeep = (object, fn, found = { break: false, value: undefined }) => { -// if (typeof object !== 'object' || object === null) return -// for (var i in object) { -// if (found.break) break -// var el = object[i] -// if (el && el.innerText !== undefined && el.innerText !== null) el = el.innerText -// if (fn(el, i, object)) { -// found.value = el -// found.break = true -// break -// } else { -// findDeep(el, fn, found) -// } -// } -// return found.value -// } - -// const find = (args, query) => { -// query = query.trim() -// var isMatch = !!findDeep(args, function check (value, key) { -// if (value === undefined || value === null) return false -// if (typeof value === 'function') return false -// if (typeof value === 'object') return false -// var contains = String(value).indexOf(query.trim()) !== -1 -// return contains -// }) -// return isMatch -// } From cb1338e0059b2ef7316e5f3686c8af82c4a080d6 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Mon, 16 Aug 2021 14:57:24 +0100 Subject: [PATCH 17/48] reduced terminal dragable border width and resolved search error --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.css | 2 +- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 5a4ffee292..73ccb7096e 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -141,7 +141,7 @@ element.style { .dragbarHorizontal { position : absolute; top : 0; - height : 0.5em; + height : 0.2em; right : 0; left : 0; cursor : row-resize; 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 9be04ca258..42cc08ea73 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -797,7 +797,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { {/* ${self._view.inputSearch} */} setSearchInput(event.target.value) } + onChange={(event) => setSearchInput(event.target.value.trim()) } type="text" className="border filter form-control" id="searchInput" @@ -830,7 +830,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
) } else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { - return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || x.tx.to.includes(searchInput)).map((trans) => { + return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => { return (
{renderKnownTransactions(trans.tx, trans.receipt, index)}
) }) } else { From 1d5bba7ec9f98b7c44d1e7ff731acf1f99534d81 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Mon, 16 Aug 2021 15:53:40 +0100 Subject: [PATCH 18/48] updated terminal css background color --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 73ccb7096e..2224326f5d 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -4,7 +4,8 @@ element.style { } #terminalCliInput{ width: 95%; - background-color: #222336; + background: transparent; + border: none; color: #a2a3bd; border-top-style: hidden; border-right-style: hidden; From 8869358eb217bccd9dd420e3a32033bd0948371c Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Mon, 16 Aug 2021 16:08:05 +0100 Subject: [PATCH 19/48] removed autoComplete highlight --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.css | 1 + libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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 2224326f5d..894a7bfd05 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -23,6 +23,7 @@ element.style { border: 1px solid #3f4455!important; } +/* seleted option should reflect the theme color */ .selectedOptions { background-color: #222336; } 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 42cc08ea73..0cdf083af7 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -744,7 +744,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{autoCompletState.data._options.map((item, index) => { return ( -
+
{getKeyOf(item)}
From fde8884d1323a8ca225f6e009f6e976f4e971b86 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 12:09:13 +0100 Subject: [PATCH 20/48] fix: resolved `remix.exeCurrent()` error --- libs/remix-ui/terminal/src/lib/commands.ts | 42 ++++++++++--------- .../terminal/src/lib/remix-ui-terminal.css | 3 +- .../terminal/src/lib/remix-ui-terminal.tsx | 25 ++++++++--- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/libs/remix-ui/terminal/src/lib/commands.ts b/libs/remix-ui/terminal/src/lib/commands.ts index 62eaafa0a0..3e4a01e646 100644 --- a/libs/remix-ui/terminal/src/lib/commands.ts +++ b/libs/remix-ui/terminal/src/lib/commands.ts @@ -9,44 +9,48 @@ 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.' }, + // { '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/' }, + // { '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.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.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).' }, + //TODO: need to break down the object return from abi response + // { '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.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' } +// { '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' } ] + + + \ No newline at end of file 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 894a7bfd05..8bc8f22d64 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -6,7 +6,8 @@ element.style { width: 95%; background: transparent; border: none; - color: #a2a3bd; + font-weight: bold; + color: #a2a3b4; border-top-style: hidden; border-right-style: hidden; border-left-style: hidden; 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 0cdf083af7..45fdfea909 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -67,6 +67,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) const [isListeningOnNetwork, setIsListeningOnNetwork] = useState(false) const [clearConsole, setClearConsole] = useState(false) + const [paste, setPaste] = useState(false) const [autoCompletState, setAutoCompleteState] = useState({ activeSuggestion: 0, data: { @@ -175,7 +176,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - const context = execute(undefined, undefined) + const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) } } } try { const cmds = vm.createContext(context) const result = vm.runInContext(script, cmds) @@ -420,7 +421,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { event.preventDefault() const inputString = event.target.value if (matched(allPrograms, inputString) || inputString.includes('.')) { - setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: true, userInput: inputString })) + console.log(paste, 'onchange') + if (paste) { + setPaste(false) + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: inputString })) + } else { + setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: true, userInput: inputString })) + } const textList = inputString.split('.') if (textList.length === 1) { setAutoCompleteState(prevState => ({ ...prevState, data: { _options: [] } })) @@ -495,7 +502,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { return (
- [block:${block} txIndex:${i}] + [block:{block} txIndex:{i}]
from: {from}
to: {to}
value: {value} wei
@@ -510,7 +517,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { return (
- [block:${block} txIndex:${i}] + [block:{block} txIndex:{i}]
from: {from}
to: {to}
value: {value} wei
@@ -759,10 +766,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { ) /* end of autoComplete */ + const handlePaste = () => { + setPaste(true) + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false})) + } + return (
{console.log({ newstate })} {console.log({ props })} + {console.log({ autoCompletState })}
{/* ${self._view.dragbar} */}
@@ -824,7 +837,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { if (x.name === 'emptyBlock') { return ( -
+
[block:{x.message} - 0 {'transactions'} ]
@@ -845,7 +858,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{'>'} - onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput}> + onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput} onPaste={handlePaste}>
From 146c5307a2725df47ec13d99b92687993ff933c4 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 13:45:15 +0100 Subject: [PATCH 21/48] feat: uncomment and implemented loadgist --- libs/remix-ui/terminal/src/lib/commands.ts | 2 +- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/terminal/src/lib/commands.ts b/libs/remix-ui/terminal/src/lib/commands.ts index 3e4a01e646..a2e85f5b07 100644 --- a/libs/remix-ui/terminal/src/lib/commands.ts +++ b/libs/remix-ui/terminal/src/lib/commands.ts @@ -9,7 +9,7 @@ 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.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/' }, 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 45fdfea909..942d3f4439 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -169,6 +169,12 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { return '' } + function loadgist (id, cb) { + console.log('load gist') + props.gistHandler.loadFromGist({ gist: id }, props._deps.fileManager) + if (cb) cb() + } + const _shell = async (script, scopedCommands, done) => { // default shell if (script.indexOf('remix:') === 0) { return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.') @@ -176,7 +182,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) } } } + const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) }, loadgist: () => { return loadgist(script, undefined) } } } try { const cmds = vm.createContext(context) const result = vm.runInContext(script, cmds) From caa5debe4aeb4b3293dca16bc4017290852fb32b Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 14:17:37 +0100 Subject: [PATCH 22/48] fix: return an empty funtion in loadgist --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 942d3f4439..5644c329b1 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -182,7 +182,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) }, loadgist: () => { return loadgist(script, undefined) } } } + const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) }, loadgist: () => { return loadgist(script, () => {}) } } } try { const cmds = vm.createContext(context) const result = vm.runInContext(script, cmds) From f676d06d1012be4b4bb7a7f6675608267e1afb9c Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 14:42:34 +0100 Subject: [PATCH 23/48] fix: fixed load gist error --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 5644c329b1..86428a1a00 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -170,7 +170,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } function loadgist (id, cb) { - console.log('load gist') props.gistHandler.loadFromGist({ gist: id }, props._deps.fileManager) if (cb) cb() } @@ -182,7 +181,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (script.indexOf('remix.') === 0) { // we keep the old feature. This will basically only be called when the command is querying the "remix" object. // for all the other case, we use the Code Executor plugin - const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) }, loadgist: () => { return loadgist(script, () => {}) } } } + const context = { remix: { exeCurrent: () => { return execute(undefined, undefined) }, loadgist: (id: any) => { return loadgist(id, () => {}) } } } try { const cmds = vm.createContext(context) const result = vm.runInContext(script, cmds) From 9a44ad0c3f88353432cc60f2123abc79a04be7a7 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 14:53:31 +0100 Subject: [PATCH 24/48] feat: emit new transaction from RunTab --- apps/remix-ide/src/app/panels/terminal.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index c595e952f3..4e73323bb7 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -139,7 +139,12 @@ class Terminal extends Plugin { txListener = {this.txListener} eventsDecoder = {this.eventsDecoder} />, - this.element + this.element, + () => { + this.blockchain.events.on('newTransaction', (tx, receipt) => { + this.emit('newTransaction', tx, receipt) + }) + } ) } From 19b38ca7b7fb34d0a981adc967ea648ca0c08af7 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 15:14:59 +0100 Subject: [PATCH 25/48] fix: knownTransaction emited from RunTab --- .../terminal/src/lib/actions/terminalAction.ts | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index d032daafc5..4c1dba994d 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -200,21 +200,8 @@ export const initListeningOnNetwork = (props, dispatch) => { await props.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => { if (!error) { console.log({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }) - console.log('knownTransaction') - // logKnownTX({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }) - registerCommandAction('knownTransaction', function (args, cmds, append) { - var data = args[0] - console.log({ data }, 'knownTransaction') - // let el - // if (data.tx.isCall) { - // console.log({ data }) - // // el = renderCall(this, data) - // } else { - // // el = renderKnownTransaction(this, data, blockchain) - // } - // this.seen[data.tx.hash] = el - // append(el) - }, { activate: true }, dispatch) + console.log('knownTransaction dispatch') + dispatch({ type: 'knownTransaction', payload: { message: [{ tx: tx, receipt: receipt }] } }) } }) } else { From 29e900a96d35232a1e4f9e3cb13e3b18fe3219be Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Tue, 17 Aug 2021 18:03:58 +0100 Subject: [PATCH 26/48] refactor: deploy from run and deploy tab error --- libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts | 2 +- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index 7b9043f6c5..b949f4a272 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -177,7 +177,7 @@ export const registerScriptRunnerReducer = (state, action) => { case 'unknownTransaction': return { ...state, - journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'knownTransaction' }) + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'unknownTransaction' }) } case 'emptyBlock': console.log({ action: action.payload.message }, ' emptyBLock reducer') 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 86428a1a00..185cad167c 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -849,9 +849,11 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { ) } else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => { + console.log({ trans }, 'first output from deploy') return (
{renderKnownTransactions(trans.tx, trans.receipt, index)}
) }) } else { + console.log({ x }, 'second output from deploy') return (
{x.message} From dc35a7f0b96f091db990666645f9cf3ff2c7071c Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 08:17:52 +0100 Subject: [PATCH 27/48] fix: now passing resolveData and logs from knownTransaction in Deploy tab --- .../terminal/src/lib/actions/terminalAction.ts | 4 ++-- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index 4c1dba994d..190c411500 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -197,11 +197,11 @@ export const initListeningOnNetwork = (props, dispatch) => { compiledContracts = await props._deps.compilersArtefacts.__last.getContracts() } console.log({ compiledContracts }) - await props.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => { + await props.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, async (error, logs) => { if (!error) { console.log({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }) console.log('knownTransaction dispatch') - dispatch({ type: 'knownTransaction', payload: { message: [{ tx: tx, receipt: receipt }] } }) + await dispatch({ type: 'knownTransaction', payload: { message: [{ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }] } }) } }) } else { 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 185cad167c..688ea1cf16 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -714,9 +714,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - const renderKnownTransactions = (tx, receipt, index) => { + const renderUnKnownTransactions = (tx, receipt, resolvedData, logs, index) => { const from = tx.from - const to = tx.to + const to = tx.to ? tx.to : resolvedData.contractName + '.' + resolvedData.fn const obj = { from, to } const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx') return ( @@ -740,9 +740,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { to, gas: tx.gas, input: tx.input, - 'decoded input': tx.resolvedData && tx.resolvedData.params ? JSON.stringify(typeConversion.stringify(tx.resoparams), null, '\t') : ' - ', - 'decoded output': tx.resolvedData && tx.resolvedData.decodedReturnValue ? JSON.stringify(typeConversion.stringify(tx.resolvedData.decodedReturnValue), null, '\t') : ' - ', - logs: tx.logs, + 'decoded input': resolvedData && resolvedData.params ? JSON.stringify(typeConversion.stringify(resolvedData.params), null, '\t') : ' - ', + 'decoded output': resolvedData && resolvedData.decodedReturnValue ? JSON.stringify(typeConversion.stringify(resolvedData.decodedReturnValue), null, '\t') : ' - ', + logs: logs, val: tx.value, transactionCost: tx.transactionCost, executionCost: tx.executionCost @@ -850,7 +850,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => { console.log({ trans }, 'first output from deploy') - return (
{renderKnownTransactions(trans.tx, trans.receipt, index)}
) + return (
{renderUnKnownTransactions(trans.tx, trans.receipt, trans.resolvedData, trans.logs, index)}
) }) } else { console.log({ x }, 'second output from deploy') From 1b0b8f7efa6f6784b1a80754cc04fd88813581bc Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 09:30:49 +0100 Subject: [PATCH 28/48] change logs array to string for test purpose --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 688ea1cf16..3c5615370a 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -499,7 +499,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
to: {to}
value: {value} wei
data: {input}
-
logs: {logs}
+
logs: {logs.toString()}
hash: {hash}
) @@ -512,7 +512,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
to: {to}
value: {value} wei
data: {input}
-
logs: {logs}
+
logs: {logs.toString()}
hash: {hash}
) @@ -718,7 +718,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const from = tx.from const to = tx.to ? tx.to : resolvedData.contractName + '.' + resolvedData.fn const obj = { from, to } - const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx') + const txType = resolvedData ? 'knownTx' : 'unknown' + (tx.isCall ? 'Call' : 'Tx') return (
txDetails(event, tx, obj)}> From 626305a0e39d846c1925573e11660366f9857291 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 09:53:23 +0100 Subject: [PATCH 29/48] log response of show table --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 3c5615370a..5609b20d39 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -499,7 +499,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
to: {to}
value: {value} wei
data: {input}
-
logs: {logs.toString()}
+
logs: {logs}
hash: {hash}
) @@ -512,7 +512,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
to: {to}
value: {value} wei
data: {input}
-
logs: {logs.toString()}
+
logs: {logs}
hash: {hash}
) @@ -544,6 +544,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const showTable = (opts) => { + console.log({ opts }, ' show table') let msg = '' let toHash const data = opts.data // opts.data = data.tx From bd3caa4a861c518b5e5e9b834d593139ed8dde9d Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 11:22:58 +0100 Subject: [PATCH 30/48] removed third params in ReactDom.render for terminal --- apps/remix-ide/src/app/panels/terminal.js | 7 +------ libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 4e73323bb7..c595e952f3 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -139,12 +139,7 @@ class Terminal extends Plugin { txListener = {this.txListener} eventsDecoder = {this.eventsDecoder} />, - this.element, - () => { - this.blockchain.events.on('newTransaction', (tx, receipt) => { - this.emit('newTransaction', tx, receipt) - }) - } + this.element ) } 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 5609b20d39..7d05de3d03 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -544,7 +544,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const showTable = (opts) => { - console.log({ opts }, ' show table') let msg = '' let toHash const data = opts.data // opts.data = data.tx From 25ce775d2b16f2e77fbbe6610a457d4476ff0282 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 11:31:18 +0100 Subject: [PATCH 31/48] commenting out vm table --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 7d05de3d03..b170c48a43 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -487,7 +487,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const input = data.input ? helper.shortenHexData(data.input) : '' const logs = data.logs && data.logs.decoded && data.logs.decoded.length ? data.logs.decoded.length : 0 const block = data.receipt ? data.receipt.blockNumber : data.blockNumber || '' - const i = data ? data.transactionIndex : data.transactionIndex + const i = data.receipt ? data.transactionIndex : data.transactionIndex const value = val ? typeConversion.toInt(val) : 0 if (blockchain.getProvider() === 'vm') { @@ -495,12 +495,12 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
[{vm}] -
from: {from}
+ {/*
from: {from}
to: {to}
value: {value} wei
data: {input}
logs: {logs}
-
hash: {hash}
+
hash: {hash}
*/}
) } else if (blockchain.getProvider() !== 'vm' && data.resolvedData) { From 9dcd0e68130937c66dd018c147380beb6d21d921 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 12:00:29 +0100 Subject: [PATCH 32/48] testing --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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 b170c48a43..8f0d1d10c9 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -465,6 +465,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } const checkTxStatus = (tx, type) => { + console.log('inside checkTxStatus') if (tx.status === '0x1' || tx.status === true) { return () } @@ -489,18 +490,19 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const block = data.receipt ? data.receipt.blockNumber : data.blockNumber || '' const i = data.receipt ? data.transactionIndex : data.transactionIndex const value = val ? typeConversion.toInt(val) : 0 - + console.log('inside context method') if (blockchain.getProvider() === 'vm') { return (
+ {console.log('inside context method return')} [{vm}] - {/*
from: {from}
+
from: {from}
to: {to}
value: {value} wei
data: {input}
logs: {logs}
-
hash: {hash}
*/} +
hash: {hash}
) } else if (blockchain.getProvider() !== 'vm' && data.resolvedData) { @@ -719,12 +721,14 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const to = tx.to ? tx.to : resolvedData.contractName + '.' + resolvedData.fn const obj = { from, to } const txType = resolvedData ? 'knownTx' : 'unknown' + (tx.isCall ? 'Call' : 'Tx') + console.log('render unknown transaction ') return (
txDetails(event, tx, obj)}> {/* onClick={e => txDetails(e, tx, data, obj)} */} {checkTxStatus(receipt || tx, txType)} {context({ from, to, tx }, props.blockchain)} + { console.log('under context and checkTxStatus')}
debug(event, tx)}>Debug
@@ -747,6 +751,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { transactionCost: tx.transactionCost, executionCost: tx.executionCost }) : null} + { console.log('end')} ) } From 650d7bd68967b99108dbc2daa2ca3fec03bcf136 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 13:02:41 +0100 Subject: [PATCH 33/48] testing if table error --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 8f0d1d10c9..8fd6cf8268 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -663,14 +663,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
)} - {opts['decoded input'] && ( + {console.log(opts['decoded input'], 'opts["decoded input"]')} + {console.log(opts.log, 'opts log')} + {/* {opts['decoded input'] && ( - )} + )} */} {opts['decoded output'] && ( @@ -679,7 +681,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { )} - {opts.logs && ( + {/* {opts.logs && ( - )} + )} */} {opts.val && ( From 1e7ea020bc66debdd1d7f810ecf63a53e1e5e742 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 15:17:48 +0100 Subject: [PATCH 34/48] creating a KnownTransaction function --- .../terminal/src/lib/remix-ui-terminal.tsx | 64 +++++++++++++++---- 1 file changed, 52 insertions(+), 12 deletions(-) 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 8fd6cf8268..6933a2cfdb 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -663,16 +663,14 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { )} - {console.log(opts['decoded input'], 'opts["decoded input"]')} - {console.log(opts.log, 'opts log')} - {/* {opts['decoded input'] && ( + {opts['decoded input'] && ( - )} */} + )} {opts['decoded output'] && ( @@ -681,7 +679,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { )} - {/* {opts.logs && ( + {opts.logs && ( - )} */} + )} {opts.val && ( @@ -718,11 +716,11 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - const renderUnKnownTransactions = (tx, receipt, resolvedData, logs, index) => { + const renderUnKnownTransactions = (tx, receipt, index) => { const from = tx.from - const to = tx.to ? tx.to : resolvedData.contractName + '.' + resolvedData.fn + const to = tx.to const obj = { from, to } - const txType = resolvedData ? 'knownTx' : 'unknown' + (tx.isCall ? 'Call' : 'Tx') + const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx') console.log('render unknown transaction ') return ( @@ -732,7 +730,44 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { {context({ from, to, tx }, props.blockchain)} { console.log('under context and checkTxStatus')}
-
debug(event, tx)}>Debug
+
debug(event, tx)}>Debug
+
+ + + {showTableHash.includes(tx.hash) ? showTable({ + hash: tx.hash, + status: receipt !== null ? receipt.status : null, + isCall: tx.isCall, + contractAddress: tx.contractAddress, + data: tx, + from, + to, + gas: tx.gas, + input: tx.input, + 'decoded output': ' - ', + val: tx.value, + transactionCost: tx.transactionCost, + executionCost: tx.executionCost + }) : null} + { console.log('end')} +
+ ) + } + + const renderKnownTransactions = (tx, receipt, resolvedData, logs, index) => { + const from = tx.from + const to = resolvedData.contractName + '.' + resolvedData.fn + const obj = { from, to } + const txType = 'knownTx' + console.log('render unknown transaction ') + return ( + +
txDetails(event, tx, obj)}> + {/* onClick={e => txDetails(e, tx, data, obj)} */} + {checkTxStatus(receipt, txType)} + {context({ from, to, tx }, props.blockchain)} +
+
debug(event, tx)}>Debug
@@ -854,10 +889,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
[block:{x.message} - 0 {'transactions'} ]
) - } else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { + } else if (x.name === 'unknownTransaction') { return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => { console.log({ trans }, 'first output from deploy') - return (
{renderUnKnownTransactions(trans.tx, trans.receipt, trans.resolvedData, trans.logs, index)}
) + return (
{renderUnKnownTransactions(trans.tx, trans.receipt, index)}
) + }) + } else if (x.name === 'knownTransaction') { + return x.message.map((trans) => { + console.log({ trans }, 'first output from deploy') + return (
{renderKnownTransactions(trans.tx, trans.receipt, trans.resolvedData, trans.logs, index)}
) }) } else { console.log({ x }, 'second output from deploy') From acc16461a35d079787875ff93dc9801afcfd8f6c Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 16:11:55 +0100 Subject: [PATCH 35/48] fix error with run and deploy --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 6933a2cfdb..42fa317c48 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -496,7 +496,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
{console.log('inside context method return')} - [{vm}] + [vm]
from: {from}
to: {to}
value: {value} wei
@@ -763,7 +763,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { return (
txDetails(event, tx, obj)}> - {/* onClick={e => txDetails(e, tx, data, obj)} */} {checkTxStatus(receipt, txType)} {context({ from, to, tx }, props.blockchain)}
From eade3392af6b41f3947174caf8a6fe8ef9dd80d1 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 16:57:50 +0100 Subject: [PATCH 36/48] fix: table status not showing true --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 42fa317c48..5642294ffd 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -579,7 +579,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
status {opts.status}{msg}
decode input {opts['decoded input']}
decode output
logs @@ -688,7 +690,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
val
decode input {opts['decoded input']}
decode output
logs @@ -690,7 +688,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
val
- + From 8bf93efdd537ee03293a21d36c10c12d87afbf7b Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 17:07:36 +0100 Subject: [PATCH 37/48] fix --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5642294ffd..c05b58bf58 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -561,7 +561,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (!opts.isCall) { if (opts.status !== undefined && opts.status !== null) { if (opts.status === '0x0' || opts.status === false) { - msg = ' Transaction mined but execution failed' + msg = 'Transaction mined but execution failed' } else if (opts.status === '0x1' || opts.status === true) { msg = ' Transaction mined and execution succeed' } From 8d6a83303e5cb7ada8ee853aa635c651292fe481 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 17:10:12 +0100 Subject: [PATCH 38/48] fix: removed empty spaces in transaction messages --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c05b58bf58..885c03e41d 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -563,10 +563,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { if (opts.status === '0x0' || opts.status === false) { msg = 'Transaction mined but execution failed' } else if (opts.status === '0x1' || opts.status === true) { - msg = ' Transaction mined and execution succeed' + msg = 'Transaction mined and execution succeed' } } else { - msg = ' Status not available at the moment' + msg = 'Status not available at the moment' } } From a048bba0e91e9e3f5ce4ab4ce966ca19e7e5eb08 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Wed, 18 Aug 2021 21:04:49 +0100 Subject: [PATCH 39/48] testing terminalJournal --- .../remix-ide-e2e/src/commands/journalLastChildIncludes.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/journalLastChildIncludes.ts b/apps/remix-ide-e2e/src/commands/journalLastChildIncludes.ts index e99f611a79..b9196128f5 100644 --- a/apps/remix-ide-e2e/src/commands/journalLastChildIncludes.ts +++ b/apps/remix-ide-e2e/src/commands/journalLastChildIncludes.ts @@ -7,11 +7,12 @@ import EventEmitter from 'events' class JournalLastChildIncludes extends EventEmitter { command (this: NightwatchBrowser, val: string): NightwatchBrowser { this.api - .waitForElementVisible('*[data-id="terminalJournal"] > div:last-child', 10000) - .getText('*[data-id="terminalJournal"] > div:last-child', (result) => { + .waitForElementVisible('*[data-id="terminalJournal"]', 10000) + .pause(80000) + .getText('*[data-id="terminalJournal"]', (result) => { console.log('JournalLastChildIncludes', result.value) if (typeof result.value === 'string' && result.value.indexOf(val) === -1) return this.api.assert.fail(`wait for ${val} in ${result.value}`) - else this.api.assert.ok(true, `<*[data-id="terminalJournal"] > div:last-child> contains ${val}.`) + else this.api.assert.ok(true, `<*[data-id="terminalJournal"]> contains ${val}.`) this.emit('complete') }) return this From 4c6157361aa7d131abbda8ff3318589a73e77ef0 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 12:32:08 +0100 Subject: [PATCH 40/48] implementing deployment failure in terminal --- .../src/tests/defaultLayout.test.ts | 1 + .../src/tests/libraryDeployment.test.ts | 1 + apps/remix-ide/src/app/panels/terminal.js | 7 ++++-- .../src/lib/actions/terminalAction.ts | 25 ++++++------------- .../src/lib/reducers/terminalReducer.ts | 7 ++++-- .../terminal/src/lib/remix-ui-terminal.tsx | 20 +++++++++------ 6 files changed, 33 insertions(+), 28 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts b/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts index 94bc20207d..239f55a448 100644 --- a/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts +++ b/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts @@ -50,6 +50,7 @@ module.exports = { 'Toggles Terminal': function (browser: NightwatchBrowser) { browser.waitForElementVisible('div[data-id="terminalContainer"]') + .pause(5000) .assert.visible('div[data-id="terminalContainerDisplay"]') .click('i[data-id="terminalToggleIcon"]') .checkElementStyle('div[data-id="terminalToggleMenu"]', 'height', '35px') diff --git a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts index 0a759aa332..ec513b9831 100644 --- a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts +++ b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts @@ -77,6 +77,7 @@ function checkDeployShouldFail (browser: NightwatchBrowser, callback: VoidFuncti .clickLaunchIcon('udapp') .selectContract('test') // deploy lib .createContract('') + .pause(60000) .getText('div[class^="terminal"]', (value) => { console.log('value: ', value) }) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index c595e952f3..638b97f5ed 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -88,6 +88,7 @@ class Terminal extends Plugin { this.call('menuicons', 'select', 'debugger') this.call('debugger', 'debug', hash) }) + this.logHtmlResponse = [] } onActivation () { @@ -102,8 +103,9 @@ class Terminal extends Plugin { } logHtml (html) { - var command = this.commands.html - if (typeof command === 'function') command(html) + // console.log({ html: html.innerText }) + this.logHtmlResponse.push(html.innerText) + this.renderComponent() } render () { @@ -138,6 +140,7 @@ class Terminal extends Plugin { commands = {this.commands} txListener = {this.txListener} eventsDecoder = {this.eventsDecoder} + logHtml = {this.logHtmlResponse} />, this.element ) diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index 190c411500..5d1023c34a 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -1,5 +1,6 @@ export const registerCommandAction = (name, command, activate, dispatch) => { + console.log(name, ' object key') const commands: any = {} const _commands: any = {} _commands[name] = command @@ -90,6 +91,8 @@ export const registerCommandAction = (name, command, activate, dispatch) => { console.log({ scopedCommands }) return scopedCommands } + + console.log('david test dispatch') } export const filterFnAction = (name, filterFn, dispatch) => { @@ -170,23 +173,8 @@ export const initListeningOnNetwork = (props, dispatch) => { // log(this, tx, null) }) props.txListener.event.register('newTransaction', (tx, receipt) => { + console.log('new Transaction now') log(props, tx, receipt, dispatch) - registerCommandAction('knownTransaction', function (args, cmds, append) { - var data = args[0] - console.log({ data }) - // let el - // if (data.tx.isCall) { - // console.log({ data }) - // // el = renderCall(this, data) - // } else { - // // el = renderKnownTransaction(this, data, blockchain) - // } - // this.seen[data.tx.hash] = el - // append(el) - }, { activate: true }, dispatch) - // const result = Object.assign([], tx) - // console.log({ result }) - // scriptRunnerDispatch({ type: 'knownTransaction', payload: { message: result } }) }) const log = async (props, tx, receipt, dispatch) => { @@ -214,9 +202,12 @@ export const initListeningOnNetwork = (props, dispatch) => { props.txListener.event.register('debuggingRequested', async (hash) => { // TODO should probably be in the run module - console.log({ hash }, 'register Call') if (!await props.options.appManager.isActive('debugger')) await props.options.appManager.activatePlugin('debugger') props.thisState.call('menuicons', 'select', 'debugger') props.thisState.call('debugger', 'debug', hash) }) + + props.thisState.on('udapp', 'logHtml', (log) => { + console.log({ log }, ' listen to logHTML call') + }) } diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index b949f4a272..332402b427 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -141,9 +141,12 @@ export const remixWelcomeTextReducer = (state, action) => { } export const registerScriptRunnerReducer = (state, action) => { - const result = Object.assign([], action.payload.message) - console.log({ result }) switch (action.type) { + case 'html': + return { + ...state, + journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log' }) + } case 'log': return { ...state, 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 885c03e41d..a186d0a4a4 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -44,7 +44,8 @@ export interface RemixUiTerminalProps { registry: any, commands: any, txListener: any, - eventsDecoder: any + eventsDecoder: any, + logHtml: any } export interface ClipboardEvent extends SyntheticEvent { @@ -102,6 +103,11 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }) } + useEffect(() => { + scriptRunnerDispatch({ type: 'html', payload: { message: props.logHtml } }) + }, [props.logHtml]) + + console.log({ logHtml: props.logHtml }) // events useEffect(() => { initListeningOnNetwork(props, scriptRunnerDispatch) @@ -109,7 +115,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) - registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch) registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch) registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch) @@ -118,12 +123,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerCommandAction('script', function execute (args, scopedCommands, append) { var script = String(args[0]) + console.log({ script }, 'script') _shell(script, scopedCommands, function (error, output) { if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } }) if (output) scriptRunnerDispatch({ type: 'script', payload: { message: '5' } }) }) }, { activate: true }, dispatch) - }, [props.thisState.autoCompletePopup, autoCompletState.text]) + }, [props.thisState.autoCompletePopup, autoCompletState.text, props.logHtml]) useEffect(() => { scrollToBottom() @@ -870,15 +876,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { { handleAutoComplete() } -
-
+
{!clearConsole && } {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { if (x.name === 'emptyBlock') { From f6fdb9c357b1438e3df4ff5f2dc4efb1bf519047 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 13:06:37 +0100 Subject: [PATCH 41/48] fix linting error --- apps/remix-ide-e2e/src/commands/verifyContracts.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide-e2e/src/commands/verifyContracts.ts b/apps/remix-ide-e2e/src/commands/verifyContracts.ts index e7dbf4a591..aef1b06217 100644 --- a/apps/remix-ide-e2e/src/commands/verifyContracts.ts +++ b/apps/remix-ide-e2e/src/commands/verifyContracts.ts @@ -17,6 +17,7 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str browser .clickLaunchIcon('solidity') .pause(opts.wait) + .pause(5000) .waitForElementPresent('*[data-id="compiledContracts"] option', 60000) .perform((done) => { if (opts.version) { From 6088d23747ace9fbaf6e85c1dc9e23e0f65d7f55 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 13:08:22 +0100 Subject: [PATCH 42/48] fix merge conflict --- tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index d9d0b3fb8c..e19463be66 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -43,7 +43,6 @@ "@remix-ui/publish-to-storage": ["libs/remix-ui/publish-to-storage/src/index.ts"], "@remix-ui/renderer": ["libs/remix-ui/renderer/src/index.ts"] } - "allowSyntheticDefaultImports": true }, "exclude": ["node_modules", "tmp"] } From 417351fa1f0d79718339529be2bf757b2003c8f6 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 14:08:02 +0100 Subject: [PATCH 43/48] commit b4 revert --- .env | 4 --- .../src/tests/defaultLayout.test.ts | 1 - .../src/tests/libraryDeployment.test.ts | 1 - libs/remix-ui/terminal/src/index.ts | 2 +- .../src/lib/actions/terminalAction.ts | 25 +++++++++++++------ .../src/lib/reducers/terminalReducer.ts | 7 ++---- .../terminal/src/lib/remix-ui-terminal.tsx | 20 ++++++--------- 7 files changed, 27 insertions(+), 33 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 8db17993d7..0000000000 --- a/.env +++ /dev/null @@ -1,4 +0,0 @@ -gist_token= -account_passphrase= -account_password= -NODE_OPTIONS=--max-old-space-size=2048 \ No newline at end of file diff --git a/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts b/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts index 239f55a448..94bc20207d 100644 --- a/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts +++ b/apps/remix-ide-e2e/src/tests/defaultLayout.test.ts @@ -50,7 +50,6 @@ module.exports = { 'Toggles Terminal': function (browser: NightwatchBrowser) { browser.waitForElementVisible('div[data-id="terminalContainer"]') - .pause(5000) .assert.visible('div[data-id="terminalContainerDisplay"]') .click('i[data-id="terminalToggleIcon"]') .checkElementStyle('div[data-id="terminalToggleMenu"]', 'height', '35px') diff --git a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts index ec513b9831..0a759aa332 100644 --- a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts +++ b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts @@ -77,7 +77,6 @@ function checkDeployShouldFail (browser: NightwatchBrowser, callback: VoidFuncti .clickLaunchIcon('udapp') .selectContract('test') // deploy lib .createContract('') - .pause(60000) .getText('div[class^="terminal"]', (value) => { console.log('value: ', value) }) diff --git a/libs/remix-ui/terminal/src/index.ts b/libs/remix-ui/terminal/src/index.ts index 1735a3cf89..5b8eeca5b5 100644 --- a/libs/remix-ui/terminal/src/index.ts +++ b/libs/remix-ui/terminal/src/index.ts @@ -1 +1 @@ -export * from './lib/remix-ui-terminal'; +export * from './lib/remix-ui-terminal' diff --git a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts index 5d1023c34a..190c411500 100644 --- a/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts +++ b/libs/remix-ui/terminal/src/lib/actions/terminalAction.ts @@ -1,6 +1,5 @@ export const registerCommandAction = (name, command, activate, dispatch) => { - console.log(name, ' object key') const commands: any = {} const _commands: any = {} _commands[name] = command @@ -91,8 +90,6 @@ export const registerCommandAction = (name, command, activate, dispatch) => { console.log({ scopedCommands }) return scopedCommands } - - console.log('david test dispatch') } export const filterFnAction = (name, filterFn, dispatch) => { @@ -173,8 +170,23 @@ export const initListeningOnNetwork = (props, dispatch) => { // log(this, tx, null) }) props.txListener.event.register('newTransaction', (tx, receipt) => { - console.log('new Transaction now') log(props, tx, receipt, dispatch) + registerCommandAction('knownTransaction', function (args, cmds, append) { + var data = args[0] + console.log({ data }) + // let el + // if (data.tx.isCall) { + // console.log({ data }) + // // el = renderCall(this, data) + // } else { + // // el = renderKnownTransaction(this, data, blockchain) + // } + // this.seen[data.tx.hash] = el + // append(el) + }, { activate: true }, dispatch) + // const result = Object.assign([], tx) + // console.log({ result }) + // scriptRunnerDispatch({ type: 'knownTransaction', payload: { message: result } }) }) const log = async (props, tx, receipt, dispatch) => { @@ -202,12 +214,9 @@ export const initListeningOnNetwork = (props, dispatch) => { props.txListener.event.register('debuggingRequested', async (hash) => { // TODO should probably be in the run module + console.log({ hash }, 'register Call') if (!await props.options.appManager.isActive('debugger')) await props.options.appManager.activatePlugin('debugger') props.thisState.call('menuicons', 'select', 'debugger') props.thisState.call('debugger', 'debug', hash) }) - - props.thisState.on('udapp', 'logHtml', (log) => { - console.log({ log }, ' listen to logHTML call') - }) } diff --git a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts index 332402b427..b949f4a272 100644 --- a/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts +++ b/libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts @@ -141,12 +141,9 @@ export const remixWelcomeTextReducer = (state, action) => { } export const registerScriptRunnerReducer = (state, action) => { + const result = Object.assign([], action.payload.message) + console.log({ result }) switch (action.type) { - case 'html': - return { - ...state, - journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log' }) - } case 'log': return { ...state, 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 a186d0a4a4..885c03e41d 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -44,8 +44,7 @@ export interface RemixUiTerminalProps { registry: any, commands: any, txListener: any, - eventsDecoder: any, - logHtml: any + eventsDecoder: any } export interface ClipboardEvent extends SyntheticEvent { @@ -103,11 +102,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }) } - useEffect(() => { - scriptRunnerDispatch({ type: 'html', payload: { message: props.logHtml } }) - }, [props.logHtml]) - - console.log({ logHtml: props.logHtml }) // events useEffect(() => { initListeningOnNetwork(props, scriptRunnerDispatch) @@ -115,6 +109,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) + registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch) registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch) registerCommandAction('info', _blocksRenderer('info'), { activate: true }, dispatch) @@ -123,13 +118,12 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { registerCommandAction('script', function execute (args, scopedCommands, append) { var script = String(args[0]) - console.log({ script }, 'script') _shell(script, scopedCommands, function (error, output) { if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } }) if (output) scriptRunnerDispatch({ type: 'script', payload: { message: '5' } }) }) }, { activate: true }, dispatch) - }, [props.thisState.autoCompletePopup, autoCompletState.text, props.logHtml]) + }, [props.thisState.autoCompletePopup, autoCompletState.text]) useEffect(() => { scrollToBottom() @@ -876,15 +870,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { { handleAutoComplete() } -
-
+
{!clearConsole && } {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { if (x.name === 'emptyBlock') { From 30736ae3d9c510502cd8e609403a78ee84ea0a5d Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 14:08:10 +0100 Subject: [PATCH 44/48] Revert "implementing deployment failure in terminal" This reverts commit 4c6157361aa7d131abbda8ff3318589a73e77ef0. --- apps/remix-ide/src/app/panels/terminal.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 638b97f5ed..c595e952f3 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -88,7 +88,6 @@ class Terminal extends Plugin { this.call('menuicons', 'select', 'debugger') this.call('debugger', 'debug', hash) }) - this.logHtmlResponse = [] } onActivation () { @@ -103,9 +102,8 @@ class Terminal extends Plugin { } logHtml (html) { - // console.log({ html: html.innerText }) - this.logHtmlResponse.push(html.innerText) - this.renderComponent() + var command = this.commands.html + if (typeof command === 'function') command(html) } render () { @@ -140,7 +138,6 @@ class Terminal extends Plugin { commands = {this.commands} txListener = {this.txListener} eventsDecoder = {this.eventsDecoder} - logHtml = {this.logHtmlResponse} />, this.element ) From 6d65346c87d4fc03f26972b22c5944042d194582 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 14:20:47 +0100 Subject: [PATCH 45/48] resolve conflict by removing tsconfig.base.json in nx.json file --- nx.json | 2 +- tsconfig.base.json | 48 ---------------------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 tsconfig.base.json diff --git a/nx.json b/nx.json index 5a9b54b1c4..7e9e61b00c 100644 --- a/nx.json +++ b/nx.json @@ -6,7 +6,7 @@ "dependencies": "*", "devDependencies": "*" }, - "tsconfig.base.json": "*", + "tsconfig.json": "*", "tslint.json": "*", ".eslintrc": "*", "nx.json": "*" diff --git a/tsconfig.base.json b/tsconfig.base.json deleted file mode 100644 index 87a3bd1b40..0000000000 --- a/tsconfig.base.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "rootDir": ".", - "sourceMap": true, - "declaration": false, - "moduleResolution": "node", - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "importHelpers": true, - "target": "es2015", - "module": "commonjs", - "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "es2019", "dom"], - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "baseUrl": ".", - "paths": { - "@remix-project/remix-analyzer": ["dist/libs/remix-analyzer/index.js"], - "@remix-project/remix-astwalker": ["dist/libs/remix-astwalker/index.js"], - "@remix-project/remix-debug": ["dist/libs/remix-debug/src/index.js"], - "@remix-project/remix-lib": ["dist/libs/remix-lib/src/index.js"], - "@remix-project/remix-simulator": ["dist/libs/remix-simulator/src/index.js"], - "@remix-project/remix-solidity": ["dist/libs/remix-solidity/index.js"], - "@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"], - "@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"], - "@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"], - "@remix-project/remixd": ["dist/libs/remixd/index.js"], - "@remix-ui/tree-view": ["libs/remix-ui/tree-view/src/index.ts"], - "@remix-ui/debugger-ui": ["libs/remix-ui/debugger-ui/src/index.ts"], - "@remix-ui/utils": ["libs/remix-ui/utils/src/index.ts"], - "@remix-ui/clipboard": ["libs/remix-ui/clipboard/src/index.ts"], - "@remix-project/remix-solidity-ts": ["libs/remix-solidity/src/index.ts"], - "@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"], - "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], - "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], - "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], - "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], - "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"], - "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"], - "@remix-project/core-plugin": ["libs/remix-core-plugin/src/index.ts"], - "@remix-ui/solidity-compiler": ["libs/remix-ui/solidity-compiler/src/index.ts"], - "@remix-ui/publish-to-storage": ["libs/remix-ui/publish-to-storage/src/index.ts"], - "@remix-ui/renderer": ["libs/remix-ui/renderer/src/index.ts"] - } - }, - "exclude": ["node_modules", "tmp"] -} From 1050a706b68bfab22776e8fed1ca416e45d2622a Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 14:28:56 +0100 Subject: [PATCH 46/48] removed unused variables --- libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 885c03e41d..556e292c79 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,8 +1,8 @@ import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line import { useWindowResize } from 'beautiful-react-hooks' -import { registerCommandAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, registerRemixWelcomeTextAction, listenOnNetworkAction, initListeningOnNetwork } from './actions/terminalAction' -import { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer, remixWelcomeTextReducer } from './reducers/terminalReducer' +import { registerCommandAction, registerLogScriptRunnerAction, registerInfoScriptRunnerAction, registerErrorScriptRunnerAction, registerWarnScriptRunnerAction, listenOnNetworkAction, initListeningOnNetwork } from './actions/terminalAction' +import { initialState, registerCommandReducer, addCommandHistoryReducer, registerScriptRunnerReducer, remixWelcomeTextReducer } from './reducers/terminalReducer' import { remixWelcome } from './reducers/remixWelcom' // eslint-disable-line import { getKeyOf, getValueOf, Objectfilter, matched } from './utils/utils' import {allCommands, allPrograms} from './commands' // eslint-disable-line From 02f71c0454a9d6b81e2e3242aee91d74e8a61259 Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 15:07:09 +0100 Subject: [PATCH 47/48] initially removed tsconfig.base.js, but replaced it back --- .../terminal/src/lib/remix-ui-terminal.tsx | 2 +- nx.json | 2 +- tsconfig.base.json | 48 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tsconfig.base.json 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 556e292c79..6ad040eca9 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -814,7 +814,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const handlePaste = () => { setPaste(true) - setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false})) + setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false })) } return ( diff --git a/nx.json b/nx.json index 7e9e61b00c..5a9b54b1c4 100644 --- a/nx.json +++ b/nx.json @@ -6,7 +6,7 @@ "dependencies": "*", "devDependencies": "*" }, - "tsconfig.json": "*", + "tsconfig.base.json": "*", "tslint.json": "*", ".eslintrc": "*", "nx.json": "*" diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000000..1213e78ff2 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,48 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "rootDir": ".", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "es2015", + "module": "commonjs", + "typeRoots": ["node_modules/@types"], + "lib": ["es2017", "es2019", "dom"], + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "baseUrl": ".", + "paths": { + "@remix-project/remix-analyzer": ["dist/libs/remix-analyzer/index.js"], + "@remix-project/remix-astwalker": ["dist/libs/remix-astwalker/index.js"], + "@remix-project/remix-debug": ["dist/libs/remix-debug/src/index.js"], + "@remix-project/remix-lib": ["dist/libs/remix-lib/src/index.js"], + "@remix-project/remix-simulator": ["dist/libs/remix-simulator/src/index.js"], + "@remix-project/remix-solidity": ["dist/libs/remix-solidity/index.js"], + "@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"], + "@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"], + "@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"], + "@remix-project/remixd": ["dist/libs/remixd/index.js"], + "@remix-ui/tree-view": ["libs/remix-ui/tree-view/src/index.ts"], + "@remix-ui/debugger-ui": ["libs/remix-ui/debugger-ui/src/index.ts"], + "@remix-ui/utils": ["libs/remix-ui/utils/src/index.ts"], + "@remix-ui/clipboard": ["libs/remix-ui/clipboard/src/index.ts"], + "@remix-project/remix-solidity-ts": ["libs/remix-solidity/src/index.ts"], + "@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"], + "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], + "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], + "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"], + "@remix-ui/terminal": ["libs/remix-ui/terminal/src/index.ts"], + "@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"], + "@remix-project/core-plugin": ["libs/remix-core-plugin/src/index.ts"], + "@remix-ui/solidity-compiler": ["libs/remix-ui/solidity-compiler/src/index.ts"], + "@remix-ui/publish-to-storage": ["libs/remix-ui/publish-to-storage/src/index.ts"], + "@remix-ui/renderer": ["libs/remix-ui/renderer/src/index.ts"] + } + }, + "exclude": ["node_modules", "tmp"] \ No newline at end of file From 627341f6a5ea4905e5a0330bcb41dc9aed7b420b Mon Sep 17 00:00:00 2001 From: "davidzagi93@gmail.com" Date: Fri, 20 Aug 2021 15:19:44 +0100 Subject: [PATCH 48/48] missing character in base.json --- tsconfig.base.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.base.json b/tsconfig.base.json index 1213e78ff2..6f01778c53 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -45,4 +45,5 @@ "@remix-ui/renderer": ["libs/remix-ui/renderer/src/index.ts"] } }, - "exclude": ["node_modules", "tmp"] \ No newline at end of file + "exclude": ["node_modules", "tmp"] +} \ No newline at end of file
status {opts.status}{msg}{`${opts.status} ${msg}`}
transaction hash