Merge branch 'master' into nxwebpack

pull/5370/head
bunsenstraat 2 years ago committed by GitHub
commit 3597446ec9
  1. 1
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  2. 6
      apps/remix-ide/src/blockchain/blockchain.js
  3. 3
      libs/remix-core-plugin/src/lib/compiler-artefacts.ts
  4. 28
      libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts
  5. 6
      libs/remix-core-plugin/src/lib/constants/uups.ts
  6. 2
      libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts
  7. 23
      libs/remix-lib/src/util.ts
  8. 8
      libs/remix-lib/test/util.ts
  9. 6
      libs/remix-ui/app/src/lib/remix-app/components/dragbar/dragbar.tsx
  10. 6
      libs/remix-ui/app/src/lib/remix-app/remix-app.tsx
  11. 2
      libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx
  12. 14
      libs/remix-ui/home-tab/src/lib/components/customButtonGroupAsArrows.tsx
  13. 8
      libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx
  14. 20
      libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
  15. 6
      libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx
  16. 32
      libs/remix-ui/home-tab/src/lib/components/homeTabFile.tsx
  17. 6
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
  18. 28
      libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx
  19. 2
      libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
  20. 3
      libs/remix-ui/publish-to-storage/src/lib/publishToIPFS.tsx
  21. 38
      libs/remix-ui/run-tab/src/lib/components/environment.tsx
  22. 2
      libs/remix-ui/run-tab/src/lib/components/network.tsx
  23. 2
      libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
  24. 4
      libs/remix-ui/run-tab/src/lib/css/run-tab.css

@ -4018,6 +4018,7 @@ input[type="submit"].btn-block {
.card-body {
flex: 1 1 auto;
padding: 1.25rem;
color: #b2b8cd;
}
.card-title {
color: #DFE1EA;

@ -11,7 +11,7 @@ import InjectedProvider from './providers/injected.js'
import NodeProvider from './providers/node.js'
import { execution, EventManager, helpers } from '@remix-project/remix-lib'
import { etherScanLink } from './helper'
import { logBuilder, cancelUpgradeMsg, cancelProxyMsg } from "@remix-ui/helper"
import { logBuilder, cancelUpgradeMsg, cancelProxyMsg, addressToString } from "@remix-ui/helper"
const { txFormat, txExecution, typeConversion, txListener: Txlistener, TxRunner, TxRunnerWeb3, txHelper } = execution
const { txResultHelper: resultToRemixTx } = helpers
const packageJson = require('../../../../package.json')
@ -180,7 +180,7 @@ export class Blockchain extends Plugin {
if (networkInfo.name === 'VM') this.config.set('vm/proxy', address)
else this.config.set(`${networkInfo.name}/${networkInfo.currentFork}/${networkInfo.id}/proxy`, address)
_paq.push(['trackEvent', 'blockchain', 'Deploy With Proxy', 'Proxy deployment successful'])
return this.call('udapp', 'resolveContractAndAddInstance', implementationContractObject, address)
this.call('udapp', 'addInstance', addressToString(address), implementationContractObject.abi, implementationContractObject.name)
}
this.runTx(args, confirmationCb, continueCb, promptCb, finalCb)
@ -223,7 +223,7 @@ export class Blockchain extends Plugin {
return this.call('terminal', 'logHtml', log)
}
_paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'Upgrade Successful'])
return this.call('udapp', 'resolveContractAndAddInstance', newImplementationContractObject, proxyAddress)
this.call('udapp', 'addInstance', addressToString(proxyAddress), newImplementationContractObject.abi, newImplementationContractObject.name)
}
this.runTx(args, confirmationCb, continueCb, promptCb, finalCb)
}

