Refactor slider into react lib

pull/453/head
ioedeveloper 4 years ago
parent be64493582
commit 1d48a9e8b7
  1. 2
      apps/remix-ide/.babelrc
  2. 4
      apps/remix-ide/src/app/tabs/debugger/debuggerUI.js
  3. 17
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/StepManager.js
  4. 1
      babel.config.js
  5. 5
      libs/debugger-ui/src/index.ts
  6. 239
      libs/debugger-ui/src/lib/debugger-ui.tsx
  7. 65
      libs/debugger-ui/src/lib/slider.tsx

@ -1,3 +1,3 @@
{
"presets": ["@babel/preset-env"]
"presets": ["@babel/preset-env", "@babel/preset-react"]
}

@ -1,3 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom'
import { Slider } from '@remix-project/debugger-ui'
var TxBrowser = require('./debuggerUI/TxBrowser')
var StepManagerUI = require('./debuggerUI/StepManager')
var VmDebugger = require('./debuggerUI/VmDebugger')
@ -272,6 +275,7 @@ class DebuggerUI {
yo.update(this.debuggerHeadPanelsView, this.vmDebugger.renderHead())
yo.update(this.debuggerPanelsView, this.vmDebugger.render())
yo.update(this.stepManagerView, this.stepManager.render())
ReactDOM.render(<Slider event={this.event} />, document.getElementById('slider-ui'))
}
}

@ -2,7 +2,7 @@ var EventManager = require('../../../../lib/events')
var yo = require('yo-yo')
var ButtonNavigator = require('./ButtonNavigator')
var Slider = require('./Slider')
// var Slider = require('./Slider')
function StepManager (stepManager) {
this.event = new EventManager()
@ -13,9 +13,8 @@ function StepManager (stepManager) {
}
StepManager.prototype.startSlider = function () {
this.slider = new Slider()
this.slider.event.register('sliderMoved', this.stepManager.jumpTo.bind(this.stepManager))
this.stepManager.event.register('traceLengthChanged', this.slider.setSliderLength.bind(this.slider))
this.event.register('sliderMoved', this.stepManager.jumpTo.bind(this.stepManager))
// this.stepManager.event.register('traceLengthChanged', this.slider.setSliderLength.bind(this.slider))
}
StepManager.prototype.startButtonNavigator = function () {
@ -34,16 +33,16 @@ StepManager.prototype.startButtonNavigator = function () {
}
StepManager.prototype.updateStep = function (step, stepState, jumpOutDisabled) {
if (!this.slider) return
this.slider.setValue(step)
// if (!this.slider) return
// this.slider.setValue(step)
this.buttonNavigator.stepChanged(stepState, jumpOutDisabled)
this.event.trigger('stepChanged', [step])
}
StepManager.prototype.remove = function () {
// used to stop listenning on event. bad and should be "refactored"
this.slider.view = null
this.slider = null
// this.slider.view = null
// this.slider = null
this.buttonNavigator.view = null
this.buttonNavigator = null
}
@ -51,7 +50,7 @@ StepManager.prototype.remove = function () {
StepManager.prototype.render = function () {
return yo`
<div class="py-1">
${this.slider.render()}
<div id="slider-ui"></div>
${this.buttonNavigator.render()}
</div>`
}

@ -1,3 +1,4 @@
module.exports = {
"presets": ["@babel/preset-react"],
"plugins": ["@babel/plugin-transform-modules-commonjs"]
}

@ -1 +1,4 @@
export * from './lib/debugger-ui';
import Slider from './lib/slider'
import * as debuggerUI from './lib/debugger-ui'
export { Slider, debuggerUI }

@ -1,13 +1,6 @@
import React from 'react'
import * as EventManager from '../../../../apps/remix-ide/src/lib/events'
const { useState } = React
const DebuggerUI = ({ debuggerModule, component, fetchContractAndCompile }) => {
const [state, setState] = useState({
debuggerModule,
fetchContractAndCompile,
event
})
const DebuggerUI = () => {
return (
<div>
<h1>Welcome to debugger-ui!</h1>
@ -15,232 +8,4 @@ const DebuggerUI = ({ debuggerModule, component, fetchContractAndCompile }) => {
)
}
export default DebuggerUi
var TxBrowser = require('./debuggerUI/TxBrowser')
var StepManagerUI = require('./debuggerUI/StepManager')
var VmDebugger = require('./debuggerUI/VmDebugger')
var toaster = require('../../ui/tooltip')
var Debugger = require('@remix-project/remix-debug').TransactionDebugger
var SourceHighlighter = require('../../editor/sourceHighlighter')
var globalRegistry = require('../../../global/registry')
var remixLib = require('@remix-project/remix-lib')
var init = remixLib.init
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
.statusMessage {
margin-left: 15px;
}
`
class DebuggerUI {
constructor (debuggerModule, component, fetchContractAndCompile) {
this.fetchContractAndCompile = fetchContractAndCompile
this.event = new EventManager()
this.isActive = false
this.sourceHighlighter = new SourceHighlighter()
this.startTxBrowser()
this.stepManager = null
this.statusMessage = ''
this.currentReceipt
this.view
component.appendChild(this.render())
this.setEditor()
}
setEditor () {
this.editor = globalRegistry.get('editor').api
this.editor.event.register('breakpointCleared', (fileName, row) => {
if (this.debugger) this.debugger.breakPointManager.remove({fileName: fileName, row: row})
})
this.editor.event.register('breakpointAdded', (fileName, row) => {
if (this.debugger) this.debugger.breakPointManager.add({fileName: fileName, row: row})
})
this.editor.event.register('contentChanged', () => {
if (this.debugger) this.debugger.unload()
})
}
listenToEvents () {
if (!this.debugger) return
this.debugger.event.register('debuggerStatus', async (isActive) => {
await this.debuggerModule.call('editor', 'discardHighlight')
this.isActive = isActive
})
this.debugger.event.register('newSourceLocation', async (lineColumnPos, rawLocation) => {
const contracts = await this.fetchContractAndCompile(
this.currentReceipt.contractAddress || this.currentReceipt.to,
this.currentReceipt)
if (contracts) {
const path = contracts.getSourceName(rawLocation.file)
if (path) {
await this.debuggerModule.call('editor', 'discardHighlight')
await this.debuggerModule.call('editor', 'highlight', lineColumnPos, path)
}
}
})
this.debugger.event.register('debuggerUnloaded', () => this.unLoad())
}
startTxBrowser () {
let txBrowser = new TxBrowser()
this.txBrowser = txBrowser
txBrowser.event.register('requestDebug', (blockNumber, txNumber, tx) => {
if (this.debugger) this.debugger.unload()
this.startDebugging(blockNumber, txNumber, tx)
})
txBrowser.event.register('unloadRequested', this, (blockNumber, txIndex, tx) => {
if (this.debugger) this.debugger.unload()
})
}
isDebuggerActive () {
return this.isActive
}
getDebugWeb3 () {
return new Promise((resolve, reject) => {
this.debuggerModule.blockchain.detectNetwork((error, network) => {
let web3
if (error || !network) {
web3 = init.web3DebugNode(this.debuggerModule.blockchain.web3())
} else {
const webDebugNode = init.web3DebugNode(network.name)
web3 = !webDebugNode ? this.debuggerModule.blockchain.web3() : webDebugNode
}
init.extendWeb3(web3)
resolve(web3)
})
})
}
async startDebugging (blockNumber, txNumber, tx) {
if (this.debugger) this.unLoad()
let web3 = await this.getDebugWeb3()
this.currentReceipt = await web3.eth.getTransactionReceipt(txNumber)
this.debugger = new Debugger({
web3,
offsetToLineColumnConverter: globalRegistry.get('offsettolinecolumnconverter').api,
compilationResult: async (address) => {
try {
return await this.fetchContractAndCompile(address, this.currentReceipt)
} catch (e) {
console.error(e)
}
return null
}
})
this.listenToEvents()
this.debugger.debug(blockNumber, txNumber, tx, () => {
this.stepManager = new StepManagerUI(this.debugger.step_manager)
this.vmDebugger = new VmDebugger(this.debugger.vmDebuggerLogic)
this.txBrowser.setState({ blockNumber, txNumber, debugging: true })
this.renderDebugger()
}).catch((error) => {
toaster(error)
this.unLoad()
})
}
getTrace (hash) {
return new Promise(async (resolve, reject) => {
const web3 = await this.getDebugWeb3()
this.currentReceipt = await web3.eth.getTransactionReceipt(hash)
const debug = new Debugger({
web3,
offsetToLineColumnConverter: globalRegistry.get('offsettolinecolumnconverter').api,
compilationResult: async (address) => {
try {
return await this.fetchContractAndCompile(address, this.currentReceipt)
} catch (e) {
console.error(e)
}
return null
}
})
debug.debugger.traceManager.traceRetriever.getTrace(hash, (error, trace) => {
if (error) return reject(error)
resolve(trace)
})
})
}
debug (txHash) {
this.startDebugging(null, txHash, null)
}
render () {
this.debuggerPanelsView = yo`<div class="px-2"></div>`
this.debuggerHeadPanelsView = yo`<div class="px-2"></div>`
this.stepManagerView = yo`<div class="px-2"></div>`
var view = yo`
<div>
<div class="px-2">
${this.txBrowser.render()}
${this.stepManagerView}
${this.debuggerHeadPanelsView}
</div>
<div class="${css.statusMessage}">${this.statusMessage}</div>
${this.debuggerPanelsView}
</div>
`
if (!this.view) {
this.view = view
}
return view
}
async unLoad () {
yo.update(this.debuggerHeadPanelsView, yo`<div></div>`)
yo.update(this.debuggerPanelsView, yo`<div></div>`)
yo.update(this.stepManagerView, yo`<div></div>`)
if (this.vmDebugger) this.vmDebugger.remove()
if (this.stepManager) this.stepManager.remove()
if (this.txBrowser) this.txBrowser.setState({debugging: false})
this.vmDebugger = null
this.stepManager = null
if (this.debugger) delete this.debugger
this.event.trigger('traceUnloaded')
}
async deleteHighlights () {
await this.debuggerModule.call('editor', 'discardHighlight')
}
renderDebugger () {
yo.update(this.debuggerHeadPanelsView, this.vmDebugger.renderHead())
yo.update(this.debuggerPanelsView, this.vmDebugger.render())
yo.update(this.stepManagerView, this.stepManager.render())
}
}
module.exports = DebuggerUI
export default DebuggerUI

@ -0,0 +1,65 @@
import React, { useState, useRef } from 'react'
const Slider = ({ event }) => {
const [state, setState] = useState({
max: null,
disabled: true,
previousValue: null,
currentValue: null
})
const sliderRef = useRef(null)
const setSliderLength = (length) => {
sliderRef.current.setAttribute('max', length - 1)
setState({
...state,
max: length - 1,
disabled: (length === 0)
})
if (state.disabled) {
sliderRef.current.setAttribute('disabled', true)
} else {
sliderRef.current.removeAttribute('disabled')
}
setValue(0)
}
const setValue = (value) => {
setState({
...state,
currentValue: value
})
}
const handleChange = (e) => {
const value = parseInt(e.target.value)
if (value === state.previousValue) return
setState({
...state,
previousValue: value,
currentValue: value
})
event.trigger('sliderMoved', [value])
}
return (
<div>
<input id='slider'
data-id="slider"
className='w-100 my-0'
type='range'
min={0}
max={state.max}
value={state.currentValue}
onChange={handleChange}
disabled={state.disabled}
ref={sliderRef}
/>
</div>
)
}
export default Slider
Loading…
Cancel
Save