diff --git a/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts b/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts
index 86624a900d..48270c6b9b 100644
--- a/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts
+++ b/apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts
@@ -21,15 +21,22 @@ function addInstance (browser: NightwatchBrowser, address: string, isValidFormat
.setValue('.ataddressinput', address, function () {
if (!isValidFormat || !isValidChecksum) browser.assert.elementPresent('button[id^="runAndDeployAtAdressButton"]:disabled')
else if (isAbi) {
- browser.click('button[id^="runAndDeployAtAdressButton"]')
- .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
+ browser
+ .click({
+ selector: '//*[@id="runAndDeployAtAdressButtonContainer"]',
+ locateStrategy: 'xpath'
+ })
+ .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]', 5000)
.execute(function () {
const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
modal.click()
})
} else {
- browser.click('button[id^="runAndDeployAtAdressButton"]')
+ browser.click({
+ selector: '//*[@id="runAndDeployAtAdressButtonContainer"]',
+ locateStrategy: 'xpath'
+ })
}
callback()
})
diff --git a/apps/remix-ide-e2e/src/commands/clickFunction.ts b/apps/remix-ide-e2e/src/commands/clickFunction.ts
index e84be6a0d0..9ae4b3c330 100644
--- a/apps/remix-ide-e2e/src/commands/clickFunction.ts
+++ b/apps/remix-ide-e2e/src/commands/clickFunction.ts
@@ -3,18 +3,18 @@ import EventEmitter from 'events'
class ClickFunction extends EventEmitter {
command (this: NightwatchBrowser, fnFullName: string, expectedInput?: NightwatchClickFunctionExpectedInput): NightwatchBrowser {
- this.api.waitForElementPresent('.instance button[title="' + fnFullName + '"]')
+ this.api.waitForElementPresent('.instance button[data-title="' + fnFullName + '"]')
.perform(function (client, done) {
client.execute(function () {
document.querySelector('#runTabView').scrollTop = document.querySelector('#runTabView').scrollHeight
}, [], function () {
if (expectedInput) {
- client.setValue('#runTabView input[title="' + expectedInput.types + '"]', expectedInput.values, _ => _)
+ client.setValue('#runTabView input[data-title="' + expectedInput.types + '"]', expectedInput.values, _ => _)
}
done()
})
})
- .scrollAndClick('.instance button[title="' + fnFullName + '"]')
+ .scrollAndClick('.instance button[data-title="' + fnFullName + '"]')
.pause(2000)
.perform(() => {
this.emit('complete')
diff --git a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts
index 00f9512814..3216bc39ed 100644
--- a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts
+++ b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts
@@ -15,18 +15,18 @@ class TestConstantFunction extends EventEmitter {
}
function testConstantFunction (browser: NightwatchBrowser, address: string, fnFullName: string, expectedInput: NightwatchTestConstantFunctionExpectedInput, expectedOutput: string, cb: VoidFunction) {
- browser.waitForElementPresent('.instance button[title="' + fnFullName + '"]').perform(function (client, done) {
+ browser.waitForElementPresent('.instance button[data-title="' + fnFullName + '"]').perform(function (client, done) {
client.execute(function () {
document.querySelector('#runTabView').scrollTop = document.querySelector('#runTabView').scrollHeight
}, [], function () {
if (expectedInput) {
- client.waitForElementPresent('#runTabView input[title="' + expectedInput.types + '"]')
- .setValue('#runTabView input[title="' + expectedInput.types + '"]', expectedInput.values)
+ client.waitForElementPresent('#runTabView input[data-title="' + expectedInput.types + '"]')
+ .setValue('#runTabView input[data-title="' + expectedInput.types + '"]', expectedInput.values)
}
done()
})
})
- .click(`#instance${address} button[title="${fnFullName}"]`)
+ .click(`#instance${address} button[data-title="${fnFullName}"]`)
.pause(1000)
.waitForElementPresent('#instance' + address + ' .udapp_contractActionsContainer .udapp_value')
.scrollInto('#instance' + address + ' .udapp_contractActionsContainer .udapp_value')
diff --git a/apps/remix-ide-e2e/src/tests/debugger.test.ts b/apps/remix-ide-e2e/src/tests/debugger.test.ts
index b9602b4b57..56965e31a9 100644
--- a/apps/remix-ide-e2e/src/tests/debugger.test.ts
+++ b/apps/remix-ide-e2e/src/tests/debugger.test.ts
@@ -19,8 +19,8 @@ module.exports = {
.clickLaunchIcon('solidity').click('*[data-id="compilerContainerCompileBtn"]')
.pause(4000)
.clickLaunchIcon('udapp')
- .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 60000)
- .click('*[title="Deploy - transact (not payable)"]')
+ .waitForElementPresent('*[data-title="Deploy - transact (not payable)"]', 60000)
+ .click('*[data-title="Deploy - transact (not payable)"]')
.debugTransaction(0)
.waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000)
.clearConsole()
@@ -30,8 +30,8 @@ module.exports = {
browser.waitForElementVisible('*[data-id="verticalIconsKindudapp"]')
.clickLaunchIcon('udapp')
.clickInstance(0)
- .scrollAndClick('*[title="string name, uint256 goal"]')
- .setValue('*[title="string name, uint256 goal"]', '"toast", 999')
+ .scrollAndClick('*[data-title="string name, uint256 goal"]')
+ .setValue('*[data-title="string name, uint256 goal"]', '"toast", 999')
.click('*[data-id="createProject - transact (not payable)"]')
.debugTransaction(0)
.pause(2000)
@@ -88,7 +88,7 @@ module.exports = {
.clickLaunchIcon('solidity')
.testContracts('externalImport.sol', sources[1]['externalImport.sol'], ['ERC20'])
.clickLaunchIcon('udapp')
- .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 35000)
+ .waitForElementPresent('*[data-title="Deploy - transact (not payable)"]', 35000)
.selectContract('ERC20')
.createContract('"tokenName", "symbol"')
.debugTransaction(0)
@@ -159,7 +159,7 @@ module.exports = {
.clickLaunchIcon('solidity')
.testContracts('locals.sol', sources[3]['locals.sol'], ['testLocals'])
.clickLaunchIcon('udapp')
- .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 40000)
+ .waitForElementPresent('*[data-title="Deploy - transact (not payable)"]', 40000)
.createContract('')
.pause(2000)
.clearConsole()
@@ -266,7 +266,7 @@ const sources = [
'blah.sol': {
content: `
pragma solidity >=0.7.0 <0.9.0;
-
+
contract Kickstarter {
enum State { Started, Completed }
@@ -276,9 +276,9 @@ const sources = [
string name;
uint goal;
State state;
- }
+ }
- Project[] public projects;
+ Project[] public projects;
constructor() {
@@ -291,7 +291,7 @@ const sources = [
project.state = State.Started;
project.goal = goal;
}
- }
+ }
`
}
},
@@ -309,12 +309,12 @@ const sources = [
function test1 (bytes calldata userData) external returns (bytes memory, bytes32, bytes32, uint) {
bytes32 idAsk = abi.decode(userData[:33], (bytes32));
bytes32 idOffer = abi.decode(userData[32:64], (bytes32));
-
+
bytes memory ro = abi.encodePacked(msg.sender, msg.sender, idAsk, idOffer);
return (ro, idAsk, idOffer, userData.length);
}
-
-
+
+
function testgp (bytes calldata userData) external returns (bytes4) {
return abi.decode(userData[:4], (bytes4));
}
@@ -341,9 +341,9 @@ const sources = [
'withGeneratedSources.sol': {
content: `
// SPDX-License-Identifier: GPL-3.0
- pragma experimental ABIEncoderV2;
- contract A {
- function f(uint[] memory) public returns (uint256) { }
+ pragma experimental ABIEncoderV2;
+ contract A {
+ function f(uint[] memory) public returns (uint256) { }
}
`
}
@@ -372,7 +372,7 @@ const sources = [
}
/**
- * @dev Return value
+ * @dev Return value
* @return value of 'number'
*/
function retrieve() public view returns (uint256){
@@ -393,14 +393,14 @@ const sources = [
function callA() public {
p = 123;
try b.callB() {
-
+
}
catch (bytes memory reason) {
-
+
}
}
}
-
+
contract B {
C c;
uint p;
@@ -413,7 +413,7 @@ const sources = [
c.callC();
}
}
-
+
contract C {
uint p;
function callC() public {
@@ -498,7 +498,7 @@ const jsGetTrace = `(async () => {
}
})()`
-const jsDebug = `(async () => {
+const jsDebug = `(async () => {
try {
const result = await remix.call('debugger', 'debug', '0x65f0813753462414f9a91f0aabea946188327995f54b893b63a8d7ff186cfca3')
console.log('result ', result)
diff --git a/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx b/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx
index f298eba01d..9418051754 100644
--- a/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx
@@ -2,15 +2,24 @@
import React from 'react'
const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => {
- const { carouselState: { currentSlide, totalItems } } = rest
+ const { carouselState: { currentSlide, totalItems, itemWidth, containerWidth } } = rest
return (
- previous()}>
+ previous()}
+ >
- {
+ {
if (currentSlide + 1 < totalItems) goToSlide(currentSlide + 1)
- }} >
+ }}
+ disabled ={((totalItems - currentSlide) * itemWidth + 5) < containerWidth}
+ >
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
index 8741d7779f..18798c3f4f 100644
--- a/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
@@ -18,7 +18,7 @@ function HomeTabFeatured() {
Featured
-
+
}
arrows={false}
@@ -40,26 +40,31 @@ function HomeTabFeatured() {
dotListClass="position-relative mt-2"
>
-
-
+
+
JUMP INTO WEB3
-
The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.
+
The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.
+
More
-
+
REMIX REWARDS
-
NFTs for our users!
-
Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second “Remixer” user NFT badge to give to any other user of their choice
+
NFTs for our users!
+
+ Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second “Remixer” user NFT badge to give to any other user of their choice.
+
+
More
-
+
BETA TESTING
-
Our community supports us.
-
You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!
+
Our community supports us.
+
You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!
+
More
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx
index a0913e4469..1741d6bb32 100644
--- a/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx
@@ -1,18 +1,18 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
-import React, { useEffect, useState, useRef, useContext } from 'react'
+import React, { useEffect, useRef, useContext } from 'react'
import { FormattedMessage } from 'react-intl'
import PluginButton from './pluginButton'
-import { ThemeContext, themes } from '../themeContext'
+import { ThemeContext } from '../themeContext'
import Carousel from 'react-multi-carousel'
import 'react-multi-carousel/lib/styles.css'
import CustomNavButtons from './customNavButtons'
+const itemsToShow = 5
declare global {
interface Window {
_paq: any
}
}
const _paq = window._paq = window._paq || [] //eslint-disable-line
-
interface HomeTabFeaturedPluginsProps {
plugin: any
}
@@ -21,16 +21,40 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
const themeFilter = useContext(ThemeContext)
const carouselRef = useRef(null)
+ const carouselRefDiv = useRef(null)
- // Todo doesn't work
useEffect(() => {
- window.addEventListener("scroll", handleScroll)
+ document.addEventListener("wheel", handleScroll)
return () => {
- window.removeEventListener("scroll", handleScroll)
+ document.removeEventListener("wheel", handleScroll)
}
}, [])
+ function isDescendant(parent, child) {
+ let node = child.parentNode;
+ while (node != null) {
+ if (node === parent) {
+ return true;
+ }
+ node = node.parentNode;
+ }
+ return false;
+ }
+
const handleScroll = (e) => {
+ if (isDescendant(carouselRefDiv.current, e.target)) {
+ e.stopPropagation()
+ let nextSlide = 0
+ if (e.wheelDelta < 0) {
+ nextSlide = carouselRef.current.state.currentSlide + 1;
+ if ((carouselRef.current.state.totalItems - carouselRef.current.state.currentSlide) * carouselRef.current.state.itemWidth + 5 < carouselRef.current.state.containerWidth) return // 5 is approx margins
+ carouselRef.current.goToSlide(nextSlide)
+ } else {
+ nextSlide = carouselRef.current.state.currentSlide - 1;
+ if (nextSlide < 0) nextSlide = 0
+ carouselRef.current.goToSlide(nextSlide)
+ }
+ }
}
const startSolidity = async () => {
@@ -62,17 +86,30 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
return (
-
+
}
+ focusOnSelect={true}
+ customButtonGroup={
+
+ }
arrows={false}
swipeable={false}
draggable={true}
showDots={false}
- responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }}
+ responsive={
+ {
+ superLargeDesktop: {
+ breakpoint: { max: 4000, min: 3000 },
+ items: itemsToShow
+ },
+ desktop: {
+ breakpoint: { max: 3000, min: 1024 },
+ items: itemsToShow
+ }
+ }
+ }
renderButtonGroupOutside={true}
ssr={true} // means to render carousel on server-side.
keyBoardControl={true}
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
index f27f489198..bea7384767 100644
--- a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
-import React, { useEffect, useState, useRef, useContext } from 'react'
-import { ThemeContext, themes } from '../themeContext'
+import React, { useEffect, useRef, useContext } from 'react'
+import { ThemeContext} from '../themeContext'
import Carousel from 'react-multi-carousel'
import WorkspaceTemplate from './workspaceTemplate'
import 'react-multi-carousel/lib/styles.css'
@@ -11,13 +11,48 @@ declare global {
}
}
const _paq = window._paq = window._paq || [] //eslint-disable-line
-
interface HomeTabGetStartedProps {
plugin: any
}
function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
const themeFilter = useContext(ThemeContext)
+ const carouselRef = useRef(null)
+ const carouselRefDiv = useRef(null)
+
+ useEffect(() => {
+ document.addEventListener("wheel", handleScroll)
+ return () => {
+ document.removeEventListener("wheel", handleScroll)
+ }
+ }, [])
+
+ function isDescendant(parent, child) {
+ let node = child.parentNode;
+ while (node != null) {
+ if (node === parent) {
+ return true;
+ }
+ node = node.parentNode;
+ }
+ return false;
+ }
+
+ const handleScroll = (e) => {
+ if (isDescendant(carouselRefDiv.current, e.target)) {
+ e.stopPropagation()
+ let nextSlide = 0
+ if (e.wheelDelta < 0) {
+ nextSlide = carouselRef.current.state.currentSlide + 1;
+ if ((carouselRef.current.state.totalItems - carouselRef.current.state.currentSlide) * carouselRef.current.state.itemWidth + 5 < carouselRef.current.state.containerWidth) return // 5 is approx margins
+ carouselRef.current.goToSlide(nextSlide)
+ } else {
+ nextSlide = carouselRef.current.state.currentSlide - 1;
+ if (nextSlide < 0) nextSlide = 0
+ carouselRef.current.goToSlide(nextSlide)
+ }
+ }
+ }
const createWorkspace = async (templateName) => {
await plugin.appManager.activatePlugin('filePanel')
@@ -36,16 +71,31 @@ function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
- Project Templates
-
+
- }
+
+ }
arrows={false}
swipeable={false}
draggable={true}
showDots={false}
- responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }}
+ responsive={
+ {
+ superLargeDesktop: {
+ breakpoint: { max: 4000, min: 3000 },
+ items: 5
+ },
+ desktop: {
+ breakpoint: { max: 3000, min: 1024 },
+ items: 5,
+ partialVisibilityGutter: 0
+ }
+ }
+ }
renderButtonGroupOutside={true}
ssr={true} // means to render carousel on server-side.
keyBoardControl={true}
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx
index 0fdc6ab5ff..e9d1a345b3 100644
--- a/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx
@@ -50,20 +50,20 @@ function HomeTabLearn ({plugin}: HomeTabLearnProps) {
setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Basics }})}>
- Remix Basics
+ Remix Basics
{(state.visibleTutorial === VisibleTutorial.Basics) &&
Introduction to Remix's interface and concepts used in Ethereum, as well as the basics of Solidity.
startLearnEthTutorial('basics')}>Get Started
}
setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Intermediate }})}>
- Remix Intermediate
+ Remix Intermediate
{(state.visibleTutorial === VisibleTutorial.Intermediate) && Using the web3.js to interact with a contract. Using Recorder tool.
startLearnEthTutorial('useofweb3js')}>Get Started
}
setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Advanced }})}>
- Remix Advanced
+ Remix Advanced
{(state.visibleTutorial === VisibleTutorial.Advanced) && Learn the Proxy Pattern and working with Libraries in Remix. Learn to use the Debugger.
startLearnEthTutorial('deploylibraries')}>Get Started
}
diff --git a/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx b/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx
index 803c9f7ec4..8a8470304d 100644
--- a/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx
@@ -23,7 +23,7 @@ function PluginButton ({ imgPath, envID, envText, callback, l2, description, rem
onClick={() => callback()}
>
-
+
diff --git a/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx b/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx
index ad079053a8..4610236f79 100644
--- a/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/workspaceTemplate.tsx
@@ -16,7 +16,7 @@ function WorkspaceTemplate ({ gsID, workspaceTitle, description, callback }: Wor
data-id={'landingPageStart' + gsID}
onClick={() => callback()}
>
-
+
{workspaceTitle}
{description}
diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css
index d6ced30e67..011a179161 100644
--- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css
+++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css
@@ -1,11 +1,9 @@
.remixui_home_text {
- cursor: pointer;
font-size: 0.8rem;
font-weight: normal;
max-width: 300px;
}
.remixui_home_text:hover {
- cursor: pointer;
text-decoration: underline;
}
.remixui_home_homeContainer {
diff --git a/libs/remix-ui/run-tab/src/lib/components/account.tsx b/libs/remix-ui/run-tab/src/lib/components/account.tsx
index 0a36eef8b5..21d0d90a6f 100644
--- a/libs/remix-ui/run-tab/src/lib/components/account.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/account.tsx
@@ -4,6 +4,7 @@ import { FormattedMessage, useIntl } from 'react-intl'
import { CopyToClipboard } from '@remix-ui/clipboard'
import { AccountProps } from '../types'
import { PassphrasePrompt } from './passphrase'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
export function AccountUI (props: AccountProps) {
const { selectedAccount, loadedAccounts } = props.accounts
@@ -153,9 +154,15 @@ export function AccountUI (props: AccountProps) {
-
-
-
+
+ {plusOpt.title}
+
+ }>
+
+
+
+
{ props.setAccount(e.target.value) }}>
@@ -164,7 +171,13 @@ export function AccountUI (props: AccountProps) {
}
-
+
+ {"Sign a message using this account"}
+
+ }>
+
+
)
diff --git a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
index 9862dad59c..c4e3801bd8 100644
--- a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
@@ -3,10 +3,10 @@ import React, { useEffect, useRef, useState } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { ContractDropdownProps, DeployMode } from '../types'
import { ContractData, FuncABI } from '@remix-project/core-plugin'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
import * as ethJSUtil from 'ethereumjs-util'
import { ContractGUI } from './contractGUI'
import { deployWithProxyMsg, upgradeWithProxyMsg } from '@remix-ui/helper'
-import { OverlayTrigger, Tooltip } from 'react-bootstrap'
const _paq = window._paq = window._paq || []
export function ContractDropdownUI (props: ContractDropdownProps) {
@@ -279,13 +279,25 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
: null}
-
+
+ {contractOptions.title}
+
+ }
+ >
+
{(contractList[currentFile] || []).map((contract, index) => {
return
{contract.alias} - {contract.file}
})}
+
{abiLabel.content}
@@ -314,14 +326,19 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
onChange={handleCheckedIPFS}
checked={props.ipfsCheckedState}
/>
-
- IPFS
-
+
+ Publishing the source code and metadata to IPFS facilitates source code verification using Sourcify and will greatly foster contract adoption (auditing, debugging, calling it, etc...)
+
+ }>
+
+ IPFS
+
+
: ''
}
@@ -329,17 +346,30 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
-
-
-
-
-
+
+
+ {atAddressOptions.title}
+
+ }>
+
+
+
+
+
+
+
+ {"address of contract"}
+
+ }>
+
+
diff --git a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
index ad5716f45c..cccbbbbb2e 100644
--- a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
@@ -3,6 +3,7 @@ import React, { useEffect, useRef, useState } from 'react'
import * as remixLib from '@remix-project/remix-lib'
import { ContractGUIProps } from '../types'
import { CopyToClipboard } from '@remix-ui/clipboard'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
const txFormat = remixLib.execution.txFormat
const txHelper = remixLib.execution.txHelper
@@ -233,66 +234,187 @@ export function ContractGUI (props: ContractGUIProps) {
}
return (
-
0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive') ? 'udapp_hasArgs' : ''}`}>
-
-
{title}
-
0) || (props.funcABI.type === 'fallback') || (props.funcABI.type === 'receive')) ? 'hidden' : 'visible' }} />
+
0) ||
+ props.funcABI.type === "fallback" ||
+ props.funcABI.type === "receive"
+ ? "udapp_hasArgs"
+ : ""
+ }`}
+ >
+
+
+ {buttonOptions.title}
+
+ }
+ >
+
+ {title}
+
+
+
+
+ {props.funcABI.type === "fallback" ||
+ props.funcABI.type === "receive"
+ ? `'(${props.funcABI.type}')`
+ : props.inputs}
+
+
+ }
+ >
+ 0) ||
+ props.funcABI.type === "fallback" ||
+ props.funcABI.type === "receive"
+ )
+ ? "hidden"
+ : "visible",
+ }}
+ />
+
0) ? 'hidden' : 'visible' }}>
+ style={{
+ visibility: !(
+ props.funcABI.inputs && props.funcABI.inputs.length > 0
+ )
+ ? "hidden"
+ : "visible",
+ }}
+ >
-
+
-
{title}
-
+
+ {title}
+
+
+ );
})}
-
+
-
+
Calldata
-
+
-
+
Parameters
-
+ {buttonOptions.title}
+
+ }
>
- { buttonOptions.content }
-
+
+ {buttonOptions.content}
+
+
- { props.deployOption && (props.deployOption || []).length > 0 ?
+ {props.deployOption && (props.deployOption || []).length > 0 ? (
<>
-
+
- {
- props.initializerOptions && props.initializerOptions.initializeInputs ?
-
-
{
- props.initializerOptions.inputs.inputs.map((inp, index) => {
- return (
-
- {inp.name}:
- { initializeFields.current[index] = el }} style={{ height: 32 }} className="form-control udapp_input" placeholder={inp.type} title={inp.name} />
-
- )})
- }
-
-
: null
- }
-
+ {props.initializerOptions &&
+ props.initializerOptions.initializeInputs ? (
+
+
+ {props.initializerOptions.inputs.inputs.map((inp, index) => {
+ return (
+
+
+ {" "}
+ {inp.name}:{" "}
+
+ {
+ initializeFields.current[index] = el;
+ }}
+ style={{ height: 32 }}
+ className="form-control udapp_input"
+ placeholder={inp.type}
+ title={inp.name}
+ />
+
+ );
+ })}
+
+
+ ) : null}
+
-
+
+ ) : (
+
+ {proxyAddress || "No proxy address available"}
+
+ )}
- > : null
- }
+ >
+ ) : null}
- )
+ );
}
diff --git a/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx b/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx
index 5cc3f69b97..98cdb72262 100644
--- a/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/deployButton.tsx
@@ -1,7 +1,7 @@
import React, { useState } from 'react'
import { FormattedMessage } from 'react-intl'
import { DeployButtonProps } from '../types'
-import { ButtonGroup, Dropdown } from 'react-bootstrap'
+import { ButtonGroup, Dropdown, OverlayTrigger, Tooltip } from 'react-bootstrap'
export function DeployButton (props: DeployButtonProps) {
const [showOptions, setShowOptions] = useState
(false)
@@ -25,9 +25,18 @@ export function DeployButton (props: DeployButtonProps) {
}
:
-
-
-
+
+ {props.buttonOptions.title}
+
+ }
+ >
+
+
+
+
}
>
)
diff --git a/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx b/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx
index 26fcf2a164..c5dc153e42 100644
--- a/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/deployInput.tsx
@@ -1,4 +1,5 @@
import React from 'react'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
import { DeployInputProps } from '../types'
import { DeployButton } from './deployButton'
@@ -6,15 +7,24 @@ export function DeployInput (props: DeployInputProps) {
return (
-
+
+ {props.funcABI.type === 'fallback' || props.funcABI.type === 'receive' ? `'(${props.funcABI.type}')` : props.inputs}
+
+ }
+ >
+
+
)
}
diff --git a/libs/remix-ui/run-tab/src/lib/components/environment.tsx b/libs/remix-ui/run-tab/src/lib/components/environment.tsx
index 04315d6d8b..2d99734d96 100644
--- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx
@@ -1,12 +1,13 @@
// eslint-disable-next-line no-use-before-define
import React from 'react'
-import { FormattedMessage, useIntl } from 'react-intl'
+import { FormattedMessage } from 'react-intl'
import { EnvironmentProps } from '../types'
import { Dropdown } from 'react-bootstrap'
import { CustomMenu, CustomToggle } from '@remix-ui/helper'
import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
export function EnvironmentUI (props: EnvironmentProps) {
+
const handleChangeExEnv = (env: string) => {
const provider = props.providers.providerList.find(exEnv => exEnv.value === env)
const fork = provider.fork // can be undefined if connected to an external source (External Http Provider / injected)
@@ -17,8 +18,6 @@ export function EnvironmentUI (props: EnvironmentProps) {
props.setExecutionContext({ context, fork })
}
- const intl = useIntl()
-
const currentProvider = props.providers.providerList.find(exEnv => exEnv.value === props.selectedEnv)
const bridges = {
'Optimism Provider': 'https://www.optimism.io/apps/bridges',
@@ -68,12 +67,13 @@ export function EnvironmentUI (props: EnvironmentProps) {
}
-
-
-
+
+
+
+ }>
+
+
)
diff --git a/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx b/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx
index 3b46a72627..77350e9099 100644
--- a/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/gasPrice.tsx
@@ -1,6 +1,7 @@
// eslint-disable-next-line no-use-before-define
import React from 'react'
import { FormattedMessage } from 'react-intl'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
import { GasPriceProps } from '../types'
export function GasPriceUI (props: GasPriceProps) {
@@ -11,7 +12,13 @@ export function GasPriceUI (props: GasPriceProps) {
return (
-
+
+ {"The default gas limit is 3M. Adjust as needed."}
+
+ }>
+
+
)
}
diff --git a/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx b/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
index e96bc6f07f..d5123be03f 100644
--- a/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
@@ -1,6 +1,7 @@
// eslint-disable-next-line no-use-before-define
import React from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
import { InstanceContainerProps } from '../types'
import { UniversalDappUI } from './universalDappUI'
@@ -15,15 +16,35 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
return (
diff --git a/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx b/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
index 9b3a99ae6f..554c75d29f 100644
--- a/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
@@ -34,7 +34,13 @@ export function RecorderUI (props: RecorderProps) {
-
{props.count}
+
+ {'The number of recorded transactions'}
+
+ }>
+ {props.count}
+
Save transactions (deployed contracts and function executions) and replay them in another environment. e.g Transactions created in Remix VM can be replayed in the Injected Provider.
@@ -62,19 +68,33 @@ export function RecorderUI (props: RecorderProps) {
-
- Save {props.count} transaction{props.count === 1 ? '' : 's'} as scenario file
+
+
+ {
+ props.count === 0 ? 'No transactions to save'
+ : props.count === 1 ? `Save ${props.count} transaction as scenario file`
+ : `Save ${props.count} transactions as scenario file`
+ }
+
}>
- Save
+
+
+ Save
+
+
Run transaction(s) from the current scenario file
}>
- Run
+
+
+ Run
+
+
diff --git a/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx b/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
index 4c2deaebcb..b9bdfa82ed 100644
--- a/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
@@ -7,6 +7,7 @@ import * as remixLib from '@remix-project/remix-lib'
import * as ethJSUtil from 'ethereumjs-util'
import { ContractGUI } from './contractGUI'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
import { BN } from 'ethereumjs-util'
import { is0XPrefixed, isHexadecimal, isNumeric, shortenAddress } from '@remix-ui/helper'
@@ -210,104 +211,190 @@ export function UniversalDappUI (props: UdappProps) {
}
return (
-
+
-
-
+
+
- {props.instance.name} at {shortenAddress(address)} ({props.context})
+ {props.instance.name} at {shortenAddress(address)} (
+ {props.context})
-
+
+
+
-
+ {'Remove from the list'}
+
+ }
>
-
-
+
+
+
+
-
+
-
- Balance: {instanceBalance} ETH
-
- {
- contractABI && contractABI.map((funcABI, index) => {
- if (funcABI.type !== 'function') return null
- const isConstant = funcABI.constant !== undefined ? funcABI.constant : false
- const lookupOnly = funcABI.stateMutability === 'view' || funcABI.stateMutability === 'pure' || isConstant
- const inputs = props.getFuncABIInputs(funcABI)
+
+ Balance: {instanceBalance} ETH
+
+ {contractABI &&
+ contractABI.map((funcABI, index) => {
+ if (funcABI.type !== "function") return null;
+ const isConstant =
+ funcABI.constant !== undefined ? funcABI.constant : false;
+ const lookupOnly =
+ funcABI.stateMutability === "view" ||
+ funcABI.stateMutability === "pure" ||
+ isConstant;
+ const inputs = props.getFuncABIInputs(funcABI);
- return
-
{
- runTransaction(lookupOnly, funcABI, valArray, inputsValues, index)
- }}
- inputs={inputs}
- evmBC={evmBC}
- lookupOnly={lookupOnly}
- key={index}
- />
-
-
- {
- Object.keys(props.instance.decodedResponse || {}).map((key) => {
- const funcIndex = index.toString()
- const response = props.instance.decodedResponse[key]
+ return (
+
+
{
+ runTransaction(
+ lookupOnly,
+ funcABI,
+ valArray,
+ inputsValues,
+ index
+ );
+ }}
+ inputs={inputs}
+ evmBC={evmBC}
+ lookupOnly={lookupOnly}
+ key={index}
+ />
+
+
+ {Object.keys(props.instance.decodedResponse || {}).map(
+ (key) => {
+ const funcIndex = index.toString();
+ const response = props.instance.decodedResponse[key];
- return key === funcIndex ? Object.keys(response || {}).map((innerkey, index) => {
- return renderData(props.instance.decodedResponse[key][innerkey], response, innerkey, innerkey)
- }) : null
- })
- }
-
+ return key === funcIndex
+ ? Object.keys(response || {}).map(
+ (innerkey, index) => {
+ return renderData(
+ props.instance.decodedResponse[key][
+ innerkey
+ ],
+ response,
+ innerkey,
+ innerkey
+ );
+ }
+ )
+ : null;
+ }
+ )}
+
+
-
- })
- }
+ );
+ })}
- { llIError }
+
+ {llIError}
+
- )
+ );
}
diff --git a/libs/remix-ui/run-tab/src/lib/components/value.tsx b/libs/remix-ui/run-tab/src/lib/components/value.tsx
index 81935ae8d2..2090f59ab3 100644
--- a/libs/remix-ui/run-tab/src/lib/components/value.tsx
+++ b/libs/remix-ui/run-tab/src/lib/components/value.tsx
@@ -4,6 +4,7 @@ import { FormattedMessage } from 'react-intl'
import { BN } from 'ethereumjs-util'
import { isNumeric } from '@remix-ui/helper'
import { ValueProps } from '../types'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
export function ValueUI (props: ValueProps) {
const [sendValue, setSendValue] = useState
(props.sendValue)
@@ -50,6 +51,11 @@ export function ValueUI (props: ValueProps) {