diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js
index 5a7c9b8dc0..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')
@@ -319,7 +318,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'])
@@ -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/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`
-
- `
- })
- }
-
- 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``
- }
-
- 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..1c4a3e61bf 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 { fileChangedToastMsg } 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', fileChangedToastMsg(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/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/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/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/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/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/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``,
- {
- 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``,
- {
- 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``,
- {
- 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`
- showFullMessage()}>Show full message
- ` : ''
-
- this.tooltip = yo`
- { over() }} onmouseleave=${() => { out() }}>
-
- ${shortTooltipText}
- ${button}
- ${actionElement}
-
-
- closeTheToaster(this)}>
-
-
`
- 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)
-}
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)
}
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)
}
})
})
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..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[],
+ 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..31c21f0564 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/helper-components'
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
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) && Show full message }
+ { state.showFullBtn && Show full message }