From 11f5de164be4d947d2c8ea243e06c166d649600c Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 10 Jan 2022 16:51:05 +0100 Subject: [PATCH 1/5] Remove plugin manager settings and replace old toaster in file-manager --- apps/remix-ide/src/app.js | 2 +- .../components/plugin-manager-component.js | 3 - .../app/components/plugin-manager-settings.js | 147 ------------------ apps/remix-ide/src/app/files/fileManager.ts | 24 +-- apps/remix-ide/src/app/plugins/modal.tsx | 6 +- .../app/src/lib/remix-app/actions/modals.ts | 2 +- .../src/lib/remix-app/context/provider.tsx | 2 +- .../app/src/lib/remix-app/interface/index.ts | 4 +- libs/remix-ui/helper/src/index.ts | 1 + libs/remix-ui/helper/src/lib/components.tsx | 12 ++ libs/remix-ui/helper/tsconfig.json | 6 + .../lib/components/permissionsSettings.tsx | 6 +- .../src/lib/components/rootView.tsx | 5 +- .../src/lib/remix-ui-plugin-manager.tsx | 4 +- libs/remix-ui/toaster/src/lib/toaster.tsx | 27 +++- 15 files changed, 59 insertions(+), 192 deletions(-) delete mode 100644 apps/remix-ide/src/app/components/plugin-manager-settings.js create mode 100644 libs/remix-ui/helper/src/lib/components.tsx diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 5a7c9b8dc0..9b39076918 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -319,7 +319,7 @@ class AppComponent { console.log("couldn't register iframe plugins", e.message) } await self.appManager.activatePlugin(['layout']) - await self.appManager.activatePlugin(['modal']) + await self.appManager.activatePlugin(['notification']) await self.appManager.activatePlugin(['editor']) await self.appManager.activatePlugin(['permissionhandler', 'theme', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter']) await self.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs']) diff --git a/apps/remix-ide/src/app/components/plugin-manager-component.js b/apps/remix-ide/src/app/components/plugin-manager-component.js index e86a62da92..72acd7cbf6 100644 --- a/apps/remix-ide/src/app/components/plugin-manager-component.js +++ b/apps/remix-ide/src/app/components/plugin-manager-component.js @@ -1,5 +1,4 @@ import { ViewPlugin } from '@remixproject/engine-web' -import { PluginManagerSettings } from './plugin-manager-settings' import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' import {RemixUiPluginManager} from '@remix-ui/plugin-manager' // eslint-disable-line @@ -24,7 +23,6 @@ class PluginManagerComponent extends ViewPlugin { super(profile) this.appManager = appManager this.engine = engine - this.pluginManagerSettings = new PluginManagerSettings() this.htmlElement = document.createElement('div') this.htmlElement.setAttribute('id', 'pluginManager') this.filter = '' @@ -90,7 +88,6 @@ class PluginManagerComponent extends ViewPlugin { ReactDOM.render( , this.htmlElement) } diff --git a/apps/remix-ide/src/app/components/plugin-manager-settings.js b/apps/remix-ide/src/app/components/plugin-manager-settings.js deleted file mode 100644 index bdd233ff15..0000000000 --- a/apps/remix-ide/src/app/components/plugin-manager-settings.js +++ /dev/null @@ -1,147 +0,0 @@ -const yo = require('yo-yo') -const csjs = require('csjs-inject') -const modalDialog = require('../ui/modaldialog') - -const css = csjs` -.remixui_permissions { - position: sticky; - bottom: 0; - display: flex; - justify-content: flex-end; - align-items: center; - padding: 5px 20px; -} -.permissions button { - padding: 2px 5px; - cursor: pointer; -} -.permissionForm h4 { - font-size: 1.3rem; - text-align: center; -} -.permissionForm h6 { - font-size: 1.1rem; -} -.permissionForm hr { - width: 80%; -} -.permissionKey { - display: flex; - justify-content: space-between; - align-items: center; -} -.permissionKey i { - cursor: pointer; -} -.checkbox { - display: flex; - align-items: center; -} -.checkbox label { - margin: 0; - font-size: 1rem; -} -` - -export class PluginManagerSettings { - constructor () { - const fromLocal = window.localStorage.getItem('plugins/permissions') - this.permissions = JSON.parse(fromLocal || '{}') - } - - openDialog () { - this.currentSetting = this.settings() - modalDialog('Plugin Manager Permissions', this.currentSetting, - { fn: () => this.onValidation() } - ) - } - - onValidation () { - const permissions = JSON.stringify(this.permissions) - window.localStorage.setItem('plugins/permissions', permissions) - } - - /** Clear one permission from a plugin */ - clearPersmission (from, to, method) { - // eslint-disable-next-line no-debugger - debugger - if (this.permissions[to] && this.permissions[to][method]) { - delete this.permissions[to][method][from] - if (Object.keys(this.permissions[to][method]).length === 0) { - delete this.permissions[to][method] - } - if (Object.keys(this.permissions[to]).length === 0) { - delete this.permissions[to] - } - yo.update(this.currentSetting, this.settings()) - } - } - - /** Clear all persmissions from a plugin */ - clearAllPersmission (to) { - // eslint-disable-next-line no-debugger - debugger - if (!this.permissions[to]) return - delete this.permissions[to] - yo.update(this.currentSetting, this.settings()) - } - - settings () { - const permissionByToPlugin = (toPlugin, funcObj) => { - const permissionByMethod = (methodName, fromPlugins) => { - const togglePermission = (fromPlugin) => { - this.permissions[toPlugin][methodName][fromPlugin].allow = !this.permissions[toPlugin][methodName][fromPlugin].allow - } - return Object.keys(fromPlugins).map(fromName => { - const fromPluginPermission = fromPlugins[fromName] - const checkbox = fromPluginPermission.allow - ? yo` togglePermission(fromName)} class="mr-2" type="checkbox" checked id="permission-checkbox-${toPlugin}-${methodName}-${toPlugin}" aria-describedby="module ${fromPluginPermission} asks permission for ${methodName}" />` - : yo` togglePermission(fromName)} class="mr-2" type="checkbox" id="permission-checkbox-${toPlugin}-${methodName}-${toPlugin}" aria-describedby="module ${fromPluginPermission} asks permission for ${methodName}" />` - return yo` -
-
- ${checkbox} - -
- -
- ` - }) - } - - const permissionsByFunctions = Object - .keys(funcObj) - .map(methodName => permissionByMethod(methodName, funcObj[methodName])) - - return yo` -
-
-