@ -198,8 +198,7 @@ export class CompilerArtefacts extends Plugin {
return this.compilersArtefactsPerFile[file]
}
// compilerData is a CompilerAbstract object
addResolvedContract (address, compilerData) {
addResolvedContract (address: string, compilerData: CompilerAbstract) {
this.compilersArtefacts[address] = compilerData
}

@ -4,6 +4,7 @@ import { util } from '@remix-project/remix-lib'
import { toChecksumAddress } from 'ethereumjs-util'
import { fetchContractFromEtherscan } from './helpers/fetch-etherscan'
import { fetchContractFromSourcify } from './helpers/fetch-sourcify'
import { UUPSDeployedByteCode, UUPSCompilerVersion } from './constants/uups'
const profile = {
name: 'fetchAndCompile',
@ -48,6 +49,33 @@ export class FetchAndCompile extends Plugin {
if (resolved) return resolved
if (this.unresolvedAddresses.includes(contractAddress)) return localCompilation()
if (codeAtAddress === '0x' + UUPSDeployedByteCode) { // proxy
const settings = {
version: UUPSCompilerVersion,
language: 'Solidity',
evmVersion: null,
optimize: false,
runs: 0
}
const compilationTargets = {
'proxy.sol': { content: 'import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.0/contracts/proxy/ERC1967/ERC1967Proxy.sol";' }
}
const compData = await compile(
compilationTargets,
settings,
async (url, cb) => {
// we first try to resolve the content from the compilation target using a more appropiate path
const path = `${targetPath}/${url}`
if (compilationTargets[path] && compilationTargets[path].content) {
return cb(null, compilationTargets[path].content)
} else {
await this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message))
}
})
await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compData)
return compData
}
// sometimes when doing an internal call, the only available artifact is the Solidity interface.
// resolving addresses of internal call would allow to step over the source code, even if the declaration was made using an Interface.

File diff suppressed because one or more lines are too long

@ -119,4 +119,4 @@ export class OpenZeppelinProxy extends Plugin {
newImplementationContractObject.name = proxyName
this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject)
}
}
}

