diff --git a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts index b082c408a5..8d16ecc734 100644 --- a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts +++ b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts @@ -8,6 +8,7 @@ export const extractNameFromKey = (key: string): string => { export const extractParentFromKey = (key: string):string => { if (!key) return const keyPath = key.split('/') + keyPath.pop() return keyPath.join('/') @@ -66,3 +67,9 @@ export const getPathIcon = (path: string) => { export const isNumeric = (value) => { return /^\+?(0|[1-9]\d*)$/.test(value) } + +export const shortenAddress = (address, etherBalance) => { + const len = address.length + + return address.slice(0, 5) + '...' + address.slice(len - 5, len) + (etherBalance ? ' (' + etherBalance.toString() + ' ether)' : '') +} diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 85f0ddb18d..01fd1f548c 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -1,8 +1,60 @@ +import { shortenAddress } from '@remix-ui/helper' +import React from 'react' +import { fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess } from './payload' + let plugin, dispatch: React.Dispatch -const initSettingsTab = (udapp) => async (reducerDispatch: React.Dispatch) => { - plugin = udapp - dispatch = reducerDispatch +export const initSettingsTab = (udapp) => async (reducerDispatch: React.Dispatch) => { + if (udapp) { + plugin = udapp + dispatch = reducerDispatch + setupEvents() + setInterval(() => { + fillAccountsList() + }, 1000) + + fillAccountsList() + } +} + +const setupEvents = () => { + plugin.blockchain.events.on('newTransaction', (tx, receipt) => { + plugin.emit('newTransaction', tx, receipt) + }) + + plugin.blockchain.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => { + // if (!lookupOnly) this.el.querySelector('#value').value = 0 + if (error) return + updateAccountBalances() + }) + + const updateAccountBalances = () => { + // const accounts = $(this.el.querySelector('#txorigin')).children('option') + + // accounts.each((index, account) => { + // plugin.blockchain.getBalanceInEther(account.value, (err, balance) => { + // if (err) return + // const updated = shortenAddress(account.value, balance) + + // if (updated !== account.innerText) { // check if the balance has been updated and update UI accordingly. + // account.innerText = updated + // } + // }) + // }) + } +} + +const fillAccountsList = async () => { + try { + dispatch(fetchAccountsListRequest()) + const promise = plugin.blockchain.getAccounts() - -} \ No newline at end of file + promise.then((accounts: string[]) => { + dispatch(fetchAccountsListSuccess(accounts)) + }).catch((e) => { + dispatch(fetchAccountsListFailed(e.message)) + }) + } catch (e) { + // addTooltip(`Cannot get account list: ${e}`) + } +} diff --git a/libs/remix-ui/run-tab/src/lib/actions/payload.ts b/libs/remix-ui/run-tab/src/lib/actions/payload.ts new file mode 100644 index 0000000000..ec8db31d45 --- /dev/null +++ b/libs/remix-ui/run-tab/src/lib/actions/payload.ts @@ -0,0 +1,19 @@ +export const fetchAccountsListRequest = () => { + return { + type: 'FETCH_ACCOUNTS_LIST_REQUEST' + } +} + +export const fetchAccountsListSuccess = (accounts: string[]) => { + return { + type: 'FETCH_ACCOUNTS_LIST_SUCCESS', + payload: accounts + } +} + +export const fetchAccountsListFailed = (error: string) => { + return { + type: 'FETCH_ACCOUNTS_LIST_FAILED', + payload: error + } +} diff --git a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx index 2acaa0febf..d429e81cb4 100644 --- a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx @@ -13,11 +13,6 @@ export function SettingsUI (props: SettingsProps) { // this.event = new EventManager() // this._components = {} - // this.blockchain.event.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => { - // if (!lookupOnly) this.el.querySelector('#value').value = 0 - // if (error) return - // this.updateAccountBalances() - // }) // this._components = { // registry: globalRegistry, // networkModule: networkModule @@ -37,20 +32,6 @@ export function SettingsUI (props: SettingsProps) { // this.loadedAccounts = {} // } - // updateAccountBalances () { - // if (!this.el) return - // var accounts = $(this.el.querySelector('#txorigin')).children('option') - // accounts.each((index, account) => { - // this.blockchain.getBalanceInEther(account.value, (err, balance) => { - // if (err) return - // const updated = helper.shortenAddress(account.value, balance) - // if (updated !== account.innerText) { // check if the balance has been updated and update UI accordingly. - // account.innerText = updated - // } - // }) - // }) - // } - // setExecutionContext (context) { // this.blockchain.changeExecutionContext(context, () => { // modalDialogCustom.prompt('External node request', this.web3ProviderDialogBody(), 'http://127.0.0.1:8545', (target) => { diff --git a/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts b/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts new file mode 100644 index 0000000000..c2207cd04a --- /dev/null +++ b/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts @@ -0,0 +1,90 @@ +interface Action { + type: string + payload: any +} + +export interface RunTabState { + accounts: { + loadedAccounts: Record, + isRequesting: boolean, + isSuccessful: boolean, + error: null + } +} + +export const runTabInitialState = { + accounts: { + loadedAccounts: {}, + isRequesting: false, + isSuccessful: false, + error: null + } +} + +export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => { + switch (action.type) { + case 'FETCH_ACCOUNTS_LIST_REQUEST': { + return { + ...state, + accounts: { + ...state.accounts, + isRequesting: true, + isSuccessful: false, + error: null + } + } + } + case 'FETCH_ACCOUNTS_LIST_SUCCESS': { + const payload: string[] = action.payload as string[] + + return { + ...state, + accounts: { + ...state.accounts, + loadedAccounts: resolveAccountsList(state, payload), + isSuccessful: true, + isRequesting: false, + error: null + } + } + } + case 'FETCH_ACCOUNTS_LIST_FAILED': { + const payload = action.payload as string + + return { + ...state, + accounts: { + ...state.accounts, + isRequesting: false, + isSuccessful: false, + error: payload + } + } + } + default: + return state + } +} + +// TODO: unclear what's the goal of accountListCallId, feels like it can be simplified +const resolveAccountsList = async (state: RunTabState, accounts: string[]) => { + // const txOrigin = this.el.querySelector('#txorigin') + const loadedAccounts = state.accounts.loadedAccounts + + if (!accounts) accounts = [] + for (const loadedaddress in loadedAccounts) { + if (accounts.indexOf(loadedaddress) === -1) { + // txOrigin.removeChild(txOrigin.querySelector('option[value="' + loadedaddress + '"]')) + delete loadedAccounts[loadedaddress] + } + } + for (const i in accounts) { + const address = accounts[i] + if (!loadedAccounts[address]) { + // txOrigin.appendChild(yo``) + loadedAccounts[address] = 1 + } + } + return loadedAccounts + // txOrigin.setAttribute('value', accounts[0]) +} diff --git a/libs/remix-ui/run-tab/src/lib/run-tab.tsx b/libs/remix-ui/run-tab/src/lib/run-tab.tsx index fd04b5ef22..9d78273659 100644 --- a/libs/remix-ui/run-tab/src/lib/run-tab.tsx +++ b/libs/remix-ui/run-tab/src/lib/run-tab.tsx @@ -1,14 +1,21 @@ // eslint-disable-next-line no-use-before-define -import React, { useState } from 'react' +import React, { useState, useEffect, useReducer } from 'react' +import { initSettingsTab } from './actions' import { ContractDropdownUI } from './components/contractDropdownUI' import { InstanceContainerUI } from './components/instanceContainerUI' import { RecorderUI } from './components/recorderCardUI' import { SettingsUI } from './components/settingsUI' import './css/run-tab.css' +import { runTabInitialState, runTabReducer } from './reducers/runTab' import { RunTabProps } from './types' export function RunTabUI (props: RunTabProps) { const [selectExEnv, setSelectExEnv] = useState('') + const [runTab, runTabDispatch] = useReducer(runTabReducer, runTabInitialState) + + useEffect(() => { + initSettingsTab(props.plugin)(runTabDispatch) + }, []) const updateExEnv = (env: string) => { setSelectExEnv(env)