${toPlugin} permissions:

- -
- ${permissionsByFunctions} -
` - } - - const byToPlugin = Object - .keys(this.permissions) - .map(toPlugin => permissionByToPlugin(toPlugin, this.permissions[toPlugin])) - - const title = byToPlugin.length === 0 - ? yo`

No Permission requested yet.

` - : yo`

Current Permission settings

` - - return yo`
- ${title} -
- ${byToPlugin} -
` - } - - render () { - return yo` -
- -
` - } -} diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index 14aa2d424c..7a1b7c375b 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -1,13 +1,11 @@ 'use strict' - -import yo from 'yo-yo' import async from 'async' import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' import { EventEmitter } from 'events' import { RemixAppManager } from '../../../../../libs/remix-ui/plugin-manager/src/types' -const toaster = require('../ui/tooltip') +import { fileChangedToasterMsg } from '@remix-ui/helper' const helper = require('../../lib/helper.js') /* @@ -317,7 +315,7 @@ class FileManager extends Plugin { if (isFile) { if (newPathExists) { - this.call('modal', 'alert', { + this.call('notification', 'alert', { id: 'fileManagerAlert', message: 'File already exists' }) @@ -326,7 +324,7 @@ class FileManager extends Plugin { return provider.rename(oldPath, newPath, false) } else { if (newPathExists) { - this.call('modal', 'alert', { + this.call('notification', 'alert', { id: 'fileManagerAlert', message: 'Directory already exists' }) @@ -528,17 +526,7 @@ class FileManager extends Plugin { const required = this.appManager.isRequired(this.currentRequest.from) if (canCall && !required) { // inform the user about modification after permission is granted and even if permission was saved before - toaster(yo` -
- - - ${this.currentRequest.from} - - is modifying - ${path} - -
- `, '', { time: 3000 }) + this.call('notification','toast', fileChangedToasterMsg(this.currentRequest.from, path)) } } return await this._setFileInternal(path, content) @@ -778,12 +766,12 @@ class FileManager extends Plugin { helper.createNonClashingName(file, self._deps.filesProviders[fileProvider], (error, name) => { if (error) { - this.call('modal', 'alert', { + this.call('notification', 'alert', { id: 'fileManagerAlert', message: 'Unexpected error loading file ' + file + ': ' + error }) } else if (helper.checkSpecialChars(name)) { - this.call('modal', 'alert', { + this.call('notification', 'alert', { id: 'fileManagerAlert', message: 'Special characters are not allowed in file names.' }) diff --git a/apps/remix-ide/src/app/plugins/modal.tsx b/apps/remix-ide/src/app/plugins/modal.tsx index f5a855f0c2..d96e9b93f2 100644 --- a/apps/remix-ide/src/app/plugins/modal.tsx +++ b/apps/remix-ide/src/app/plugins/modal.tsx @@ -14,9 +14,9 @@ interface IModalApi { } const profile:LibraryProfile = { - name: 'modal', - displayName: 'Modal', - description: 'Modal', + name: 'notification', + displayName: 'Notification', + description: 'Displays notifications', methods: ['modal', 'alert', 'toast'] } 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 95400ca77b..3a1788a8ad 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 @@ -21,7 +21,7 @@ export const enum modalActionTypes { type ModalPayload = { [modalActionTypes.setModal]: AppModal [modalActionTypes.handleHideModal]: any - [modalActionTypes.setToast]: string + [modalActionTypes.setToast]: string | JSX.Element [modalActionTypes.handleToaster]: any } 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 61b98a4873..ab444470f6 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 @@ -30,7 +30,7 @@ export const ModalProvider = ({ children = [], reducer = modalReducer, initialSt }) } - const toast = (message: string) => { + const toast = (message: string | JSX.Element) => { dispatch({ type: modalActionTypes.setToast, payload: message 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 6546f22b0f..46aacf70b8 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 @@ -24,7 +24,7 @@ export interface AlertModal { export interface ModalState { modals: AppModal[], - toasters: string[], + toasters: string[] | JSX.Element[], focusModal: AppModal, - focusToaster: string + focusToaster: string | JSX.Element } diff --git a/libs/remix-ui/helper/src/index.ts b/libs/remix-ui/helper/src/index.ts index 961f14639b..0bd8695a4a 100644 --- a/libs/remix-ui/helper/src/index.ts +++ b/libs/remix-ui/helper/src/index.ts @@ -1 +1,2 @@ export * from './lib/remix-ui-helper' +export * from './lib/components' diff --git a/libs/remix-ui/helper/src/lib/components.tsx b/libs/remix-ui/helper/src/lib/components.tsx new file mode 100644 index 0000000000..361a4e1d87 --- /dev/null +++ b/libs/remix-ui/helper/src/lib/components.tsx @@ -0,0 +1,12 @@ +import React from 'react' + +export const fileChangedToasterMsg = (from: string, path: string) => ( +
+ + {from} + + is modifying + {path} + +
+) \ No newline at end of file diff --git a/libs/remix-ui/helper/tsconfig.json b/libs/remix-ui/helper/tsconfig.json index f4023e39ff..d52e31ad74 100644 --- a/libs/remix-ui/helper/tsconfig.json +++ b/libs/remix-ui/helper/tsconfig.json @@ -1,5 +1,11 @@ { "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, "files": [], "include": [], "references": [ diff --git a/libs/remix-ui/plugin-manager/src/lib/components/permissionsSettings.tsx b/libs/remix-ui/plugin-manager/src/lib/components/permissionsSettings.tsx index 690dadad8a..5936ec3f0d 100644 --- a/libs/remix-ui/plugin-manager/src/lib/components/permissionsSettings.tsx +++ b/libs/remix-ui/plugin-manager/src/lib/components/permissionsSettings.tsx @@ -5,11 +5,7 @@ import { ModalDialog } from '@remix-ui/modal-dialog' import useLocalStorage from '../custom-hooks/useLocalStorage' import { PluginPermissions } from '../../types' -interface PermissionSettingsProps { - pluginSettings: any -} - -function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) { +function PermisssionsSettings () { const [modalVisibility, setModalVisibility] = useState(true) const [permissions, setPermissions] = useLocalStorage('plugins/permissions', {} as PluginPermissions) const [permissionCache, setpermissionCache] = useState() diff --git a/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx b/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx index 0e6d377146..1359e04ec3 100644 --- a/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx +++ b/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx @@ -7,7 +7,6 @@ import LocalPluginForm from './LocalPluginForm' interface RootViewProps { pluginComponent: PluginManagerComponent - pluginManagerSettings: PluginManagerSettings children: ReactNode } @@ -21,7 +20,7 @@ export interface pluginActivated { profile: Profile } -function RootView ({ pluginComponent, pluginManagerSettings, children }: RootViewProps) { +function RootView ({ pluginComponent, children }: RootViewProps) { const [visible, setVisible] = useState(true) const [filterPlugins, setFilterPlugin] = useState('') @@ -52,7 +51,7 @@ function RootView ({ pluginComponent, pluginManagerSettings, children }: RootVie {children} - + { +export const RemixUiPluginManager = ({ pluginComponent }: RemixUiPluginManagerProps) => { const [activeProfiles, setActiveProfiles] = useState(pluginComponent.activePlugins) const [inactiveProfiles, setinactiveProfiles] = useState(pluginComponent.inactivePlugins) return ( - +
void } export const Toaster = (props: ToasterProps) => { - const [state, setState] = useState({ + const [state, setState] = useState<{ + message: string | JSX.Element, + hide: boolean, + hiding: boolean, + timeOutId: any, + timeOut: number, + showModal: boolean, + showFullBtn: boolean + }>({ message: '', hide: true, hiding: false, timeOutId: null, timeOut: props.timeOut || 7000, - showModal: false + showModal: false, + showFullBtn: false }) useEffect(() => { @@ -29,9 +38,15 @@ export const Toaster = (props: ToasterProps) => { }, state.timeOut) setState(prevState => { - const shortTooltipText = props.message.length > 201 ? props.message.substring(0, 200) + '...' : props.message + if (typeof props.message === 'string' && (props.message.length > 201)) { + const shortTooltipText = props.message.substring(0, 200) + '...' - return { ...prevState, hide: false, hiding: false, timeOutId, message: shortTooltipText } + return { ...prevState, hide: false, hiding: false, timeOutId, message: shortTooltipText } + } else { + const shortTooltipText = props.message + + return { ...prevState, hide: false, hiding: false, timeOutId, message: shortTooltipText } + } }) } }, [props.message]) @@ -103,7 +118,7 @@ export const Toaster = (props: ToasterProps) => {
{ state.message } - { (props.message.length > 201) && } + { state.showFullBtn && } From 153614ee9e9cf5dd0bc89d3a8427b4fbb3d19458 Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 11 Jan 2022 14:01:47 +0100 Subject: [PATCH 2/5] Replace yo-yo toaster with new toaster plugin call in debugger and compiler plugins --- apps/remix-ide/src/app/files/fileManager.ts | 4 +- apps/remix-ide/src/app/files/fileProvider.js | 8 +-- apps/remix-ide/src/app/tabs/compile-tab.js | 19 +++---- apps/remix-ide/src/app/tabs/debugger-tab.js | 33 +++++------ .../app/src/lib/remix-app/interface/index.ts | 2 +- libs/remix-ui/helper/src/index.ts | 2 +- libs/remix-ui/helper/src/lib/components.tsx | 12 ---- .../helper/src/lib/helper-components.tsx | 55 +++++++++++++++++++ 8 files changed, 84 insertions(+), 51 deletions(-) delete mode 100644 libs/remix-ui/helper/src/lib/components.tsx create mode 100644 libs/remix-ui/helper/src/lib/helper-components.tsx diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index 7a1b7c375b..1c4a3e61bf 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -5,7 +5,7 @@ import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' import { EventEmitter } from 'events' import { RemixAppManager } from '../../../../../libs/remix-ui/plugin-manager/src/types' -import { fileChangedToasterMsg } from '@remix-ui/helper' +import { fileChangedToastMsg } from '@remix-ui/helper' const helper = require('../../lib/helper.js') /* @@ -526,7 +526,7 @@ class FileManager extends Plugin { const required = this.appManager.isRequired(this.currentRequest.from) if (canCall && !required) { // inform the user about modification after permission is granted and even if permission was saved before - this.call('notification','toast', fileChangedToasterMsg(this.currentRequest.from, path)) + this.call('notification','toast', fileChangedToastMsg(this.currentRequest.from, path)) } } return await this._setFileInternal(path, content) diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index d5873e43ef..9ab67a84b3 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -2,8 +2,6 @@ import { CompilerImports } from '@remix-project/core-plugin' const EventManager = require('events') -const modalDialogCustom = require('../ui/modal-dialog-custom') -const tooltip = require('../ui/tooltip') const remixLib = require('@remix-project/remix-lib') const Storage = remixLib.Storage @@ -49,7 +47,7 @@ class FileProvider { return this.externalFolders.includes(path) } - discardChanges (path) { + discardChanges (path, toastCb, modalCb) { this.remove(path) const compilerImport = new CompilerImports() this.providerExternalsStorage.keys().map(value => { @@ -57,10 +55,10 @@ class FileProvider { compilerImport.import( this.getNormalizedName(value), true, - (loadingMsg) => { tooltip(loadingMsg) }, + (loadingMsg) => { toastCb(loadingMsg) }, (error, content, cleanUrl, type, url) => { if (error) { - modalDialogCustom.alert(error) + modalCb(error) } else { this.addExternal(type + '/' + cleanUrl, content, url) } diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index f409129bb1..bcc11fa2dd 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -8,11 +8,7 @@ import { ViewPlugin } from '@remixproject/engine-web' import QueryParams from '../../lib/query-params' // import { ICompilerApi } from '@remix-project/remix-lib-ts' import * as packageJson from '../../../../../package.json' - -const yo = require('yo-yo') -const addTooltip = require('../ui/tooltip') - -const css = require('./styles/compile-tab-styles') +import { compilerConfigChangedToastMsg, compileToastMsg } from '@remix-ui/helper' const profile = { name: 'solidity', @@ -41,6 +37,8 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA this.compiler = this.compileTabLogic.compiler this.compileTabLogic.init() this.initCompilerApi() + this.el = document.createElement('div') + this.el.setAttribute('id', 'compileTabView') } renderComponent () { @@ -70,11 +68,6 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA } render () { - if (this.el) return this.el - this.el = yo` -
-
-
` this.renderComponent() return this.el @@ -101,11 +94,13 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA super.setCompilerConfig(settings) this.renderComponent() // @todo(#2875) should use loading compiler return value to check whether the compiler is loaded instead of "setInterval" - addTooltip(yo`
${this.currentRequest.from} is updating the Solidity compiler configuration.
${JSON.stringify(settings, null, '\t')}
`) + const value = JSON.stringify(settings, null, '\t') + + this.call('notification', 'toast', compilerConfigChangedToastMsg(this.currentRequest.from, value)) } compile (fileName) { - addTooltip(yo`
${this.currentRequest.from} is requiring to compile ${fileName}
`) + this.call('notification', 'toast', compileToastMsg(this.currentRequest.from, fileName)) super.compile(fileName) } diff --git a/apps/remix-ide/src/app/tabs/debugger-tab.js b/apps/remix-ide/src/app/tabs/debugger-tab.js index 97fc748e91..741a433795 100644 --- a/apps/remix-ide/src/app/tabs/debugger-tab.js +++ b/apps/remix-ide/src/app/tabs/debugger-tab.js @@ -1,14 +1,12 @@ -import toaster from '../ui/tooltip' import { DebuggerUI } from '@remix-ui/debugger-ui' // eslint-disable-line import { DebuggerApiMixin } from '@remixproject/debugger-plugin' import { ViewPlugin } from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' -import modalDialogCustom from '../ui/modal-dialog-custom' import * as remixBleach from '../../lib/remixBleach' +import { compilationFinishedToastMsg, compilingToastMsg, localCompilationToastMsg, notFoundToastMsg, sourceVerificationNotAvailableToastMsg } from '@remix-ui/helper' const css = require('./styles/debugger-tab-styles') -const yo = require('yo-yo') const profile = { name: 'debugger', @@ -26,46 +24,45 @@ const profile = { export class DebuggerTab extends DebuggerApiMixin(ViewPlugin) { constructor () { super(profile) - this.el = null + this.el = document.createElement('div') + this.el.setAttribute('id', 'debugView') + this.el.classList.add(css.debuggerTabView) this.initDebuggerApi() } render () { - if (this.el) return this.el - - this.el = yo` -
-
-
` - this.on('fetchAndCompile', 'compiling', (settings) => { - toaster(yo`
Recompiling and debugging with params
${JSON.stringify(settings, null, '\t')}
`) + settings = JSON.stringify(settings, null, '\t') + this.call('notification', 'toast', compilingToastMsg(settings)) }) this.on('fetchAndCompile', 'compilationFailed', (data) => { - toaster(yo`
Compilation failed... continuing without source code debugging.
`) + this.call('notification', 'toast', compilationFinishedToastMsg()) }) this.on('fetchAndCompile', 'notFound', (contractAddress) => { - toaster(yo`
Contract ${contractAddress} not found in source code repository continuing without source code debugging.
`) + this.call('notification', 'toast', notFoundToastMsg(contractAddress)) }) this.on('fetchAndCompile', 'usingLocalCompilation', (contractAddress) => { - toaster(yo`
Using compilation result from Solidity module
`) + this.call('notification', 'toast', localCompilationToastMsg()) }) this.on('fetchAndCompile', 'sourceVerificationNotAvailable', () => { - toaster(yo`
Source verification plugin not activated or not available. continuing without source code debugging.
`) + this.call('notification', 'toast', sourceVerificationNotAvailableToastMsg()) }) this.renderComponent() - return this.el } showMessage (title, message) { try { - modalDialogCustom.alert(title, remixBleach.sanitize(message)) + this.call('notification', 'alert', { + id: 'debuggerTabShowMessage', + title, + message: remixBleach.sanitize(message) + }) } catch (e) { console.log(e) } 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 46aacf70b8..0432c71e2d 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 @@ -24,7 +24,7 @@ export interface AlertModal { export interface ModalState { modals: AppModal[], - toasters: string[] | JSX.Element[], + toasters: (string | JSX.Element)[], focusModal: AppModal, focusToaster: string | JSX.Element } diff --git a/libs/remix-ui/helper/src/index.ts b/libs/remix-ui/helper/src/index.ts index 0bd8695a4a..31c21f0564 100644 --- a/libs/remix-ui/helper/src/index.ts +++ b/libs/remix-ui/helper/src/index.ts @@ -1,2 +1,2 @@ export * from './lib/remix-ui-helper' -export * from './lib/components' +export * from './lib/helper-components' diff --git a/libs/remix-ui/helper/src/lib/components.tsx b/libs/remix-ui/helper/src/lib/components.tsx deleted file mode 100644 index 361a4e1d87..0000000000 --- a/libs/remix-ui/helper/src/lib/components.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' - -export const fileChangedToasterMsg = (from: string, path: string) => ( -
- - {from} - - is modifying - {path} - -
-) \ No newline at end of file diff --git a/libs/remix-ui/helper/src/lib/helper-components.tsx b/libs/remix-ui/helper/src/lib/helper-components.tsx new file mode 100644 index 0000000000..daa07cc110 --- /dev/null +++ b/libs/remix-ui/helper/src/lib/helper-components.tsx @@ -0,0 +1,55 @@ +import React from 'react' + +export const fileChangedToastMsg = (from: string, path: string) => ( +
+ + {from} + + is modifying + {path} + +
+) + +export const compilerConfigChangedToastMsg = (from: string, value: string) => ( +
+ { from } is updating the Solidity compiler configuration. +
{value}
+
+) + +export const compileToastMsg = (from: string, fileName: string) => ( +
+ {from} is requiring to compile {fileName} +
+) + +export const compilingToastMsg = (settings: string) => ( +
+ Recompiling and debugging with params +
{settings}
+) + +export const compilationFinishedToastMsg = () => ( +
+ Compilation failed... continuing without source code debugging. +
+) + +export const notFoundToastMsg = (address: string) => ( +
+ Contract {address} not found in source code repository continuing without source code debugging. +
+) + +export const localCompilationToastMsg = () => ( +
+ Using compilation result from Solidity module +
+) + +export const sourceVerificationNotAvailableToastMsg = () => ( +
+ Source verification plugin not activated or not available. continuing without source code debugging. +
+) \ No newline at end of file From db43f1926f0e770701a2d5cfc757459f3bf4fda6 Mon Sep 17 00:00:00 2001 From: David Disu Date: Tue, 11 Jan 2022 15:18:16 +0100 Subject: [PATCH 3/5] Remove old toaster and modal in yo-yo --- apps/remix-ide/src/app.js | 3 +- .../src/app/ui/modal-dialog-custom.js | 114 ------------- apps/remix-ide/src/app/ui/modaldialog.js | 150 ------------------ apps/remix-ide/src/app/ui/tooltip.js | 110 ------------- 4 files changed, 1 insertion(+), 376 deletions(-) delete mode 100644 apps/remix-ide/src/app/ui/modal-dialog-custom.js delete mode 100644 apps/remix-ide/src/app/ui/modaldialog.js delete mode 100644 apps/remix-ide/src/app/ui/tooltip.js diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 9b39076918..d327647549 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -36,7 +36,6 @@ const FileManager = require('./app/files/fileManager') const FileProvider = require('./app/files/fileProvider') const DGitProvider = require('./app/files/dgitProvider') const WorkspaceFileProvider = require('./app/files/workspaceFileProvider') -const toolTip = require('./app/ui/tooltip') const PluginManagerComponent = require('./app/components/plugin-manager-component') @@ -368,7 +367,7 @@ class AppComponent { if (params.call) { const callDetails = params.call.split('//') if (callDetails.length > 1) { - toolTip(`initiating ${callDetails[0]} ...`) + self.appManager.call('notification', 'toast', `initiating ${callDetails[0]} ...`) // @todo(remove the timeout when activatePlugin is on 0.3.0) self.appManager.call(...callDetails).catch(console.error) } diff --git a/apps/remix-ide/src/app/ui/modal-dialog-custom.js b/apps/remix-ide/src/app/ui/modal-dialog-custom.js deleted file mode 100644 index d2b1daba44..0000000000 --- a/apps/remix-ide/src/app/ui/modal-dialog-custom.js +++ /dev/null @@ -1,114 +0,0 @@ -var modal = require('./modaldialog.js') -var yo = require('yo-yo') -var css = require('./styles/modal-dialog-custom-styles') - -module.exports = { - alert: function (title, text) { - if (text) return modal(title, yo`
${text}
`, null, { label: null }) - return modal('Alert', yo`
${title}
`, null, { label: null }) - }, - prompt: function (title, text, inputValue, ok, cancel, focus) { - return prompt(title, text, false, inputValue, ok, cancel, focus) - }, - promptPassphrase: function (title, text, inputValue, ok, cancel) { - return prompt(title, text, true, inputValue, ok, cancel) - }, - promptPassphraseCreation: function (ok, cancel) { - var text = 'Please provide a Passphrase for the account creation' - var input = yo` -
- -
-
- -
- ` - return modal(null, yo`
${text}
${input}
`, - { - fn: () => { - if (typeof ok === 'function') { - if (input.querySelector('#prompt1').value === input.querySelector('#prompt2').value) { - ok(null, input.querySelector('#prompt1').value) - } else { - ok('Passphase does not match') - } - } - } - }, - { - fn: () => { - if (typeof cancel === 'function') cancel() - } - } - ) - }, - promptMulti: function ({ title, text, inputValue }, ok, cancel) { - if (!inputValue) inputValue = '' - const input = yo` - - ` - return modal(title, yo`
${text}
${input}
`, - { - fn: () => { if (typeof ok === 'function') ok(document.getElementById('prompt_text').value) } - }, - { - fn: () => { if (typeof cancel === 'function') cancel() } - } - ) - }, - confirm: function (title, text, ok, cancel) { - return modal(title, yo`
${text}
`, - { - fn: () => { if (typeof ok === 'function') ok() } - }, - { - fn: () => { if (typeof cancel === 'function') cancel() } - } - ) - } -} - -const validateInput = (e) => { - if (!document.getElementById('modal-footer-ok')) return - - if (e.target.value === '') { - document.getElementById('modal-footer-ok').classList.add('disabled') - document.getElementById('modal-footer-ok').style.pointerEvents = 'none' - } else { - document.getElementById('modal-footer-ok').classList.remove('disabled') - document.getElementById('modal-footer-ok').style.pointerEvents = 'auto' - } -} - -function prompt (title, text, hidden, inputValue, ok, cancel, focus) { - if (!inputValue) inputValue = '' - var type = hidden ? 'password' : 'text' - var input = yo` - - ` - - modal(title, yo`
${text}
${input}
`, - { - fn: () => { if (typeof ok === 'function') ok(document.getElementById('prompt_text').value) } - }, - { - fn: () => { if (typeof cancel === 'function') cancel() } - }, - focus ? '#prompt_text' : undefined - ) -} diff --git a/apps/remix-ide/src/app/ui/modaldialog.js b/apps/remix-ide/src/app/ui/modaldialog.js deleted file mode 100644 index 1aeae287a4..0000000000 --- a/apps/remix-ide/src/app/ui/modaldialog.js +++ /dev/null @@ -1,150 +0,0 @@ -var yo = require('yo-yo') -var css = require('./styles/modaldialog-styles') - -let incomingModal = false // in case modals are queued, ensure we are not hiding the last one. -module.exports = (title, content, ok, cancel, focusSelector, opts) => { - let agreed = true - let footerIsActive = false - opts = opts || {} - var container = document.getElementById('modal-dialog') - if (!container) { - document.querySelector('body').appendChild(html(opts)) - container = document.getElementById('modal-dialog') - incomingModal = false - } else incomingModal = true - - var closeDiv = document.getElementById('modal-close') - if (opts.hideClose) closeDiv.style.display = 'none' - - var okDiv = document.getElementById('modal-footer-ok') - okDiv.innerHTML = (ok && ok.label !== undefined) ? ok.label : 'OK' - okDiv.style.display = okDiv.innerHTML === '' ? 'none' : 'inline-block' - - var cancelDiv = document.getElementById('modal-footer-cancel') - cancelDiv.innerHTML = (cancel && cancel.label !== undefined) ? cancel.label : 'Cancel' - cancelDiv.style.display = cancelDiv.innerHTML === '' ? 'none' : 'inline-block' - - var modal = document.getElementById('modal-body-id') - var modalTitle = document.getElementById('modal-title-h6') - - modalTitle.innerHTML = '' - if (title) modalTitle.innerText = title - - modal.innerHTML = '' - if (content) modal.appendChild(content) - - setFocusOn('ok') - - show() - - function setFocusOn (btn) { - var okDiv = document.getElementById('modal-footer-ok') - var cancelDiv = document.getElementById('modal-footer-cancel') - if (btn === 'ok') { - okDiv.className = okDiv.className.replace(/\bbtn-light\b/g, 'btn-dark') - cancelDiv.className = cancelDiv.className.replace(/\bbtn-dark\b/g, 'btn-light') - } else { - cancelDiv.className = cancelDiv.className.replace(/\bbtn-light\b/g, 'btn-dark') - okDiv.className = okDiv.className.replace(/\bbtn-dark\b/g, 'btn-light') - } - } - - function okListener () { - removeEventListener() - if (ok && ok.fn && agreed) ok.fn() - if (!incomingModal) hide() - incomingModal = false - } - - function cancelListener () { - removeEventListener() - if (cancel && cancel.fn) cancel.fn() - if (!incomingModal) hide() - incomingModal = false - } - - function modalKeyEvent (e) { - if (e.keyCode === 27) { // Esc - cancelListener() - } else if (e.keyCode === 13) { // Enter - e.preventDefault() - okListener() - } else if (e.keyCode === 37 && footerIsActive) { // Arrow Left - e.preventDefault() - agreed = true - setFocusOn('ok') - } else if (e.keyCode === 39 && footerIsActive) { // Arrow Right - e.preventDefault() - agreed = false - setFocusOn('cancel') - } - } - - function hide () { - if (!container) return - container.style.display = 'none' - if (container.parentElement) container.parentElement.removeChild(container) - container = null - incomingModal = false - } - - function show () { - if (!container) return - container.style.display = 'block' - if (focusSelector) { - const focusTarget = document.querySelector(`.modal ${focusSelector}`) - if (focusTarget) { - focusTarget.focus() - if (typeof focusTarget.setSelectionRange === 'function') { - focusTarget.setSelectionRange(0, focusTarget.value.length) - } - } - } - } - - function removeEventListener () { - okDiv.removeEventListener('click', okListener) - cancelDiv.removeEventListener('click', cancelListener) - closeDiv.removeEventListener('click', cancelListener) - document.removeEventListener('keydown', modalKeyEvent) - if (document.getElementById('modal-background')) { - document.getElementById('modal-background').removeEventListener('click', cancelListener) - } - } - okDiv.addEventListener('click', okListener) - cancelDiv.addEventListener('click', cancelListener) - closeDiv.addEventListener('click', cancelListener) - document.addEventListener('keydown', modalKeyEvent) - - const modalDialog = document.getElementById('modal-dialog') - if (modalDialog) { - modalDialog.addEventListener('click', (e) => { - footerIsActive = document.activeElement === modalDialog - if (e.toElement === modalDialog) { - cancelListener() // click is outside of modal-content - } - }) - } - return { container, okListener, cancelListener, hide } -} - -function html (opts) { - return yo` - ` -} diff --git a/apps/remix-ide/src/app/ui/tooltip.js b/apps/remix-ide/src/app/ui/tooltip.js deleted file mode 100644 index 700a08ef56..0000000000 --- a/apps/remix-ide/src/app/ui/tooltip.js +++ /dev/null @@ -1,110 +0,0 @@ -/* global Element */ -var yo = require('yo-yo') -var css = require('./styles/tooltip-styles') -var modal = require('./modal-dialog-custom') - -/** - * Open a tooltip - * @param {string} tooltipText The text shown by the tooltip - * @param {function} [action] Returns An HTMLElement to display for action - */ -module.exports = function addTooltip (tooltipText, action, opts) { - action = action || function () { return yo`
` } - const t = new Toaster() - return t.render(tooltipText, action(t), opts) -} - -class Toaster { - hide () { - if (this.id) clearTimeout(this.id) - setTimeout(() => { - // remove from body after the animation is finished - if (this.tooltip.parentElement) this.tooltip.parentElement.removeChild(this.tooltip) - }, 2000) - animation(this.tooltip, css.animateTop.className) - } - - render (tooltipText, actionElement, opts) { - opts = defaultOptions(opts) - let canShorten = true - if (tooltipText instanceof Element) { - canShorten = false - } else { - if (typeof tooltipText === 'object') { - if (tooltipText.message) { - tooltipText = tooltipText.message - } else { - try { - tooltipText = JSON.stringify(tooltipText) - } catch (e) { - } - } - } - } - - return new Promise((resolve, reject) => { - const shortTooltipText = (canShorten && tooltipText.length > 201) ? tooltipText.substring(0, 200) + '...' : tooltipText - this.resolveFn = resolve - - function showFullMessage () { - modal.alert(tooltipText) - } - - function closeTheToaster (self) { - self.hide() - over() - resolve() - } - const button = tooltipText.length > 201 ? yo` - - ` : '' - - this.tooltip = yo` -
{ over() }} onmouseleave=${() => { out() }}> - - ${shortTooltipText} - ${button} - ${actionElement} - - - - -
` - const timeOut = () => { - return setTimeout(() => { - if (this.id) { - this.hide() - resolve() - } - }, opts.time) - } - const over = () => { - if (this.id) { - clearTimeout(this.id) - this.id = null - } - } - const out = () => { - if (!this.id) this.id = timeOut() - } - this.id = timeOut() - document.body.appendChild(this.tooltip) - animation(this.tooltip, css.animateBottom.className) - }) - } -} - -const defaultOptions = (opts) => { - opts = opts || {} - return { - time: opts.time || 7000 - } -} - -const animation = (tooltip, anim) => { - tooltip.classList.remove(css.animateTop.className) - tooltip.classList.remove(css.animateBottom.className) - // eslint-disable-next-line - void tooltip.offsetWidth // trick for restarting the animation - tooltip.classList.add(anim) -} From a90caf699f5312542410d1e2204ccb26f20e2dac Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 11 Jan 2022 16:42:24 +0100 Subject: [PATCH 4/5] rn modal --- .../src/app/plugins/permission-handler-plugin.tsx | 4 ++-- apps/remix-ide/src/app/plugins/remixd-handle.tsx | 6 +++--- apps/remix-ide/src/app/tabs/hardhat-provider.tsx | 4 ++-- libs/remix-core-plugin/src/lib/gist-handler.ts | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx b/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx index ce76cc7cc6..1b947d75dd 100644 --- a/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx +++ b/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx @@ -72,7 +72,7 @@ export class PermissionHandlerPlugin extends Plugin { const { allow, hash } = this.permissions[to.name][method][from.name] if (!allow) { const warning = this.notAllowWarning(from, to, method) - this.call('modal', 'toast', warning) + this.call('notification', 'toast', warning) return false } return hash === from.hash @@ -100,7 +100,7 @@ export class PermissionHandlerPlugin extends Plugin { cancelLabel: 'Decline' } - const result = await this.call('modal', 'modal', modal) + const result = await this.call('notification', 'modal', modal) return new Promise((resolve, reject) => { if (result) { if (this.permissions[to.name][method][from.name]) { diff --git a/apps/remix-ide/src/app/plugins/remixd-handle.tsx b/apps/remix-ide/src/app/plugins/remixd-handle.tsx index 6f4c522647..68367d1df3 100644 --- a/apps/remix-ide/src/app/plugins/remixd-handle.tsx +++ b/apps/remix-ide/src/app/plugins/remixd-handle.tsx @@ -69,7 +69,7 @@ export class RemixdHandle extends WebsocketPlugin { id: 'connectionAlert', message: 'Cannot connect to the remixd daemon. Please make sure you have the remixd running in the background.' } - this.call('modal', 'alert', alert) + this.call('notification', 'alert', alert) this.canceled() } else { const intervalId = setInterval(() => { @@ -80,7 +80,7 @@ export class RemixdHandle extends WebsocketPlugin { id: 'connectionAlert', message: 'Connection to remixd terminated.Please make sure remixd is still running in the background.' } - this.call('modal', 'alert', alert) + this.call('notification', 'alert', alert) this.canceled() } }, 3000) @@ -102,7 +102,7 @@ export class RemixdHandle extends WebsocketPlugin { okLabel: 'Connect', cancelLabel: 'Cancel', } - const result = await this.call('modal', 'modal', mod) + const result = await this.call('notification', 'modal', mod) if(result) { try { this.localhostProvider.preInit() diff --git a/apps/remix-ide/src/app/tabs/hardhat-provider.tsx b/apps/remix-ide/src/app/tabs/hardhat-provider.tsx index c84a6d09c2..1ca0547d9a 100644 --- a/apps/remix-ide/src/app/tabs/hardhat-provider.tsx +++ b/apps/remix-ide/src/app/tabs/hardhat-provider.tsx @@ -83,7 +83,7 @@ export class HardhatProvider extends Plugin { }, defaultValue: 'http://127.0.0.1:8545' } - this.call('modal', 'modal', modalContent) + this.call('notification', 'modal', modalContent) }) })() } catch (e) { @@ -114,7 +114,7 @@ export class HardhatProvider extends Plugin { title: 'Hardhat Provider', message: `Error while connecting to the hardhat provider: ${error.message}`, } - this.call('modal', 'alert', modalContent) + this.call('notification', 'alert', modalContent) await this.call('udapp', 'setEnvironmentMode', { context: 'vm', fork: 'london' }) this.provider = null setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm diff --git a/libs/remix-core-plugin/src/lib/gist-handler.ts b/libs/remix-core-plugin/src/lib/gist-handler.ts index 6c22c29aa8..23ea64b937 100644 --- a/libs/remix-core-plugin/src/lib/gist-handler.ts +++ b/libs/remix-core-plugin/src/lib/gist-handler.ts @@ -45,7 +45,7 @@ export class GistHandler extends Plugin { setTimeout(() => reject(new Error('Hide')), 0) } } - this.call('modal', 'modal', modalContent) + this.call('notification', 'modal', modalContent) }) })() } catch (e) { @@ -63,7 +63,7 @@ export class GistHandler extends Plugin { title: 'Gist load error', message: 'Error while loading gist. Please provide a valid Gist ID or URL.' } - this.call('modal', 'alert', modalContent) + this.call('notification', 'alert', modalContent) } } else { const modalContent = { @@ -71,7 +71,7 @@ export class GistHandler extends Plugin { title: 'Gist load error', message: 'Error while loading gist. Id cannot be empty.' } - this.call('modal', 'alert', modalContent) + this.call('notification', 'alert', modalContent) } return loadingFromGist } else { @@ -97,7 +97,7 @@ export class GistHandler extends Plugin { modalType: 'alert', okLabel: 'OK' } - await this.call('modal', 'modal', modalContent) + await this.call('notification', 'modal', modalContent) return } } catch (e: any) { @@ -107,7 +107,7 @@ export class GistHandler extends Plugin { message: e.message } - await this.call('modal', 'alert', modalContent) + await this.call('notification', 'alert', modalContent) return } @@ -124,7 +124,7 @@ export class GistHandler extends Plugin { message: errorSavingFiles.message || errorSavingFiles } - this.call('modal', 'alert', modalContent) + this.call('notification', 'alert', modalContent) } }) }) From 605ce3c08b782b1894175bcec090d823604d2d4b Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 11 Jan 2022 16:45:01 +0100 Subject: [PATCH 5/5] rn modal --- apps/remix-ide/src/remixAppManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index a841c84f1b..b6a0b0e0b6 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -8,12 +8,12 @@ const _paq = window._paq = window._paq || [] const requiredModules = [ // services + layout views + system views 'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', - 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout', 'modal', 'permissionhandler'] + 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout', 'notification', 'permissionhandler'] const dependentModules = ['git', 'hardhat', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd) export function isNative (name) { - const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'modal'] + const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification'] return nativePlugins.includes(name) || requiredModules.includes(name) }