Merge branch 'master' into parserfix

pull/2908/head
bunsenstraat 2 years ago committed by GitHub
commit fbbddb20de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      apps/remix-ide/src/app/editor/editor.js
  2. 3
      apps/remix-ide/src/app/tabs/compile-tab.js
  3. 2
      apps/remix-ide/src/app/tabs/web3-provider.js
  4. 3
      apps/remix-ide/src/remixAppManager.js
  5. 1
      libs/remix-ui/app/src/lib/remix-app/components/dragbar/dragbar.tsx
  6. 1
      libs/remix-ui/panel/src/lib/dragbar/dragbar.tsx
  7. 10
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  8. 55
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx

@ -5,6 +5,7 @@ import { EditorUI } from '@remix-ui/editor' // eslint-disable-line
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
import { PluginViewWrapper } from '@remix-ui/helper' import { PluginViewWrapper } from '@remix-ui/helper'
import { exists } from 'fs'
const EventManager = require('../../lib/events') const EventManager = require('../../lib/events')
@ -74,30 +75,15 @@ class Editor extends Plugin {
updateComponent(state) { updateComponent(state) {
return <EditorUI return <EditorUI
editorAPI={state.api} editorAPI={state.api}
themeType={state.currentThemeType} themeType={state.currentThemeType}
currentFile={state.currentFile} currentFile={state.currentFile}
events={state.events} events={state.events}
plugin={state.plugin} plugin={state.plugin}
/> />
} }
render () { render () {
/* if (this.el) return this.el
this.el = document.createElement('div')
this.el.setAttribute('id', 'editorView')
this.el.currentContent = () => this.currentContent() // used by e2e test
this.el.setCurrentContent = (value) => {
if (this.sessions[this.currentFile]) {
this.sessions[this.currentFile].setValue(value)
this._onChange(this.currentFile)
}
}
this.el.gotoLine = (line, column) => this.gotoLine(line, column || 0)
this.el.getCursorPosition = () => this.getCursorPosition() */
return <div ref={(element)=>{ return <div ref={(element)=>{
this.ref = element this.ref = element
this.ref.currentContent = () => this.currentContent() // used by e2e test this.ref.currentContent = () => this.currentContent() // used by e2e test
@ -113,7 +99,7 @@ class Editor extends Plugin {
this.ref.clearDecorationsByPlugin = (filePath, plugin, typeOfDecoration) => this.clearDecorationsByPlugin(filePath, plugin, typeOfDecoration) this.ref.clearDecorationsByPlugin = (filePath, plugin, typeOfDecoration) => this.clearDecorationsByPlugin(filePath, plugin, typeOfDecoration)
this.ref.keepDecorationsFor = (name, typeOfDecoration) => this.keepDecorationsFor(name, typeOfDecoration) this.ref.keepDecorationsFor = (name, typeOfDecoration) => this.keepDecorationsFor(name, typeOfDecoration)
}} id='editorView'> }} id='editorView'>
<PluginViewWrapper plugin={this} /> <PluginViewWrapper plugin={this} />
</div> </div>
} }
@ -229,15 +215,20 @@ class Editor extends Plugin {
try { try {
// we can't use the fileManager plugin call directly // we can't use the fileManager plugin call directly
// because it's itself called in a plugin context, and that causes a timeout in the plugin stack // because it's itself called in a plugin context, and that causes a timeout in the plugin stack
const contentDep = await readFile(pathDep) const pathExists = await exists(pathDep)
if (contentDep !== null) { let contentDep = ''
this.emit('addModel', contentDep, 'typescript', pathDep, false) if (pathExists) {
contentDep = await readFile(pathDep)
if (contentDep !== '') {
this.emit('addModel', contentDep, 'typescript', pathDep, false)
}
} else {
console.log("The file ", pathDep, " can't be found.")
} }
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} }
} }
} }
} }

