From 0f7a30f530025dc9fa5b5c8d747c291041033d94 Mon Sep 17 00:00:00 2001 From: Anthony Laibe Date: Tue, 14 Aug 2018 10:23:48 +0100 Subject: [PATCH] Show ENS records --- embark-ui/src/actions/index.js | 2 +- embark-ui/src/api/index.js | 4 +- embark-ui/src/components/EnsLookup.js | 44 ++++++++++++ embark-ui/src/components/EnsRecords.js | 41 ++++++++++++ embark-ui/src/components/EnsRegister.js | 56 ++++++++++++++++ embark-ui/src/components/EnsResolve.js | 44 ++++++++++++ embark-ui/src/components/ExplorerLayout.js | 4 +- embark-ui/src/components/Versions.js | 35 ++++++++++ .../src/containers/CommunicationContainer.js | 45 +++++++------ embark-ui/src/containers/ENSContainer.js | 67 ------------------- embark-ui/src/containers/EnsContainer.js | 64 ++++++++++++++++++ embark-ui/src/containers/HomeContainer.js | 12 +++- embark-ui/src/reducers/index.js | 6 ++ embark-ui/src/reducers/selectors.js | 23 ++++++- embark-ui/src/sagas/index.js | 12 ++-- 15 files changed, 357 insertions(+), 102 deletions(-) create mode 100644 embark-ui/src/components/EnsLookup.js create mode 100644 embark-ui/src/components/EnsRecords.js create mode 100644 embark-ui/src/components/EnsRegister.js create mode 100644 embark-ui/src/components/EnsResolve.js create mode 100644 embark-ui/src/components/Versions.js delete mode 100644 embark-ui/src/containers/ENSContainer.js create mode 100644 embark-ui/src/containers/EnsContainer.js diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js index 6f603860..425370f9 100644 --- a/embark-ui/src/actions/index.js +++ b/embark-ui/src/actions/index.js @@ -142,7 +142,7 @@ export const ensRecord = { export const ENS_RECORDS = createRequestTypes('ENS_RECORDS'); export const ensRecords = { - post: (name, address) => action(ENSENS_RECORDS_RECORD[REQUEST], {name, address}), + post: (name, address) => action(ENS_RECORDS[REQUEST], {name, address}), success: (_record, payload) => action(ENS_RECORDS[SUCCESS], {ensRecords: [{name: payload.name, address: payload.address}]}), failure: (error) => action(ENS_RECORDS[FAILURE], {error}) }; diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js index 615f97ed..7bdc21e4 100644 --- a/embark-ui/src/api/index.js +++ b/embark-ui/src/api/index.js @@ -84,7 +84,7 @@ export function fetchContractProfile(payload) { return get(`/profiler/${payload.contractName}`); } -export function fetchENSRecord(payload) { +export function fetchEnsRecord(payload) { if (payload.name) { return get('/ens/resolve', {params: payload}); } else { @@ -92,7 +92,7 @@ export function fetchENSRecord(payload) { } } -export function postENSRecord(payload) { +export function postEnsRecord(payload) { return post('/ens/register', payload); } diff --git a/embark-ui/src/components/EnsLookup.js b/embark-ui/src/components/EnsLookup.js new file mode 100644 index 00000000..acb319f2 --- /dev/null +++ b/embark-ui/src/components/EnsLookup.js @@ -0,0 +1,44 @@ +import React, {Component} from 'react'; +import { + Button, + Form +} from "tabler-react"; +import PropTypes from 'prop-types'; + +class EnsLookup extends Component { + constructor(props) { + super(props); + + this.state = { + address: '' + }; + } + + handleChange(e) { + this.setState({address: e.target.value}); + } + + handleLookup() { + this.props.lookup(this.state.address); + } + + render(){ + return ( + +

Lookup

+ + + this.handleChange(e)}/> + + + +
+ ); + } +} + +EnsLookup.propTypes = { + lookup: PropTypes.func +}; + +export default EnsLookup; diff --git a/embark-ui/src/components/EnsRecords.js b/embark-ui/src/components/EnsRecords.js new file mode 100644 index 00000000..b1be757a --- /dev/null +++ b/embark-ui/src/components/EnsRecords.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { + Page, + Grid, + Card, + Table +} from "tabler-react"; +import PropTypes from 'prop-types'; + +const EnsRecords = ({ensRecords}) => ( + + + + + { + return ([ + {content: ensRecord.name}, + {content: ensRecord.address} + ]); + }) + } + /> + + + + +); + +EnsRecords.propTypes = { + ensRecords: PropTypes.arrayOf(PropTypes.object) +}; + +export default EnsRecords; diff --git a/embark-ui/src/components/EnsRegister.js b/embark-ui/src/components/EnsRegister.js new file mode 100644 index 00000000..7f738463 --- /dev/null +++ b/embark-ui/src/components/EnsRegister.js @@ -0,0 +1,56 @@ +import React, {Component} from 'react'; +import { + Button, + Form, Grid +} from "tabler-react"; +import PropTypes from 'prop-types'; + +class EnsRegister extends Component { + constructor(props) { + super(props); + + this.state = { + name: '', + address: '' + }; + } + + handleChange(e, name) { + this.setState({ + [name]: e.target.value + }); + } + + handleRegister() { + this.props.register(this.state.name, this.state.address); + } + + render(){ + return ( + +

Register

+ + + + + this.handleChange(e, "name")}/> + + + + + this.handleChange(e, "address")}/> + + + + + +
+ ); + } +} + +EnsRegister.propTypes = { + register: PropTypes.func +}; + +export default EnsRegister; diff --git a/embark-ui/src/components/EnsResolve.js b/embark-ui/src/components/EnsResolve.js new file mode 100644 index 00000000..1f21f0f5 --- /dev/null +++ b/embark-ui/src/components/EnsResolve.js @@ -0,0 +1,44 @@ +import React, {Component} from 'react'; +import { + Button, + Form +} from "tabler-react"; +import PropTypes from 'prop-types'; + +class EnsResolve extends Component { + constructor(props) { + super(props); + + this.state = { + name: '' + }; + } + + handleChange(e) { + this.setState({name: e.target.value}); + } + + handleResolve() { + this.props.resolve(this.state.name); + } + + render(){ + return ( + +

Resolve

+ + + this.handleChange(e)}/> + + + +
+ ); + } +} + +EnsResolve.propTypes = { + resolve: PropTypes.func +}; + +export default EnsResolve; diff --git a/embark-ui/src/components/ExplorerLayout.js b/embark-ui/src/components/ExplorerLayout.js index 0ad2a318..5fd32a19 100644 --- a/embark-ui/src/components/ExplorerLayout.js +++ b/embark-ui/src/components/ExplorerLayout.js @@ -13,7 +13,7 @@ import BlockContainer from '../containers/BlockContainer'; import TransactionsContainer from '../containers/TransactionsContainer'; import TransactionContainer from '../containers/TransactionContainer'; import CommunicationContainer from '../containers/CommunicationContainer'; -import ENSContainer from '../containers/ENSContainer'; +import EnsContainer from '../containers/EnsContainer'; const groupItems = [ {to: "/embark/explorer/accounts", icon: "users", value: "Accounts"}, @@ -53,7 +53,7 @@ const ExplorerLayout = () => ( - + diff --git a/embark-ui/src/components/Versions.js b/embark-ui/src/components/Versions.js new file mode 100644 index 00000000..48abacbf --- /dev/null +++ b/embark-ui/src/components/Versions.js @@ -0,0 +1,35 @@ +import PropTypes from "prop-types"; +import React from 'react'; +import {Link} from "react-router-dom"; +import {Grid, Card} from 'tabler-react'; + +const Version = ({version}) => ( + + +
+ + + +
+

{version.name}: {version.value}

+
+
+
+
+); + +Version.propTypes = { + version: PropTypes.object +}; + +const Versions = ({versions}) => ( + + {versions.map((version) => )} + +); + +Versions.propTypes = { + versions: PropTypes.arrayOf(PropTypes.object) +}; + +export default Versions; diff --git a/embark-ui/src/containers/CommunicationContainer.js b/embark-ui/src/containers/CommunicationContainer.js index 57a125cf..93d17a58 100644 --- a/embark-ui/src/containers/CommunicationContainer.js +++ b/embark-ui/src/containers/CommunicationContainer.js @@ -1,10 +1,10 @@ import PropTypes from "prop-types"; import React, {Component} from 'react'; import connect from "react-redux/es/connect/connect"; -import {Alert, Loader, Page} from 'tabler-react'; +import {Alert, Page} from 'tabler-react'; import {messageSend, messageListen} from "../actions"; import Communication from "../components/Communication"; -import {getMessages, getMessageChannels} from "../reducers/selectors"; +import {getMessages, getMessageChannels, isOldWeb3, isWeb3Enabled} from "../reducers/selectors"; class CommunicationContainer extends Component { sendMessage(topic, message) { @@ -15,24 +15,29 @@ class CommunicationContainer extends Component { this.props.messageListen(channel); } - render() { - let isEnabledMessage = ''; - if (this.props.messageVersion === undefined || this.props.messageVersion === null) { - isEnabledMessage = - Checking Whisper support, please wait; - } else if (!this.props.messageVersion) { - isEnabledMessage = The node you are using does not support Whisper; - } else if (this.props.messageVersion === -1) { - isEnabledMessage = The node uses an unsupported version of Whisper; - } + web3DisabledWarning() { + return The node you are using does not support Whisper + } + web3Enabled() { + return this.props.isOldWeb3 ? this.web3DisabledWarning() : this.showCommunication(); + } + + web3OldWarning() { + return The node uses an unsupported version of Whisper; + } + + showCommunication() { + return this.listenToChannel(channel)} + sendMessage={(channel, message) => this.sendMessage(channel, message)} + channels={this.props.messages} + subscriptions={this.props.messageChannels}/>; + } + + render() { return ( - {isEnabledMessage} - this.listenToChannel(channel)} - sendMessage={(channel, message) => this.sendMessage(channel, message)} - channels={this.props.messages} - subscriptions={this.props.messageChannels}/> + {this.props.isWeb3Enabled ? this.web3Enabled() : this.web3DisabledWarning()} ); } @@ -41,7 +46,8 @@ class CommunicationContainer extends Component { CommunicationContainer.propTypes = { messageSend: PropTypes.func, messageListen: PropTypes.func, - isWhisperEnabled: PropTypes.bool, + isOldWeb3: PropTypes.bool, + isWeb3Enabled: PropTypes.bool, messages: PropTypes.object, messageChannels: PropTypes.array }; @@ -50,7 +56,8 @@ function mapStateToProps(state) { return { messages: getMessages(state), messageChannels: getMessageChannels(state), - isWhisperEnabled: isWhisperEnabled(state) + isOldWeb3: isOldWeb3(state), + isWeb3Enabled: isWeb3Enabled(state) }; } diff --git a/embark-ui/src/containers/ENSContainer.js b/embark-ui/src/containers/ENSContainer.js deleted file mode 100644 index da118914..00000000 --- a/embark-ui/src/containers/ENSContainer.js +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from "prop-types"; -import React, {Component} from 'react'; -import connect from "react-redux/es/connect/connect"; -import {Alert, Loader, Page} from 'tabler-react'; -import {messageSend, messageListen, messageVersion} from "../actions"; -import Communication from "../components/Communication"; -import Loading from "../components/Loading"; -import {getMessages, getMessageChannels} from "../reducers/selectors"; - -class CommunicationContainer extends Component { - sendMessage(topic, message) { - this.props.messageSend({topic, message}); - } - - listenToChannel(channel) { - this.props.messageListen(channel); - } - - render() { - let isEnabledMessage = ''; - if (this.props.messageVersion === undefined || this.props.messageVersion === null) { - isEnabledMessage = - Checking Whisper support, please wait; - } else if (!this.props.messageVersion) { - isEnabledMessage = The node you are using does not support Whisper; - } else if (this.props.messageVersion === -1) { - isEnabledMessage = The node uses an unsupported version of Whisper; - } - - if (!this.props.messages) { - return ; - } - return ( - - {isEnabledMessage} - this.listenToChannel(channel)} - sendMessage={(channel, message) => this.sendMessage(channel, message)} - channels={this.props.messages} - subscriptions={this.props.messageChannels}/> - - ); - } -} - -CommunicationContainer.propTypes = { - messageSend: PropTypes.func, - messageListen: PropTypes.func, - messageVersion: PropTypes.number, - messages: PropTypes.object, - messageChannels: PropTypes.array -}; - -function mapStateToProps(state) { - return { - messages: getMessages(state), - messageChannels: getMessageChannels(state) - }; -} - -export default connect( - mapStateToProps, - { - messageSend: messageSend.request, - messageListen: messageListen.request - } -)(CommunicationContainer); - diff --git a/embark-ui/src/containers/EnsContainer.js b/embark-ui/src/containers/EnsContainer.js new file mode 100644 index 00000000..f5c8a127 --- /dev/null +++ b/embark-ui/src/containers/EnsContainer.js @@ -0,0 +1,64 @@ +import PropTypes from "prop-types"; +import React, {Component} from 'react'; +import connect from "react-redux/es/connect/connect"; +import {Alert, Page} from "tabler-react"; +import {ensRecord, ensRecords} from "../actions"; +import DataWrapper from "../components/DataWrapper"; +import EnsRegister from "../components/EnsRegister"; +import EnsLookup from "../components/EnsLookup"; +import EnsResolve from "../components/EnsResolve"; +import EnsRecords from "../components/EnsRecords"; +import {getEnsRecords, isEnsEnabled} from "../reducers/selectors"; + +class EnsContainer extends Component { + + showEns() { + return ( + + + + + 0} {...this.props} render={({ensRecords}) => ( + + )} /> + + ); + } + + showWarning() { + return Please enable Ens in Embark first; + } + + render() { + return ( + + {this.props.isEnsEnabled ? this.showEns() : this.showWarning()} + + ); + } +} + +EnsContainer.propTypes = { + ensRecords: PropTypes.array, + resolve: PropTypes.func, + lookup: PropTypes.func, + register: PropTypes.func, + isEnsEnabled: PropTypes.bool +}; + +function mapStateToProps(state) { + return { + ensRecords: getEnsRecords(state), + isEnsEnabled: isEnsEnabled(state) + }; +} + +export default connect( + mapStateToProps, + { + resolve: ensRecord.resolve, + lookup: ensRecord.lookup, + register: ensRecords.post + } +)(EnsContainer); + diff --git a/embark-ui/src/containers/HomeContainer.js b/embark-ui/src/containers/HomeContainer.js index a9d91c03..cd714274 100644 --- a/embark-ui/src/containers/HomeContainer.js +++ b/embark-ui/src/containers/HomeContainer.js @@ -6,8 +6,9 @@ import {Page} from "tabler-react"; import {commands as commandsAction} from "../actions"; import DataWrapper from "../components/DataWrapper"; import Processes from '../components/Processes'; +import Versions from '../components/Versions'; import Console from '../components/Console'; -import {getProcesses, getCommands} from "../reducers/selectors"; +import {getProcesses, getCommands, getVersions} from "../reducers/selectors"; class HomeContainer extends Component { render() { @@ -17,6 +18,9 @@ class HomeContainer extends Component { 0 } {...this.props} render={({processes}) => ( )} /> + 0 } {...this.props} render={({versions}) => ( + + )} /> ); @@ -25,12 +29,16 @@ class HomeContainer extends Component { HomeContainer.propTypes = { processes: PropTypes.arrayOf(PropTypes.object), + versions: PropTypes.arrayOf(PropTypes.object), postCommand: PropTypes.func, - commands: PropTypes.arrayOf(PropTypes.object) + commands: PropTypes.arrayOf(PropTypes.object), + error: PropTypes.string, + loading: PropTypes.bool }; function mapStateToProps(state) { return { + versions: getVersions(state), processes: getProcesses(state), commands: getCommands(state), error: state.errorMessage, diff --git a/embark-ui/src/reducers/index.js b/embark-ui/src/reducers/index.js index 626794cc..9f9c552b 100644 --- a/embark-ui/src/reducers/index.js +++ b/embark-ui/src/reducers/index.js @@ -2,6 +2,7 @@ import {combineReducers} from 'redux'; import {REQUEST} from "../actions"; const BN_FACTOR = 10000; +const voidAddress = '0x0000000000000000000000000000000000000000'; const entitiesDefaultState = { accounts: [], @@ -56,6 +57,11 @@ const filtrer = { return index === self.findIndex((t) => ( t.blockNumber === tx.blockNumber && t.transactionIndex === tx.transactionIndex )); + }, + ensRecords: function(record, index, self) { + return record.name && record.address && record.address !== voidAddress && index === self.findIndex((r) => ( + r.address=== record.address && r.name === record.name + )); } }; diff --git a/embark-ui/src/reducers/selectors.js b/embark-ui/src/reducers/selectors.js index c4db980e..7112032d 100644 --- a/embark-ui/src/reducers/selectors.js +++ b/embark-ui/src/reducers/selectors.js @@ -62,8 +62,17 @@ export function getContractProfile(state, contractName) { return state.entities.contractProfiles.find((contractProfile => contractProfile.name === contractName)); } -export function getMessageVersion(state) { - return state.entities.messageVersion; +export function getVersions(state) { + return state.entities.versions; +} + +export function isWeb3Enabled(state) { + return Boolean(state.entities.versions.find((version) => version.name === 'web3')); +} + +export function isOldWeb3(state) { + const web3 = state.entities.versions.find((version) => version.name === 'web3'); + return web3 && parseInt(web3[0], 10) === 0; } export function getMessageChannels(state) { @@ -81,6 +90,14 @@ export function getMessages(state) { return messages; } -export function getFiddle(state){ +export function getFiddle(state) { return state.entities.fiddle; } + +export function getEnsRecords(state) { + return state.entities.ensRecords; +} + +export function isEnsEnabled(state) { + return Boolean(state.entities.plugins.find((plugin) => plugin.name === 'ens')); +} diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index 5e23a5d7..2e056a67 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -33,8 +33,8 @@ export const fetchContract = doRequest.bind(null, contract, api.fetchContract); export const fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile); export const fetchFiddle = doRequest.bind(null, fiddle, api.fetchFiddle); export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage); -export const fetchENSRecord = doRequest.bind(null, ensRecord, api.fetchENSRecord); -export const postENSRecord = doRequest.bind(null, ensRecords, api.postENSRecord); +export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord); +export const postEnsRecord = doRequest.bind(null, ensRecords, api.postEnsRecord); export function *watchFetchTransaction() { yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction); @@ -100,12 +100,12 @@ export function *watchSendMessage() { yield takeEvery(actions.MESSAGE_SEND[actions.REQUEST], sendMessage); } -export function *watchFetchENSRecord() { - yield takeEvery(actions.ENS_RECORD[actions.REQUEST], fetchENSRecord); +export function *watchFetchEnsRecord() { + yield takeEvery(actions.ENS_RECORD[actions.REQUEST], fetchEnsRecord); } -export function *watchPostENSRecords() { - yield takeEvery(actions.ENS_RECORDS[actions.REQUEST], postENSRecord); +export function *watchPostEnsRecords() { + yield takeEvery(actions.ENS_RECORDS[actions.REQUEST], postEnsRecord); } function createChannel(socket) {