@ -239,6 +239,8 @@ export function compareByteCode (code1, code2) {
code2 = replaceLibReference(code2, pos)
code1 = replaceLibReference(code1, pos)
}
code1 = removeImmutableReference(code1, code2)
code1 = extractinputParameters(code1)
code1 = extractSwarmHash(code1)
code1 = extractcborMetadata(code1)
@ -276,6 +278,27 @@ function replaceLibReference (code, pos) {
return code.substring(0, pos) + '0000000000000000000000000000000000000000' + code.substring(pos + 40)
}
function removeByIndex (code, index, length, emptyRef) {
if (!code) return code
return code.slice(0, index) + emptyRef + code.slice(index + length)
}
function removeImmutableReference (code1, code2) {
try {
const refOccurence = code2.match(/7f000000000000000000000000000000000000000000000000000000000000000073/g)
if (!refOccurence) return code1
let offset = 0
refOccurence.map((value) => {
offset = code2.indexOf(value, offset)
code1 = removeByIndex(code1, offset, value.length, '7f000000000000000000000000000000000000000000000000000000000000000073')
offset = offset + 1
})
} catch (e) {
console.log('error removeImmutableReference', e)
}
return code1
}
function findCallInternal (index, rootCall, callsPath) {
const calls = Object.keys(rootCall.calls)
const ret = rootCall

File diff suppressed because one or more lines are too long

@ -58,9 +58,10 @@ const DragBar = (props: IRemixDragBarUi) => {
return () => window.removeEventListener('resize', handleResize)
}, [])
function stopDrag(e: MouseEvent, data: any) {
function stopDrag(data: any) {
setDragState(false)
if (data.x < props.minWidth) {
console.log("drag")
if (data.x < props.minWidth + offset) {
setDragBarPosX(offset)
props.setHideStatus(true)
} else {
@ -70,7 +71,6 @@ const DragBar = (props: IRemixDragBarUi) => {
setDragBarPosX(offset + props.refObject.current.offsetWidth)
}, 300)
}
}
function startDrag() {

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useRef, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import './style/remix-app.css'
import { RemixUIMainPanel } from '@remix-ui/panel'
import MatomoDialog from './components/modals/matomo'
@ -8,7 +8,6 @@ import { AppProvider } from './context/provider'
import AppDialogs from './components/modals/dialogs'
import DialogViewPlugin from './components/modals/dialogViewPlugin'
import { AppContext } from './context/context'
import { RemixUiVerticalIconsPanel } from '@remix-ui/vertical-icons-panel'
import { IntlProvider } from 'react-intl'
interface IRemixAppUi {
@ -83,11 +82,10 @@ const RemixApp = (props: IRemixAppUi) => {
<AppProvider value={value}>
<OriginWarning></OriginWarning>
<MatomoDialog hide={!appReady}></MatomoDialog>
<div className={`remixIDE ${appReady ? '' : 'd-none'}`} data-id="remixIDE">
<div id="icon-panel" data-id="remixIdeIconPanel" className="iconpanel bg-light">{props.app.menuicons.render()}</div>
<div ref={sidePanelRef} id="side-panel" data-id="remixIdeSidePanel" className={`sidepanel border-right border-left ${hideSidePanel ? 'd-none' : ''}`}>{props.app.sidePanel.render()}</div>
<DragBar resetTrigger={resetTrigger} maximiseTrigger={maximiseTrigger} minWidth={250} refObject={sidePanelRef} hidden={hideSidePanel} setHideStatus={setHideSidePanel}></DragBar>
<DragBar resetTrigger={resetTrigger} maximiseTrigger={maximiseTrigger} minWidth={285} refObject={sidePanelRef} hidden={hideSidePanel} setHideStatus={setHideSidePanel}></DragBar>
<div id="main-panel" data-id="remixIdeMainPanel" className='mainpanel'>
<RemixUIMainPanel Context={AppContext}></RemixUIMainPanel>
</div>

@ -13,7 +13,7 @@ export const CustomToggle = React.forwardRef(({ children, onClick, icon, classNa
className={className.replace('dropdown-toggle', '')}
>
<div className="d-flex">
<div className="mr-auto">{ children }</div>
<div className="mr-auto text-nowrap">{ children }</div>
{ icon && <div className="pr-1"><i className={`${icon} pr-1`}></i></div> }
<div><i className="fad fa-sort-circle"></i></div>
</div>

@ -1,14 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react'
function CustomButtonGroupAsArrows ({ next, previous }) {
return (
<div style={{ textAlign: "center" }}>
<h4>These buttons can be positioned anywhere you want on the screen</h4>
<button onClick={previous}>Prev</button>
<button onClick={next}>Next</button>
</div>
)
}
export default CustomButtonGroupAsArrows

@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react'
const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => {
const { carouselState: { currentSlide, totalItems, itemWidth, containerWidth } } = rest
const CustomNavButtons = ({ parent, next, previous, goToSlide, ...rest }) => {
const { carouselState: { currentSlide, totalItems, containerWidth, transform } } = rest
return (
<div className="mt-1 d-flex justify-content-end carousel-button-group">
<button
@ -14,11 +14,11 @@ const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => {
</button>
<button
className={
((totalItems - currentSlide) * itemWidth + 5) < containerWidth ? 'disable py-1 border btn' : 'py-1 border btn'}
(Math.abs(transform) >= parent?.current?.containerRef?.current?.scrollWidth - containerWidth) ? 'disable py-1 border btn' : 'py-1 border btn'}
onClick={() => {
if (currentSlide + 1 < totalItems) goToSlide(currentSlide + 1)
}}
disabled ={((totalItems - currentSlide) * itemWidth + 5) < containerWidth}
disabled ={Math.abs(transform) >= parent?.current?.containerRef?.current?.scrollWidth - containerWidth}
>
<i className="fas fa-angle-right"></i>
</button>

@ -3,17 +3,11 @@ import React, { useEffect, useState, useRef, useContext } from 'react'
import { ThemeContext, themes } from '../themeContext'
import Carousel from 'react-multi-carousel'
import 'react-multi-carousel/lib/styles.css'
import CustomNavButtons from './customNavButtons'
const _paq = window._paq = window._paq || [] // eslint-disable-line
function HomeTabFeatured() {
const themeFilter = useContext(ThemeContext)
useEffect(() => {
return () => {
}
}, [])
return (
<div className="pt-3 pl-2" id="hTFeaturedeSection">
<label style={{ fontSize: "1.2rem" }}>Featured</label>
@ -21,7 +15,6 @@ function HomeTabFeatured() {
<div className="w-100 d-flex flex-column" style={{ height: "200px" }}>
<ThemeContext.Provider value={themeFilter}>
<Carousel
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />}
arrows={false}
swipeable={false}
draggable={true}
@ -30,17 +23,18 @@ function HomeTabFeatured() {
renderDotsOutside={true}
ssr={true} // means to render carousel on server-side.
infinite={true}
partialVisible={false}
centerMode={false}
autoPlay={true}
keyBoardControl={true}
containerClass="border carousel-container"
sliderClass="px-2 h-100 justify-content-between"
containerClass="border w-full carousel-container"
sliderClass="h-100 justify-content-between"
deviceType={"desktop"}
itemClass="px-2 carousel-item-padding-10-px"
itemClass=""
autoPlaySpeed={15000}
dotListClass="position-relative mt-2"
>
<div className="d-flex">
<div className="mx-1 px-1 d-flex">
<img src={"assets/img/bgRemi.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img>
<div className="h6 w-50 p-4" style={{ flex: "1" }}>
<h5>JUMP INTO WEB3</h5>
@ -48,7 +42,7 @@ function HomeTabFeatured() {
<a className="remixui_home_text" onClick={() => _paq.push(['trackEvent', 'hometab', 'featuredSection', 'jumpIntoWeb3'])} target="__blank" href="https://remix-project.org">More</a>
</div>
</div>
<div className="d-flex">
<div className="mx-1 px-1 d-flex">
<img src={"/assets/img/remixRewardUser.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img>
<div className="h6 p-4" style={{ flex: "1" }}>
<h5>REMIX REWARDS</h5>
@ -59,7 +53,7 @@ function HomeTabFeatured() {
<a className="remixui_home_text" target="__blank" onClick={() => _paq.push(['trackEvent', 'hometab', 'featuredSection', 'remixRewards'])} href="https://rewards.remix.ethereum.eth.limo">More</a>
</div>
</div>
<div className="d-flex">
<div className="mx-1 px-1 d-flex">
<img src={"/assets/img/remixRewardBetaTester.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img>
<div className="h6 p-4" style={{ flex: "1" }}>
<h5>BETA TESTING</h5>

@ -20,7 +20,7 @@ interface HomeTabFeaturedPluginsProps {
function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
const themeFilter = useContext(ThemeContext)
const carouselRef = useRef(null)
const carouselRef = useRef<any>({})
const carouselRefDiv = useRef(null)
useEffect(() => {
@ -47,7 +47,7 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
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
if (Math.abs(carouselRef.current.state.transform) >= carouselRef.current.containerRef.current.scrollWidth - carouselRef.current.state.containerWidth) return
carouselRef.current.goToSlide(nextSlide)
} else {
nextSlide = carouselRef.current.state.currentSlide - 1;
@ -92,7 +92,7 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
ref={carouselRef}
focusOnSelect={true}
customButtonGroup={
<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />
<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} parent={carouselRef} />
}
arrows={false}
swipeable={false}

@ -23,13 +23,13 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
const [state, setState] = useState<{
searchInput: string,
showModalDialog: boolean,
modalInfo: { title: string, loadItem: string, examples: Array<string> },
modalInfo: { title: string, loadItem: string, examples: Array<string>, prefix?: string },
importSource: string,
toasterMsg: string
}>({
searchInput: '',
showModalDialog: false,
modalInfo: { title: '', loadItem: '', examples: [] },
modalInfo: { title: '', loadItem: '', examples: [], prefix: '' },
importSource: '',
toasterMsg: ''
})
@ -42,8 +42,15 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
_paq.push(['trackEvent', 'hometab', 'filesSection', 'importFrom' + type])
const contentImport = plugin.contentImport
const workspace = plugin.fileManager.getProvider('workspace')
const startsWith = state.importSource.substring(0, 4)
if ((type === 'ipfs' || type === 'IPFS') && (startsWith !== 'ipfs' && startsWith !== "IPFS")) {
setState(prevState => {
return { ...prevState, importSource: startsWith + state.importSource}
})
}
contentImport.import(
state.importSource,
state.modalInfo.prefix + state.importSource,
(loadingMsg) => dispatch({ tooltip: loadingMsg }),
async (error, content, cleanUrl, type, url) => {
if (error) {
@ -93,9 +100,9 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
plugin.verticalIcons.select('filePanel')
}
const showFullMessage = (title: string, loadItem: string, examples: Array<string>) => {
const showFullMessage = (title: string, loadItem: string, examples: Array<string>, prefix = '') => {
setState(prevState => {
return { ...prevState, showModalDialog: true, modalInfo: { title: title, loadItem: loadItem, examples: examples } }
return { ...prevState, showModalDialog: true, modalInfo: { title: title, loadItem: loadItem, examples: examples, prefix } }
})
}
@ -126,7 +133,9 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
{ examples }
</div>
</> }
<input
<div className="d-flex flex-row">
{ state.modalInfo.prefix && <span className='text-nowrap align-self-center mr-2'>ipfs://</span> }
<input
ref={inputValue}
type='text'
name='prompt_text'
@ -140,6 +149,7 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
})
}}
/>
</div>
</div>
</ModalDialog>
<Toaster message={state.toasterMsg} />
@ -155,9 +165,15 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
<button className="btn p-2 border my-1" style={{width: 'fit-content'}} onClick={() => connectToLocalhost()}><FormattedMessage id='home.connectToLocalhost' defaultMessage='Connect to Localhost' /></button>
<label className="pt-2"><FormattedMessage id='home.loadFrom' defaultMessage='Load From' /></label>
<div className="d-flex">
<button className="btn p-2 border mr-2" data-id="landingPageImportFromGitHubButton" onClick={() => showFullMessage('GitHub', 'github URL', ['https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol', 'https://github.com/OpenZeppelin/openzeppelin-solidity/blob/67bca857eedf99bf44a4b6a0fc5b5ed553135316/contracts/access/Roles.sol'])}>GitHub</button>
<button
className="btn p-2 border mr-2"
data-id="landingPageImportFromGitHubButton"
onClick={() => showFullMessage('GitHub', 'github URL', ['https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol', 'https://github.com/OpenZeppelin/openzeppelin-solidity/blob/67bca857eedf99bf44a4b6a0fc5b5ed553135316/contracts/access/Roles.sol'])}
>
GitHub
</button>
<button className="btn p-2 border mr-2" data-id="landingPageImportFromGistButton" onClick={() => importFromGist()}>Gist</button>
<button className="btn p-2 border mr-2" onClick={() => showFullMessage('Ipfs', 'ipfs URL', ['ipfs://<ipfs-hash>'])}>IPFS</button>
<button className="btn p-2 border mr-2" onClick={() => showFullMessage('Ipfs', 'ipfs hash', ['ipfs://QmQQfBMkpDgmxKzYaoAtqfaybzfgGm9b2LWYyT56Chv6xH'], "ipfs://")}>IPFS</button>
<button className="btn p-2 border" onClick={() => showFullMessage('Https', 'http/https raw content', ['https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/token/ERC20/ERC20.sol'])}>HTTPS</button>
</div>
</div>

@ -17,7 +17,7 @@ interface HomeTabGetStartedProps {
function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
const themeFilter = useContext(ThemeContext)
const carouselRef = useRef(null)
const carouselRef = useRef<any>({})
const carouselRefDiv = useRef(null)
useEffect(() => {
@ -44,7 +44,7 @@ function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
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
if (Math.abs(carouselRef.current.state.transform) >= carouselRef.current.containerRef.current.scrollWidth - carouselRef.current.state.containerWidth) return
carouselRef.current.goToSlide(nextSlide)
} else {
nextSlide = carouselRef.current.state.currentSlide - 1;
@ -77,7 +77,7 @@ function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
ref={carouselRef}
focusOnSelect={true}
customButtonGroup={
<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />
<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} parent={carouselRef} />
}
arrows={false}
swipeable={false}

@ -49,25 +49,27 @@ function HomeTabLearn ({plugin}: HomeTabLearnProps) {
</button>
</div>
<div className="d-flex flex-column">
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Basics }})}>
<label className="m-0 float-left" style={{fontSize: "1rem"}}>Remix Basics</label>
<label className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Basics }})}>
<label className="card-title align-self-start m-0 float-left" style={{fontSize: "1rem"}}>Remix Basics</label>
{(state.visibleTutorial === VisibleTutorial.Basics) && <div className="pt-2 d-flex flex-column text-left">
<span>Introduction to Remix's interface and concepts used in Ethereum, as well as the basics of Solidity.</span>
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('basics')}>Get Started</button>
</div>}
</button>
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Intermediate }})}>
<label className="m-0 float-left" style={{fontSize: "1rem"}}>Remix Intermediate</label>
{(state.visibleTutorial === VisibleTutorial.Intermediate) && <div className="pt-2 d-flex flex-column text-left">Using the web3.js to interact with a contract. Using Recorder tool.
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('useofweb3js')}>Get Started</button>
</label>
<label className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Intermediate }})}>
<label className="card-title align-self-start m-0 float-left" style={{fontSize: "1rem"}}>Remix Intermediate</label>
{(state.visibleTutorial === VisibleTutorial.Intermediate) && <div className="pt-2 d-flex flex-column text-left">
<span>Using the web3.js to interact with a contract. Using Recorder tool.</span>
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('useofweb3js')}>Get Started</button>
</div>}
</button>
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Advanced }})}>
<label className="m-0 float-left" style={{fontSize: "1rem"}}>Remix Advanced</label>
{(state.visibleTutorial === VisibleTutorial.Advanced) && <div className="pt-2 d-flex flex-column text-left">Learn the Proxy Pattern and working with Libraries in Remix. Learn to use the Debugger.
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('deploylibraries')}>Get Started</button>
</label>
<label className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Advanced }})}>
<label className="card-title align-self-start m-0 float-left" style={{fontSize: "1rem"}}>Remix Advanced</label>
{(state.visibleTutorial === VisibleTutorial.Advanced) && <div className="pt-2 d-flex flex-column text-left">
<span>Learn the Proxy Pattern and working with Libraries in Remix. Learn to use the Debugger.</span>
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('deploylibraries')}>Get Started</button>
</div>}
</button>
</label>
</div>
</div>
)

