Fix demo style and improve (#1818)

* fix(@mbark/embarkjs): enable using wss in embarkjs and the Dapp

* fix(@embark/demo): fix demo style by and improvise

* update yarn.lock. CI please be gentle
This commit is contained in:
Jonathan Rainville 2019-08-23 11:51:03 -04:00 committed by Iuri Matias
parent d2fc210706
commit 844e8ca55f
9 changed files with 185 additions and 131 deletions

View File

@ -1,7 +1,7 @@
import EmbarkJS from 'Embark/EmbarkJS';
import SimpleStorage from '../../embarkArtifacts/contracts/SimpleStorage';
import React from 'react';
import { Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
import {Form, FormGroup, Input, HelpBlock, Button, FormText} from 'reactstrap';
class Blockchain extends React.Component {
@ -51,24 +51,25 @@ class Blockchain extends React.Component {
render() {
return (<React.Fragment>
<h3> 1. Set the value in the blockchain</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.setValue)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.setValue)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
defaultValue={this.state.valueSet}
onChange={(e) => this.handleChange(e)}/>
<Button bsStyle="primary" onClick={(e) => this.setValue(e)}>Set Value</Button>
<HelpBlock>Once you set the value, the transaction will need to be mined and then the value will be updated
on the blockchain.</HelpBlock>
<Button color="primary" onClick={(e) => this.setValue(e)}>Set Value</Button>
<FormText color="muted">Once you set the value, the transaction will need to be mined and then the value will be updated
on the blockchain.</FormText>
</FormGroup>
</Form>
<h3> 2. Get the current value</h3>
<Form inline>
<Form>
<FormGroup>
<HelpBlock>current value is <span className="value">{this.state.valueGet}</span></HelpBlock>
<Button bsStyle="primary" onClick={(e) => this.getValue(e)}>Get Value</Button>
<HelpBlock>Click the button to get the current value. The initial value is 100.</HelpBlock>
<Button color="primary" onClick={(e) => this.getValue(e)}>Get Value</Button>
<FormText color="muted">Click the button to get the current value. The initial value is 100.</FormText>
{this.state.valueGet && this.state.valueGet !== 0 &&
<p>Current value is <span className="value font-weight-bold">{this.state.valueGet}</span></p>}
</FormGroup>
</Form>

View File

@ -1,9 +1,7 @@
/*global web3*/
import EmbarkJS from 'Embark/EmbarkJS';
import React from 'react';
import { Alert, Form, FormGroup, FormControl, Button } from 'react-bootstrap';
window.EmbarkJS = EmbarkJS;
import { Alert, Form, FormGroup, Input, Button } from 'reactstrap';
class ENS extends React.Component {
@ -35,7 +33,7 @@ class ENS extends React.Component {
this.setState({
addressRegister: web3.eth.defaultAccount,
valueLookup: web3.eth.defaultAccount
})
});
});
}
@ -115,53 +113,54 @@ class ENS extends React.Component {
render() {
return (<React.Fragment>
{this.state.globalError && <Alert bsStyle="danger">{this.state.globalError}</Alert>}
{this.state.globalError && <Alert color="danger">{this.state.globalError}</Alert>}
<h3>Resolve a name</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.resolveName)}>
<FormGroup>
<Form onKeyDown={(e) => this.checkEnter(e, this.resolveName)}>
<FormGroup className="inline-input-btn">
{this.state.responseResolve &&
<Alert className="alert-result" bsStyle={this.state.isResolveError ? 'danger' : 'success'}>
<Alert className="alert-result" color={this.state.isResolveError ? 'danger' : 'success'}>
Resolved address: <span className="value">{this.state.responseResolve}</span>
</Alert>}
<FormControl
<Input
type="text"
defaultValue={this.state.valueResolve}
onChange={(e) => this.handleChange('valueResolve', e)}/>
<Button bsStyle="primary" onClick={(e) => this.resolveName(e)}>Resolve name</Button>
<Button color="primary" onClick={(e) => this.resolveName(e)}>Resolve name</Button>
</FormGroup>
</Form>
<h3>Lookup an address</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.lookupAddress)}>
<FormGroup>
<Form onKeyDown={(e) => this.checkEnter(e, this.lookupAddress)}>
<FormGroup className="inline-input-btn">
{this.state.responseLookup &&
<Alert className="alert-result" bsStyle={this.state.isLookupError ? 'danger' : 'success'}>
<Alert className="alert-result" color={this.state.isLookupError ? 'danger' : 'success'}>
Looked up domain: <span className="value">{this.state.responseLookup}</span>
</Alert>}
<FormControl
<Input
type="text"
defaultValue={this.state.valueLookup}
onChange={(e) => this.handleChange('valueLookup', e)}/>
<Button bsStyle="primary" onClick={(e) => this.lookupAddress(e)}>Lookup address</Button>
<Button color="primary" onClick={(e) => this.lookupAddress(e)}>Lookup address</Button>
</FormGroup>
</Form>
<h3>Register subdomain</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.registerSubDomain)}>
<Form onKeyDown={(e) => this.checkEnter(e, this.registerSubDomain)}>
<FormGroup>
{this.state.responseRegister &&
<Alert className="alert-result" bsStyle={this.state.isRegisterError ? 'danger' : 'success'}>
<Alert className="alert-result" color={this.state.isRegisterError ? 'danger' : 'success'}>
<span className="value">{this.state.responseRegister}</span>
</Alert>}
<FormControl
type="text"
defaultValue={this.state.valueRegister}
<Input
defaultValue={this.state.valueRegister} className="small-input float-left"
onChange={(e) => this.handleChange('valueRegister', e)}/>
<FormControl
<div className="inline-input-btn m-0">
<Input
type="text"
defaultValue={this.state.addressRegister}
onChange={(e) => this.handleChange('addressRegister', e)}/>
<Button bsStyle="primary" onClick={(e) => this.registerSubDomain(e)}>Register subdomain</Button>
<Button color="primary" onClick={(e) => this.registerSubDomain(e)}>Register subdomain</Button>
</div>
</FormGroup>
</Form>