@ -8,6 +8,7 @@ import { QueryParams } from '@remix-project/remix-lib'
// import { ICompilerApi } from '@remix-project/remix-lib-ts' // import { ICompilerApi } from '@remix-project/remix-lib-ts'
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
import { compilerConfigChangedToastMsg, compileToastMsg } from '@remix-ui/helper' import { compilerConfigChangedToastMsg, compileToastMsg } from '@remix-ui/helper'
import { isNative } from '../../remixAppManager'
const profile = { const profile = {
name: 'solidity', name: 'solidity',
@ -104,7 +105,7 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA
} }
compile (fileName) { compile (fileName) {
this.call('notification', 'toast', compileToastMsg(this.currentRequest.from, fileName)) if (!isNative(this.currentRequest.from)) this.call('notification', 'toast', compileToastMsg(this.currentRequest.from, fileName))
super.compile(fileName) super.compile(fileName)
} }

@ -30,7 +30,7 @@ export class Web3ProviderModule extends Plugin {
// see https://github.com/ethereum/web3.js/pull/1018/files#diff-d25786686c1053b786cc2626dc6e048675050593c0ebaafbf0814e1996f22022R129 // see https://github.com/ethereum/web3.js/pull/1018/files#diff-d25786686c1053b786cc2626dc6e048675050593c0ebaafbf0814e1996f22022R129
provider[provider.sendAsync ? 'sendAsync' : 'send'](payload, async (error, message) => { provider[provider.sendAsync ? 'sendAsync' : 'send'](payload, async (error, message) => {
if (error) { if (error) {
const errorData = error.data ? error.data : error.message const errorData = error.data ? error.data : error.message ? error.message : error
// See: https://github.com/ethers-io/ethers.js/issues/901 // See: https://github.com/ethers-io/ethers.js/issues/901
if (!(typeof errorData === 'string' && errorData.includes("unknown method eth_chainId"))) this.call('terminal', 'log', error.data ? error.data : error.message) if (!(typeof errorData === 'string' && errorData.includes("unknown method eth_chainId"))) this.call('terminal', 'log', error.data ? error.data : error.message)
return reject(errorData) return reject(errorData)

@ -25,7 +25,8 @@ const sensitiveCalls = {
export function isNative(name) { export function isNative(name) {
// nativePlugin allows to bypass the permission request // nativePlugin allows to bypass the permission request
const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic', 'solidityStaticAnalysis', 'solidityUnitTesting', const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic', 'solidityStaticAnalysis', 'solidityUnitTesting',
'layout', 'notification', 'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected-optimism-provider', 'injected-arbitrum-one-provider'] 'layout', 'notification', 'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected-optimism-provider',
'tabs', 'injected-arbitrum-one-provider']
return nativePlugins.includes(name) || requiredModules.includes(name) return nativePlugins.includes(name) || requiredModules.includes(name)
} }

@ -45,6 +45,7 @@ const DragBar = (props: IRemixDragBarUi) => {
}, [props.resetTrigger]) }, [props.resetTrigger])
const handleResize = () => { const handleResize = () => {
if (!props.refObject.current) return
setOffSet(props.refObject.current.offsetLeft) setOffSet(props.refObject.current.offsetLeft)
setDragBarPosX(props.refObject.current.offsetLeft + props.refObject.current.offsetWidth) setDragBarPosX(props.refObject.current.offsetLeft + props.refObject.current.offsetWidth)
} }

@ -23,6 +23,7 @@ const DragBar = (props: IRemixDragBarUi) => {
props.setHideStatus(false) props.setHideStatus(false)
} }
const handleResize = () => { const handleResize = () => {
if (!props.refObject.current) return
setDragBarPosY(window.innerHeight - props.refObject.current.offsetHeight) setDragBarPosY(window.innerHeight - props.refObject.current.offsetHeight)
} }

@ -863,7 +863,13 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</OverlayTrigger> </OverlayTrigger>
</button> </button>
<div className='d-flex align-items-center'> <div className='d-flex align-items-center'>
<button id="compileAndRunBtn" data-id="compilerContainerCompileAndRunBtn" className="btn btn-secondary btn-block d-block w-100 text-break remixui_solidityCompileAndRunButton d-inline-block remixui_disabled mb-1 mt-3" onClick={compileAndRun} disabled={(configFilePath === '' && state.useFileConfiguration) || disableCompileButton}> <button
id="compileAndRunBtn"
data-id="compilerContainerCompileAndRunBtn"
className="btn btn-secondary btn-block d-block w-100 text-break remixui_solidityCompileAndRunButton d-inline-block remixui_disabled mb-1 mt-3"
onClick={compileAndRun}
disabled={(configFilePath === '' && state.useFileConfiguration) || disableCompileButton}
>
<OverlayTrigger overlay={ <OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile-run"> <Tooltip id="overlay-tooltip-compile-run">
<div className="text-left"> <div className="text-left">
@ -875,7 +881,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<span> <span>
Compile and Run script Compile and Run script
</span> </span>
</OverlayTrigger> </OverlayTrigger>
</button> </button>
<OverlayTrigger overlay={ <OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile-run-doc"> <Tooltip id="overlay-tooltip-compile-run-doc">

@ -1,8 +1,8 @@
import { fileDecoration, FileDecorationIcons } from '@remix-ui/file-decorators' import { fileDecoration, FileDecorationIcons } from '@remix-ui/file-decorators'
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line
import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs' import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'
import './remix-ui-tabs.css' import './remix-ui-tabs.css'
@ -17,26 +17,25 @@ export interface TabsUIProps {
onReady: (api: any) => void onReady: (api: any) => void
themeQuality: string themeQuality: string
} }
export interface TabsUIApi { export interface TabsUIApi {
activateTab: (namee: string) => void activateTab: (name: string) => void
active: () => string active: () => string
} }
interface ITabsState { interface ITabsState {
selectedIndex: number, selectedIndex: number,
fileDecorations: fileDecoration[], fileDecorations: fileDecoration[],
currentExt: string
} }
interface ITabsAction { interface ITabsAction {
type: string, type: string,
payload: any, payload: any,
ext?: string,
} }
const initialTabsState: ITabsState = { const initialTabsState: ITabsState = {
selectedIndex: -1, selectedIndex: -1,
fileDecorations: [], fileDecorations: [],
currentExt: ''
} }
const tabsReducer = (state: ITabsState, action: ITabsAction) => { const tabsReducer = (state: ITabsState, action: ITabsAction) => {
@ -44,6 +43,7 @@ const tabsReducer = (state: ITabsState, action: ITabsAction) => {
case 'SELECT_INDEX': case 'SELECT_INDEX':
return { return {
...state, ...state,
currentExt: action.ext,
selectedIndex: action.payload, selectedIndex: action.payload,
} }
case 'SET_FILE_DECORATIONS': case 'SET_FILE_DECORATIONS':
@ -71,8 +71,6 @@ export const TabsUI = (props: TabsUIProps) => {
} }
}, [tabsState.selectedIndex]) }, [tabsState.selectedIndex])
const getFileDecorationClasses = (tab: any) => { const getFileDecorationClasses = (tab: any) => {
const fileDecoration = tabsState.fileDecorations.find((fileDecoration: fileDecoration) => { const fileDecoration = tabsState.fileDecorations.find((fileDecoration: fileDecoration) => {
if(`${fileDecoration.workspace.name}/${fileDecoration.path}` === tab.name) return true if(`${fileDecoration.workspace.name}/${fileDecoration.path}` === tab.name) return true
@ -84,8 +82,7 @@ export const TabsUI = (props: TabsUIProps) => {
return <FileDecorationIcons file={{path: tab.name}} fileDecorations={tabsState.fileDecorations} /> return <FileDecorationIcons file={{path: tab.name}} fileDecorations={tabsState.fileDecorations} />
} }
const renderTab = (tab, index) => {
const renderTab = (tab, index) => {
const classNameImg = 'my-1 mr-1 text-dark ' + tab.iconClass const classNameImg = 'my-1 mr-1 text-dark ' + tab.iconClass
const classNameTab = 'nav-item nav-link d-flex justify-content-center align-items-center px-2 py-1 tab' + (index === currentIndexRef.current ? ' active' : '') const classNameTab = 'nav-item nav-link d-flex justify-content-center align-items-center px-2 py-1 tab' + (index === currentIndexRef.current ? ' active' : '')
const invert = props.themeQuality === 'dark' ? 'invert(1)' : 'invert(0)' const invert = props.themeQuality === 'dark' ? 'invert(1)' : 'invert(0)'
@ -106,10 +103,11 @@ export const TabsUI = (props: TabsUIProps) => {
if (currentIndexRef.current < 0) return '' if (currentIndexRef.current < 0) return ''
return tabs.current[currentIndexRef.current].name return tabs.current[currentIndexRef.current].name
} }
const activateTab = (name: string) => { const activateTab = (name: string) => {
const index = tabs.current.findIndex((tab) => tab.name === name) const index = tabs.current.findIndex((tab) => tab.name === name)
currentIndexRef.current = index currentIndexRef.current = index
dispatch({ type: 'SELECT_INDEX', payload: index }) dispatch({ type: 'SELECT_INDEX', payload: index, ext: getExt(name)})
} }
const setFileDecorations = (fileStates: fileDecoration[]) => { const setFileDecorations = (fileStates: fileDecoration[]) => {
@ -135,10 +133,41 @@ export const TabsUI = (props: TabsUIProps) => {
return () => { tabsElement.current.removeEventListener('wheel', transformScroll) } return () => { tabsElement.current.removeEventListener('wheel', transformScroll) }
}, []) }, [])
const getExt = (path) => {
const root = path.split('#')[0].split('?')[0]
const ext = root.indexOf('.') !== -1 ? /[^.]+$/.exec(root) : null
if (ext) return ext[0].toLowerCase()
else return ''
}
return ( return (
<div className="remix-ui-tabs d-flex justify-content-between border-0 header nav-tabs" data-id="tabs-component"> <div className="remix-ui-tabs d-flex justify-content-between border-0 header nav-tabs" data-id="tabs-component">
<div className="d-flex flex-row" style={{ maxWidth: 'fit-content', width: '97%' }}> <div className="d-flex flex-row" style={{ maxWidth: 'fit-content', width: '97%' }}>
<div className="d-flex flex-row justify-content-center align-items-center m-1 mt-2"> <div className="d-flex flex-row justify-content-center align-items-center m-1 mt-1">
<button
className="btn text-success py-0"
disabled={!(tabsState.currentExt === 'js' || tabsState.currentExt === 'ts' || tabsState.currentExt === 'sol')}
onClick={async () => {
const path = active().substr(active().indexOf('/') + 1, active().length)
const content = await props.plugin.call('fileManager', "readFile", path)
if (tabsState.currentExt === 'js' || tabsState.currentExt === 'ts') {
await props.plugin.call('scriptRunner', 'execute', content)
} else if (tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul') {
await props.plugin.call('solidity', 'compile', path)
}
}}
>
<OverlayTrigger placement="bottom" overlay={
<Tooltip id="overlay-tooltip-run-script">
<span>
{(tabsState.currentExt === 'js' || tabsState.currentExt === 'ts') ? "Run script (CTRL + SHIFT + S)" :
tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul'? "Compile CTRL + S" : "Select .sol or .yul file to compile or a .ts or .js file and run it"}
</span>
</Tooltip>
}>
<i className="fad fa-play"></i>
</OverlayTrigger>
</button>
<span data-id="tabProxyZoomOut" className="btn btn-sm px-2 fas fa-search-minus text-dark" title="Zoom out" onClick={() => props.onZoomOut()}></span> <span data-id="tabProxyZoomOut" className="btn btn-sm px-2 fas fa-search-minus text-dark" title="Zoom out" onClick={() => props.onZoomOut()}></span>
<span data-id="tabProxyZoomIn" className="btn btn-sm px-2 fas fa-search-plus text-dark" title="Zoom in" onClick={() => props.onZoomIn()}></span> <span data-id="tabProxyZoomIn" className="btn btn-sm px-2 fas fa-search-plus text-dark" title="Zoom in" onClick={() => props.onZoomIn()}></span>
</div> </div>
@ -153,7 +182,7 @@ export const TabsUI = (props: TabsUIProps) => {
onSelect={(index) => { onSelect={(index) => {
props.onSelect(index) props.onSelect(index)
currentIndexRef.current = index currentIndexRef.current = index
dispatch({ type: 'SELECT_INDEX', payload: index }) dispatch({ type: 'SELECT_INDEX', payload: index, ext: getExt(props.tabs[currentIndexRef.current].name)})
}} }}
> >
<TabList className="d-flex flex-row align-items-center"> <TabList className="d-flex flex-row align-items-center">

Loading…
Cancel
Save