@ -157,7 +157,7 @@ function HomeTabTitle() {
ref={searchInputRef}
type="text"
className="border form-control border-right-0"
id="searchInput"
id="homeTabSearchInput"
placeholder="Search Documentation"
data-id="terminalInputSearch"
/>

@ -1,7 +1,5 @@
import IpfsHttpClient from 'ipfs-http-client'
let ipfsNodes = []
export const publishToIPFS = async (contract, api) => {
@ -93,7 +91,6 @@ export const publishToIPFS = async (contract, api) => {
try {
const result = await ipfsVerifiedPublish(metadataContent, '', api)
try {
contract.metadataHash = result.url.match('dweb:/ipfs/(.+)')[1]
} catch (e) {

@ -28,20 +28,28 @@ export function EnvironmentUI (props: EnvironmentProps) {
<div className="udapp_crow">
<label id="selectExEnv" className="udapp_settingsLabel">
<FormattedMessage id='udapp.environment' defaultMessage='Environment' />
<CustomTooltip placement={'right'} tooltipClasses="text-nowrap" tooltipId="info-recorder"
tooltipText="Open chainlist and add a new provider for the chain you want to interact to.">
<a href='https://chainlist.org/' target='_blank'><i style={{ fontSize: 'medium' }} className={'ml-2 fad fa-plug'} aria-hidden="true"></i></a>
</CustomTooltip>
<CustomTooltip
placement={'right'}
tooltipClasses="text-nowrap"
tooltipId="info-recorder"
tooltipText="Open chainlist and add a new provider for the chain you want to interact to."
>
<a href='https://chainlist.org/' target='_blank'><i style={{ fontSize: 'medium' }} className={'ml-2 fad fa-plug'} aria-hidden="true"></i></a>
</CustomTooltip>
</label>
<div className="udapp_environment">
<Dropdown id="selectExEnvOptions" data-id="settingsSelectEnvOptions" className='udapp_selectExEnvOptions'>
<Dropdown id="selectExEnvOptions" data-id="settingsSelectEnvOptions" className='udapp_selectExEnvOptions'>
<Dropdown.Toggle as={CustomToggle} id="dropdown-custom-components" className="btn btn-light btn-block w-100 d-inline-block border border-dark form-control" icon={null}>
{ isL2(currentProvider) && 'L2 - '}
{ currentProvider && currentProvider.content }
{ currentProvider && bridges[currentProvider.value] && <CustomTooltip placement={'right'} tooltipClasses="text-nowrap" tooltipId="info-recorder" tooltipText="Click to open a bridge for converting L1 mainnet ETH to the selected network currency.">
<i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-plug'} aria-hidden="true" onClick={() => { window.open(bridges[currentProvider.value], '_blank') }}></i>
</CustomTooltip>}
{ currentProvider && bridges[currentProvider.value] && <CustomTooltip
placement={'right'}
tooltipClasses="text-nowrap"
tooltipId="info-recorder"
tooltipText="Click to open a bridge for converting L1 mainnet ETH to the selected network currency."
>
<i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-plug'} aria-hidden="true" onClick={() => { window.open(bridges[currentProvider.value], '_blank') }}></i>
</CustomTooltip>}
</Dropdown.Toggle>
<Dropdown.Menu as={CustomMenu} className='w-100 custom-dropdown-items' data-id="custom-dropdown-items" >
{
@ -53,14 +61,20 @@ export function EnvironmentUI (props: EnvironmentProps) {
}}
data-id={`dropdown-item-${value}`}
>
<span className="pl-3">{ isL2({ value }) && 'L2 - ' }{ content }</span>
<span className="">{ isL2({ value }) && 'L2 - ' }{ content }</span>
</Dropdown.Item>
))
}
</Dropdown.Menu>
</Dropdown>
<CustomTooltip placement={'bottom-start'} tooltipClasses="text-wrap" tooltipId="runAndDeployAddresstooltip"
tooltipText={<FormattedMessage id='udapp.environmentDocs' defaultMessage='Click for docs about Environment' />}>
<CustomTooltip
placement={'bottom-start'}
tooltipClasses="text-wrap"
tooltipId="runAndDeployAddresstooltip"
tooltipText={<FormattedMessage
id='udapp.environmentDocs'
defaultMessage='Click for docs about Environment' />}
>
<a href="https://remix-ide.readthedocs.io/en/latest/run.html#environment" target="_blank" rel="noreferrer"><i className="udapp_infoDeployAction ml-2 fas fa-info"></i></a>
</CustomTooltip>
</div>

@ -4,7 +4,7 @@ import { NetworkProps } from '../types'
export function NetworkUI (props: NetworkProps) {
return (
<div className="udapp_crow">
<div className="">
<div className="udapp_settingsLabel">
</div>
<div className="udapp_environment" data-id="settingsNetworkEnv">

@ -28,7 +28,7 @@ export function RecorderUI (props: RecorderProps) {
return (
<div className="udapp_cardContainer list-group-item border border-bottom">
<div className="udapp_cardContainer list-group-item border-top border-bottom">
<div className="udapp_recorderSection d-flex justify-content-between" onClick={toggleClass}>
<div className="d-flex justify-content-center align-items-center">
<label className="mt-1 udapp_recorderSectionLabel">

@ -45,8 +45,6 @@
width: 164px;
min-width: 164px;
}
.udapp_col2_2 {
}
.udapp_select {
font-weight: normal;
width: 100%;
@ -314,7 +312,7 @@
.udapp_cActionsWrapper {
border-top-left-radius: 0;
border-bottom-left-radius: 0.25rem;
border-top-rightt-radius: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0.25rem;
padding: 8px 10px 7px;
}

Loading…
Cancel
Save