View File

@ -1,6 +1,6 @@
import EmbarkJS from 'Embark/EmbarkJS';
import React from 'react';
import {Alert, Form, FormGroup, FormControl, HelpBlock, Button} from 'react-bootstrap';
import React, {Fragment} from 'react';
import {Alert, Form, FormGroup, Input, FormText, Button} from 'reactstrap';
class Storage extends React.Component {
@ -19,7 +19,7 @@ class Storage extends React.Component {
logs: [],
storageError: '',
valueRegister: '',
valueResolver: '',
valueResolver: ''
};
}
@ -101,7 +101,7 @@ class Storage extends React.Component {
});
}
loadFile(e) {
loadFile(_e) {
let _url = EmbarkJS.Storage.getUrl(this.state.imageToDownload);
this.setState({url: _url});
this.addToLog("EmbarkJS.Storage.getUrl('" + this.state.imageToDownload + "')");
@ -116,7 +116,7 @@ class Storage extends React.Component {
let isRegisterError = false;
if (err) {
isRegisterError = true;
responseRegister = "Name Register Error: " + (err.message || err)
responseRegister = "Name Register Error: " + (err.message || err);
} else {
responseRegister = name;
}
@ -138,7 +138,7 @@ class Storage extends React.Component {
let isResolverError = false;
if (err) {
isResolverError = true;
responseResolver = "Name Resolve Error: " + (err.message || err)
responseResolver = "Name Resolve Error: " + (err.message || err);
} else {
responseResolver = path;
}
@ -157,101 +157,101 @@ class Storage extends React.Component {
render() {
return <React.Fragment>
{
!this.props.enabled ?
{this.props.enabled &&
<React.Fragment>
<Alert bsStyle="warning">The node you are using does not support IPFS. Please ensure <a
<Alert color="warning">The node you are using does not support IPFS. Please ensure <a
href="https://github.com/ipfs/js-ipfs-api#cors" target="_blank">CORS</a> is setup for the IPFS
node.</Alert>
</React.Fragment> : ''
}
{
this.state.storageError !== '' ?
<Alert bsStyle="danger">{this.state.storageError}</Alert>
: ''
}
</React.Fragment>}
{this.state.storageError !== '' &&
<Alert color="danger">{this.state.storageError}</Alert>}
<h3>Save text to storage</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.setText)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.setText)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
defaultValue={this.state.textToSave}
onChange={e => this.handleChange(e, 'textToSave')}/>
<Button bsStyle="primary" onClick={(e) => this.setText(e)}>Save Text</Button>
<HelpBlock>generated Hash: <span className="textHash">{this.state.generatedHash}</span></HelpBlock>
<Button color="primary" onClick={(e) => this.setText(e)}>Save Text</Button>
{this.state.generatedHash && <FormText>Generated Hash: <span className="textHash font-weight-bold">{this.state.generatedHash}</span></FormText>}
</FormGroup>
</Form>
<h3>Load text from storage given an hash</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.loadHash)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.loadHash)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
value={this.state.loadText}
onChange={e => this.handleChange(e, 'loadText')}/>
<Button bsStyle="primary" onClick={(e) => this.loadHash(e)}>Load</Button>
<HelpBlock>result: <span className="textHash">{this.state.storedText}</span></HelpBlock>
<Button color="primary" onClick={(e) => this.loadHash(e)}>Load</Button>
{this.state.storedText && <FormText>Result: <span className="textHash font-weight-bold">{this.state.storedText}</span></FormText>}
</FormGroup>
</Form>
<h3>Upload file to storage</h3>
<Form inline>
<Form>
<FormGroup>
<FormControl
<Input
type="file"
onChange={(e) => this.handleFileUpload(e)}/>
<Button bsStyle="primary" onClick={(e) => this.uploadFile(e)}>Upload</Button>
<HelpBlock>generated hash: <span className="fileHash">{this.state.fileHash}</span></HelpBlock>
<Button color="primary" onClick={(e) => this.uploadFile(e)} className="mt-2">Upload</Button>
{this.state.fileHash && <FormText>Generated hash: <span className="fileHash">{this.state.fileHash}</span></FormText>}
</FormGroup>
</Form>
<h3>Get file or image from storage</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.loadFile)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.loadFile)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
value={this.state.imageToDownload}
onChange={e => this.handleChange(e, 'imageToDownload')}/>
<Button bsStyle="primary" onClick={(e) => this.loadFile(e)}>Download</Button>
<HelpBlock>file available at: <span><a href={this.state.url}
target="_blank">{this.state.url}</a></span></HelpBlock>
<HelpBlock><img src={this.state.url}/></HelpBlock>
<Button color="primary" onClick={(e) => this.loadFile(e)}>Download</Button>
{this.state.url && <Fragment>
<FormText>
File available at: <span><a href={this.state.url} target="_blank">{this.state.url}</a></span>
</FormText>
<FormText><img alt="file image" src={this.state.url}/></FormText>
</Fragment>}
</FormGroup>
</Form>
{!this.isIpfs() && <Alert bsStyle="warning">The 2 functions below are only available with IPFS</Alert>}
{!this.isIpfs() && <Alert color="warning">The 2 functions below are only available with IPFS</Alert>}
<h3>Register to IPNS</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.ipnsRegister)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.ipnsRegister)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
value={this.state.valueRegister}
onChange={e => this.handleChange(e, 'valueRegister')}/>
<Button bsStyle="primary" onClick={(e) => this.ipnsRegister(e)}>
<Button color="primary" onClick={(e) => this.ipnsRegister(e)}>
{this.state.registering ? 'Registering...' : 'Register' }
</Button>
<HelpBlock>It will take around 1 minute</HelpBlock>
<FormText>It will take around 1 minute</FormText>
{this.state.responseRegister &&
<Alert className="alert-result" bsStyle={this.state.isRegisterError ? 'danger' : 'success'}>
<Alert className="alert-result" color={this.state.isRegisterError ? 'danger' : 'success'}>
<span className="value">{this.state.responseRegister}</span>
</Alert>}
</FormGroup>
</Form>
<h3>Resolve name</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.ipnsResolve)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.ipnsResolve)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
value={this.state.valueResolver}
onChange={e => this.handleChange(e, 'valueResolver')}/>
<Button bsStyle="primary" onClick={(e) => this.ipnsResolve(e)}>
<Button color="primary" onClick={(e) => this.ipnsResolve(e)}>
{this.state.resolving ? 'Resolving...' : 'Resolve' }
</Button>
<HelpBlock>It will take around 1 minute</HelpBlock>
<FormText>It will take around 1 minute</FormText>
{this.state.responseResolver &&
<Alert className="alert-result" bsStyle={this.state.isResolverError ? 'danger' : 'success'}>
<Alert className="alert-result" color={this.state.isResolverError ? 'danger' : 'success'}>
<span className="value">{this.state.responseResolver}</span>
</Alert>}
</FormGroup>

