Merge branch 'master' of https://github.com/ethereum/remix-project into terminalwrapper

pull/5370/head
filip mertens 9 months ago
commit 5ba2f43a86
  1. 22
      apps/remix-ide/src/app/tabs/locales/en/udapp.json
  2. 2
      apps/remix-ide/src/app/tabs/locales/es/udapp.json
  3. 2
      apps/remix-ide/src/app/tabs/locales/fr/udapp.json
  4. 2
      apps/remix-ide/src/app/tabs/locales/it/udapp.json
  5. 2
      apps/remix-ide/src/app/tabs/locales/zh/udapp.json
  6. 4
      libs/remix-ui/run-tab/src/lib/actions/actions.ts
  7. 2
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  8. 5
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  9. 9
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  10. 72
      libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
  11. 26
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  12. 4
      libs/remix-ui/run-tab/src/lib/types/index.ts
  13. 2
      libs/remix-ui/workspace/src/lib/components/flat-tree.tsx

@ -65,16 +65,18 @@
"udapp.tooltipText3": "Click to open a bridge for converting L1 mainnet ETH to the selected network currency.",
"udapp._comment_instanceContainerUI.tsx": "libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx",
"udapp.deployedContracts": "Deployed Contracts",
"udapp.deployedContracts": "Deployed/Unpinned Contracts",
"udapp.deployAndRunClearInstances": "Clear instances list and reset recorder",
"udapp.deployAndRunNoInstanceText": "Currently you have no deployed contracts to interact with.",
"udapp.tooltipText6": "Autogenerated generic user interfaces for interaction with deployed contracts",
"udapp.deployAndRunNoInstanceText": "Currently you have no unpinned contracts to interact with.",
"udapp.tooltipText6": "Autogenerated generic user interfaces for interaction with deployed/unpinned contracts",
"udapp.savedContracts": "Saved Contracts",
"udapp.NoSavedInstanceText": "No saved contracts found.",
"udapp.tooltipTextUnsave": "Unsave & move to Deployed Contracts list",
"udapp.savedOn": "Saved On",
"udapp.filePath": "File Path",
"udapp.savedContracts": "Pinned Contracts",
"udapp.tooltipTextPinnedContracts": "List of pinned contracts for selected network",
"udapp.NoSavedInstanceText": "No contracts pinned yet. Pinned contracts stay after reloading Remix IDE.",
"udapp.tooltipTextDelete": "Delete pinned contract",
"udapp.tooltipTextUnpin": "Unpin contract",
"udapp.savedOn": "Pinned at",
"udapp.filePath": "File path",
"udapp._comment_recorderCardUI.tsx": "libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx",
"udapp.transactionsRecorded": "Transactions recorded",
@ -104,8 +106,8 @@
"udapp.tooltipText13": "Deployed {date}",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "Remove from the list",
"udapp.tooltipText14": "Save & move to Saved Contracts list",
"udapp.tooltipTextRemove": "Remove from the list",
"udapp.tooltipTextPin": "Pin contract",
"udapp.tooltipText8": "Click for docs about using 'receive'/'fallback'",
"udapp.tooltipText9": "The Calldata to send to fallback function of the contract.",
"udapp.tooltipText10": "Send data to contract.",

@ -88,7 +88,7 @@
"udapp.tooltipText12": "Entrada requerida",
"udapp.tooltipText13": "Publicado en {date}",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "Eliminar de la lista",
"udapp.tooltipTextRemove": "Eliminar de la lista",
"udapp.tooltipText8": "Haga clic para ver los documentos sobre el uso de 'receive'/'fallback'",
"udapp.tooltipText9": "El datos de llamada a enviar a la función fallback del contrato.",
"udapp.tooltipText10": "Enviar datos al contrato.",

@ -88,7 +88,7 @@
"udapp.tooltipText12": "Entrée nécessaire",
"udapp.tooltipText13": "Déployé {date}",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "Supprimer de la liste",
"udapp.tooltipTextRemove": "Supprimer de la liste",
"udapp.tooltipText8": "Cliquez sur la documentation à propos de l'utilisation de 'receive'/'fallback'",
"udapp.tooltipText9": "Les Calldata à envoyer à la fonction fallback du contrat.",
"udapp.tooltipText10": "Envoyer des données au contrat.",

@ -88,7 +88,7 @@
"udapp.tooltipText12": "Input richiesto",
"udapp.tooltipText13": "Deploiato",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "Rimuovi dalla lista",
"udapp.tooltipTextRemove": "Rimuovi dalla lista",
"udapp.tooltipText8": "Fare clic per i documenti sull'uso di 'receive'/'fallback'",
"udapp.tooltipText9": "Il Calldata per inviare alla funzione di fallback del contratto.",
"udapp.tooltipText10": "Invia dati al contratto.",

