Unverified Commit 532fe52a authored by David Zagi's avatar David Zagi Committed by GitHub

Merge branch 'master' into remixd_terminal

parents 69029a97 11c6d10e
...@@ -36,7 +36,7 @@ module.exports = { ...@@ -36,7 +36,7 @@ module.exports = {
.click('*[class="ace_content"]') .click('*[class="ace_content"]')
.sendKeys('*[class="ace_text-input"]', 'error') .sendKeys('*[class="ace_text-input"]', 'error')
.pause(2000) .pause(2000)
.waitForElementVisible('.ace_error', 60000) .waitForElementVisible('.ace_error', 120000)
.checkAnnotations('error', 28) .checkAnnotations('error', 28)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.checkAnnotationsNotPresent('error') .checkAnnotationsNotPresent('error')
......
...@@ -3,7 +3,7 @@ import { NightwatchBrowser } from 'nightwatch' ...@@ -3,7 +3,7 @@ import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init' import init from '../helpers/init'
const testData = { const testData = {
validGistId: '1859c97c6e1efc91047d725d5225888e', validGistId: '02a847917a6a7ecaf4a7e0d4e68715bf',
invalidGistId: '6368b389f9302v32902msk2402' invalidGistId: '6368b389f9302v32902msk2402'
} }
// 99266d6da54cc12f37f11586e8171546c7700d67 // 99266d6da54cc12f37f11586e8171546c7700d67
...@@ -20,7 +20,7 @@ module.exports = { ...@@ -20,7 +20,7 @@ module.exports = {
- switch to a file in the new gist - switch to a file in the new gist
*/ */
console.log('token', process.env.gist_token) console.log('token', process.env.gist_token)
const gistid = 'c15ed7c182a7991ea0a4dea1544fa254' const gistid = '17ac9315bc065a3d95cf8dc1b28d71f8'
browser browser
.refresh() .refresh()
.pause(10000) .pause(10000)
...@@ -125,9 +125,9 @@ module.exports = { ...@@ -125,9 +125,9 @@ module.exports = {
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', testData.validGistId) .setValue('*[data-id="modalDialogCustomPromptText"]', testData.validGistId)
.modalFooterOKClick() .modalFooterOKClick()
.openFile(`gist-${testData.validGistId}/ApplicationRegistry`) .openFile(`gist-${testData.validGistId}/README.txt`)
.waitForElementVisible(`div[title='default_workspace/gist-${testData.validGistId}/ApplicationRegistry']`) .waitForElementVisible(`div[title='default_workspace/gist-${testData.validGistId}/README.txt']`)
.assert.containsText(`div[title='default_workspace/gist-${testData.validGistId}/ApplicationRegistry'] > span`, 'ApplicationRegistry') .assert.containsText(`div[title='default_workspace/gist-${testData.validGistId}/README.txt'] > span`, 'README.txt')
.end() .end()
} }
} }
...@@ -65,7 +65,7 @@ export default class HardhatProvider extends Plugin { ...@@ -65,7 +65,7 @@ export default class HardhatProvider extends Plugin {
if (error) { if (error) {
this.blocked = true this.blocked = true
modalDialogCustom.alert('Hardhat Provider', `Error while connecting to the hardhat provider: ${error.message}`) modalDialogCustom.alert('Hardhat Provider', `Error while connecting to the hardhat provider: ${error.message}`)
await this.call('udapp', 'setEnvironmentMode', 'vm') await this.call('udapp', 'setEnvironmentMode', { context: 'vm', fork: 'berlin' })
this.provider = null this.provider = null
setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm
return reject(error) return reject(error)
......
...@@ -4,7 +4,6 @@ import ReactDOM from 'react-dom' ...@@ -4,7 +4,6 @@ import ReactDOM from 'react-dom'
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
import { RemixUiSettings } from '@remix-ui/settings' //eslint-disable-line import { RemixUiSettings } from '@remix-ui/settings' //eslint-disable-line
const globalRegistry = require('../../global/registry') const globalRegistry = require('../../global/registry')
const EventManager = require('../../lib/events')
const profile = { const profile = {
name: 'settings', name: 'settings',
...@@ -21,36 +20,16 @@ const profile = { ...@@ -21,36 +20,16 @@ const profile = {
} }
module.exports = class SettingsTab extends ViewPlugin { module.exports = class SettingsTab extends ViewPlugin {
constructor (config, editor, appManager) { constructor (config, editor) {
super(profile) super(profile)
this.config = config this.config = config
this.editor = editor this.editor = editor
this.appManager = appManager
this._components = {}
this._deps = { this._deps = {
themeModule: globalRegistry.get('themeModule').api themeModule: globalRegistry.get('themeModule').api
} }
this._view = { /* eslint-disable */
el: null,
optionVM: null,
optionVMLabel: null,
personal: null,
personalLabel: null,
useMatomoAnalytics: null,
useMatomoAnalyticsLabel: null,
useMatomoAnalyticsMode: null,
warnPersonalMode: null,
generateContractMetadata: null,
generateContractMetadataLabel: null,
config: {
general: null, themes: null
},
textWrap: null,
textWrapLabel: null
} /* eslint-enable */
this.event = new EventManager()
this.element = document.createElement('div') this.element = document.createElement('div')
this.element.setAttribute('id', 'settingsTab') this.element.setAttribute('id', 'settingsTab')
this.useMatomoAnalytics = null
} }
onActivation () { onActivation () {
...@@ -67,6 +46,7 @@ module.exports = class SettingsTab extends ViewPlugin { ...@@ -67,6 +46,7 @@ module.exports = class SettingsTab extends ViewPlugin {
config = { this.config } config = { this.config }
editor = { this.editor } editor = { this.editor }
_deps = { this._deps } _deps = { this._deps }
useMatomoAnalytics = {this.useMatomoAnalytics}
/>, />,
this.element this.element
) )
...@@ -78,14 +58,7 @@ module.exports = class SettingsTab extends ViewPlugin { ...@@ -78,14 +58,7 @@ module.exports = class SettingsTab extends ViewPlugin {
updateMatomoAnalyticsChoice (isChecked) { updateMatomoAnalyticsChoice (isChecked) {
this.config.set('settings/matomo-analytics', isChecked) this.config.set('settings/matomo-analytics', isChecked)
if (isChecked) { this.useMatomoAnalytics = isChecked
this._view.useMatomoAnalytics.setAttribute('checked', '') this.renderComponent()
this._view.useMatomoAnalyticsLabel.classList.remove('text-secondary')
this._view.useMatomoAnalyticsLabel.classList.add('text-dark')
} else {
this._view.useMatomoAnalytics.removeAttribute('checked')
this._view.useMatomoAnalyticsLabel.classList.remove('text-dark')
this._view.useMatomoAnalyticsLabel.classList.add('text-secondary')
}
} }
} }
{ {
"name": "@remix-project/remix-analyzer", "name": "@remix-project/remix-analyzer",
"version": "0.5.11", "version": "0.5.12",
"description": "Tool to perform static analysis on Solidity smart contracts", "description": "Tool to perform static analysis on Solidity smart contracts",
"main": "index.js", "main": "index.js",
"types": ".index.d.ts", "types": ".index.d.ts",
...@@ -23,10 +23,11 @@ ...@@ -23,10 +23,11 @@
"@ethereumjs/tx": "^3.2.1", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.4.1", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-astwalker": "^0.0.26", "@remix-project/remix-astwalker": "^0.0.26",
"@remix-project/remix-lib": "^0.5.2", "@remix-project/remix-lib": "^0.5.3",
"async": "^2.6.2", "async": "^2.6.2",
"ethereumjs-util": "^7.0.10", "ethereumjs-util": "^7.0.10",
"ethers": "^5.1.4", "ethers": "^5.1.4",
"string-similarity": "^4.0.4",
"web3": "1.2.4" "web3": "1.2.4"
}, },
"publishConfig": { "publishConfig": {
...@@ -50,5 +51,5 @@ ...@@ -50,5 +51,5 @@
"typescript": "^3.7.5" "typescript": "^3.7.5"
}, },
"typings": "index.d.ts", "typings": "index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
{ {
"name": "@remix-project/remix-astwalker", "name": "@remix-project/remix-astwalker",
"version": "0.0.32", "version": "0.0.33",
"description": "Tool to walk through Solidity AST", "description": "Tool to walk through Solidity AST",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
...@@ -37,12 +37,13 @@ ...@@ -37,12 +37,13 @@
"@ethereumjs/block": "^3.3.0", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/tx": "^3.2.1", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.4.1", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.2", "@remix-project/remix-lib": "^0.5.3",
"@types/tape": "^4.2.33", "@types/tape": "^4.2.33",
"async": "^2.6.2", "async": "^2.6.2",
"ethereumjs-util": "^7.0.10", "ethereumjs-util": "^7.0.10",
"ethers": "^5.1.4", "ethers": "^5.1.4",
"nyc": "^13.3.0", "nyc": "^13.3.0",
"string-similarity": "^4.0.4",
"tape": "^4.10.1", "tape": "^4.10.1",
"ts-node": "^8.0.3", "ts-node": "^8.0.3",
"typescript": "^3.4.3", "typescript": "^3.4.3",
...@@ -52,5 +53,5 @@ ...@@ -52,5 +53,5 @@
"tap-spec": "^5.0.0" "tap-spec": "^5.0.0"
}, },
"typings": "index.d.ts", "typings": "index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
{ {
"name": "@remix-project/remix-debug", "name": "@remix-project/remix-debug",
"version": "0.5.2", "version": "0.5.3",
"description": "Tool to debug Ethereum transactions", "description": "Tool to debug Ethereum transactions",
"contributors": [ "contributors": [
{ {
...@@ -23,12 +23,13 @@ ...@@ -23,12 +23,13 @@
"@ethereumjs/tx": "^3.2.1", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.4.1", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-astwalker": "^0.0.26", "@remix-project/remix-astwalker": "^0.0.26",
"@remix-project/remix-lib": "^0.5.2", "@remix-project/remix-lib": "^0.5.3",
"async": "^2.6.2", "async": "^2.6.2",
"commander": "^2.19.0", "commander": "^2.19.0",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"ethereumjs-util": "^7.0.10", "ethereumjs-util": "^7.0.10",
"ethers": "^5.1.4", "ethers": "^5.1.4",
"string-similarity": "^4.0.4",
"web3": "^1.2.4" "web3": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
...@@ -60,5 +61,5 @@ ...@@ -60,5 +61,5 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
{ {
"name": "@remix-project/remix-lib", "name": "@remix-project/remix-lib",
"version": "0.5.2", "version": "0.5.3",
"description": "Library to various Remix tools", "description": "Library to various Remix tools",
"contributors": [ "contributors": [
{ {
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
"ethers": "^4.0.40", "ethers": "^4.0.40",
"events": "^3.0.0", "events": "^3.0.0",
"solc": "^0.7.4", "solc": "^0.7.4",
"string-similarity": "^4.0.4",
"web3": "^1.2.4" "web3": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
...@@ -52,5 +53,5 @@ ...@@ -52,5 +53,5 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
...@@ -113,17 +113,31 @@ export function checkVMError (execResult, abi, contract) { ...@@ -113,17 +113,31 @@ export function checkVMError (execResult, abi, contract) {
if (contract && fn.functions && Object.keys(fn.functions).length) { if (contract && fn.functions && Object.keys(fn.functions).length) {
const functionSignature = Object.keys(fn.functions)[0] const functionSignature = Object.keys(fn.functions)[0]
// we check in the 'devdoc' if there's a developer documentation for this error // we check in the 'devdoc' if there's a developer documentation for this error
devdoc = contract.object.devdoc.errors[functionSignature][0] || {} try {
devdoc = (contract.object.devdoc.errors && contract.object.devdoc.errors[functionSignature][0]) || {}
} catch (e) {
console.error(e.message)
}
// we check in the 'userdoc' if there's an user documentation for this error // we check in the 'userdoc' if there's an user documentation for this error
const userdoc = contract.object.userdoc.errors[functionSignature][0] || {} try {
if (userdoc) customError += ' : ' + (userdoc as any).notice // we append the user doc if any const userdoc = (contract.object.userdoc.errors && contract.object.userdoc.errors[functionSignature][0]) || {}
if (userdoc && (userdoc as any).notice) customError += ' : ' + (userdoc as any).notice // we append the user doc if any
} catch (e) {
console.error(e.message)
}
} }
let inputIndex = 0
for (const input of functionDesc.inputs) { for (const input of functionDesc.inputs) {
const v = decodedCustomErrorInputs[input.name] const inputKey = input.name || inputIndex
decodedCustomErrorInputsClean[input.name] = { const v = decodedCustomErrorInputs[inputKey]
value: v.toString ? v.toString() : v,
documentation: (devdoc as any).params[input.name] // we add the developer documentation for this input parameter if any decodedCustomErrorInputsClean[inputKey] = {
value: v.toString ? v.toString() : v
}
if (devdoc && (devdoc as any).params) {
decodedCustomErrorInputsClean[input.name].documentation = (devdoc as any).params[inputKey] // we add the developer documentation for this input parameter if any
} }
inputIndex++
} }
break break
} }
......
{ {
"name": "@remix-project/remix-simulator", "name": "@remix-project/remix-simulator",
"version": "0.2.2", "version": "0.2.3",
"description": "Ethereum IDE and tools for the web", "description": "Ethereum IDE and tools for the web",
"contributors": [ "contributors": [
{ {
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.2.1", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.4.1", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.2", "@remix-project/remix-lib": "^0.5.3",
"ansi-gray": "^0.1.1", "ansi-gray": "^0.1.1",
"async": "^3.1.0", "async": "^3.1.0",
"body-parser": "^1.18.2", "body-parser": "^1.18.2",
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
"express": "^4.16.3", "express": "^4.16.3",
"express-ws": "^4.0.0", "express-ws": "^4.0.0",
"merge": "^1.2.0", "merge": "^1.2.0",
"string-similarity": "^4.0.4",
"time-stamp": "^2.0.0", "time-stamp": "^2.0.0",
"web3": "^1.2.4" "web3": "^1.2.4"
}, },
...@@ -65,5 +66,5 @@ ...@@ -65,5 +66,5 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
{ {
"name": "@remix-project/remix-solidity", "name": "@remix-project/remix-solidity",
"version": "0.4.2", "version": "0.4.3",
"description": "Tool to load and run Solidity compiler", "description": "Tool to load and run Solidity compiler",
"main": "index.js", "main": "index.js",
"types": "./index.d.ts", "types": "./index.d.ts",
...@@ -18,12 +18,13 @@ ...@@ -18,12 +18,13 @@
"@ethereumjs/block": "^3.3.0", "@ethereumjs/block": "^3.3.0",
"@ethereumjs/tx": "^3.2.1", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.4.1", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.2", "@remix-project/remix-lib": "^0.5.3",
"async": "^2.6.2", "async": "^2.6.2",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"ethereumjs-util": "^7.0.10", "ethereumjs-util": "^7.0.10",
"ethers": "^5.1.4", "ethers": "^5.1.4",
"solc": "^0.7.4", "solc": "^0.7.4",
"string-similarity": "^4.0.4",
"web3": "1.2.4", "web3": "1.2.4",
"webworkify-webpack": "^2.1.5" "webworkify-webpack": "^2.1.5"
}, },
...@@ -58,5 +59,5 @@ ...@@ -58,5 +59,5 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme",
"typings": "index.d.ts", "typings": "index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
{ {
"name": "@remix-project/remix-tests", "name": "@remix-project/remix-tests",
"version": "0.2.2", "version": "0.2.3",
"description": "Tool to test Solidity smart contracts", "description": "Tool to test Solidity smart contracts",
"main": "src/index.js", "main": "src/index.js",
"types": "./src/index.d.ts", "types": "./src/index.d.ts",
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.2.1", "@ethereumjs/tx": "^3.2.1",
"@ethereumjs/vm": "^5.4.1", "@ethereumjs/vm": "^5.4.1",
"@remix-project/remix-lib": "^0.5.2", "@remix-project/remix-lib": "^0.5.3",
"@remix-project/remix-simulator": "^0.2.2", "@remix-project/remix-simulator": "^0.2.3",
"@remix-project/remix-solidity": "^0.4.2", "@remix-project/remix-solidity": "^0.4.3",
"ansi-gray": "^0.1.1", "ansi-gray": "^0.1.1",
"async": "^2.6.0", "async": "^2.6.0",
"axios": ">=0.21.1", "axios": ">=0.21.1",
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
"express-ws": "^4.0.0", "express-ws": "^4.0.0",
"merge": "^1.2.0", "merge": "^1.2.0",
"signale": "^1.4.0", "signale": "^1.4.0",
"string-similarity": "^4.0.4",
"time-stamp": "^2.2.0", "time-stamp": "^2.2.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"web3": "^1.2.4", "web3": "^1.2.4",
...@@ -76,5 +77,5 @@ ...@@ -76,5 +77,5 @@
"typescript": "^3.3.1" "typescript": "^3.3.1"
}, },
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
...@@ -101,7 +101,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => ...@@ -101,7 +101,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) =>
break break
} }
hideContextMenu() hideContextMenu()
}}>{item.name}</li> }}>{item.label || item.name}</li>
}) })
} }
......
...@@ -35,7 +35,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -35,7 +35,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'newFolder', id: 'newFolder',
name: 'New Folder', name: 'New Folder',
...@@ -43,7 +44,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -43,7 +44,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'rename', id: 'rename',
name: 'Rename', name: 'Rename',
...@@ -51,7 +53,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -51,7 +53,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'delete', id: 'delete',
name: 'Delete', name: 'Delete',
...@@ -59,7 +62,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -59,7 +62,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'run', id: 'run',
name: 'Run', name: 'Run',
...@@ -67,7 +71,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -67,7 +71,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: ['.js'], extension: ['.js'],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'pushChangesToGist', id: 'pushChangesToGist',
name: 'Push changes to gist', name: 'Push changes to gist',
...@@ -75,7 +80,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -75,7 +80,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'publishFolderToGist', id: 'publishFolderToGist',
name: 'Publish folder to gist', name: 'Publish folder to gist',
...@@ -83,7 +89,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -83,7 +89,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'publishFileToGist', id: 'publishFileToGist',
name: 'Publish file to gist', name: 'Publish file to gist',
...@@ -91,7 +98,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -91,7 +98,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'copy', id: 'copy',
name: 'Copy', name: 'Copy',
...@@ -99,7 +107,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -99,7 +107,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}, { }, {
id: 'deleteAll', id: 'deleteAll',
name: 'Delete All', name: 'Delete All',
...@@ -107,7 +116,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -107,7 +116,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: true multiselect: true,
label: ''
}], }],
focusContext: { focusContext: {
element: null, element: null,
...@@ -282,7 +292,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -282,7 +292,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}]) }])
} else { } else {
removeMenuItems([{ removeMenuItems([{
...@@ -292,7 +303,8 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -292,7 +303,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
path: [], path: [],
extension: [], extension: [],
pattern: [], pattern: [],
multiselect: false multiselect: false,
label: ''
}]) }])
} }
}, [canPaste]) }, [canPaste])
......
...@@ -266,8 +266,8 @@ const removePath = (root, path: string, pathName, files) => { ...@@ -266,8 +266,8 @@ const removePath = (root, path: string, pathName, files) => {
return Array.isArray(cur) ? [...acc, ...cur] : [...acc, cur] return Array.isArray(cur) ? [...acc, ...cur] : [...acc, cur]
}, []) }, [])
const prevFiles = _.get(files, _path) const prevFiles = _.get(files, _path)
if (prevFiles) {
prevFiles && prevFiles.child && prevFiles.child[pathName] && delete prevFiles.child[pathName] prevFiles.child && prevFiles.child[pathName] && delete prevFiles.child[pathName]
files = _.set(files, _path, { files = _.set(files, _path, {
isDirectory: true, isDirectory: true,
path, path,
...@@ -275,6 +275,7 @@ const removePath = (root, path: string, pathName, files) => { ...@@ -275,6 +275,7 @@ const removePath = (root, path: string, pathName, files) => {
type: extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder', type: extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder',
child: prevFiles ? prevFiles.child : {} child: prevFiles ? prevFiles.child : {}
}) })
}
return files return files
} }
......
...@@ -32,7 +32,7 @@ export interface FileExplorerMenuProps { ...@@ -32,7 +32,7 @@ export interface FileExplorerMenuProps {
uploadFile: (target: EventTarget & HTMLInputElement) => void uploadFile: (target: EventTarget & HTMLInputElement) => void
} }
export type action = { name: string, type: string[], path: string[], extension: string[], pattern: string[], id: string, multiselect: boolean } export type action = { name: string, type: string[], path: string[], extension: string[], pattern: string[], id: string, multiselect: boolean, label: string }
export type MenuItems = action[] export type MenuItems = action[]
export interface FileExplorerContextMenuProps { export interface FileExplorerContextMenuProps {
......
...@@ -6,7 +6,7 @@ export const gitAccessTokenTitle = 'Github Access Token' ...@@ -6,7 +6,7 @@ export const gitAccessTokenTitle = 'Github Access Token'
export const gitAccessTokenText = 'Manage the access token used to publish to Gist and retrieve Github contents.' export const gitAccessTokenText = 'Manage the access token used to publish to Gist and retrieve Github contents.'
export const gitAccessTokenText2 = 'Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only \'create gist\' permission.' export const gitAccessTokenText2 = 'Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only \'create gist\' permission.'
export const gitAccessTokenLink = 'https://github.com/settings/tokens' export const gitAccessTokenLink = 'https://github.com/settings/tokens'
export const ethereunVMText = 'Always use Ethereum VM at load' export const ethereunVMText = 'Always use Javascript VM at load'
export const wordWrapText = 'Word wrap in editor' export const wordWrapText = 'Word wrap in editor'
export const enablePersonalModeText = ' Enable Personal Mode for web3 provider. Transaction sent over Web3 will use the web3.personal API.\n' export const enablePersonalModeText = ' Enable Personal Mode for web3 provider. Transaction sent over Web3 will use the web3.personal API.\n'
export const matomoAnalytics = 'Enable Matomo Analytics. We do not collect personally identifiable information (PII). The info is used to improve the site’s UX & UI. See more about ' export const matomoAnalytics = 'Enable Matomo Analytics. We do not collect personally identifiable information (PII). The info is used to improve the site’s UX & UI. See more about '
...@@ -4,7 +4,7 @@ import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line ...@@ -4,7 +4,7 @@ import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line
import { enablePersonalModeText, ethereunVMText, generateContractMetadataText, gitAccessTokenLink, gitAccessTokenText, gitAccessTokenText2, gitAccessTokenTitle, matomoAnalytics, textDark, textSecondary, warnText, wordWrapText } from './constants' import { enablePersonalModeText, ethereunVMText, generateContractMetadataText, gitAccessTokenLink, gitAccessTokenText, gitAccessTokenText2, gitAccessTokenTitle, matomoAnalytics, textDark, textSecondary, warnText, wordWrapText } from './constants'
import './remix-ui-settings.css' import './remix-ui-settings.css'
import { etherumVM, generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast } from './settingsAction' import { ethereumVM, generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast } from './settingsAction'
import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer' import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer'
import { Toaster } from '@remix-ui/toaster'// eslint-disable-line import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
...@@ -12,7 +12,8 @@ import { Toaster } from '@remix-ui/toaster'// eslint-disable-line ...@@ -12,7 +12,8 @@ import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
export interface RemixUiSettingsProps { export interface RemixUiSettingsProps {
config: any, config: any,
editor: any, editor: any,
_deps: any _deps: any,
useMatomoAnalytics: boolean
} }
export const RemixUiSettings = (props: RemixUiSettingsProps) => { export const RemixUiSettings = (props: RemixUiSettingsProps) => {
...@@ -33,24 +34,34 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { ...@@ -33,24 +34,34 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
} }
}, [themeName, state.message]) }, [themeName, state.message])
useEffect(() => {
if (props.useMatomoAnalytics !== null) useMatomoAnalytics(props.config, props.useMatomoAnalytics, dispatch)
}, [props.useMatomoAnalytics])
useEffect(() => {
const javascriptVM = props.config.get('settings/always-use-vm')
if ((javascriptVM === null) || (javascriptVM === undefined)) ethereumVM(props.config, true, dispatch)
}, [props.config])
const onchangeGenerateContractMetadata = (event) => { const onchangeGenerateContractMetadata = (event) => {
generateContractMetadat(props, event, dispatch) generateContractMetadat(props.config, event.target.checked, dispatch)
} }
const onchangeOption = (event) => { const onchangeOption = (event) => {
etherumVM(props, event, dispatch) ethereumVM(props.config, event.target.checked, dispatch)
} }
const textWrapEvent = (event) => { const textWrapEvent = (event) => {
textWrapEventAction(props, event, dispatch) textWrapEventAction(props.config, props.editor, event.target.checked, dispatch)
} }
const onchangePersonal = event => { const onchangePersonal = event => {
personal(props, event, dispatch) personal(props.config, event.target.checked, dispatch)
} }
const onchangeMatomoAnalytics = event => { const onchangeMatomoAnalytics = event => {
useMatomoAnalytics(props, event, dispatch) useMatomoAnalytics(props.config, event.target.checked, dispatch)
} }
const onswitchTheme = (event, name) => { const onswitchTheme = (event, name) => {
...@@ -66,31 +77,38 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { ...@@ -66,31 +77,38 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
} }
} }
const generalConfig = () => ( const generalConfig = () => {
const isMetadataChecked = props.config.get('settings/generate-contract-metadata') || false
const isEthereumVMChecked = props.config.get('settings/always-use-vm') || false
const isEditorWrapChecked = props.config.get('settings/text-wrap') || false
const isPersonalChecked = props.config.get('settings/personal-mode') || false
const isMatomoChecked = props.config.get('settings/matomo-analytics') || false
return (
<div className="$border-top"> <div className="$border-top">
<div className="card-body pt-3 pb-2"> <div className="card-body pt-3 pb-2">
<h6 className="card-title">General settings</h6> <h6 className="card-title">General settings</h6>
<div className="mt-2 custom-control custom-checkbox mb-1"> <div className="mt-2 custom-control custom-checkbox mb-1">
<input onChange={onchangeGenerateContractMetadata} id="generatecontractmetadata" data-id="settingsTabGenerateContractMetadata" type="checkbox" className="custom-control-input" name="contractMetadata" checked = { props.config.get('settings/generate-contract-metadata') }/> <input onChange={onchangeGenerateContractMetadata} id="generatecontractmetadata" data-id="settingsTabGenerateContractMetadata" type="checkbox" className="custom-control-input" name="contractMetadata" checked = { isMetadataChecked }/>
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/generate-contract-metadata')}`} data-id="settingsTabGenerateContractMetadataLabel" htmlFor="generatecontractmetadata">{generateContractMetadataText}</label> <label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/generate-contract-metadata')}`} data-id="settingsTabGenerateContractMetadataLabel" htmlFor="generatecontractmetadata">{generateContractMetadataText}</label>
</div> </div>
<div className="fmt-2 custom-control custom-checkbox mb-1"> <div className="fmt-2 custom-control custom-checkbox mb-1">
<input onChange={onchangeOption} className="custom-control-input" id="alwaysUseVM" data-id="settingsTabAlwaysUseVM" type="checkbox" name="ethereumVM" checked={ props.config.get('settings/always-use-vm') }/> <input onChange={onchangeOption} className="custom-control-input" id="alwaysUseVM" data-id="settingsTabAlwaysUseVM" type="checkbox" name="ethereumVM" checked={ isEthereumVMChecked }/>
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/always-use-vm')}`} htmlFor="alwaysUseVM">{ethereunVMText}</label> <label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/always-use-vm')}`} htmlFor="alwaysUseVM">{ethereunVMText}</label>
</div> </div>
<div className="mt-2 custom-control custom-checkbox mb-1"> <div className="mt-2 custom-control custom-checkbox mb-1">
<input id="editorWrap" className="custom-control-input" type="checkbox" onChange={textWrapEvent} checked = { props.config.get('settings/text-wrap')}/> <input id="editorWrap" className="custom-control-input" type="checkbox" onChange={textWrapEvent} checked = { isEditorWrapChecked }/>
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/text-wrap')}`} htmlFor="editorWrap">{wordWrapText}</label> <label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/text-wrap')}`} htmlFor="editorWrap">{wordWrapText}</label>
</div> </div>
<div className="custom-control custom-checkbox mb-1"> <div className="custom-control custom-checkbox mb-1">
<input onChange={onchangePersonal} id="personal" type="checkbox" className="custom-control-input" checked = { props.config.get('settings/personal-mode')}/> <input onChange={onchangePersonal} id="personal" type="checkbox" className="custom-control-input" checked = { isPersonalChecked }/>
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/personal-mode')}`} htmlFor="personal"> <label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/personal-mode')}`} htmlFor="personal">
<i className="fas fa-exclamation-triangle text-warning" aria-hidden="true"></i> <span> </span> <i className="fas fa-exclamation-triangle text-warning" aria-hidden="true"></i> <span> </span>
<span> </span>{enablePersonalModeText} {warnText} <span> </span>{enablePersonalModeText} {warnText}
</label> </label>
</div> </div>
<div className="custom-control custom-checkbox mb-1"> <div className="custom-control custom-checkbox mb-1">
<input onChange={onchangeMatomoAnalytics} id="settingsMatomoAnalytics" type="checkbox" className="custom-control-input" checked={ props.config.get('settings/matomo-analytics')}/> <input onChange={onchangeMatomoAnalytics} id="settingsMatomoAnalytics" type="checkbox" className="custom-control-input" checked={ isMatomoChecked }/>
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/matomo-analytics')}`} htmlFor="settingsMatomoAnalytics"> <label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/matomo-analytics')}`} htmlFor="settingsMatomoAnalytics">
<span>{matomoAnalytics}</span> <span>{matomoAnalytics}</span>
<a href="https://medium.com/p/66ef69e14931/" target="_blank"> Analytics in Remix IDE</a> <span>&</span> <a target="_blank" href="https://matomo.org/free-software">Matomo</a> <a href="https://medium.com/p/66ef69e14931/" target="_blank"> Analytics in Remix IDE</a> <span>&</span> <a target="_blank" href="https://matomo.org/free-software">Matomo</a>
...@@ -99,14 +117,15 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { ...@@ -99,14 +117,15 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
</div> </div>
</div> </div>
) )
}
const saveToken = () => { const saveToken = () => {
saveTokenToast(props, dispatchToast, tokenValue) saveTokenToast(props.config, dispatchToast, tokenValue)
} }
const removeToken = () => { const removeToken = () => {
setTokenValue('') setTokenValue('')
removeTokenToast(props, dispatchToast) removeTokenToast(props.config, dispatchToast)
} }
const handleSaveTokenState = useCallback( const handleSaveTokenState = useCallback(
......
...@@ -8,31 +8,31 @@ declare global { ...@@ -8,31 +8,31 @@ declare global {
const _paq = window._paq = window._paq || [] //eslint-disable-line const _paq = window._paq = window._paq || [] //eslint-disable-line
export const generateContractMetadat = (element, event, dispatch) => { export const generateContractMetadat = (config, checked, dispatch) => {
element.config.set('settings/generate-contract-metadata', event.target.checked) config.set('settings/generate-contract-metadata', checked)
dispatch({ type: 'contractMetadata', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) dispatch({ type: 'contractMetadata', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
} }
export const etherumVM = (element, event, dispatch) => { export const ethereumVM = (config, checked: boolean, dispatch) => {
element.config.set('settings/always-use-vm', event.target.checked) config.set('settings/always-use-vm', checked)
dispatch({ type: 'ethereumVM', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) dispatch({ type: 'ethereumVM', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
} }
export const textWrapEventAction = (element, event, dispatch) => { export const textWrapEventAction = (config, editor, checked, dispatch) => {
element.config.set('settings/text-wrap', event.target.checked) config.set('settings/text-wrap', checked)
element.editor.resize(event.target.checked) editor.resize(checked)
dispatch({ type: 'textWrap', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) dispatch({ type: 'textWrap', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
} }
export const personal = (element, event, dispatch) => { export const personal = (config, checked, dispatch) => {
element.config.set('settings/personal-mode', event.target.checked) config.set('settings/personal-mode', checked)
dispatch({ type: 'personal', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) dispatch({ type: 'personal', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
} }
export const useMatomoAnalytics = (element, event, dispatch) => { export const useMatomoAnalytics = (config, checked, dispatch) => {
element.config.set('settings/matomo-analytics', event.target.checked) config.set('settings/matomo-analytics', checked)
dispatch({ type: 'useMatomoAnalytics', payload: { name: event.target.name, isChecked: event.target.checked, textClass: event.target.checked ? textDark : textSecondary } }) dispatch({ type: 'useMatomoAnalytics', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
if (event.target.checked) { if (checked) {
_paq.push(['forgetUserOptOut']) _paq.push(['forgetUserOptOut'])
// @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used
document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'
...@@ -41,12 +41,12 @@ export const useMatomoAnalytics = (element, event, dispatch) => { ...@@ -41,12 +41,12 @@ export const useMatomoAnalytics = (element, event, dispatch) => {
} }
} }
export const saveTokenToast = (props, dispatch, tokenValue) => { export const saveTokenToast = (config, dispatch, tokenValue) => {
props.config.set('settings/gist-access-token', tokenValue) config.set('settings/gist-access-token', tokenValue)
dispatch({ type: 'save', payload: { message: 'Access token has been saved' } }) dispatch({ type: 'save', payload: { message: 'Access token has been saved' } })
} }
export const removeTokenToast = (props, dispatch) => { export const removeTokenToast = (config, dispatch) => {
props.config.set('settings/gist-access-token', '') config.set('settings/gist-access-token', '')
dispatch({ type: 'removed', payload: { message: 'Access token removed' } }) dispatch({ type: 'removed', payload: { message: 'Access token removed' } })
} }
{ {
"name": "@remix-project/remix-url-resolver", "name": "@remix-project/remix-url-resolver",
"version": "0.0.23", "version": "0.0.24",
"description": "Solidity import url resolver engine", "description": "Solidity import url resolver engine",
"main": "index.js", "main": "index.js",
"types": "./index.d.ts", "types": "./index.d.ts",
...@@ -42,5 +42,5 @@ ...@@ -42,5 +42,5 @@
"typescript": "^3.1.6" "typescript": "^3.1.6"
}, },
"typings": "index.d.ts", "typings": "index.d.ts",
"gitHead": "50b32cc20d2d4dcc793bf7de955957e073e5b5b8" "gitHead": "5e91f3010a7198f1b2d90cc7796bda750c58f1ea"
} }
\ No newline at end of file
{ {
"name": "@remix-project/remixd", "name": "@remix-project/remixd",
"version": "0.4.1", "version": "0.4.2",
"description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)", "description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)",
"main": "index.js", "main": "index.js",
"types": "./index.d.ts", "types": "./index.d.ts",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment