setup environment list and events

yann300-patch-36
ioedeveloper 3 years ago committed by yann300
parent 97810af2eb
commit c0ba0f6a98
  1. 23
      apps/remix-ide/src/app/udapp/run-tab.js
  2. 106
      libs/remix-ui/run-tab/src/lib/actions/custom.ts
  3. 37
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  4. 58
      libs/remix-ui/run-tab/src/lib/components/account.tsx
  5. 39
      libs/remix-ui/run-tab/src/lib/components/environment.tsx
  6. 2
      libs/remix-ui/run-tab/src/lib/components/network.tsx
  7. 46
      libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx
  8. 185
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  9. 26
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  10. 14
      libs/remix-ui/run-tab/src/lib/types/index.ts

@ -222,29 +222,6 @@ export class RunTab extends ViewPlugin {
this.renderDropdown(this.udappUI, this.fileManager, this.compilersArtefacts, this.config, this.editor, this.logCallback) this.renderDropdown(this.udappUI, this.fileManager, this.compilersArtefacts, this.config, this.editor, this.logCallback)
this.renderRecorder(this.udappUI, this.fileManager, this.config, this.logCallback) this.renderRecorder(this.udappUI, this.fileManager, this.config, this.logCallback)
this.renderRecorderCard() this.renderRecorderCard()
const addPluginProvider = (profile) => {
if (profile.kind === 'provider') {
((profile, app) => {
const web3Provider = {
async sendAsync (payload, callback) {
try {
const result = await app.call(profile.name, 'sendAsync', payload)
callback(null, result)
} catch (e) {
callback(e)
}
}
}
app.blockchain.addProvider({ name: profile.displayName, provider: web3Provider })
})(profile, this)
}
}
const removePluginProvider = (profile) => {
if (profile.kind === 'provider') this.blockchain.removeProvider(profile.displayName)
}
this.on('manager', 'pluginActivated', addPluginProvider.bind(this))
this.on('manager', 'pluginDeactivated', removePluginProvider.bind(this))
return this.renderContainer() return this.renderContainer()
} }

@ -3,7 +3,7 @@ import React from 'react'
import * as ethJSUtil from 'ethereumjs-util' import * as ethJSUtil from 'ethereumjs-util'
import Web3 from 'web3' import Web3 from 'web3'
import { shortenAddress } from '@remix-ui/helper' import { shortenAddress } from '@remix-ui/helper'
import { fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, setGasLimit, setSelectedAccount, setSendUnit, setSendValue } from './payload' import { addProvider, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, removeProvider, setExecutionEnvironment, setGasLimit, setNetworkName, setSelectedAccount, setSendUnit, setSendValue } from './payload'
import { runTabInitialState, runTabReducer } from '../reducers/runTab' import { runTabInitialState, runTabReducer } from '../reducers/runTab'
export function useRunTabPlugin (plugin) { export function useRunTabPlugin (plugin) {
@ -20,6 +20,26 @@ export function useRunTabPlugin (plugin) {
updateAccountBalances() updateAccountBalances()
}) })
plugin.blockchain.event.register('contextChanged', (context, silent) => {
setFinalContext()
})
plugin.blockchain.event.register('networkStatus', ({ error, network }) => {
if (error) {
const netUI = 'can\'t detect network '
setNetworkNameFromProvider(netUI)
return
}
const networkProvider = plugin.networkModule.getNetworkProvider.bind(plugin.networkModule)
const netUI = (networkProvider() !== 'vm') ? `${network.name} (${network.id || '-'}) network` : ''
setNetworkNameFromProvider(netUI)
})
plugin.blockchain.event.register('addProvider', provider => addExternalProvider(provider))
plugin.blockchain.event.register('removeProvider', name => removeExternalProvider(name))
plugin.blockchain.resetAndInit(plugin.config, { plugin.blockchain.resetAndInit(plugin.config, {
getAddress: (cb) => { getAddress: (cb) => {
cb(null, runTab.accounts.selectedAccount) cb(null, runTab.accounts.selectedAccount)
@ -42,7 +62,6 @@ export function useRunTabPlugin (plugin) {
} }
} }
}) })
console.log('called: reset and init')
} }
const updateAccountBalances = () => { const updateAccountBalances = () => {
@ -56,6 +75,7 @@ export function useRunTabPlugin (plugin) {
accounts[value] = updated accounts[value] = updated
}) })
}) })
dispatch(fetchAccountsListSuccess(accounts))
} }
const fillAccountsList = async () => { const fillAccountsList = async () => {
@ -64,7 +84,18 @@ export function useRunTabPlugin (plugin) {
const promise = plugin.blockchain.getAccounts() const promise = plugin.blockchain.getAccounts()
promise.then((accounts: string[]) => { promise.then((accounts: string[]) => {
dispatch(fetchAccountsListSuccess(accounts)) const loadedAccounts = {}
if (!accounts) accounts = []
accounts.forEach((account) => {
plugin.blockchain.getBalanceInEther(account, (err, balance) => {
if (err) return
const updated = shortenAddress(account, balance)
loadedAccounts[account] = updated
})
})
dispatch(fetchAccountsListSuccess(loadedAccounts))
}).catch((e) => { }).catch((e) => {
dispatch(fetchAccountsListFailed(e.message)) dispatch(fetchAccountsListFailed(e.message))
}) })
@ -85,5 +116,72 @@ export function useRunTabPlugin (plugin) {
dispatch(setGasLimit(value)) dispatch(setGasLimit(value))
} }
return { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee } const addPluginProvider = (profile) => {
if (profile.kind === 'provider') {
((profile, app) => {
const web3Provider = {
async sendAsync (payload, callback) {
try {
const result = await app.call(profile.name, 'sendAsync', payload)
callback(null, result)
} catch (e) {
callback(e)
}
}
}
app.blockchain.addProvider({ name: profile.displayName, provider: web3Provider })
})(profile, plugin)
}
}
const removePluginProvider = (profile) => {
if (profile.kind === 'provider') plugin.blockchain.removeProvider(profile.displayName)
}
const setFinalContext = () => {
// set the final context. Cause it is possible that this is not the one we've originaly selected
const value = _getProviderDropdownValue()
setExecEnv(value)
// this.event.trigger('clearInstance', [])
}
const _getProviderDropdownValue = (): string => {
const provider = plugin.blockchain.getProvider()
const fork = plugin.blockchain.getCurrentFork()
return provider === 'vm' ? provider + '-' + fork : provider
}
const setExecEnv = (env: string) => {
dispatch(setExecutionEnvironment(env))
}
const setNetworkNameFromProvider = (networkName: string) => {
dispatch(setNetworkName(networkName))
}
const addExternalProvider = (network) => {
dispatch(addProvider(network))
// addTooltip(yo`<span><b>${network.name}</b> provider added</span>`)
}
const removeExternalProvider = (name) => {
dispatch(removeProvider(name))
}
const setExecutionContext = (executionContext: { context: string, fork: string }) => {
plugin.blockchain.changeExecutionContext(executionContext, () => {
// modalDialogCustom.prompt('External node request', this.web3ProviderDialogBody(), 'http://127.0.0.1:8545', (target) => {
// this.blockchain.setProviderFromEndpoint(target, context, (alertMsg) => {
// if (alertMsg) addTooltip(alertMsg)
// setFinalContext()
// })
// }, this.setFinalContext.bind(this))
// }, (alertMsg) => {
// addTooltip(alertMsg)
}, setFinalContext())
}
return { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee, addPluginProvider, removePluginProvider, setExecEnv, setFinalContext, setExecutionContext }
} }

@ -5,7 +5,7 @@ export const fetchAccountsListRequest = () => {
} }
} }
export const fetchAccountsListSuccess = (accounts: string[]) => { export const fetchAccountsListSuccess = (accounts: Record<string, string>) => {
return { return {
type: 'FETCH_ACCOUNTS_LIST_SUCCESS', type: 'FETCH_ACCOUNTS_LIST_SUCCESS',
payload: accounts payload: accounts
@ -46,3 +46,38 @@ export const setGasLimit = (gasLimit: number) => {
payload: gasLimit payload: gasLimit
} }
} }
export const setExecutionEnvironment = (executionEnvironment: string) => {
return {
type: 'SET_EXECUTION_ENVIRONMENT',
payload: executionEnvironment
}
}
export const setPersonalMode = (mode: boolean) => {
return {
type: 'SET_PERSONAL_MODE',
payload: mode
}
}
export const setNetworkName = (networkName: string) => {
return {
type: 'SET_NETWORK_NAME',
payload: networkName
}
}
export const addProvider = (provider: string) => {
return {
type: 'ADD_PROVIDER',
payload: provider
}
}
export const removeProvider = (provider: string) => {
return {
type: 'REMOVE_PROVIDER',
payload: provider
}
}

@ -1,42 +1,58 @@
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
import React, { useEffect, useRef } from 'react' import React, { useEffect, useState } from 'react'
import { CopyToClipboard } from '@remix-ui/clipboard' import { CopyToClipboard } from '@remix-ui/clipboard'
import { AccountProps } from '../types' import { AccountProps } from '../types'
export function AccountUI (props: AccountProps) { export function AccountUI (props: AccountProps) {
const { selectedAccount, loadedAccounts } = props.accounts const { selectedAccount, loadedAccounts } = props.accounts
const accounts = Object.keys(loadedAccounts) const accounts = Object.keys(loadedAccounts)
const plusBtn = useRef(null) const [plusOpt, setPlusOpt] = useState({
const plusTitle = useRef(null) classList: '',
title: ''
})
useEffect(() => { useEffect(() => {
if (!selectedAccount && accounts.length > 0) props.setAccount(accounts[0]) if (!selectedAccount && accounts.length > 0) props.setAccount(accounts[0])
}, [accounts, selectedAccount]) }, [accounts, selectedAccount])
const updatePlusButton = () => { useEffect(() => {
// enable/disable + button
switch (props.selectExEnv) { switch (props.selectExEnv) {
case 'injected': case 'injected':
plusBtn.current.classList.add('udapp_disableMouseEvents') setPlusOpt({
plusTitle.current.title = "Unfortunately it's not possible to create an account using injected web3. Please create the account directly from your provider (i.e metamask or other of the same type)." classList: 'udapp_disableMouseEvents',
title: "Unfortunately it's not possible to create an account using injected web3. Please create the account directly from your provider (i.e metamask or other of the same type)."
})
break break
case 'vm':
plusBtn.current.classList.remove('udapp_disableMouseEvents')
plusTitle.current.title = 'Create a new account'
case 'vm':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break break
case 'web3': case 'web3':
this.onPersonalChange() if (!props.personalMode) {
setPlusOpt({
classList: 'disableMouseEvents',
title: 'Creating an account is possible only in Personal mode. Please go to Settings to enable it.'
})
} else {
setPlusOpt({
classList: '',
title: 'Create a new account'
})
}
break break
default: {
plusBtn.current.classList.add('udapp_disableMouseEvents') default:
plusTitle.current.title = `Unfortunately it's not possible to create an account using an external wallet (${props.selectExEnv}).` setPlusOpt({
} classList: 'disableMouseEvents',
title: `Unfortunately it's not possible to create an account using an external wallet (${props.selectExEnv}).`
})
} }
} // this._deps.config.get('settings/personal-mode')
}, [props.selectExEnv, props.personalMode])
const newAccount = () => { const newAccount = () => {
// dispatch createNewBlockchainAccount // dispatch createNewBlockchainAccount
@ -110,14 +126,14 @@ export function AccountUI (props: AccountProps) {
<div className="udapp_crow"> <div className="udapp_crow">
<label className="udapp_settingsLabel"> <label className="udapp_settingsLabel">
Account Account
<span ref={plusTitle} id="remixRunPlusWraper" title="Create a new account" onLoad={updatePlusButton}> <span id="remixRunPlusWraper" title={plusOpt.title}>
<i ref={plusBtn} id="remixRunPlus" className="fas fa-plus-circle udapp_icon" aria-hidden="true" onClick={newAccount}></i> <i id="remixRunPlus" className={`fas fa-plus-circle udapp_icon ${plusOpt.classList}`} aria-hidden="true" onClick={newAccount}></i>
</span> </span>
</label> </label>
<div className="udapp_account"> <div className="udapp_account">
<select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount} onChange={(e) => { props.setAccount(e.target.value) }}> <select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount} onChange={(e) => { props.setAccount(e.target.value) }}>
{ {
Object.keys(loadedAccounts).map((value) => <option value={value}>{ loadedAccounts[value] }</option>) Object.keys(loadedAccounts).map((value, index) => <option value={value} key={index}>{ loadedAccounts[value] }</option>)
} }
</select> </select>
<div style={{ marginLeft: -5 }}><CopyToClipboard content={selectedAccount} direction='top' /></div> <div style={{ marginLeft: -5 }}><CopyToClipboard content={selectedAccount} direction='top' /></div>

@ -1,10 +1,8 @@
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
import React, { useState } from 'react' import React from 'react'
import { EnvironmentProps } from '../types' import { EnvironmentProps } from '../types'
export function EnvironmentUI (props: EnvironmentProps) { export function EnvironmentUI (props: EnvironmentProps) {
const [exEnv, setExEnv] = useState<string>('')
// setDropdown (selectExEnv) { // setDropdown (selectExEnv) {
// this.selectExEnv = selectExEnv // this.selectExEnv = selectExEnv
@ -41,33 +39,28 @@ export function EnvironmentUI (props: EnvironmentProps) {
// } // }
const handleChangeExEnv = (env: string) => { const handleChangeExEnv = (env: string) => {
setExEnv(env) props.setExecEnv(env)
props.updateExEnv(env) const fork = provider.getAttribute('fork') // can be undefined if connected to an external source (web3 provider / injected)
let context = provider.value
context = context.startsWith('vm') ? 'vm' : context // context has to be 'vm', 'web3' or 'injected'
this.setExecutionContext({ context, fork })
} }
return ( return (
<div className="udapp_crow"> <div className="udapp_crow">
<label id="selectExEnv" className="udapp_settingsLabel"> <label id="selectExEnv" className="udapp_settingsLabel">
Environment Environment
</label> </label>
<div className="udapp_environment"> <div className="udapp_environment">
<select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" className="form-control udapp_select custom-select" value={exEnv} onChange={(e) => { handleChangeExEnv(e.target.value) }}> <select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" className="form-control udapp_select custom-select" value={props.selectedEnv} onChange={(e) => { handleChangeExEnv(e.target.value) }}>
<option id="vm-mode-london" data-id="settingsVMLondonMode" {
title="Execution environment does not connect to any node, everything is local and in memory only." props.providerList.map((provider) =>
value="vm-london"> JavaScript VM (London) {/* fork="london" */} <option id={provider.id} data-id={provider.dataId}
</option> title={provider.title}
<option id="vm-mode-berlin" data-id="settingsVMBerlinMode" value={provider.value}> Web3 Provider
title="Execution environment does not connect to any node, everything is local and in memory only." </option>
value="vm-berlin"> JavaScript VM (Berlin) {/* fork="berlin" */} )
</option> }
<option id="injected-mode" data-id="settingsInjectedMode"
title="Execution environment has been provided by Metamask or similar provider."
value="injected"> Injected Web3
</option>
<option id="web3-mode" data-id="settingsWeb3Mode"
title="Execution environment connects to node at localhost (or via IPC if available), transactions will be sent to the network and can cause loss of money or worse!
If this page is served via https and you access your node via http, it might not work. In this case, try cloning the repository and serving it via http."
value="web3"> Web3 Provider
</option>
</select> </select>
<a href="https://remix-ide.readthedocs.io/en/latest/run.html#run-setup" target="_blank"><i className="udapp_infoDeployAction ml-2 fas fa-info" title="check out docs to setup Environment"></i></a> <a href="https://remix-ide.readthedocs.io/en/latest/run.html#run-setup" target="_blank"><i className="udapp_infoDeployAction ml-2 fas fa-info" title="check out docs to setup Environment"></i></a>
</div> </div>

@ -8,7 +8,7 @@ export function NetworkUI (props: NetworkProps) {
<div className="udapp_settingsLabel"> <div className="udapp_settingsLabel">
</div> </div>
<div className="udapp_environment" data-id="settingsNetworkEnv"> <div className="udapp_environment" data-id="settingsNetworkEnv">
<span className="udapp_network badge badge-secondary"></span> <span className="udapp_network badge badge-secondary">{ props.networkName }</span>
</div> </div>
</div> </div>
) )

@ -77,25 +77,6 @@ export function SettingsUI (props: SettingsProps) {
// return provider === 'vm' ? provider + '-' + fork : provider // return provider === 'vm' ? provider + '-' + fork : provider
// } // }
// setFinalContext () {
// // set the final context. Cause it is possible that this is not the one we've originaly selected
// this.selectExEnv.value = this._getProviderDropdownValue()
// this.event.trigger('clearInstance', [])
// this.updatePlusButton()
// }
// onPersonalChange () {
// const plusBtn = document.getElementById('remixRunPlus')
// const plusTitle = document.getElementById('remixRunPlusWraper')
// if (!this._deps.config.get('settings/personal-mode')) {
// plusBtn.classList.add(css.disableMouseEvents)
// plusTitle.title = 'Creating an account is possible only in Personal mode. Please go to Settings to enable it.'
// } else {
// plusBtn.classList.remove(css.disableMouseEvents)
// plusTitle.title = 'Create a new account'
// }
// }
// getSelectedAccount () { // getSelectedAccount () {
// return this.el.querySelector('#txorigin').selectedOptions[0].value // return this.el.querySelector('#txorigin').selectedOptions[0].value
// } // }
@ -105,31 +86,10 @@ export function SettingsUI (props: SettingsProps) {
// } // }
return ( return (
// this.blockchain.event.register('contextChanged', (context, silent) => {
// this.setFinalContext()
// })
// this.blockchain.event.register('networkStatus', ({ error, network }) => {
// if (error) {
// this.netUI.innerHTML = 'can\'t detect network '
// return
// }
// const networkProvider = this._components.networkModule.getNetworkProvider.bind(this._components.networkModule)
// this.netUI.innerHTML = (networkProvider() !== 'vm') ? `${network.name} (${network.id || '-'}) network` : ''
// })
// setInterval(() => {
// this.fillAccountsList()
// }, 1000)
// this.el = el
// this.fillAccountsList()
// return el
<div className="udapp_settings"> <div className="udapp_settings">
<EnvironmentUI updateExEnv={props.updateExEnv} /> <EnvironmentUI setExecEnv={props.setExecEnv} selectedEnv={props.selectExEnv} />
<NetworkUI /> <NetworkUI networkName={props.networkName} />
<AccountUI selectExEnv={props.selectExEnv} accounts={props.accounts} setAccount={props.setAccount} /> <AccountUI personalMode={props.personalMode} selectExEnv={props.selectExEnv} accounts={props.accounts} setAccount={props.setAccount} />
<GasPriceUI gasLimit={props.gasLimit} setGasFee={props.setGasFee} /> <GasPriceUI gasLimit={props.gasLimit} setGasFee={props.setGasFee} />
<ValueUI setUnit={props.setUnit} sendValue={props.sendValue} sendUnit={props.sendUnit} /> <ValueUI setUnit={props.setUnit} sendValue={props.sendValue} sendUnit={props.sendUnit} />
</div> </div>

@ -5,7 +5,7 @@ interface Action {
export interface RunTabState { export interface RunTabState {
accounts: { accounts: {
loadedAccounts: Record<string, any>, loadedAccounts: Record<string, string>,
isRequesting: boolean, isRequesting: boolean,
isSuccessful: boolean, isSuccessful: boolean,
error: string, error: string,
@ -13,7 +13,23 @@ export interface RunTabState {
}, },
sendValue: string, sendValue: string,
sendUnit: 'ether' | 'finney' | 'gwei' | 'wei', sendUnit: 'ether' | 'finney' | 'gwei' | 'wei',
gasLimit: number gasLimit: number,
selectExEnv: string,
personalMode: boolean,
networkName: string,
providers: {
providerList: {
id?: string,
dataId?: string,
title?: string,
value: string,
fork?: string
content: string
}[],
isRequesting: boolean,
isSuccessful: boolean,
error: string
}
} }
export const runTabInitialState: RunTabState = { export const runTabInitialState: RunTabState = {
@ -26,7 +42,43 @@ export const runTabInitialState: RunTabState = {
}, },
sendValue: '0', sendValue: '0',
sendUnit: 'ether', sendUnit: 'ether',
gasLimit: 3000000 gasLimit: 3000000,
selectExEnv: 'vm',
personalMode: false,
networkName: '',
providers: {
providerList: [{
id: 'vm-mode-london',
dataId: 'settingsVMLondonMode',
title: 'Execution environment does not connect to any node, everything is local and in memory only.',
value: 'vm-london',
fork: 'london',
content: 'JavaScript VM (London)'
}, {
id: 'vm-mode-berlin',
dataId: 'settingsVMBerlinMode',
title: 'Execution environment does not connect to any node, everything is local and in memory only.',
value: 'vm-berlin',
fork: 'berlin',
content: 'JavaScript VM (Berlin)'
}, {
id: 'injected-mode',
dataId: 'settingsInjectedMode',
title: 'Execution environment has been provided by Metamask or similar provider.',
value: 'injected',
content: 'Injected Web3'
}, {
id: 'web3-mode',
dataId: 'settingsWeb3Mode',
title: `Execution environment connects to node at localhost (or via IPC if available), transactions will be sent to the network and can cause loss of money or worse!
If this page is served via https and you access your node via http, it might not work. In this case, try cloning the repository and serving it via http.`,
value: 'web3',
content: 'Web3 Provider'
}],
isRequesting: false,
isSuccessful: false,
error: null
}
} }
export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => { export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => {
@ -42,22 +94,24 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
} }
} }
case 'FETCH_ACCOUNTS_LIST_SUCCESS': { case 'FETCH_ACCOUNTS_LIST_SUCCESS': {
const payload: string[] = action.payload as string[] const payload: Record<string, string> = action.payload
return { return {
...state, ...state,
accounts: { accounts: {
...state.accounts, ...state.accounts,
loadedAccounts: resolveAccountsList(state, payload), loadedAccounts: payload,
isSuccessful: true, isSuccessful: true,
isRequesting: false, isRequesting: false,
error: null error: null
} }
} }
} }
case 'FETCH_ACCOUNTS_LIST_FAILED': { case 'FETCH_ACCOUNTS_LIST_FAILED': {
const payload = action.payload as string const payload: string = action.payload
return { return {
...state, ...state,
@ -69,16 +123,18 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
} }
} }
case 'SET_SEND_VALUE': { case 'SET_SEND_VALUE': {
const payload = action.payload as string const payload: string = action.payload
return { return {
...state, ...state,
sendValue: payload sendValue: payload
} }
} }
case 'SET_SELECTED_ACCOUNT': { case 'SET_SELECTED_ACCOUNT': {
const payload = action.payload as string const payload: string = action.payload
return { return {
...state, ...state,
@ -88,8 +144,9 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
} }
} }
case 'SET_SEND_UNIT': { case 'SET_SEND_UNIT': {
const payload = action.payload as 'ether' | 'finney' | 'gwei' | 'wei' const payload: 'ether' | 'finney' | 'gwei' | 'wei' = action.payload
return { return {
...state, ...state,
@ -98,33 +155,107 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
case 'SET_GAS_LIMIT': { case 'SET_GAS_LIMIT': {
const payload = action.payload as number const payload: number = action.payload
return { return {
...state, ...state,
gasLimit: payload gasLimit: payload
} }
} }
default:
return state
}
}
// TODO: unclear what's the goal of accountListCallId, feels like it can be simplified case 'SET_EXECUTION_ENVIRONMENT': {
const resolveAccountsList = async (state: RunTabState, accounts: string[]) => { const payload: string = action.payload
const loadedAccounts = state.accounts.loadedAccounts
if (!accounts) accounts = [] return {
for (const loadedaddress in loadedAccounts) { ...state,
if (accounts.indexOf(loadedaddress) === -1) { selectExEnv: payload
delete loadedAccounts[loadedaddress] }
} }
}
for (const i in accounts) { case 'SET_PERSONAL_MODE': {
const address = accounts[i] const payload: boolean = action.payload
if (!loadedAccounts[address]) {
loadedAccounts[address] = 1 return {
...state,
personalMode: payload
}
}
case 'SET_NETWORK_NAME': {
const payload: string = action.payload
return {
...state,
networkName: payload
}
}
case 'FETCH_PROVIDER_LIST_REQUEST': {
return {
...state,
providers: {
...state.providers,
isRequesting: true,
isSuccessful: false,
error: null
}
}
}
case 'FETCH_PROVIDER_LIST_SUCCESS': {
const payload: Record<string, string> = action.payload
return {
...state,
providers: {
...state.providers,
providerList: payload,
isSuccessful: true,
isRequesting: false,
error: null
}
}
}
case 'FETCH_PROVIDER_LIST_FAILED': {
const payload: string = action.payload
return {
...state,
providers: {
...state.providers,
isRequesting: false,
isSuccessful: false,
error: payload
}
}
}
case 'ADD_PROVIDER': {
const payload: string = action.payload
return {
...state,
providers: {
...state.providers,
providerList: { ...state.providers.providerList, payload }
}
}
} }
case 'REMOVE_PROVIDER': {
const payload: string = action.payload
return {
...state,
providers: {
...state.providers,
providerList: delete state.providers.providerList[payload] ? state.providers.providerList : state.providers.providerList
}
}
}
default:
return state
} }
return loadedAccounts
} }

@ -1,5 +1,5 @@
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
import React, { useState, useEffect } from 'react' import React, { useEffect } from 'react'
import { useRunTabPlugin } from './actions/custom' import { useRunTabPlugin } from './actions/custom'
import { ContractDropdownUI } from './components/contractDropdownUI' import { ContractDropdownUI } from './components/contractDropdownUI'
import { InstanceContainerUI } from './components/instanceContainerUI' import { InstanceContainerUI } from './components/instanceContainerUI'
@ -9,27 +9,27 @@ import './css/run-tab.css'
import { RunTabProps } from './types' import { RunTabProps } from './types'
export function RunTabUI (props: RunTabProps) { export function RunTabUI (props: RunTabProps) {
const { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee } = useRunTabPlugin(props.plugin) const { runTab, setupEvents, fillAccountsList, setAccount, setUnit, setGasFee, addPluginProvider, removePluginProvider, setExecEnv, setExecutionContext } = useRunTabPlugin(props.plugin)
const [selectExEnv, setSelectExEnv] = useState<string>('')
useEffect(() => { useEffect(() => {
setupEvents() setupEvents()
// setInterval(() => {
setInterval(() => { // fillAccountsList()
// }, 1000)
// fillAccountsList()
setTimeout(() => {
fillAccountsList() fillAccountsList()
}, 1000) }, 0)
fillAccountsList()
}, [])
const updateExEnv = (env: string) => { props.plugin.on('manager', 'pluginActivated', addPluginProvider.bind(props.plugin))
setSelectExEnv(env) props.plugin.on('manager', 'pluginDeactivated', removePluginProvider.bind(props.plugin))
} }, [])
return ( return (
<div className="udapp_runTabView run-tab" id="runTabView" data-id="runTabView"> <div className="udapp_runTabView run-tab" id="runTabView" data-id="runTabView">
<div className="list-group list-group-flush"> <div className="list-group list-group-flush">
<SettingsUI selectExEnv={selectExEnv} updateExEnv={updateExEnv} accounts={runTab.accounts} setAccount={setAccount} setUnit={setUnit} sendValue={runTab.sendValue} sendUnit={runTab.sendUnit} gasLimit={runTab.gasLimit} setGasFee={setGasFee} /> <SettingsUI networkName={runTab.networkName} personalMode={runTab.personalMode} selectExEnv={runTab.selectExEnv} setExecEnv={setExecEnv} accounts={runTab.accounts} setAccount={setAccount} setUnit={setUnit} sendValue={runTab.sendValue} sendUnit={runTab.sendUnit} gasLimit={runTab.gasLimit} setGasFee={setGasFee} />
<ContractDropdownUI exEnvironment={selectExEnv} /> <ContractDropdownUI exEnvironment={runTab.selectExEnv} />
<RecorderUI /> <RecorderUI />
<InstanceContainerUI /> <InstanceContainerUI />
</div> </div>

@ -4,7 +4,6 @@ export interface RunTabProps {
export interface SettingsProps { export interface SettingsProps {
selectExEnv: string, selectExEnv: string,
updateExEnv: (env: string) => void,
accounts: { accounts: {
loadedAccounts: Record<string, any>, loadedAccounts: Record<string, any>,
selectedAccount: string, selectedAccount: string,
@ -17,15 +16,19 @@ export interface SettingsProps {
sendValue: string, sendValue: string,
sendUnit: string, sendUnit: string,
gasLimit: number, gasLimit: number,
setGasFee: (value: number) => void setGasFee: (value: number) => void,
setExecEnv: (env: string) => void,
personalMode: boolean,
networkName: string
} }
export interface EnvironmentProps { export interface EnvironmentProps {
updateExEnv: (env: string) => void setExecEnv: (env: string) => void,
selectedEnv: string
} }
export interface NetworkProps { export interface NetworkProps {
networkName: string
} }
export interface AccountProps { export interface AccountProps {
@ -37,7 +40,8 @@ export interface AccountProps {
isSuccessful: boolean, isSuccessful: boolean,
error: string error: string
}, },
setAccount: (account: string) => void setAccount: (account: string) => void,
personalMode: boolean
} }
export interface GasPriceProps { export interface GasPriceProps {

Loading…
Cancel
Save