-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Display vouched overlay on dapps #6710
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"constant":true,"inputs":[],"name":"certifier","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_what","type":"bytes32"}],"name":"vouch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_what","type":"bytes32"},{"name":"_index","type":"uint256"}],"name":"vouched","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_what","type":"bytes32"},{"name":"_index","type":"uint256"}],"name":"unvouch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"uint256"}],"name":"vouchers","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_certifier","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"who","type":"address"},{"indexed":false,"name":"what","type":"bytes32"}],"name":"Vouched","type":"event"}] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
/* This file is part of Parity. | ||
/* | ||
/* Parity is free software: you can redistribute it and/or modify | ||
/* it under the terms of the GNU General Public License as published by | ||
/* the Free Software Foundation, either version 3 of the License, or | ||
/* (at your option) any later version. | ||
/* | ||
/* Parity is distributed in the hope that it will be useful, | ||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
/* GNU General Public License for more details. | ||
/* | ||
/* You should have received a copy of the GNU General Public License | ||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
.tag { | ||
color: inherit; | ||
position: absolute; | ||
top: 1em; | ||
right: 1em; | ||
|
||
.image { | ||
position: absolute; | ||
right: 0; | ||
top: 0; | ||
width: 32px; | ||
height: 32px; | ||
} | ||
|
||
.bubble { | ||
background: red; | ||
border-radius: 0.25em; | ||
color: white; | ||
font-size: 0.75em; | ||
padding: 0.1em 0.5em; | ||
position: absolute; | ||
right: 0; | ||
top: 0; | ||
z-index: 100; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
// This file is part of Parity. | ||
|
||
// Parity is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Parity is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
import React, { Component, PropTypes } from 'react'; | ||
import { observer } from 'mobx-react'; | ||
|
||
import IdentityIcon from '../IdentityIcon'; | ||
|
||
import Store from './store'; | ||
import styles from './dappVouchFor.css'; | ||
|
||
@observer | ||
export default class DappVouchFor extends Component { | ||
static contextTypes = { | ||
api: PropTypes.object.isRequired | ||
}; | ||
|
||
static propTypes = { | ||
app: PropTypes.object.isRequired | ||
}; | ||
|
||
store = new Store(this.context.api, this.props.app); | ||
|
||
render () { | ||
const count = this.store.vouchers.length; | ||
|
||
if (!count) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<div className={ styles.tag }> | ||
<IdentityIcon | ||
address={ this.store.vouchers[0] } | ||
className={ styles.image } | ||
alt={ `${count} identities vouch for this dapp` } | ||
/> | ||
<div className={ styles.bubble }> | ||
{ count } | ||
</div> | ||
</div> | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
// This file is part of Parity. | ||
|
||
// Parity is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Parity is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
export default from './dappVouchFor'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2015-2017 Parity Technologies (UK) Ltd. | ||
// This file is part of Parity. | ||
|
||
// Parity is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Parity is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Parity. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
import { action, observable } from 'mobx'; | ||
import { uniq } from 'lodash'; | ||
|
||
import Contracts from '~/contracts'; | ||
import { vouchfor as vouchForAbi } from '~/contracts/abi'; | ||
|
||
export default class Store { | ||
@observable vouchers = []; | ||
|
||
constructor (api, app) { | ||
this._api = api; | ||
this._app = app; | ||
|
||
Contracts | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That won't really work in case of re-connection or dynamic change, but I supposed we don't need that for initial PoC. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 100%, added to list of next PR cleanups. |
||
.get().registry | ||
.lookupAddress('vouchfor') | ||
.then((address) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not write everything as
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tried it, eslint didn't like that approach at all. (But probably due to the fact that I mixed promises/async as I still do here instead of fully async function). Good point, added to the list of cleanups. |
||
if (!address || /^0x0*$/.test(address)) { | ||
return null; | ||
} | ||
|
||
return api.newContract(vouchForAbi, address); | ||
}) | ||
.then(async (contract) => { | ||
const { contentHash } = app; | ||
|
||
if (!contentHash) { | ||
return; | ||
} | ||
|
||
let lastItem = false; | ||
|
||
for (let index = 0; !lastItem; index++) { | ||
const voucher = await contract.instance.vouched.call({}, [`0x${contentHash}`, index]); | ||
|
||
if (/^0x0*$/.test(voucher)) { | ||
lastItem = true; | ||
} else { | ||
this.addVoucher(voucher); | ||
} | ||
} | ||
}) | ||
.catch((error) => { | ||
console.error('vouchFor', error); | ||
|
||
return null; | ||
}); | ||
} | ||
|
||
@action addVoucher = (voucher) => { | ||
this.vouchers = uniq([].concat(this.vouchers.peek(), [voucher])); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MobX idisyncracy - arrays are actually objects, .peek() returns the actual observed array. If no peek, basically it concats an object. |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I'm pretty sure it will lead to a broken behaviour.
The component instance can be re-used by react and just receive new props, should re-initialize
Store
oncomponentWillReceiveProps
if we want to do it right.(side note: it will also do some excessive calls for each dapp, might be worth to only limit it to network dapps?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. It is not optimal usage-wise atm, that will make it better for at least the intial version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: added only for apps where we have an actual contentHash