diff --git a/apps/remix-ide-e2e/src/commands/getModalBody.ts b/apps/remix-ide-e2e/src/commands/getModalBody.ts index 80e2169ff7..602b2c8d60 100644 --- a/apps/remix-ide-e2e/src/commands/getModalBody.ts +++ b/apps/remix-ide-e2e/src/commands/getModalBody.ts @@ -3,7 +3,7 @@ import EventEmitter from 'events' class GetModalBody extends EventEmitter { command (this: NightwatchBrowser, callback: (value: string, cb: VoidFunction) => void) { - this.api.waitForElementPresent('.modal-body') + this.api.waitForElementVisible('[data-id="modalDialogModalBody"]') .getText('#modal-dialog', (result) => { console.log(result) const value = typeof result.value === 'string' ? result.value : null diff --git a/apps/remix-ide-e2e/src/tests/publishContract.test.ts b/apps/remix-ide-e2e/src/tests/publishContract.test.ts index f435321c0d..a68219401b 100644 --- a/apps/remix-ide-e2e/src/tests/publishContract.test.ts +++ b/apps/remix-ide-e2e/src/tests/publishContract.test.ts @@ -20,24 +20,33 @@ module.exports = { .verifyContracts(['Ballot']) .click('#publishOnIpfs') .pause(8000) - .getModalBody((value, done) => { - if (value.indexOf('Metadata of "ballot" was published successfully.') === -1) browser.assert.fail('ipfs deploy failed', '', '') - if (value.indexOf('ipfs://') === -1) browser.assert.fail('ipfs deploy failed', '', '') - done() + .waitForElementVisible('[data-id="publishToStorageModalDialogModalBody-react"]', 60000) + .getText('[data-id="publishToStorageModalDialogModalBody-react"]', (result) => { + const value = (result.value) + + browser.perform((done) => { + if (value.indexOf('Metadata of "ballot" was published successfully.') === -1) browser.assert.fail('ipfs deploy failed') + // if (value.indexOf('ipfs://') === -1) browser.assert.fail('ipfs deploy failed') + done() + }) }) - .modalFooterOKClick() + .click('[data-id="publishToStorage-modal-footer-ok-react"]') }, 'Publish on Swarm': '' + function (browser: NightwatchBrowser) { browser .click('#publishOnSwarm') .pause(8000) - .getModalBody((value, done) => { - if (value.indexOf('Metadata of "ballot" was successfully.') === -1) browser.assert.fail('swarm deploy failed', '', '') - if (value.indexOf('bzz') === -1) browser.assert.fail('swarm deploy failed', '', '') - done() + .getText('[data-id="publishToStorageModalDialogModalBody-react"]', (result) => { + const value = (result.value) + + browser.perform((done) => { + if (value.indexOf('Metadata of "ballot" was published successfully.') === -1) browser.assert.fail('swarm deploy failed') + if (value.indexOf('bzz') === -1) browser.assert.fail('swarm deploy failed') + done() + }) }) - .modalFooterOKClick() + .click('[data-id="publishToStorage-modal-footer-ok-react"]') }, 'Should publish contract metadata to ipfs on deploy': function (browser: NightwatchBrowser) { @@ -48,6 +57,7 @@ module.exports = { .clickLaunchIcon('udapp') .waitForElementPresent('*[data-id="contractDropdownIpfsCheckbox"]') .click('*[data-id="contractDropdownIpfsCheckbox"]') + .waitForElementVisible('*[data-id="Deploy - transact (not payable)"]') .click('*[data-id="Deploy - transact (not payable)"]') .pause(8000) .getModalBody((value, done) => { diff --git a/libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx b/libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx index f22aeff061..c07e43ab70 100644 --- a/libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx +++ b/libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx @@ -56,7 +56,7 @@ export const PublishToStorage = (props: RemixUiPublishToStorageProps) => { }, [storage]) const publishMessage = (uploaded) => ( - Metadata of {contract.name.toLowerCase()} was published successfully.
+ Metadata of "{contract.name.toLowerCase()}" was published successfully.
         
{ uploaded.map((value, index) =>
{ value.filename } :
{ value.output.url }
) } @@ -94,7 +94,7 @@ export const PublishToStorage = (props: RemixUiPublishToStorageProps) => { return ( = null - -export const fetchCompilerError = (error: any) => { +export const setEditorMode = (mode: string) => { return { - type: 'FETCH_COMPILER_ERROR', - payload: error + type: 'SET_EDITOR_MODE', + payload: mode } } -export const fetchCompilerRequest = (promise: Promise) => { - return { - type: 'FETCH_COMPILER_REQUEST', - payload: promise - } +export const resetEditorMode = () => (dispatch: React.Dispatch) => { + dispatch({ + type: 'RESET_EDITOR_MODE' + }) } -export const fetchCompilerSuccess = (compiler) => { +export const setCompilerMode = (mode: string, ...args) => { return { - type: 'FETCH_COMPILER_SUCCESS', - payload: compiler + type: 'SET_COMPILER_MODE', + payload: { mode, args } } } -export const fetchCompiler = (provider, path: string) => (dispatch: React.Dispatch) => { - const promise = fetchDirectoryContent(provider, path) +export const resetCompilerMode = () => (dispatch: React.Dispatch) => { + dispatch({ + type: 'RESET_COMPILER_MODE' + }) +} + +export const listenToEvents = (editor, compileTabLogic) => (dispatch: React.Dispatch) => { + editor.event.register('sessionSwitched', () => { + dispatch(setEditorMode('sessionSwitched')) + }) + + compileTabLogic.event.on('startingCompilation', () => { + dispatch(setCompilerMode('startingCompilation')) + }) + + compileTabLogic.compiler.event.register('compilationDuration', (speed) => { + dispatch(setCompilerMode('compilationDuration', speed)) + }) + + editor.event.register('contentChanged', () => { + dispatch(setEditorMode('contentChanged')) + }) + + compileTabLogic.compiler.event.register('loadingCompiler', () => { + dispatch(setCompilerMode('compilationDuration')) + }) + + compileTabLogic.compiler.event.register('compilerLoaded', () => { + dispatch(setCompilerMode('compilerLoaded')) + }) - dispatch(fetchDirectoryRequest(promise)) - promise.then((files) => { - dispatch(fetchDirectorySuccess(path, files)) - }).catch((error) => { - dispatch(fetchDirectoryError({ error })) + compileTabLogic.compiler.event.register('compilationFinished', (success, data, source) => { + dispatch(setCompilerMode('compilationFinished', success, data, source)) }) - return promise } diff --git a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx index 5792dd2bec..060ede455a 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx @@ -1,8 +1,10 @@ -import React, { useEffect, useState, useRef } from 'react' // eslint-disable-line +import React, { useEffect, useState, useRef, useReducer } from 'react' // eslint-disable-line import semver from 'semver' import { CompilerContainerProps } from './types' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '../../../../../apps/remix-ide/src/app/compiler/compiler-utils' // eslint-disable-line +import { compilerReducer, compilerInitialState } from './reducers/compiler' +import { resetCompilerMode, resetEditorMode, listenToEvents } from './actions/compiler' import './css/style.css' @@ -29,6 +31,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => { const warningIcon = useRef(null) const promptMessageInput = useRef(null) const [hhCompilation, sethhCompilation] = useState(false) + const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState) useEffect(() => { fetchAllVersion((allversions, selectedVersion, isURL) => { @@ -47,12 +50,11 @@ export const CompilerContainer = (props: CompilerContainerProps) => { const currentFileName = config.get('currentFile') currentFile(currentFileName) - listenToEvents() + listenToEvents(editor, compileTabLogic)(dispatch) }, []) useEffect(() => { if (compileTabLogic && compileTabLogic.compiler) { - compileTabLogic.compiler.event.register('compilerLoaded', compilerLoaded) setState(prevState => { return { ...prevState, @@ -71,13 +73,47 @@ export const CompilerContainer = (props: CompilerContainerProps) => { }) }, [compiledFileName]) - const compilerLoaded = (version: string) => { - setVersionText(version) - } + useEffect(() => { + if (compilerContainer.compiler.mode) { + switch (compilerContainer.compiler.mode) { + case 'startingCompilation': + startingCompilation() + resetCompilerMode()(dispatch) + break + case 'compilationDuration': + compilationDuration(compilerContainer.compiler.args) + resetCompilerMode()(dispatch) + break + case 'loadingCompiler': + loadingCompiler() + resetCompilerMode()(dispatch) + break + case 'compilerLoaded': + compilerLoaded() + resetCompilerMode()(dispatch) + break + case 'compilationFinished': + compilationFinished(compilerContainer.compiler.args) + resetCompilerMode()(dispatch) + break + } + } + }, [compilerContainer.compiler.mode]) - const setVersionText = (text) => { - // if (this._view.version) this._view.version.innerText = text - } + useEffect(() => { + if (compilerContainer.editor.mode) { + switch (compilerContainer.editor.mode) { + case 'sessionSwitched': + sessionSwitched() + resetEditorMode()(dispatch) + break + case 'contentChanged': + contentChanged() + resetEditorMode()(dispatch) + break + } + } + }, [compilerContainer.editor.mode]) // fetching both normal and wasm builds and creating a [version, baseUrl] map const fetchAllVersion = async (callback) => { @@ -176,67 +212,64 @@ export const CompilerContainer = (props: CompilerContainerProps) => { return extention.toLowerCase() === 'sol' || extention.toLowerCase() === 'yul' } - const listenToEvents = () => { - editor.event.register('sessionSwitched', () => { - if (!compileIcon.current) return - scheduleCompilation() - }) + const sessionSwitched = () => { + if (!compileIcon.current) return + scheduleCompilation() + } - compileTabLogic.event.on('startingCompilation', () => { - if (!compileIcon.current) return - compileIcon.current.setAttribute('title', 'compiling...') - compileIcon.current.classList.remove('remixui_bouncingIcon') - compileIcon.current.classList.add('remixui_spinningIcon') - }) + const startingCompilation = () => { + if (!compileIcon.current) return + compileIcon.current.setAttribute('title', 'compiling...') + compileIcon.current.classList.remove('remixui_bouncingIcon') + compileIcon.current.classList.add('remixui_spinningIcon') + } - compileTabLogic.compiler.event.register('compilationDuration', (speed) => { - if (!warningIcon.current) return - if (speed > 1000) { - const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.` + const compilationDuration = ({ speed }) => { + if (!warningIcon.current) return + if (speed > 1000) { + const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.` - warningIcon.current.setAttribute('title', msg) - warningIcon.current.style.visibility = 'visible' - } else { - warningIcon.current.style.visibility = 'hidden' - } - }) + warningIcon.current.setAttribute('title', msg) + warningIcon.current.style.visibility = 'visible' + } else { + warningIcon.current.style.visibility = 'hidden' + } + } - editor.event.register('contentChanged', () => { - if (!compileIcon.current) return - scheduleCompilation() - compileIcon.current.classList.add('remixui_bouncingIcon') // @TODO: compileView tab - }) + const contentChanged = () => { + if (!compileIcon.current) return + scheduleCompilation() + compileIcon.current.classList.add('remixui_bouncingIcon') // @TODO: compileView tab + } - compileTabLogic.compiler.event.register('loadingCompiler', () => { - if (!compileIcon.current) return - // _disableCompileBtn(true) - compileIcon.current.setAttribute('title', 'compiler is loading, please wait a few moments.') - compileIcon.current.classList.add('remixui_spinningIcon') - warningIcon.current.style.visibility = 'hidden' - _updateLanguageSelector() - }) + const loadingCompiler = () => { + if (!compileIcon.current) return + // _disableCompileBtn(true) + compileIcon.current.setAttribute('title', 'compiler is loading, please wait a few moments.') + compileIcon.current.classList.add('remixui_spinningIcon') + warningIcon.current.style.visibility = 'hidden' + _updateLanguageSelector() + } - compileTabLogic.compiler.event.register('compilerLoaded', () => { - if (!compileIcon.current) return - // _disableCompileBtn(false) - compileIcon.current.setAttribute('title', '') - compileIcon.current.classList.remove('remixui_spinningIcon') - if (state.autoCompile) compile() - }) + const compilerLoaded = () => { + if (!compileIcon.current) return + // _disableCompileBtn(false) + compileIcon.current.setAttribute('title', '') + compileIcon.current.classList.remove('remixui_spinningIcon') + if (state.autoCompile) compile() + } - compileTabLogic.compiler.event.register('compilationFinished', (success, data, source) => { + const compilationFinished = ({ success, data, source }) => { if (!compileIcon.current) return compileIcon.current.setAttribute('title', 'idle') compileIcon.current.classList.remove('remixui_spinningIcon') compileIcon.current.classList.remove('remixui_bouncingIcon') - }) } const scheduleCompilation = () => { - const autoCompile = config.get('autoCompile') - if (!autoCompile) return + if (!state.autoCompile) return if (state.compileTimeout) window.clearTimeout(state.compileTimeout) - const compileTimeout = window.setTimeout(() => autoCompile && compile(), state.timeout) + const compileTimeout = window.setTimeout(() => state.autoCompile && compile(), state.timeout) setState(prevState => { return { ...prevState, compileTimeout } diff --git a/libs/remix-ui/solidity-compiler/src/lib/reducers/compiler.ts b/libs/remix-ui/solidity-compiler/src/lib/reducers/compiler.ts index 2fd8b933ff..6507d84b7b 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/reducers/compiler.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/reducers/compiler.ts @@ -5,47 +5,58 @@ interface Action { export const compilerInitialState = { compiler: { - compiler: null, - isRequesting: false, - isSuccessful: false, - error: null + mode: '', + args: null + }, + editor: { + mode: '' } } export const compilerReducer = (state = compilerInitialState, action: Action) => { switch (action.type) { - case 'FETCH_COMPILER_REQUEST': { + case 'SET_COMPILER_MODE': { return { ...state, - compiler: action.payload, - isRequesting: true, - isSuccessful: false, - error: null + compiler: { + ...state.compiler, + mode: action.payload.mode, + args: action.payload.args || null + } } } - case 'FETCH_COMPILER_SUCCESS': { + + case 'RESET_COMPILER_MODE': { return { ...state, - provider: { - ...state, - compiler: action.payload, - isRequesting: false, - isSuccessful: true, - error: null + compiler: { + ...state.compiler, + mode: '', + args: null } } } - case 'FETCH_COMPILER_ERROR': { + + case 'SET_EDITOR_MODE': { + return { + ...state, + editor: { + ...state.editor, + mode: action.payload + } + } + } + + case 'RESET_EDITOR_MODE': { return { ...state, - provider: { - ...state, - isRequesting: false, - isSuccessful: false, - error: action.payload + editor: { + ...state.editor, + mode: '' } } } + default: throw new Error() }