From 993c3d5535acfdc8e6ad91f89caefdfc43849b48 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 20 Jan 2022 17:50:02 +0530 Subject: [PATCH 1/9] lazy loading --- apps/remix-ide/src/index.tsx | 8 +++++--- apps/remix-ide/tsconfig.json | 2 -- libs/remix-ui/app/src/index.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide/src/index.tsx b/apps/remix-ide/src/index.tsx index 9a20939ed4..3f7f54674b 100644 --- a/apps/remix-ide/src/index.tsx +++ b/apps/remix-ide/src/index.tsx @@ -1,16 +1,18 @@ // eslint-disable-next-line no-use-before-define -import React from 'react' +import React, { Suspense, lazy } from 'react' import ReactDOM from 'react-dom' import AppComponent from './app' // eslint-disable-next-line no-unused-vars -import { RemixApp } from '@remix-ui/app' +const RemixApp = lazy(() => import ('@remix-ui/app')); const appComponent = new AppComponent() appComponent.run() ReactDOM.render( - + Loading...}> + + , document.getElementById('root') ) diff --git a/apps/remix-ide/tsconfig.json b/apps/remix-ide/tsconfig.json index 04d219a926..b2a6956c94 100644 --- a/apps/remix-ide/tsconfig.json +++ b/apps/remix-ide/tsconfig.json @@ -4,10 +4,8 @@ "jsx": "react", "allowJs": true, "esModuleInterop": true, - "resolveJsonModule": true, "allowSyntheticDefaultImports": true, "types": ["node", "jest"], - "module": "es6", "resolveJsonModule": true }, "files": [ diff --git a/libs/remix-ui/app/src/index.ts b/libs/remix-ui/app/src/index.ts index e706f1ad94..13056623bd 100644 --- a/libs/remix-ui/app/src/index.ts +++ b/libs/remix-ui/app/src/index.ts @@ -1,4 +1,4 @@ -export { default as RemixApp } from './lib/remix-app/remix-app' +export { default as default } from './lib/remix-app/remix-app' export { dispatchModalContext } from './lib/remix-app/context/context' export { ModalProvider } from './lib/remix-app/context/provider' export { AppModal } from './lib/remix-app/interface/index' From e208e0d3da30a3f73151eab25938bf1b484ce4f0 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 25 Jan 2022 14:18:54 +0530 Subject: [PATCH 2/9] dynamic imports --- apps/remix-ide/src/app.js | 30 ++++++++++-------------------- apps/remix-ide/src/index.tsx | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 71360c1e9d..5d0308983f 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -1,16 +1,6 @@ 'use strict' import { RunTab, makeUdapp } from './app/udapp' -import { RemixEngine } from './remixEngine' import { RemixAppManager } from './remixAppManager' -import { ThemeModule } from './app/tabs/theme-module' -import { NetworkModule } from './app/tabs/network-module' -import { Web3ProviderModule } from './app/tabs/web3-provider' -import { SidePanel } from './app/components/side-panel' -import { HiddenPanel } from './app/components/hidden-panel' -import { VerticalIcons } from './app/components/vertical-icons' -import { LandingPage } from './app/ui/landing-page/landing-page' -import { MainPanel } from './app/components/main-panel' -import { PermissionHandlerPlugin } from './app/plugins/permission-handler-plugin' import { WalkthroughService } from './walkthroughService' @@ -95,7 +85,7 @@ class AppComponent { const pluginLoader = self.appManager.pluginLoader self.panels = {} self.workspace = pluginLoader.get() - self.engine = new RemixEngine() + self.engine = new (await import('./remixEngine')).RemixEngine self.engine.register(appManager) const matomoDomains = { @@ -126,7 +116,7 @@ class AppComponent { // ----------------- gist service --------------------------------- self.gistHandler = new GistHandler() // ----------------- theme service --------------------------------- - self.themeModule = new ThemeModule() + self.themeModule = new (await import('./app/tabs/theme-module')).ThemeModule() Registry.getInstance().put({ api: self.themeModule, name: 'themeModule' }) // ----------------- editor service ---------------------------- @@ -159,9 +149,9 @@ class AppComponent { // service which fetch contract artifacts from sourve-verify, put artifacts in remix and compile it const fetchAndCompile = new FetchAndCompile() // ----------------- network service (resolve network id / name) ----- - const networkModule = new NetworkModule(blockchain) + const networkModule = new (await import('./app/tabs/network-module')).NetworkModule(blockchain) // ----------------- represent the current selected web3 provider ---- - const web3Provider = new Web3ProviderModule(blockchain) + const web3Provider = new (await import('./app/tabs/web3-provider')).Web3ProviderModule(blockchain) const hardhatProvider = new HardhatProvider(blockchain) // ----------------- convert offset to line/column service ----------- const offsetToLineColumnConverter = new OffsetToLineColumnConverter() @@ -192,7 +182,7 @@ class AppComponent { const configPlugin = new ConfigPlugin() self.layout = new Layout() - const permissionHandler = new PermissionHandlerPlugin() + const permissionHandler = new (await import('./app/plugins/permission-handler-plugin')).PermissionHandlerPlugin() self.engine.register([ permissionHandler, @@ -219,22 +209,22 @@ class AppComponent { ]) // LAYOUT & SYSTEM VIEWS - const appPanel = new MainPanel() + const appPanel = new (await import('./app/components/main-panel')).MainPanel() Registry.getInstance().put({ api: self.mainview, name: 'mainview' }) const tabProxy = new TabProxy(fileManager, editor) self.engine.register([appPanel, tabProxy]) // those views depend on app_manager - self.menuicons = new VerticalIcons() - self.sidePanel = new SidePanel() - self.hiddenPanel = new HiddenPanel() + self.menuicons = new (await import('./app/components/vertical-icons')).VerticalIcons() + self.sidePanel = new (await import('./app/components/side-panel')).SidePanel() + self.hiddenPanel = new (await import('./app/components/hidden-panel')).HiddenPanel() const pluginManagerComponent = new PluginManagerComponent( appManager, self.engine ) const filePanel = new FilePanel(appManager) - const landingPage = new LandingPage( + const landingPage = new (await import('./app/ui/landing-page/landing-page')).LandingPage( appManager, self.menuicons, fileManager, diff --git a/apps/remix-ide/src/index.tsx b/apps/remix-ide/src/index.tsx index 3f7f54674b..dd1641e154 100644 --- a/apps/remix-ide/src/index.tsx +++ b/apps/remix-ide/src/index.tsx @@ -6,13 +6,13 @@ import AppComponent from './app' const RemixApp = lazy(() => import ('@remix-ui/app')); const appComponent = new AppComponent() -appComponent.run() - -ReactDOM.render( - - Loading...}> - - - , - document.getElementById('root') -) +appComponent.run().then(() => { + ReactDOM.render( + + Loading...}> + + + , + document.getElementById('root') + ) +}) From 0a90116625f4aad18d434e31414c1ba06e978686 Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 25 Jan 2022 12:11:05 +0100 Subject: [PATCH 3/9] Use plugin calls for toaster and modal. --- apps/remix-ide/src/app.js | 6 +-- .../plugins/{modal.tsx => notification.tsx} | 8 ++-- .../app/src/lib/remix-app/context/context.tsx | 4 +- .../app/src/lib/remix-app/remix-app.tsx | 2 +- .../src/lib/components/web3Dialog.tsx | 0 .../helper/src/lib/helper-components.tsx | 17 ++++++++ .../remix-ui/run-tab/src/lib/actions/index.ts | 39 +++++++++++-------- .../run-tab/src/lib/actions/payload.ts | 7 ---- .../src/lib/components/environment.tsx | 3 +- .../run-tab/src/lib/components/settingsUI.tsx | 2 +- .../run-tab/src/lib/reducers/runTab.ts | 26 +------------ libs/remix-ui/run-tab/src/lib/run-tab.tsx | 25 +----------- libs/remix-ui/run-tab/src/lib/types/index.ts | 6 +-- 13 files changed, 58 insertions(+), 87 deletions(-) rename apps/remix-ide/src/app/plugins/{modal.tsx => notification.tsx} (82%) rename libs/remix-ui/{run-tab => helper}/src/lib/components/web3Dialog.tsx (100%) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 71360c1e9d..7859ecb23c 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -19,7 +19,7 @@ import { OffsetToLineColumnConverter, CompilerMetadata, CompilerArtefacts, Fetch import Registry from './app/state/registry' import { ConfigPlugin } from './app/plugins/config' import { Layout } from './app/panels/layout' -import { ModalPlugin } from './app/plugins/modal' +import { NotificationPlugin } from './app/plugins/notification' import { Blockchain } from './blockchain/blockchain.js' import { HardhatProvider } from './app/tabs/hardhat-provider' @@ -187,7 +187,7 @@ class AppComponent { ) const contextualListener = new EditorContextListener() - self.modal = new ModalPlugin() + self.notification = new NotificationPlugin() const configPlugin = new ConfigPlugin() self.layout = new Layout() @@ -197,7 +197,7 @@ class AppComponent { self.engine.register([ permissionHandler, self.layout, - self.modal, + self.notification, self.gistHandler, configPlugin, blockchain, diff --git a/apps/remix-ide/src/app/plugins/modal.tsx b/apps/remix-ide/src/app/plugins/notification.tsx similarity index 82% rename from apps/remix-ide/src/app/plugins/modal.tsx rename to apps/remix-ide/src/app/plugins/notification.tsx index d96e9b93f2..975f6943fa 100644 --- a/apps/remix-ide/src/app/plugins/modal.tsx +++ b/apps/remix-ide/src/app/plugins/notification.tsx @@ -4,7 +4,7 @@ import { AppModal } from '@remix-ui/app' import { AlertModal } from 'libs/remix-ui/app/src/lib/remix-app/interface' import { dispatchModalInterface } from 'libs/remix-ui/app/src/lib/remix-app/context/context' -interface IModalApi { +interface INotificationApi { events: StatusEvents, methods: { modal: (args: AppModal) => void @@ -13,14 +13,14 @@ interface IModalApi { } } -const profile:LibraryProfile = { +const profile:LibraryProfile = { name: 'notification', displayName: 'Notification', description: 'Displays notifications', methods: ['modal', 'alert', 'toast'] } -export class ModalPlugin extends Plugin implements MethodApi { +export class NotificationPlugin extends Plugin implements MethodApi { dispatcher: dispatchModalInterface constructor () { super(profile) @@ -38,7 +38,7 @@ export class ModalPlugin extends Plugin implements MethodApi { return this.dispatcher.alert(args) } - async toast (message: string) { + async toast (message: string | JSX.Element) { this.dispatcher.toast(message) } } diff --git a/libs/remix-ui/app/src/lib/remix-app/context/context.tsx b/libs/remix-ui/app/src/lib/remix-app/context/context.tsx index 3745fcddf0..a60b3e5409 100644 --- a/libs/remix-ui/app/src/lib/remix-app/context/context.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/context/context.tsx @@ -7,7 +7,7 @@ export const AppContext = React.createContext(null) export interface dispatchModalInterface { modal: (data: AppModal) => void - toast: (message: string) => void + toast: (message: string | JSX.Element) => void alert: (data: AlertModal) => void handleHideModal: () => void, handleToaster: () => void @@ -15,7 +15,7 @@ export interface dispatchModalInterface { export const dispatchModalContext = React.createContext({ modal: (data: AppModal) => { }, - toast: (message: string) => {}, + toast: (message: string | JSX.Element) => {}, alert: (data: AlertModal) => {}, handleHideModal: () => {}, handleToaster: () => {} diff --git a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx index 27d5a7b832..e0cfba860e 100644 --- a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx @@ -83,7 +83,7 @@ const RemixApp = (props: IRemixAppUi) => { settings: props.app.settings, showMatamo: props.app.showMatamo, appManager: props.app.appManager, - modal: props.app.modal, + modal: props.app.notification, layout: props.app.layout } diff --git a/libs/remix-ui/run-tab/src/lib/components/web3Dialog.tsx b/libs/remix-ui/helper/src/lib/components/web3Dialog.tsx similarity index 100% rename from libs/remix-ui/run-tab/src/lib/components/web3Dialog.tsx rename to libs/remix-ui/helper/src/lib/components/web3Dialog.tsx diff --git a/libs/remix-ui/helper/src/lib/helper-components.tsx b/libs/remix-ui/helper/src/lib/helper-components.tsx index 65ff10608a..edd85b1b31 100644 --- a/libs/remix-ui/helper/src/lib/helper-components.tsx +++ b/libs/remix-ui/helper/src/lib/helper-components.tsx @@ -1,4 +1,5 @@ import React from 'react' +import { Web3ProviderDialog } from './components/web3Dialog' export const fileChangedToastMsg = (from: string, path: string) => (
@@ -52,3 +53,19 @@ export const sourceVerificationNotAvailableToastMsg = () => ( Source verification plugin not activated or not available. continuing without source code debugging.
) + +export const web3Dialog = (externalEndpoint: string, setWeb3Endpoint: (value: string) => void) => ( + +) + +export const envChangeNotification = (env: { context: string, fork: string }, from: string) => ( +
+ + + { from + ' '} + + is changing your environment to + {env && env.context} + +
+) diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 44ce22a873..25bbb89d93 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -2,8 +2,8 @@ import React from 'react' import * as ethJSUtil from 'ethereumjs-util' import Web3 from 'web3' -import { addressToString, createNonClashingNameAsync, extractNameFromKey, shortenAddress } from '@remix-ui/helper' -import { addNewInstance, addProvider, clearAllInstances, clearRecorderCount, displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, fetchContractListSuccess, hidePopUp, removeExistingInstance, removeProvider, resetUdapp, setBaseFeePerGas, setConfirmSettings, setCurrentFile, setDecodedResponse, setEnvToasterContent, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setLoadType, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setPassphrase, setPathToScenario, setRecorderCount, setSelectedAccount, setSendUnit, setSendValue, setTxFeeContent, setWeb3Dialog } from './payload' +import { addressToString, createNonClashingNameAsync, envChangeNotification, extractNameFromKey, shortenAddress, web3Dialog } from '@remix-ui/helper' +import { addNewInstance, addProvider, clearAllInstances, clearRecorderCount, displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, fetchContractListSuccess, hidePopUp, removeExistingInstance, removeProvider, resetUdapp, setBaseFeePerGas, setConfirmSettings, setCurrentFile, setDecodedResponse, setEnvToasterContent, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setLoadType, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setPassphrase, setPathToScenario, setRecorderCount, setSelectedAccount, setSendUnit, setSendValue, setTxFeeContent } from './payload' import { RunTab } from '../types/run-tab' import { CompilerAbstract } from '@remix-project/remix-solidity' import * as remixLib from '@remix-project/remix-lib' @@ -75,8 +75,8 @@ const setupEvents = () => { plugin.on('yulp', 'compilationFinished', (file, source, languageVersion, data) => broadcastCompilationResult(file, source, languageVersion, data)) plugin.on('udapp', 'setEnvironmentModeReducer', (env: { context: string, fork: string }, from: string) => { - dispatch(displayPopUp(plugin.REACT_API.envToasterContent(env, from))) - setExecutionContext(env, plugin.REACT_API.web3Dialog()) + plugin.call('notification', 'toast', envChangeNotification(env, from)) + setExecutionContext(env) }) plugin.on('filePanel', 'setWorkspace', () => { @@ -106,11 +106,6 @@ const setupEvents = () => { }) } -export const initWebDialogs = (envToasterContent: (env: { context: string, fork: string }, from: string) => void, web3Dialog: () => void) => async (dispatch: React.Dispatch) => { - dispatch(setEnvToasterContent(envToasterContent)) - dispatch(setWeb3Dialog(web3Dialog)) -} - const updateAccountBalances = () => { const accounts = plugin.REACT_API.accounts.loadedAccounts @@ -225,16 +220,28 @@ const removeExternalProvider = (name) => { dispatch(removeProvider(name)) } -export const setExecutionContext = (executionContext: { context: string, fork: string }, displayContent: JSX.Element) => { +export const setExecutionContext = (executionContext: { context: string, fork: string }) => { + const displayContent = web3Dialog(plugin.REACT_API.externalEndpoint, setWeb3Endpoint) + plugin.blockchain.changeExecutionContext(executionContext, () => { - dispatch(displayNotification('External node request', displayContent, 'OK', 'Cancel', () => { - plugin.blockchain.setProviderFromEndpoint(plugin.REACT_API.externalEndpoint, executionContext, (alertMsg) => { - if (alertMsg) dispatch(displayPopUp(alertMsg)) + plugin.call('notification', 'modal', { + id: 'envNotification', + title: 'External node request', + message: displayContent, + okLabel: 'OK', + cancelLabel: 'Cancel', + okFn: () => { + plugin.blockchain.setProviderFromEndpoint(plugin.REACT_API.externalEndpoint, executionContext, (alertMsg) => { + if (alertMsg) plugin.call('notification', 'toast', alertMsg) + setFinalContext() + }) + }, + cancelFn: () => { setFinalContext() - }) - }, () => { setFinalContext() })) + } + }) }, (alertMsg) => { - dispatch(displayPopUp(alertMsg)) + plugin.call('notification', 'toast', alertMsg) }, () => { setFinalContext() }) } diff --git a/libs/remix-ui/run-tab/src/lib/actions/payload.ts b/libs/remix-ui/run-tab/src/lib/actions/payload.ts index 4d70582ce3..812b51711a 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/payload.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/payload.ts @@ -278,13 +278,6 @@ export const setEnvToasterContent = (content: (env: { context: string, fork: str } } -export const setWeb3Dialog = (web3Dialog: () => void) => { - return { - type: 'SET_WEB3_DIALOG', - payload: web3Dialog - } -} - export const resetUdapp = () => { return { type: 'RESET_STATE' 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 29a9d7fc58..23d04f6d20 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -9,9 +9,8 @@ export function EnvironmentUI (props: EnvironmentProps) { let context = provider.value context = context.startsWith('vm') ? 'vm' : context // context has to be 'vm', 'web3' or 'injected' - const displayContent = props.web3ProviderDialog() - props.setExecutionContext({ context, fork }, displayContent) + props.setExecutionContext({ context, fork }) } return ( diff --git a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx index 842d047899..d8fa122317 100644 --- a/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx @@ -12,7 +12,7 @@ export function SettingsUI (props: SettingsProps) { return (
- + diff --git a/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts b/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts index 9f0624d561..2aaf3f4c1a 100644 --- a/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts +++ b/libs/remix-ui/run-tab/src/lib/reducers/runTab.ts @@ -78,9 +78,7 @@ export interface RunTabState { recorder: { pathToScenario: string, transactionCount: number - }, - envToasterContent: (env: { context: string, fork: string }, from: string) => JSX.Element - web3Dialog: () => JSX.Element + } } export const runTabInitialState: RunTabState = { @@ -166,9 +164,7 @@ export const runTabInitialState: RunTabState = { recorder: { pathToScenario: 'scenario.json', transactionCount: 0 - }, - envToasterContent: null, - web3Dialog: null + } } type AddProvider = { @@ -650,24 +646,6 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A } } - case 'SET_ENV_TOASTER_CONTENT': { - const payload: (env: string, from: string) => JSX.Element = action.payload - - return { - ...state, - envToasterContent: payload - } - } - - case 'SET_WEB3_DIALOG': { - const payload: () => JSX.Element = action.payload - - return { - ...state, - web3Dialog: payload - } - } - case 'RESET_STATE': { return { ...runTabInitialState, diff --git a/libs/remix-ui/run-tab/src/lib/run-tab.tsx b/libs/remix-ui/run-tab/src/lib/run-tab.tsx index 8cf8615b09..6d9f13a3c3 100644 --- a/libs/remix-ui/run-tab/src/lib/run-tab.tsx +++ b/libs/remix-ui/run-tab/src/lib/run-tab.tsx @@ -24,15 +24,14 @@ import { removeInstance, getContext, runTransactions, loadAddress, storeScenario, runCurrentScenario, - updateScenarioPath, initWebDialogs, - getFuncABIInputs, setNetworkNameFromProvider + updateScenarioPath, getFuncABIInputs, + setNetworkNameFromProvider } from './actions' import './css/run-tab.css' import { PublishToStorage } from '@remix-ui/publish-to-storage' import { PassphrasePrompt } from './components/passphrase' import { MainnetPrompt } from './components/mainnet' import { ScenarioPrompt } from './components/scenario' -import { Web3ProviderDialog } from './components/web3Dialog' import { setIpfsCheckedState } from './actions/payload' export function RunTabUI (props: RunTabProps) { @@ -61,7 +60,6 @@ export function RunTabUI (props: RunTabProps) { useEffect(() => { initRunTab(plugin)(dispatch) - initWebDialogs(envChangeNotification, web3Dialog)(dispatch) }, [plugin]) useEffect(() => { @@ -197,24 +195,6 @@ export function RunTabUI (props: RunTabProps) { /> } - const envChangeNotification = (env: { context: string, fork: string }, from: string) => { - return ( -
- - - {from} - - is changing your environment to - {env && env.context} - -
- ) - } - - const web3Dialog = () => { - return - } - return (
@@ -241,7 +221,6 @@ export function RunTabUI (props: RunTabProps) { tooltip={toast} signMessageWithAddress={signMessageWithAddress} passphrase={runTab.passphrase} - web3ProviderDialog={web3Dialog} /> void, + setExecutionContext: (executionContext: { context: string, fork: string }) => void, createNewBlockchainAccount: (cbMessage: JSX.Element) => void, setPassphrase: (passphrase: string) => void, setMatchPassphrase: (passphrase: string) => void, @@ -42,7 +42,6 @@ export interface SettingsProps { tooltip: (toasterMsg: string) => void, signMessageWithAddress: (account: string, message: string, modalContent: (hash: string, data: string) => JSX.Element, passphrase?: string) => void, passphrase: string, - web3ProviderDialog: () => JSX.Element, setSendValue: (value: string) => void } @@ -61,8 +60,7 @@ export interface EnvironmentProps { isSuccessful: boolean, error: string }, - setExecutionContext: (executionContext: { context: string, fork: string }, displayContent: JSX.Element) => void, - web3ProviderDialog: () => JSX.Element + setExecutionContext: (executionContext: { context: string, fork: string }) => void } export interface NetworkProps { From 506434803fd0e87c7ba33e9ec7ccf8ccbb98c098 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 26 Jan 2022 13:38:05 +0100 Subject: [PATCH 4/9] fix modal/toaster (queue) --- .../src/local-plugin/src/app/app.tsx | 2 +- apps/remix-ide-e2e/src/tests/ballot.test.ts | 4 +- .../src/tests/ballot_0_4_11.test.ts | 4 +- apps/remix-ide-e2e/src/tests/plugin_api.ts | 72 ++++++++++++-- apps/remix-ide-e2e/src/tests/terminal.test.ts | 2 +- apps/remix-ide/src/remixEngine.js | 1 + .../app/src/lib/remix-app/reducer/modals.ts | 97 +++++++++++-------- 7 files changed, 131 insertions(+), 51 deletions(-) diff --git a/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx b/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx index d1a559764e..298316e6cd 100644 --- a/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx +++ b/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx @@ -33,7 +33,7 @@ function App () { useEffect(() => { client.onload(async () => { - const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider'] + const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider', 'notification'] client.testCommand = async (data: any) => { console.log(data) diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index cc2a32cb2f..794dee9775 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -84,9 +84,9 @@ module.exports = { .openFile('Untitled.sol') .clickLaunchIcon('udapp') .click('*[data-id="settingsWeb3Mode"]') - .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]') + .waitForElementPresent('[data-id="envNotification-modal-footer-ok-react"]') .execute(function () { - const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any + const modal = document.querySelector('[data-id="envNotification-modal-footer-ok-react"]') as any modal.click() }) diff --git a/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts b/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts index a8bfa626e4..28b03219fc 100644 --- a/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts @@ -79,9 +79,9 @@ module.exports = { .openFile('Untitled.sol') .clickLaunchIcon('udapp') .click('*[data-id="settingsWeb3Mode"]') - .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]') + .waitForElementPresent('[data-id="envNotification-modal-footer-ok-react"]') .execute(function () { - const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any + const modal = document.querySelector('[data-id="envNotification-modal-footer-ok-react"]') as any modal.click() }) diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index fc09a9c8f1..c450228af4 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -64,12 +64,16 @@ const clearPayLoad = async (browser: NightwatchBrowser) => { }) } -const clickButton = async (browser: NightwatchBrowser, buttonText: string) => { +const clickButton = async (browser: NightwatchBrowser, buttonText: string, waitResult: boolean = true) => { return new Promise((resolve) => { browser.useXpath().waitForElementVisible(`//*[@data-id='${buttonText}']`).pause(100) .click(`//*[@data-id='${buttonText}']`, async () => { await checkForAcceptAndRemember(browser) - browser.waitForElementContainsText('//*[@id="callStatus"]', 'stop').perform(() => resolve(true)) + if (waitResult) { + browser.waitForElementContainsText('//*[@id="callStatus"]', 'stop').perform(() => resolve(true)) + } else { + resolve(true) + } }) }) } @@ -103,7 +107,7 @@ const checkForAcceptAndRemember = async function (browser: NightwatchBrowser) { * @return {Promise} */ -const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any) => { +const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any, waitResult: boolean = true) => { if (payload) { await setPayload(browser, payload) } else { @@ -112,10 +116,14 @@ const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, if (methodResult && typeof methodResult !== 'string') { methodResult = JSON.stringify(methodResult) } if (eventResult && typeof eventResult !== 'string') { eventResult = JSON.stringify(eventResult) } if (buttonText) { - await clickButton(browser, buttonText) + await clickButton(browser, buttonText, waitResult) + } + if (methodResult) { + await debugValues(browser, 'methods', methodResult) + } + if (eventResult) { + await debugValues(browser, 'events', eventResult) } - await debugValues(browser, 'methods', methodResult) - await debugValues(browser, 'events', eventResult) } const assertPluginIsActive = function (browser: NightwatchBrowser, id: string, shouldBeVisible: boolean) { @@ -364,5 +372,57 @@ module.exports = { const result = '{"jsonrpc":"2.0","result":true,"id":9999}' await clickAndCheckLog(browser, 'hardhat-provider:sendAsync', result, null, request) }) + }, + + // MODAL + + 'Should open 2 alert in a row and trigger 2 toaster in between #group9': function (browser: NightwatchBrowser) { + browser + .frameParent() + .useCss() + .addFile('test_modal.js', { content: testModalToasterApi }) + .executeScript('remix.execute(\'test_modal.js\')') + .clickLaunchIcon('localPlugin') + .useXpath() + // @ts-ignore + .frame(0) + .perform(async () => { + await clickAndCheckLog(browser, 'notification:toast', null, null, 'message toast from local plugin', false) // create a toast on behalf of the localplugin + await clickAndCheckLog(browser, 'notification:alert', null, null, { message: 'message from local plugin', id: 'test_id_1_local_plugin' }, false) // create an alert on behalf of the localplugin + }) + .frameParent() + .useCss() + // check the local plugin notifications + .waitForElementVisible('*[data-id="test_id_1_local_pluginModalDialogModalBody-react"]') + .assert.containsText('*[data-id="test_id_1_local_pluginModalDialogModalBody-react"]', 'message from local plugin') + .modalFooterOKClick('test_id_1_local_plugin') + // check the script runner notifications + .waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]') + .assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1') + .modalFooterOKClick('test_id_1_') + .waitForElementVisible('*[data-id="test_id_2_ModalDialogModalBody-react"]') + .assert.containsText('*[data-id="test_id_2_ModalDialogModalBody-react"]', 'message 2') + .modalFooterOKClick('test_id_2_') + // check the toasters + .waitForElementVisible('*[data-shared="tooltipPopup"]') + .waitForElementContainsText('*[data-shared="tooltipPopup"]', 'message toast from local plugin') + .waitForElementContainsText('*[data-shared="tooltipPopup"]', 'I am a toast') + .waitForElementContainsText('*[data-shared="tooltipPopup"]', 'I am a re-toast') } } + +const testModalToasterApi = ` +// Right click on the script name and hit "Run" to execute +(async () => { + try { + setTimeout(() => { + console.log('test .. ') + remix.call('notification', 'alert', { message: 'message 1', id: 'test_id_1_' }) + remix.call('notification', 'toast', 'I am a toast') + remix.call('notification', 'toast', 'I am a re-toast') + remix.call('notification', 'alert', { message: 'message 2', id: 'test_id_2_' }) + }, 500) + } catch (e) { + console.log(e.message) + } +})() ` diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 69c3acc765..f56dccf174 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -51,7 +51,7 @@ module.exports = { .click('*[data-id="terminalClearConsole"]') // clear the terminal .clickLaunchIcon('udapp') .click('*[data-id="settingsWeb3Mode"]') - .modalFooterOKClick('udappNotify') + .modalFooterOKClick('envNotification') .executeScript('web3.eth.getAccounts()') .waitForElementContainsText('*[data-id="terminalJournal"]', '["', 60000) // we check if an array is present, don't need to check for the content .waitForElementContainsText('*[data-id="terminalJournal"]', '"]', 60000) diff --git a/apps/remix-ide/src/remixEngine.js b/apps/remix-ide/src/remixEngine.js index 1ad385146b..cbdf6c86c6 100644 --- a/apps/remix-ide/src/remixEngine.js +++ b/apps/remix-ide/src/remixEngine.js @@ -14,6 +14,7 @@ export class RemixEngine extends Engine { if (name === 'slither') return { queueTimeout: 60000 * 4 } // Requires when a solc version is installed if (name === 'hardhat') return { queueTimeout: 60000 * 4 } if (name === 'localPlugin') return { queueTimeout: 60000 * 4 } + if (name === 'notification') return { queueTimeout: 60000 * 4 } return { queueTimeout: 10000 } } diff --git a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts index d83b9792c7..1572343a42 100644 --- a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts +++ b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts @@ -5,49 +5,68 @@ import { AppModal, ModalState } from '../interface' export const modalReducer = (state: ModalState = ModalInitialState, action: ModalAction) => { switch (action.type) { case modalActionTypes.setModal: { - let modalList:AppModal[] = state.modals - modalList.push(action.payload) - if (state.modals.length === 1 && state.focusModal.hide === true) { // if it's the first one show it - const focusModal: AppModal = { - id: modalList[0].id, - hide: false, - title: modalList[0].title, - message: modalList[0].message, - okLabel: modalList[0].okLabel, - okFn: modalList[0].okFn, - cancelLabel: modalList[0].cancelLabel, - cancelFn: modalList[0].cancelFn, - modalType: modalList[0].modalType, - defaultValue: modalList[0].defaultValue, - hideFn: modalList[0].hideFn, - resolve: modalList[0].resolve - } + const focusModal: AppModal = { + id: action.payload.id || Date.now().toString(), + hide: false, + title: action.payload.title, + message: action.payload.message, + okLabel: action.payload.okLabel, + okFn: action.payload.okFn, + cancelLabel: action.payload.cancelLabel, + cancelFn: action.payload.cancelFn, + modalType: action.payload.modalType, + defaultValue: action.payload.defaultValue, + hideFn: action.payload.hideFn, + resolve: action.payload.resolve + } + + const modalList: AppModal[] = state.modals.slice() + modalList.push(focusModal) - modalList = modalList.slice() - modalList.shift() - return { ...state, modals: modalList, focusModal: focusModal } + if (modalList.length === 1) { + return { ...state, modals: modalList, focusModal } + } else { + return { ...state, modals: modalList } } - return { ...state, modals: modalList } } - case modalActionTypes.handleHideModal: - if (state.focusModal.hideFn) { - state.focusModal.hideFn() - } else if (state.focusModal.resolve) { - state.focusModal.resolve(undefined) + case modalActionTypes.handleHideModal: { + setTimeout(() => { + if (state.focusModal.hideFn) { + state.focusModal.hideFn() + } + if (state.focusModal.resolve) { + state.focusModal.resolve(undefined) + } + }, 250) + const modalList: AppModal[] = state.modals.slice() + modalList.shift() // remove the current modal from the list + if (modalList.length) { + const focusModal = modalList[0] // extract the next modal from the list + return { ...state, modals: modalList, focusModal } + } else { + state.focusModal = { ...state.focusModal, hide: true, message: null } + return { ...state, modals: [] } } - state.focusModal = { ...state.focusModal, hide: true, message: null } - return { ...state } - - case modalActionTypes.setToast: - state.toasters.push(action.payload) - if (state.toasters.length > 0) { - const focus = state.toasters[0] - state.toasters.shift() - return { ...state, focusToaster: focus } + } + case modalActionTypes.setToast: { + const toasterList = state.toasters.slice() + const message = action.payload + toasterList.push(message) + if (toasterList.length === 1) { + return { ...state, toasters: toasterList, focusToaster: action.payload } + } else { + return { ...state, toasters: toasterList } } - return { ...state } - - case modalActionTypes.handleToaster: - return { ...state, focusToaster: '' } + } + case modalActionTypes.handleToaster: { + const toasterList = state.toasters.slice() + toasterList.shift() + if (toasterList.length) { + const toaster = toasterList[0] + return { ...state, toasters: toasterList, focusToaster: toaster } + } else { + return { ...state, toasters: [] } + } + } } } From 4e70a573aaa487186f9d2631d521511cde7a5248 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 27 Jan 2022 13:30:39 +0530 Subject: [PATCH 5/9] splash screen before app loading --- apps/remix-ide/src/index.tsx | 39 +++++++++++++++++++++++++--------- libs/remix-ui/app/src/index.ts | 2 +- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/apps/remix-ide/src/index.tsx b/apps/remix-ide/src/index.tsx index dd1641e154..ff690d4c5e 100644 --- a/apps/remix-ide/src/index.tsx +++ b/apps/remix-ide/src/index.tsx @@ -1,18 +1,37 @@ // eslint-disable-next-line no-use-before-define -import React, { Suspense, lazy } from 'react' -import ReactDOM from 'react-dom' -import AppComponent from './app' +import React from 'react' +import { render } from 'react-dom' // eslint-disable-next-line no-unused-vars -const RemixApp = lazy(() => import ('@remix-ui/app')); +import { RemixApp } from '@remix-ui/app' -const appComponent = new AppComponent() -appComponent.run().then(() => { - ReactDOM.render( +(function () { + render( - Loading...
}> - - +
+ + + + + +
+ REMIX IDE +
+
, document.getElementById('root') ) +})() + +import ('./app').then((AppComponent) => { + const appComponent = new AppComponent.default() + appComponent.run().then(() => { + render( + + + , + document.getElementById('root') + ) + }) +}).catch(err => { + console.log('Error on loading Remix:', err) }) diff --git a/libs/remix-ui/app/src/index.ts b/libs/remix-ui/app/src/index.ts index 13056623bd..e706f1ad94 100644 --- a/libs/remix-ui/app/src/index.ts +++ b/libs/remix-ui/app/src/index.ts @@ -1,4 +1,4 @@ -export { default as default } from './lib/remix-app/remix-app' +export { default as RemixApp } from './lib/remix-app/remix-app' export { dispatchModalContext } from './lib/remix-app/context/context' export { ModalProvider } from './lib/remix-app/context/provider' export { AppModal } from './lib/remix-app/interface/index' From 808e2367f104fee60d6dbece14be848df77bcd0b Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 27 Jan 2022 13:18:08 +0100 Subject: [PATCH 6/9] fix showing to direct modal in a row --- libs/remix-ui/app/src/lib/remix-app/interface/index.ts | 1 + libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts | 4 +++- libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx | 4 ++-- libs/remix-ui/modal-dialog/src/lib/types/index.ts | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libs/remix-ui/app/src/lib/remix-app/interface/index.ts b/libs/remix-ui/app/src/lib/remix-app/interface/index.ts index 0432c71e2d..7338032bc7 100644 --- a/libs/remix-ui/app/src/lib/remix-app/interface/index.ts +++ b/libs/remix-ui/app/src/lib/remix-app/interface/index.ts @@ -2,6 +2,7 @@ import { ModalTypes } from '../types' export interface AppModal { id: string + timestamp?: number hide?: boolean title: string // eslint-disable-next-line no-undef diff --git a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts index 1572343a42..ccb91eb58e 100644 --- a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts +++ b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts @@ -5,8 +5,10 @@ import { AppModal, ModalState } from '../interface' export const modalReducer = (state: ModalState = ModalInitialState, action: ModalAction) => { switch (action.type) { case modalActionTypes.setModal: { + const timestamp = Date.now() const focusModal: AppModal = { - id: action.payload.id || Date.now().toString(), + timestamp, + id: action.payload.id || timestamp.toString(), hide: false, title: action.payload.title, message: action.payload.message, diff --git a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx index 714255aa93..80391a5701 100644 --- a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx +++ b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx @@ -20,9 +20,9 @@ export const ModalDialog = (props: ModalDialogProps) => { } useEffect(() => { - calledHideFunctionOnce.current = props.hide + calledHideFunctionOnce.current = false modal.current.focus() - }, [props.hide]) + }, [props.timestamp]) useEffect(() => { function handleBlur (e) { diff --git a/libs/remix-ui/modal-dialog/src/lib/types/index.ts b/libs/remix-ui/modal-dialog/src/lib/types/index.ts index dd12c8e680..91feca5294 100644 --- a/libs/remix-ui/modal-dialog/src/lib/types/index.ts +++ b/libs/remix-ui/modal-dialog/src/lib/types/index.ts @@ -1,6 +1,7 @@ /* eslint-disable no-undef */ export interface ModalDialogProps { id: string + timestamp?: number, title?: string, message?: string | JSX.Element, okLabel?: string, From 811669d310472b3c5b50080c0ebb1913284eeae7 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 27 Jan 2022 13:37:48 +0100 Subject: [PATCH 7/9] e2e test modal prompt --- apps/remix-ide-e2e/src/tests/plugin_api.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index c450228af4..277b65181f 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -403,6 +403,9 @@ module.exports = { .waitForElementVisible('*[data-id="test_id_2_ModalDialogModalBody-react"]') .assert.containsText('*[data-id="test_id_2_ModalDialogModalBody-react"]', 'message 2') .modalFooterOKClick('test_id_2_') + .waitForElementVisible('*[data-id="test_id_3_ModalDialogModalBody-react"]') + .modalFooterOKClick('test_id_3_') + .journalLastChildIncludes('default value... ') // check the return value of the prompt // check the toasters .waitForElementVisible('*[data-shared="tooltipPopup"]') .waitForElementContainsText('*[data-shared="tooltipPopup"]', 'message toast from local plugin') @@ -415,12 +418,24 @@ const testModalToasterApi = ` // Right click on the script name and hit "Run" to execute (async () => { try { - setTimeout(() => { + setTimeout(async () => { console.log('test .. ') remix.call('notification', 'alert', { message: 'message 1', id: 'test_id_1_' }) remix.call('notification', 'toast', 'I am a toast') remix.call('notification', 'toast', 'I am a re-toast') remix.call('notification', 'alert', { message: 'message 2', id: 'test_id_2_' }) + + const modalContent = { + id: 'test_id_3_' + title: 'test with input title', + message: 'test with input content', + modalType: 'prompt', + okLabel: 'OK', + cancelLabel: 'Cancel', + defaultValue: 'default value... ' + } + const result = await remix.call('notification', 'modal', modalContent) + console.log(result) }, 500) } catch (e) { console.log(e.message) From f3b04045f913240ca751f706ba0d298b691c0896 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Thu, 27 Jan 2022 15:55:42 +0100 Subject: [PATCH 8/9] fix queue processing --- .../app/src/lib/remix-app/actions/modals.ts | 4 +++- .../app/src/lib/remix-app/context/provider.tsx | 8 +++++++- .../app/src/lib/remix-app/interface/index.ts | 3 ++- .../app/src/lib/remix-app/reducer/modals.ts | 14 +++++++++++--- .../modal-dialog/src/lib/remix-ui-modal-dialog.tsx | 4 ++-- libs/remix-ui/modal-dialog/src/lib/types/index.ts | 1 + 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/libs/remix-ui/app/src/lib/remix-app/actions/modals.ts b/libs/remix-ui/app/src/lib/remix-app/actions/modals.ts index 3a1788a8ad..4a567a83c0 100644 --- a/libs/remix-ui/app/src/lib/remix-app/actions/modals.ts +++ b/libs/remix-ui/app/src/lib/remix-app/actions/modals.ts @@ -14,6 +14,7 @@ type ActionMap = { export const enum modalActionTypes { setModal = 'SET_MODAL', setToast = 'SET_TOAST', + processQueue = 'PROCESS_QUEUEU', handleHideModal = 'HANDLE_HIDE_MODAL', handleToaster = 'HANDLE_HIDE_TOAST' } @@ -22,7 +23,8 @@ type ModalPayload = { [modalActionTypes.setModal]: AppModal [modalActionTypes.handleHideModal]: any [modalActionTypes.setToast]: string | JSX.Element - [modalActionTypes.handleToaster]: any + [modalActionTypes.handleToaster]: any, + [modalActionTypes.processQueue]: any } export type ModalAction = ActionMap[keyof ActionMap< diff --git a/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx b/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx index ab444470f6..5d9a3a5815 100644 --- a/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx @@ -9,12 +9,18 @@ import { AppContext, dispatchModalContext, modalContext } from './context' export const ModalProvider = ({ children = [], reducer = modalReducer, initialState = ModalInitialState } = {}) => { const [{ modals, toasters, focusModal, focusToaster }, dispatch] = useReducer(reducer, initialState) + const onNextFn = async () => { + dispatch({ + type: modalActionTypes.processQueue + }) + } + const modal = (data: AppModal) => { const { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType, defaultValue, hideFn } = data return new Promise((resolve, reject) => { dispatch({ type: modalActionTypes.setModal, - payload: { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue, hideFn, resolve } + payload: { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue, hideFn, resolve, next: onNextFn } }) }) } diff --git a/libs/remix-ui/app/src/lib/remix-app/interface/index.ts b/libs/remix-ui/app/src/lib/remix-app/interface/index.ts index 7338032bc7..af25ce13b9 100644 --- a/libs/remix-ui/app/src/lib/remix-app/interface/index.ts +++ b/libs/remix-ui/app/src/lib/remix-app/interface/index.ts @@ -14,7 +14,8 @@ export interface AppModal { modalType?: ModalTypes, defaultValue?: string hideFn?: () => void, - resolve?: (value?:any) => void + resolve?: (value?:any) => void, + next?: () => void } export interface AlertModal { diff --git a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts index ccb91eb58e..8a1c89ac79 100644 --- a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts +++ b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts @@ -19,7 +19,8 @@ export const modalReducer = (state: ModalState = ModalInitialState, action: Moda modalType: action.payload.modalType, defaultValue: action.payload.defaultValue, hideFn: action.payload.hideFn, - resolve: action.payload.resolve + resolve: action.payload.resolve, + next: action.payload.next } const modalList: AppModal[] = state.modals.slice() @@ -39,15 +40,22 @@ export const modalReducer = (state: ModalState = ModalInitialState, action: Moda if (state.focusModal.resolve) { state.focusModal.resolve(undefined) } + if (state.focusModal.next) { + state.focusModal.next() + } }, 250) const modalList: AppModal[] = state.modals.slice() modalList.shift() // remove the current modal from the list + state.focusModal = { ...state.focusModal, hide: true, message: null } + return { ...state, modals: modalList } + } + case modalActionTypes.processQueue: { + const modalList: AppModal[] = state.modals.slice() if (modalList.length) { const focusModal = modalList[0] // extract the next modal from the list return { ...state, modals: modalList, focusModal } } else { - state.focusModal = { ...state.focusModal, hide: true, message: null } - return { ...state, modals: [] } + return { ...state, modals: modalList } } } case modalActionTypes.setToast: { diff --git a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx index 80391a5701..714255aa93 100644 --- a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx +++ b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx @@ -20,9 +20,9 @@ export const ModalDialog = (props: ModalDialogProps) => { } useEffect(() => { - calledHideFunctionOnce.current = false + calledHideFunctionOnce.current = props.hide modal.current.focus() - }, [props.timestamp]) + }, [props.hide]) useEffect(() => { function handleBlur (e) { diff --git a/libs/remix-ui/modal-dialog/src/lib/types/index.ts b/libs/remix-ui/modal-dialog/src/lib/types/index.ts index 91feca5294..db473683d1 100644 --- a/libs/remix-ui/modal-dialog/src/lib/types/index.ts +++ b/libs/remix-ui/modal-dialog/src/lib/types/index.ts @@ -14,4 +14,5 @@ export interface ModalDialogProps { handleHide: (hideState?: boolean) => void, children?: React.ReactNode, resolve?: (value?:any) => void, + next?: () => void } From 922ddc62d116c16bd9c3a37aea091d310414dcf9 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Thu, 27 Jan 2022 16:09:34 +0100 Subject: [PATCH 9/9] syntax err --- apps/remix-ide-e2e/src/tests/plugin_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index 277b65181f..48405241a2 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -426,7 +426,7 @@ const testModalToasterApi = ` remix.call('notification', 'alert', { message: 'message 2', id: 'test_id_2_' }) const modalContent = { - id: 'test_id_3_' + id: 'test_id_3_', title: 'test with input title', message: 'test with input content', modalType: 'prompt',