cleaning up code

pull/1342/head
davidzagi93@gmail.com 3 years ago
parent 0d86cc2f63
commit f4159099f9
  1. 8
      apps/remix-ide/src/app/panels/terminal.js
  2. 2
      apps/remix-ide/src/lib/cmdInterpreterAPI.js
  3. 6
      libs/remix-ui/terminal/src/lib/commands.ts
  4. 11
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.css
  5. 270
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  6. 30
      libs/remix-ui/terminal/src/lib/terminalWelcome.tsx
  7. 176
      libs/remix-ui/terminal/src/lib/utils/helper.ts

@ -37,7 +37,7 @@ class Terminal extends Plugin {
this.registry = registry this.registry = registry
this.globalRegistry = globalRegistry this.globalRegistry = globalRegistry
this.element = document.createElement('div') this.element = document.createElement('div')
this.element.setAttribute('class', 'panel_2A0YE0') this.element.setAttribute('class', 'panel')
this.element.setAttribute('id', 'terminal-view') this.element.setAttribute('id', 'terminal-view')
this.eventsDecoder = this.globalRegistry.get('eventsDecoder').api this.eventsDecoder = this.globalRegistry.get('eventsDecoder').api
this.txListener = this.globalRegistry.get('txlistener').api this.txListener = this.globalRegistry.get('txlistener').api
@ -82,6 +82,12 @@ class Terminal extends Plugin {
this._INDEX.commandsMain = {} this._INDEX.commandsMain = {}
if (opts.shell) this._shell = opts.shell // ??? if (opts.shell) this._shell = opts.shell // ???
register(this) 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 () { onActivation () {

@ -93,7 +93,7 @@ class CmdInterpreterAPI {
if (cb) cb() if (cb) cb()
return return
} }
console.log({ content }, ' contents')
self._components.terminal.commands.script(content) self._components.terminal.commands.script(content)
} }

@ -2,13 +2,13 @@ export const allPrograms = [
{ ethers: 'The ethers.js library is a compact and complete JavaScript library for Ethereum.' }, { ethers: 'The ethers.js library is a compact and complete JavaScript library for Ethereum.' },
{ remix: 'Ethereum IDE and tools for the web.' }, { 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.' }, { 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 = [ 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.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.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.loadurl(url)': 'Load the given url in the file explorer. The url can be of type github, swarm or ipfs.' },

@ -14,9 +14,6 @@ element.style {
#terminalCliInput:focus { #terminalCliInput:focus {
outline: none; outline: none;
} }
input #terminalCliInput {
}
.border-primary { .border-primary {
border-color: #007aa6!important; border-color: #007aa6!important;
@ -90,13 +87,13 @@ input #terminalCliInput {
font-family : monospace; font-family : monospace;
padding : .4em; padding : .4em;
color : var(--primary); color : var(--primary);
border-top : solid 2px var(--secondary);
} }
.prompt { .prompt {
margin-right : 0.5em; margin-right : 0.5em;
font-family : monospace; font-family : monospace;
font-weight : bold; font-weight : bold;
font-size : 14px; font-size : 14px;
color : lightgray;
} }
.input { .input {
word-break : break-word; word-break : break-word;
@ -275,8 +272,6 @@ input #terminalCliInput {
.arrow:hover { .arrow:hover {
color: var(--secondary); color: var(--secondary);
} }
.txLog {
}
.txStatus { .txStatus {
display: flex; display: flex;
font-size: 20px; font-size: 20px;
@ -324,6 +319,10 @@ input #terminalCliInput {
font-size: 10px; font-size: 10px;
color: var(--text-info); color: var(--text-info);
border: 1px solid 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 { #txTable {
margin-top: 1%; margin-top: 1%;

@ -1,23 +1,21 @@
import React, { useState, useEffect, useReducer, 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 { useKeyPress } from './custom-hooks/useKeyPress' // eslint-disable-line
import { useWindowResize } from 'beautiful-react-hooks' 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 { initialState, registerCommandReducer, registerFilterReducer, addCommandHistoryReducer, registerScriptRunnerReducer, remixWelcomeTextReducer } from './reducers/terminalReducer'
import { remixWelcome } from './reducers/remixWelcom' import { remixWelcome } from './reducers/remixWelcom' // eslint-disable-line
import { getKeyOf, getValueOf, Objectfilter, matched, find } from './utils/utils' import { getKeyOf, getValueOf, Objectfilter, matched } from './utils/utils'
import {allCommands, allPrograms} from './commands' // eslint-disable-line import {allCommands, allPrograms} from './commands' // eslint-disable-line
import { CopyToClipboard } from '@remix-ui/clipboard' // 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/' // const TxLogger from '../../../apps/'
import vm from 'vm' import vm from 'vm'
import javascriptserialize from 'javascript-serialize' import javascriptserialize from 'javascript-serialize'
import jsbeautify from 'js-beautify' import jsbeautify from 'js-beautify'
import helper from '../../../../../apps/remix-ide/src/lib/helper' 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') const remixLib = require('@remix-project/remix-lib')
var typeConversion = remixLib.execution.typeConversion var typeConversion = remixLib.execution.typeConversion
@ -55,7 +53,6 @@ export interface ClipboardEvent<T = Element> extends SyntheticEvent<T, any> {
export const RemixUiTerminal = (props: RemixUiTerminalProps) => { export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down')
const [inserted, setInserted] = useState(false)
const [_cmdIndex, setCmdIndex] = useState(-1) const [_cmdIndex, setCmdIndex] = useState(-1)
const [_cmdTemp, setCmdTemp] = useState('') const [_cmdTemp, setCmdTemp] = useState('')
const [_cmdHistory, setCmdHistory] = useState([]) const [_cmdHistory, setCmdHistory] = useState([])
@ -66,11 +63,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [dragging, setDragging] = useState(false) const [dragging, setDragging] = useState(false)
const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) const [newstate, dispatch] = useReducer(registerCommandReducer, initialState)
const [filterState, filterDispatch] = useReducer(registerFilterReducer, initialState)
const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState)
const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) const [scriptRunnserState, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState)
const [welcomeTextState, welcomTextDispath] = useReducer(remixWelcomeTextReducer, initialState)
const [isListeningOnNetwork, setIsListeningOnNetwork] = useState(false) const [isListeningOnNetwork, setIsListeningOnNetwork] = useState(false)
const [clearConsole, setClearConsole] = useState(false)
const [autoCompletState, setAutoCompleteState] = useState({ const [autoCompletState, setAutoCompleteState] = useState({
activeSuggestion: 0, activeSuggestion: 0,
data: { data: {
@ -91,7 +87,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [searchInput, setSearchInput] = useState('') const [searchInput, setSearchInput] = useState('')
// const [showTableDetails, setShowTableDetails] = useState([]) // const [showTableDetails, setShowTableDetails] = useState([])
const [showTableDetails, setShowTableDetails] = useState(null) const [showTableHash, setShowTableHash] = useState([])
useWindowResize(() => { useWindowResize(() => {
setWindowHeight(window.innerHeight) setWindowHeight(window.innerHeight)
@ -99,14 +95,20 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
// terminal inputRef // terminal inputRef
const inputEl = useRef(null) const inputEl = useRef(null)
const messagesEndRef = useRef(null)
const scrollToBottom = () => {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
}
// events // events
useEffect(() => { useEffect(() => {
initListeningOnNetwork(props, scriptRunnerDispatch) initListeningOnNetwork(props, scriptRunnerDispatch)
// registerRemixWelcomeTextAction(remixWelcome, welcomTextDispath)
registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch) registerLogScriptRunnerAction(props.thisState, 'log', newstate.commands, scriptRunnerDispatch)
registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch) registerInfoScriptRunnerAction(props.thisState, 'info', newstate.commands, scriptRunnerDispatch)
registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch) registerWarnScriptRunnerAction(props.thisState, 'warn', newstate.commands, scriptRunnerDispatch)
registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch) registerErrorScriptRunnerAction(props.thisState, 'error', newstate.commands, scriptRunnerDispatch)
registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch) registerCommandAction('html', _blocksRenderer('html'), { activate: true }, dispatch)
registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch) registerCommandAction('log', _blocksRenderer('log'), { activate: true }, dispatch)
registerCommandAction('info', _blocksRenderer('info'), { 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) { registerCommandAction('script', function execute (args, scopedCommands, append) {
var script = String(args[0]) var script = String(args[0])
console.log({ script })
console.log({ scopedCommands })
_shell(script, scopedCommands, function (error, output) { _shell(script, scopedCommands, function (error, output) {
if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } }) if (error) scriptRunnerDispatch({ type: 'error', payload: { message: error } })
if (output) scriptRunnerDispatch({ type: 'script', payload: { message: '5' } }) if (output) scriptRunnerDispatch({ type: 'script', payload: { message: '5' } })
}) })
}, { activate: true }, dispatch) }, { 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]) }, [props.thisState.autoCompletePopup, autoCompletState.text])
const placeCaretAtEnd = (el) => { useEffect(() => {
el.focus() scrollToBottom()
const range = document.createRange() console.log({ messagesEndRef: messagesEndRef.current }, ' onScroll')
range.selectNodeContents(el) }, [newstate.journalBlocks.length])
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)
}
function execute (file, cb) { function execute (file, cb) {
console.log('called execute scriptRunner')
function _execute (content, cb) { function _execute (content, cb) {
if (!content) { if (!content) {
// toolTip('no content to execute') // toolTip('no content to execute')
@ -194,44 +165,36 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
_execute(content, cb) _execute(content, cb)
}) })
return ''
} }
const _shell = async (script, scopedCommands, done) => { // default shell const _shell = async (script, scopedCommands, done) => { // default shell
if (script.indexOf('remix:') === 0) { 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.') 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) { if (script.indexOf('remix.') === 0) {
// we keep the old feature. This will basically only be called when the command is querying the "remix" object. // 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 // for all the other case, we use the Code Executor plugin
var context = domTerminalFeatures() const context = execute(undefined, undefined)
try { try {
const cmds = vm.createContext(context) const cmds = vm.createContext(context)
// const result const result = vm.runInContext(script, cmds)
let result = vm.runInContext(script, cmds) console.log(done, ' done func')
if (script === 'remix.exeCurrent()') { return done(null, result)
result = exeCurrent(undefined)
} else {
if (result === {}) {
for (const k in result) {
result = +`<div> {k}: ${result[k]}</div> <br>`
}
}
}
console.log(result === {}, ' is result === object')
console.log({ result })
return done(null, '')
} catch (error) { } catch (error) {
return done(error.message) return done(error.message)
} }
} }
try { try {
console.log(' remix command by david 2')
let result: any let result: any
if (script.trim().startsWith('git')) { if (script.trim().startsWith('git')) {
// result = await this.call('git', 'execute', script) // result = await this.call('git', 'execute', script)
} else { } else {
console.log(' remix command by david 3')
result = await props.thisState.call('scriptRunner', 'execute', script) result = await props.thisState.call('scriptRunner', 'execute', script)
console.log({ result }, ' me ')
} }
console.log({ result }) console.log({ result })
done() done()
@ -240,25 +203,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
} }
} }
// handle events
const handlePaste = (event: ClipboardEvent<HTMLInputElement>) => {
// 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) => { const handleMinimizeTerminal = (event) => {
event.preventDefault() event.preventDefault()
event.stopPropagation() 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 = () => { const focusinput = () => {
inputEl.current.focus() inputEl.current.focus()
} }
@ -311,15 +241,19 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const handleKeyDown = (event) => { const handleKeyDown = (event) => {
const suggestionCount = autoCompletState.activeSuggestion const suggestionCount = autoCompletState.activeSuggestion
if (autoCompletState.userInput !== '' && (event.which === 27 || event.which === 8 || event.which === 46)) { 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 // backspace or any key that should remove the autocompletion
setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false })) setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false }))
} }
if (autoCompletState.showSuggestions && (event.which === 13 || event.which === 9)) { if (autoCompletState.showSuggestions && (event.which === 13 || event.which === 9)) {
if (autoCompletState.userInput.length === 1) { if (autoCompletState.userInput.length === 1) {
setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: Object.keys(autoCompletState.data._options[0]).toString() })) setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: 0, showSuggestions: false, userInput: Object.keys(autoCompletState.data._options[0]).toString() }))
} else { }
setAutoCompleteState(prevState => ({ ...prevState, showSuggestions: false, userInput: autoCompletState.userInput })) // 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) { if (event.which === 13 && !autoCompletState.showSuggestions) {
@ -328,7 +262,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
inputEl.current.focus() inputEl.current.focus()
} else { // <enter> } else { // <enter>
event.preventDefault() event.preventDefault()
console.log('hit enter')
setCmdIndex(-1) setCmdIndex(-1)
setCmdTemp('') setCmdTemp('')
const script = autoCompletState.userInput.trim() // inputEl.current.innerText.trim() const script = autoCompletState.userInput.trim() // inputEl.current.innerText.trim()
@ -347,43 +280,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
event.preventDefault() event.preventDefault()
console.log(newstate._commandHistory[0], ' up value') console.log(newstate._commandHistory[0], ' up value')
setAutoCompleteState(prevState => ({ ...prevState, userInput: newstate._commandHistory[0] })) 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) { } else if (event.which === 38 && autoCompletState.showSuggestions) {
event.preventDefault() event.preventDefault()
if (autoCompletState.activeSuggestion === 0) { if (autoCompletState.activeSuggestion === 0) {
return return
} }
setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount - 1, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion - 1]).toString() })) setAutoCompleteState(prevState => ({ ...prevState, activeSuggestion: suggestionCount - 1, userInput: Object.keys(autoCompletState.data._options[autoCompletState.activeSuggestion]).toString() }))
console.log('disable up an down key in input box') console.log({ autoCompletState }, 'disable up an down key in input box')
} else if (event.which === 38 && !autoCompletState.showSuggestions) { // <arrowUp> } else if (event.which === 38 && !autoCompletState.showSuggestions) { // <arrowUp>
const len = _cmdHistory.length const len = _cmdHistory.length
if (len === 0) event.preventDefault() if (len === 0) event.preventDefault()
@ -408,21 +311,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
} else { } else {
setCmdTemp(inputEl.current.innerText) 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 */ /* 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 */ /* end of block content that gets rendered from script Runner */
const handleClearConsole = () => { const handleClearConsole = () => {
setClearConsole(true)
dispatch({ type: 'clearconsole', payload: [] }) dispatch({ type: 'clearconsole', payload: [] })
inputEl.current.focus() inputEl.current.focus()
} }
@ -637,21 +520,15 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
} }
const txDetails = (event, tx, obj) => { const txDetails = (event, tx, obj) => {
if (showTableDetails === null) { if (showTableHash.includes(tx.hash)) {
setShowTableDetails(true) const index = showTableHash.indexOf(tx.hash)
console.log({tx: tx.hash}) console.log({ index })
if (index > -1) {
setShowTableHash((prevState) => prevState.filter((x) => x !== tx.hash))
}
} else { } 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) => { const showTable = (opts) => {
@ -685,7 +562,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
} }
const val = opts.val != null ? typeConversion.toInt(opts.val) : 0 const val = opts.val != null ? typeConversion.toInt(opts.val) : 0
return ( return (
<table className='txTable' id='txTable' data-id={`txLoggerTable${opts.hash}`}> <table className={`txTable ${showTableHash.includes(opts.hash) ? 'active' : ''}`} id='txTable' data-id={`txLoggerTable${opts.hash}`}>
<tr className='tr'> <tr className='tr'>
<td className='td' data-shared={`key_${opts.hash}`}> status </td> <td className='td' data-shared={`key_${opts.hash}`}> status </td>
<td className='td' data-id={`txLoggerTableStatus${opts.hash}`} data-shared={`pair_${opts.hash}`}>{opts.status}{msg}</td> <td className='td' data-id={`txLoggerTableStatus${opts.hash}`} data-shared={`pair_${opts.hash}`}>{opts.status}{msg}</td>
@ -829,7 +706,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const from = tx.from const from = tx.from
const to = tx.to const to = tx.to
const obj = { from, to } const obj = { from, to }
const showDetails = showTableDetails === tx.from
const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx') const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx')
return ( return (
<span id={`tx${tx.hash}`} key={index}> <span id={`tx${tx.hash}`} key={index}>
@ -840,9 +716,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
<div className='buttons'> <div className='buttons'>
<div className='debug btn btn-primary btn-sm' onClick={(event) => debug(event, tx)}>Debug</div> <div className='debug btn btn-primary btn-sm' onClick={(event) => debug(event, tx)}>Debug</div>
</div> </div>
<i className = {`arrow fas ${(showDetails) ? 'fa-angle-up' : 'fa-angle-down'}`}></i> <i className = {`arrow fas ${(showTableHash.includes(tx.hash)) ? 'fa-angle-up' : 'fa-angle-down'}`}></i>
</div> </div>
{showTableDetails ? showTable({ {showTableHash.includes(tx.hash) ? showTable({
hash: tx.hash, hash: tx.hash,
status: receipt !== null ? receipt.status : null, status: receipt !== null ? receipt.status : null,
isCall: tx.isCall, isCall: tx.isCall,
@ -884,23 +760,23 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
/* end of autoComplete */ /* end of autoComplete */
return ( return (
<div style={{ height: '323px', flexGrow: 1 }} className='panel_2A0YE0'> <div style={{ height: '323px', flexGrow: 1 }} className='panel'>
{console.log({ newstate })} {console.log({ newstate })}
{console.log({ props })} {console.log({ props })}
<div className="bar_2A0YE0"> <div className="bar">
{/* ${self._view.dragbar} */} {/* ${self._view.dragbar} */}
<div className="dragbarHorizontal" onMouseDown={mousedown} id='dragId'></div> <div className="dragbarHorizontal" onMouseDown={mousedown} id='dragId'></div>
<div className="menu_2A0YE0 border-top border-dark bg-light" data-id="terminalToggleMenu"> <div className="menu border-top border-dark bg-light" data-id="terminalToggleMenu">
{/* ${self._view.icon} */} {/* ${self._view.icon} */}
<i className={`mx-2 toggleTerminal_2A0YE0 fas ${toggleDownUp}`} data-id="terminalToggleIcon" onClick={ handleMinimizeTerminal }></i> <i className={`mx-2 toggleTerminal fas ${toggleDownUp}`} data-id="terminalToggleIcon" onClick={ handleMinimizeTerminal }></i>
<div className="mx-2 console" id="clearConsole" data-id="terminalClearConsole" onClick={handleClearConsole} > <div className="mx-2 console" id="clearConsole" data-id="terminalClearConsole" onClick={handleClearConsole} >
<i className="fas fa-ban" aria-hidden="true" title="Clear console" <i className="fas fa-ban" aria-hidden="true" title="Clear console"
></i> ></i>
</div> </div>
{/* ${self._view.pendingTxCount} */} {/* ${self._view.pendingTxCount} */}
<div className="mx-2" title='Pending Transactions'>0</div> <div className="mx-2" title='Pending Transactions'>0</div>
<div className="verticalLine_2A0YE0"></div> <div className="verticalLine"></div>
<div className="pt-1 h-80 mx-3 align-items-center listenOnNetwork_2A0YE0 custom-control custom-checkbox"> <div className="pt-1 h-80 mx-3 align-items-center listenOnNetwork custom-control custom-checkbox">
<input <input
className="custom-control-input" className="custom-control-input"
id="listenNetworkCheck" id="listenNetworkCheck"
@ -916,14 +792,14 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
listen on network listen on network
</label> </label>
</div> </div>
<div className="search_2A0YE0"> <div className="search">
<i className="fas fa-search searchIcon_2A0YE0 bg-light" aria-hidden="true"></i> <i className="fas fa-search searchIcon bg-light" aria-hidden="true"></i>
{/* ${self._view.inputSearch} */} {/* ${self._view.inputSearch} */}
<input <input
// spellcheck = "false" // spellcheck = "false"
onChange={(event) => setSearchInput(event.target.value) } onChange={(event) => setSearchInput(event.target.value) }
type="text" type="text"
className="border filter_2A0YE0 form-control" className="border filter form-control"
id="searchInput" id="searchInput"
// onkeydown=${filter} // onkeydown=${filter}
placeholder="Search with transaction hash or address" placeholder="Search with transaction hash or address"
@ -931,7 +807,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
</div> </div>
</div> </div>
</div> </div>
<div tabIndex={-1} className="terminal_container_2A0YE0" data-id="terminalContainer" > <div tabIndex={-1} className="terminal_container" data-id="terminalContainer" >
{ {
handleAutoComplete() handleAutoComplete()
} }
@ -942,38 +818,34 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
opacity: '0.1', opacity: '0.1',
zIndex: -1 zIndex: -1
}}></div> }}></div>
<div className="terminal_2A0YE0"> <div className="terminal">
<div id="journal" className="journal_2A0YE0" data-id="terminalJournal"> <div id="journal" className="journal" data-id="terminalJournal">
{!clearConsole && <TerminalWelcomeMessage packageJson={props.version}/>}
{newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => {
if (x.name === 'emptyBlock') { if (x.name === 'emptyBlock') {
return ( return (
<div className="px-4 block_2A0YE0" data-id="block_null" key={index}> <div className="px-4 block" data-id="block_null" key={index}>
<span className='txLog'> <span className='txLog'>
<span className='tx'><div className='txItem'>[<span className='txItemTitle'>block:{x.message} - </span> 0 {'transactions'} ] </div></span></span> <span className='tx'><div className='txItem'>[<span className='txItemTitle'>block:{x.message} - </span> 0 {'transactions'} ] </div></span></span>
</div> </div>
) )
} else if (x.name === 'unknownTransaction' || x.name === 'knownTransaction') { } 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 (<div className='px-4 block_2A0YE0' data-id={`block_tx${trans.tx.hash}`}> {renderKnownTransactions(trans.tx, trans.receipt, index)} </div>) return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`}> {renderKnownTransactions(trans.tx, trans.receipt, index)} </div>)
}) })
} else { } else {
return ( return (
<div className="px-4 block_2A0YE0" data-id="block_null" key={index}> <div className="px-4 block" data-id="block_null" key={index}>
<span className={x.style}>{x.message}</span> <span className={x.style}>{x.message}</span>
</div> </div>
) )
} }
})} })}
<div className="anchor"> <div ref={messagesEndRef} />
{/* ${background} */}
<div className="overlay background"></div>
{/* ${text} */}
<div className="overlay text"></div>
</div>
</div> </div>
<div id="terminalCli" data-id="terminalCli" className="cli_2A0YE0" onClick={focusinput}> <div id="terminalCli" data-id="terminalCli" className="cli" onClick={focusinput}>
<span className="prompt_2A0YE0">{'>'}</span> <span className="prompt">{'>'}</span>
<input className="input_2A0YE0" ref={inputEl} spellCheck="false" contentEditable="true" id="terminalCliInput" data-id="terminalCliInput" onChange={(event) => onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput}></input> <input className="input" ref={inputEl} spellCheck="false" contentEditable="true" id="terminalCliInput" data-id="terminalCliInput" onChange={(event) => onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput}></input>
</div> </div>
</div> </div>
</div> </div>

@ -0,0 +1,30 @@
import React from 'react'
const TerminalWelcomeMessage = ({ packageJson }) => {
return (
<div className="px-4 block" data-id="block_null">
<div> - Welcome to Remix {packageJson} - </div><br />
<div>You can use this terminal to: </div>
<ul className='ul'>
<li>Check transactions details and start debugging.</li>
<li>Execute JavaScript scripts:
<br />
<i> - Input a script directly in the command line interface </i>
<br />
<i> - Select a Javascript file in the file explorer and then run \`remix.execute()\` or \`remix.exeCurrent()\` in the command line interface </i>
<br />
<i> - Right click on a JavaScript file in the file explorer and then click \`Run\` </i>
</li>
</ul>
<div>The following libraries are accessible:</div>
<ul className='ul'>
<li><a target="_blank" href="https://web3js.readthedocs.io/en/1.0/">web3 version 1.0.0</a></li>
<li><a target="_blank" href="https://docs.ethers.io">ethers.js</a> </li>
<li><a target="_blank" href="https://www.npmjs.com/package/swarmgw">swarmgw</a> </li>
<li>remix (run remix.help() for more info)</li>
</ul>
</div>
)
}
export default TerminalWelcomeMessage

@ -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
// }
Loading…
Cancel
Save