View File

@ -1,6 +1,6 @@
import EmbarkJS from 'Embark/EmbarkJS';
import React from 'react';
import {Alert, Form, FormGroup, FormControl, Button} from 'react-bootstrap';
import {Alert, Form, FormGroup, Input, Button, FormText} from 'reactstrap';
class Whisper extends React.Component {
@ -80,28 +80,25 @@ class Whisper extends React.Component {
return (
<React.Fragment>
{
!this.props.enabled ?
!this.props.enabled &&
<React.Fragment>
<Alert bsStyle="warning">The node you are using does not support Whisper</Alert>
<Alert bsStyle="warning">The node uses an unsupported version of Whisper</Alert>
</React.Fragment> : ''
}
<Alert color="warning">The node you are using does not support Whisper</Alert>
<Alert color="warning">The node uses an unsupported version of Whisper</Alert>
</React.Fragment>}
<h3>Listen To channel</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.listenToChannel)}>
<FormGroup>
<FormControl
<Form onKeyDown={(e) => this.checkEnter(e, this.listenToChannel)}>
<FormGroup className="inline-input-btn">
<Input
type="text"
defaultValue={this.state.listenTo}
placeholder="channel"
onChange={e => this.handleChange(e, 'listenTo')}/>
<Button disabled={!this.state.listenToChannelIsValid} bsStyle="primary" onClick={(e) => this.listenToChannel(e)}>Start Listening</Button>
{!this.state.listenToChannelIsValid && <p><span className="alert-danger">Channel has to be at least 4 characters long</span></p>}
<Button disabled={!this.state.listenToChannelIsValid} color="primary" onClick={(e) => this.listenToChannel(e)}>Start Listening</Button>
{!this.state.listenToChannelIsValid && <FormText color="danger">Channel has to be at least 4 characters long</FormText>}
<div id="subscribeList">
{this.state.subscribedChannels.map((item, i) => {
return <p key={i}><span>Subscribed to <b>{item}</b>. Now try sending a message</span></p>
})}
{this.state.subscribedChannels.map((item, i) => <p key={i}><span>Subscribed to <b>{item}</b>. Now try sending a message</span></p>)}
</div>
<p>messages received:</p>
<h5>Messages received:</h5>
<div id="messagesList">
{this.state.messageList.map((item, i) => <p key={i}>{item}</p>)}
</div>
@ -111,17 +108,20 @@ class Whisper extends React.Component {
<h3>Send Message</h3>
<Form inline onKeyDown={(e) => this.checkEnter(e, this.sendMessage)}>
<FormGroup>
<FormControl
<Input
type="text"
defaultValue={this.state.channel}
placeholder="channel"
onChange={e => this.handleChange(e, 'channel')}/>
<FormControl
<div className="inline-input-btn m-0">
<Input
type="text"
defaultValue={this.state.message}
placeholder="message"
onChange={e => this.handleChange(e, 'message')}/>
<Button bsStyle="primary" disabled={!this.state.channelIsValid} onClick={(e) => this.sendMessage(e)}>Send Message</Button>
<Button color="primary" disabled={!this.state.channelIsValid} onClick={(e) => this.sendMessage(e)}>Send
Message</Button>
</div>
</FormGroup>
</Form>

View File

@ -55,3 +55,19 @@ input.form-control {
.alert-result {
margin-left: 0;
}
.small-input {
width: 200px;
}
.inline-input-btn .form-control {
margin: 0;
width: 200px;
border-radius: 0.25rem 0 0 0.25rem;
float: left;
border-right: 0;
}
.inline-input-btn .btn {
border-radius: 0 0.25rem 0.25rem 0;
}

View File

@ -1,6 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {Tabs, Tab} from 'react-bootstrap';
import {TabContent, TabPane, Nav, NavItem, NavLink} from 'reactstrap';
import classnames from 'classnames';
import EmbarkJS from 'Embark/EmbarkJS';
import Blockchain from './components/blockchain';
@ -8,18 +9,16 @@ import Whisper from './components/whisper';
import Storage from './components/storage';
import ENS from './components/ens';
import 'bootstrap/dist/css/bootstrap.css';
import './dapp.css';
class App extends React.Component {
constructor(props) {
super(props);
this.handleSelect = this.handleSelect.bind(this);
this.state = {
error: null,
activeKey: 1,
activeKey: '1',
whisperEnabled: false,
storageEnabled: false,
blockchainEnabled: false
@ -63,28 +62,52 @@ class App extends React.Component {
const ensEnabled = EmbarkJS.Names.currentNameSystems && EmbarkJS.Names.isAvailable();
if (this.state.error) {
return (<div>
<div>Something went wrong connecting to ethereum. Please make sure you have a node running or are using metamask to connect to the ethereum network:</div>
<div>Something went wrong connecting to ethereum. Please make sure you have a node running or are using metamask
to connect to the ethereum network:
</div>
<div>{this.state.error}</div>
</div>);
}
return (<div>
<h3>Embark - Usage Example</h3>
<Tabs onSelect={this.handleSelect} activeKey={this.state.activeKey} id="uncontrolled-tab-example">
<Tab eventKey={1} title={this._renderStatus('Blockchain', this.state.blockchainEnabled)}>
<Nav tabs>
<NavItem>
<NavLink onClick={() => this.handleSelect('1')} className={classnames({ active: this.state.activeKey === '1' })}>
{this._renderStatus('Blockchain', this.state.blockchainEnabled)}
</NavLink>
</NavItem>
<NavItem>
<NavLink onClick={() => this.handleSelect('2')} className={classnames({ active: this.state.activeKey === '2' })}>
{this._renderStatus('Decentralized Storage', this.state.storageEnabled)}
</NavLink>
</NavItem>
<NavItem>
<NavLink onClick={() => this.handleSelect('3')} className={classnames({ active: this.state.activeKey === '3' })}>
{this._renderStatus('P2P communication (Whisper)', this.state.whisperEnabled)}
</NavLink>
</NavItem>
<NavItem>
<NavLink onClick={() => this.handleSelect('4')} className={classnames({ active: this.state.activeKey === '4' })}>
{this._renderStatus('Naming (ENS)', ensEnabled)}
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={this.state.activeKey}>
<TabPane tabId="1">
<Blockchain/>
</Tab>
<Tab eventKey={2} title={this._renderStatus('Decentralized Storage', this.state.storageEnabled)}>
</TabPane>
<TabPane tabId="2">
<Storage enabled={this.state.storageEnabled}/>
</Tab>
<Tab eventKey={3} title={this._renderStatus('P2P communication (Whisper)', this.state.whisperEnabled)}>
</TabPane>
<TabPane tabId="3">
<Whisper enabled={this.state.whisperEnabled}/>
</Tab>
<Tab eventKey={4} title={this._renderStatus('Naming (ENS)', ensEnabled)}>
</TabPane>
<TabPane tabId="4">
<ENS enabled={ensEnabled}/>
</Tab>
</Tabs>
</TabPane>
</TabContent>
</div>);
}
}
ReactDOM.render(<App></App>, document.getElementById('app'));
ReactDOM.render(<App/>, document.getElementById('app'));

View File

@ -1,7 +1,6 @@
<html>
<head>
<title>Embark - SimpleStorage Demo</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
</head>
<body class="container">
<div id="app">

View File

@ -34,11 +34,12 @@
},
"devDependencies": {
"bootstrap": "4.3.1",
"classnames": "2.2.6",
"embark": "^4.1.0",
"embark-reset": "^4.1.0",
"npm-run-all": "4.1.5",
"react": "16.7.0",
"react-bootstrap": "0.32.4",
"reactstrap": "8.0.1",
"react-dom": "16.7.0",
"rimraf": "3.0.0"
}

View File

@ -17715,6 +17715,21 @@ reactstrap@6.5.0, reactstrap@^6.5.0:
react-popper "^0.10.4"
react-transition-group "^2.3.1"
reactstrap@8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.0.1.tgz#0b663c8195f540bc1d6d5dbcbcf73cab56fe7c79"
integrity sha512-GvUWEL+a2+3npK1OxTXcNBMHXX4x6uc1KQRzK7yAOl+8sAHTRWqjunvMUfny3oDh8yKVzgqpqQlWWvs1B2HR9A==
dependencies:
"@babel/runtime" "^7.2.0"
classnames "^2.2.3"
lodash.isfunction "^3.0.9"
lodash.isobject "^3.0.2"
lodash.tonumber "^4.0.3"
prop-types "^15.5.8"
react-lifecycles-compat "^3.0.4"
react-popper "^1.3.3"
react-transition-group "^2.3.1"
read-cmd-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b"