@ -88,7 +88,7 @@
"udapp.tooltipText12": "必填",
"udapp.tooltipText13": "已部署 {date}",
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "从列表中删除",
"udapp.tooltipTextRemove": "从列表中删除",
"udapp.tooltipText8": "点击查看有关使用 'receive'/'fallback' 的文档",
"udapp.tooltipText9": "发送到合约 fallback 函数的 Calldata。",
"udapp.tooltipText10": "将数据发送到合约。",

@ -75,8 +75,8 @@ export const addSavedInstance = (dispatch: React.Dispatch<any>, instance: { cont
dispatch(addNewSavedInstance(instance))
}
export const removeInstance = (dispatch: React.Dispatch<any>, index: number, isSavedContract: boolean) => {
dispatch(removeExistingInstance(index, isSavedContract))
export const removeInstance = (dispatch: React.Dispatch<any>, index: number, isSavedContract: boolean, shouldDelete: boolean) => {
dispatch(removeExistingInstance(index, isSavedContract, shouldDelete))
}
export const clearInstances = (dispatch: React.Dispatch<any>) => {

@ -48,7 +48,7 @@ export const setGasPriceStatus = (status: boolean) => updateGasPriceStatus(dispa
export const setMaxFee = (fee: string) => updateMaxFee(dispatch, fee)
export const setMaxPriorityFee = (fee: string) => updateMaxPriorityFee(dispatch, fee)
export const removeInstances = () => clearInstances(dispatch)
export const removeSingleInstance = (index: number, isSavedContract: boolean) => removeInstance(dispatch, index, isSavedContract)
export const removeSingleInstance = (index: number, isSavedContract: boolean, shouldDelete: boolean) => removeInstance(dispatch, index, isSavedContract, shouldDelete)
export const getExecutionContext = () => getContext(plugin)
export const executeTransactions = (instanceIndex: number, isSavedContract: boolean, lookupOnly: boolean, funcABI: FuncABI, inputsValues: string, contractName: string, contractABI, contract, address, logMsg:string, mainnetPrompt: MainnetPrompt, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, funcIndex?: number) => runTransactions(plugin, dispatch, instanceIndex, isSavedContract, lookupOnly, funcABI, inputsValues, contractName, contractABI, contract, address, logMsg, mainnetPrompt, gasEstimationPrompt, passphrasePrompt, funcIndex)
export const loadFromAddress = (contract: ContractData, address: string) => loadAddress(plugin, dispatch, contract, address)

@ -237,12 +237,13 @@ export const addNewSavedInstance = (instance: { contractData?: ContractData, add
}
}
export const removeExistingInstance = (index: number, isSavedContract: boolean) => {
export const removeExistingInstance = (index: number, isSavedContract: boolean, shouldDelete: boolean) => {
return {
type: REMOVE_INSTANCE,
payload: {
index,
isSavedContract
isSavedContract,
shouldDelete
}
}
}

@ -8,17 +8,19 @@ import { UniversalDappUI } from './universalDappUI'
export function InstanceContainerUI(props: InstanceContainerProps) {
const { instanceList } = props.instances
const enableSave = useRef(false)
const chainId = useRef()
useEffect(() => {
const fetchSavedContracts = async () => {
if (props.plugin.REACT_API.selectExEnv && props.plugin.REACT_API.selectExEnv.startsWith('vm-')) enableSave.current = false
else enableSave.current = true
if (enableSave.current) {
const { network } = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
chainId.current = network.id
const allSavedContracts = localStorage.getItem('savedContracts')
if (allSavedContracts) {
await props.plugin.call('udapp', 'clearAllSavedInstances')
const savedContracts = JSON.parse(allSavedContracts)
const { network } = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
if (savedContracts && savedContracts[network.id]) {
const instances = savedContracts[network.id]
for (const inst of instances)
@ -38,9 +40,10 @@ export function InstanceContainerUI(props: InstanceContainerProps) {
<div className="udapp_instanceContainer mt-3 border-0 list-group-item">
{ enableSave.current ? (
<div className="d-flex justify-content-between align-items-center pl-2">
<CustomTooltip placement="top-start" tooltipClasses="text-nowrap" tooltipId="deployAndRunClearInstancesTooltip" tooltipText={<FormattedMessage id="udapp.tooltipText6" />}>
<CustomTooltip placement="top-start" tooltipClasses="text-nowrap" tooltipId="deployAndRunPinnedContractsTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextPinnedContracts" />}>
<label className="udapp_deployedContracts">
<FormattedMessage id="udapp.savedContracts" />
<FormattedMessage id="udapp.savedContracts" />
<span style={{fontSize: '0.75rem'}}> (chain id: {chainId.current})</span>
</label>
</CustomTooltip>
</div>) : null }

@ -10,6 +10,7 @@ import {ContractGUI} from './contractGUI'
import {TreeView, TreeViewItem} from '@remix-ui/tree-view'
import {BN} from 'bn.js'
import {CustomTooltip, is0XPrefixed, isHexadecimal, isNumeric, shortenAddress} from '@remix-ui/helper'
const _paq = (window._paq = window._paq || [])
const txHelper = remixLib.execution.txHelper
@ -111,20 +112,31 @@ export function UniversalDappUI(props: UdappProps) {
setToggleExpander(!toggleExpander)
}
const unsavePinnedContract = async () => {
const {network} = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
const savedContracts = localStorage.getItem('savedContracts')
const savedContractsJson = JSON.parse(savedContracts)
const instanceIndex = savedContractsJson[network.id].findIndex(instance => instance && instance.address === props.instance.address)
delete savedContractsJson[network.id][instanceIndex]
savedContractsJson[network.id] = savedContractsJson[network.id].filter(Boolean)
localStorage.setItem('savedContracts', JSON.stringify(savedContractsJson))
}
const remove = async() => {
if (props.isSavedContract) {
const {network} = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
const savedContracts = localStorage.getItem('savedContracts')
const savedContractsJson = JSON.parse(savedContracts)
const instanceIndex = savedContractsJson[network.id].findIndex(instance => instance && instance.address === props.instance.address)
delete savedContractsJson[network.id][instanceIndex]
savedContractsJson[network.id] = savedContractsJson[network.id].filter(Boolean)
localStorage.setItem('savedContracts', JSON.stringify(savedContractsJson))
await unsavePinnedContract()
_paq.push(['trackEvent', 'udapp', 'pinContracts', 'unpinned'])
}
props.removeInstance(props.index, props.isSavedContract)
props.removeInstance(props.index, props.isSavedContract, false)
}
const saveContract = async() => {
const deletePinnedContract = async() => {
await unsavePinnedContract()
_paq.push(['trackEvent', 'udapp', 'pinContracts', 'deletePinned'])
props.removeInstance(props.index, props.isSavedContract, true)
}
const pinContract = async() => {
const workspace = await props.plugin.call('filePanel', 'getCurrentWorkspace')
const {network} = await props.plugin.call('blockchain', 'getCurrentNetworkStatus')
const savedContracts = localStorage.getItem('savedContracts')
@ -144,8 +156,9 @@ export function UniversalDappUI(props: UdappProps) {
localStorage.setItem('savedContracts', JSON.stringify(objToSave))
// Add contract to saved contracts list on UI
await props.plugin.call('udapp', 'addSavedInstance', props.instance.address, props.instance.abi || props.instance.contractData.abi, props.instance.name, props.instance.savedOn, props.instance.filePath)
_paq.push(['trackEvent', 'udapp', 'pinContracts', 'pinned'])
// Remove contract from deployed contracts list on UI
props.removeInstance(props.index, false)
props.removeInstance(props.index, false, false)
}
const runTransaction = (lookupOnly, funcABI: FuncABI, valArr, inputsValues, funcIndex?: number) => {
@ -252,27 +265,44 @@ export function UniversalDappUI(props: UdappProps) {
data-shared="universalDappUiInstance"
>
<div className="udapp_title pb-0 alert alert-secondary">
<span data-id={`universalDappUiTitleExpander${props.index}`} className="btn udapp_titleExpander" onClick={toggleClass}>
<span data-id={`universalDappUiTitleExpander${props.index}`} className="btn udapp_titleExpander" onClick={toggleClass} style={{padding: "0.45rem"}}>
<i className={`fas ${toggleExpander ? 'fa-angle-right' : 'fa-angle-down'}`} aria-hidden="true"></i>
</span>
<div className="input-group udapp_nameNbuts">
<div className="udapp_titleText input-group-prepend">
<span className="input-group-text udapp_spanTitleText">
{ props.isSavedContract ? ( <CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappUnpinTooltip" tooltipText={props.isSavedContract ? `Contract: ${props.instance.name}, Address: ${address}, Pinned at: ${new Date(props.instance.savedOn).toLocaleString()}` : '' }>
<span className="input-group-text udapp_spanTitleText">
{props.instance.name} at {shortenAddress(address)}
</span>
</CustomTooltip>) : ( <span className="input-group-text udapp_spanTitleText">
{props.instance.name} at {shortenAddress(address)} ({props.context})
</span>
</span>) }
</div>
<div className="btn" style={{padding: '0.15rem'}}>
<CopyToClipboard tip={intl.formatMessage({id: 'udapp.copy'})} content={address} direction={'top'} />
</div>
{ props.isSavedContract || !(props.plugin.REACT_API.selectExEnv && props.plugin.REACT_API.selectExEnv.startsWith('vm-')) ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappSaveTooltip" tooltipText={<FormattedMessage id="udapp.tooltipText14" />}>
<i className="far fa-save p-2" aria-hidden="true" data-id="universalDappUiUdappSave" onClick={saveContract}></i>
</CustomTooltip>
</div> ) : null }
{ !(props.plugin.REACT_API.selectExEnv && props.plugin.REACT_API.selectExEnv.startsWith('vm-')) ?
props.isSavedContract ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappUnpinTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextUnpin" />}>
<i className="fas fa-thumbtack p-2 text-success" aria-hidden="true" data-id="universalDappUiUdappUnpin" onClick={remove}></i>
</CustomTooltip>
</div> ) : ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappPinTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextPin" />}>
<i className="far fa-thumbtack p-2" aria-hidden="true" data-id="universalDappUiUdappPin" onClick={pinContract}></i>
</CustomTooltip>
</div> )
: null}
</div>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappCloseTooltip" tooltipText={ !props.isSavedContract ? (<FormattedMessage id="udapp.tooltipText7" />) : (<FormattedMessage id="udapp.tooltipTextUnsave" />)}>
<i className="udapp_closeIcon m-1 fas fa-times align-self-center" aria-hidden="true" data-id="universalDappUiUdappClose" onClick={remove}></i>
</CustomTooltip>
{ props.isSavedContract ? ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappDeleteTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextDelete" />}>
<i className="far fa-trash p-2" aria-hidden="true" data-id="universalDappUiUdappDelete" onClick={deletePinnedContract}></i>
</CustomTooltip>
</div> ) : ( <div className="btn" style={{padding: '0.15rem', marginLeft: '-0.5rem'}}>
<CustomTooltip placement="top" tooltipClasses="text-nowrap" tooltipId="udapp_udappCloseTooltip" tooltipText={<FormattedMessage id="udapp.tooltipTextRemove" />}>
<i className="fas fa-times p-2" aria-hidden="true" data-id="universalDappUiUdappClose" onClick={remove}></i>
</CustomTooltip>
</div> )
}
</div>
<div className="udapp_cActionsWrapper" data-id="universalDappUiContractActionWrapper">
<div className="udapp_contractActionsContainer">

@ -515,28 +515,34 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
}
case REMOVE_INSTANCE: {
const payload: { index: number, isSavedContract: boolean } = action.payload
const payload: { index: number, isSavedContract: boolean, shouldDelete: boolean } = action.payload
if (payload.isSavedContract)
return {
if (payload.isSavedContract) {
if (payload.shouldDelete) return {
...state,
savedInstances: {
...state.savedInstances,
instanceList: state.savedInstances.instanceList.filter((_, index) => index !== payload.index)
},
instances: {
...state.instances,
instanceList: [...state.instances.instanceList, state.savedInstances.instanceList[payload.index]]
}
}
else
return {
else return {
...state,
savedInstances: {
...state.savedInstances,
instanceList: state.savedInstances.instanceList.filter((_, index) => index !== payload.index)
},
instances: {
...state.instances,
instanceList: state.instances.instanceList.filter((_, index) => index !== payload.index)
instanceList: [...state.instances.instanceList, state.savedInstances.instanceList[payload.index]]
}
}
} else return {
...state,
instances: {
...state.instances,
instanceList: state.instances.instanceList.filter((_, index) => index !== payload.index)
}
}
}
case CLEAR_INSTANCES: {

@ -321,7 +321,7 @@ export interface InstanceContainerProps {
error: string
},
clearInstances: () => void,
removeInstance: (index: number, isSavedContract:boolean) => void,
removeInstance: (index: number, isSavedContract:boolean, shouldDelete: boolean) => void,
getContext: () => 'memory' | 'blockchain',
runTransactions: (
instanceIndex: number,
@ -428,7 +428,7 @@ export interface UdappProps {
},
context: 'memory' | 'blockchain',
isSavedContract?: boolean
removeInstance: (index: number, isSavedContract: boolean) => void,
removeInstance: (index: number, isSavedContract: boolean, shouldDelete: boolean) => void,
index: number,
gasEstimationPrompt: (msg: string) => JSX.Element,
passphrasePrompt: (message: string) => JSX.Element,

@ -86,7 +86,7 @@ export const FlatTree = (props: FlatTreeProps) => {
path = path.replace(/^\//g, '')
const pathArray = path.split('/')
const level = pathArray.length - 1
const indent = level * 4
const indent = level * 12
return (<div style={{ paddingLeft: `${indent}px` }}></div>)
}

Loading…
Cancel
Save