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

View File

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

View File

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

View File

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

View File

@ -55,3 +55,19 @@ input.form-control {
.alert-result { .alert-result {
margin-left: 0; 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 React from 'react';
import ReactDOM from 'react-dom'; 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 EmbarkJS from 'Embark/EmbarkJS';
import Blockchain from './components/blockchain'; import Blockchain from './components/blockchain';
@ -8,18 +9,16 @@ import Whisper from './components/whisper';
import Storage from './components/storage'; import Storage from './components/storage';
import ENS from './components/ens'; import ENS from './components/ens';
import 'bootstrap/dist/css/bootstrap.css';
import './dapp.css'; import './dapp.css';
class App extends React.Component { class App extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleSelect = this.handleSelect.bind(this);
this.state = { this.state = {
error: null, error: null,
activeKey: 1, activeKey: '1',
whisperEnabled: false, whisperEnabled: false,
storageEnabled: false, storageEnabled: false,
blockchainEnabled: false blockchainEnabled: false
@ -56,35 +55,59 @@ class App extends React.Component {
} }
handleSelect(key) { handleSelect(key) {
this.setState({ activeKey: key }); this.setState({activeKey: key});
} }
render() { render() {
const ensEnabled = EmbarkJS.Names.currentNameSystems && EmbarkJS.Names.isAvailable(); const ensEnabled = EmbarkJS.Names.currentNameSystems && EmbarkJS.Names.isAvailable();
if (this.state.error) { if (this.state.error) {
return (<div> 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>{this.state.error}</div>
</div>); </div>);
} }
return (<div> return (<div>
<h3>Embark - Usage Example</h3> <h3>Embark - Usage Example</h3>
<Tabs onSelect={this.handleSelect} activeKey={this.state.activeKey} id="uncontrolled-tab-example"> <Nav tabs>
<Tab eventKey={1} title={this._renderStatus('Blockchain', this.state.blockchainEnabled)}> <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/> <Blockchain/>
</Tab> </TabPane>
<Tab eventKey={2} title={this._renderStatus('Decentralized Storage', this.state.storageEnabled)}> <TabPane tabId="2">
<Storage enabled={this.state.storageEnabled}/> <Storage enabled={this.state.storageEnabled}/>
</Tab> </TabPane>
<Tab eventKey={3} title={this._renderStatus('P2P communication (Whisper)', this.state.whisperEnabled)}> <TabPane tabId="3">
<Whisper enabled={this.state.whisperEnabled}/> <Whisper enabled={this.state.whisperEnabled}/>
</Tab> </TabPane>
<Tab eventKey={4} title={this._renderStatus('Naming (ENS)', ensEnabled)}> <TabPane tabId="4">
<ENS enabled={ensEnabled}/> <ENS enabled={ensEnabled}/>
</Tab> </TabPane>
</Tabs> </TabContent>
</div>); </div>);
} }
} }
ReactDOM.render(<App></App>, document.getElementById('app')); ReactDOM.render(<App/>, document.getElementById('app'));

View File

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

View File

@ -34,11 +34,12 @@
}, },
"devDependencies": { "devDependencies": {
"bootstrap": "4.3.1", "bootstrap": "4.3.1",
"classnames": "2.2.6",
"embark": "^4.1.0", "embark": "^4.1.0",
"embark-reset": "^4.1.0", "embark-reset": "^4.1.0",
"npm-run-all": "4.1.5", "npm-run-all": "4.1.5",
"react": "16.7.0", "react": "16.7.0",
"react-bootstrap": "0.32.4", "reactstrap": "8.0.1",
"react-dom": "16.7.0", "react-dom": "16.7.0",
"rimraf": "3.0.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-popper "^0.10.4"
react-transition-group "^2.3.1" 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: read-cmd-shim@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b"