1
0
mirror of https://github.com/dap-ps/discover.git synced 2025-02-24 23:18:19 +00:00

vote learn more links

This commit is contained in:
Kamen Stoykov 2019-05-31 18:21:11 +03:00
parent 1069143140
commit 7ba65c13e7
13 changed files with 356 additions and 765 deletions

Binary file not shown.

After

(image error) Size: 70 KiB

@ -1,633 +0,0 @@
import * as Categories from './categories'
const Dapps = [
{
metadata: {
name: 'Airswap',
url: 'https://instant.airswap.io/',
image: '/images/dapps/airswap.png',
description: 'Meet the future of trading',
category: Categories.EXCHANGES,
dateAdded: '2019-05-05',
categoryPosition: 13,
},
rate: 45,
},
{
metadata: {
name: 'Bancor',
url: 'https://www.bancor.network/',
image: '/images/dapps/bancor.png',
description: 'Bancor is a decentralized liquidity network',
category: Categories.EXCHANGES,
dateAdded: '2019-03-05',
categoryPosition: 12,
},
rate: 345,
},
{
metadata: {
name: 'Kyber',
url: 'https://web3.kyber.network',
description:
'On-chain, instant and liquid platform for exchange and payment',
image: '/images/dapps/kyber.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 11,
},
rate: 2345,
},
{
metadata: {
name: 'Uniswap',
url: 'https://uniswap.exchange/',
description:
'Seamlessly exchange ERC20 tokens, or use a formalized model to pool liquidity reserves',
image: '/images/dapps/uniswap.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-23',
categoryPosition: 10,
},
rate: 12345,
},
{
metadata: {
name: 'DAI by MakerDao',
url: 'https://dai.makerdao.com',
description: 'Stability for the blockchain',
image: '/images/dapps/dai.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 9,
},
rate: 22345,
},
{
metadata: {
name: 'Augur',
url: 'https://augur.net',
description:
'A prediction market protocol owned and operated by the people that use it',
image: '/images/dapps/augur.svg',
category: Categories.EXCHANGES,
dateAdded: '2019-04-11',
categoryPosition: 8,
},
rate: 32345,
},
{
metadata: {
name: 'LocalEthereum',
url: 'https://localethereum.com/',
description: 'The smartest way to buy and sell Ether',
image: '/images/dapps/local-ethereum.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 7,
},
rate: 42345,
},
{
metadata: {
name: 'Eth2phone',
url: 'https://eth2.io',
description: 'Send Ether by phone number',
image: '/images/dapps/eth2phone.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 6,
},
rate: 52345,
},
{
metadata: {
name: 'DDEX',
url: 'https://ddex.io/',
description:
'Instant, real-time order matching with secure on-chain settlement',
image: '/images/dapps/ddex.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 5,
},
rate: 62345,
},
{
metadata: {
name: 'Nuo',
url: 'https://app.nuo.network/lend/',
description:
'The non-custodial way to lend, borrow or margin trade cryptocurrency',
image: '/images/dapps/nuo.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 4,
},
rate: 72345,
},
{
metadata: {
name: 'EasyTrade',
url: 'https://easytrade.io',
description: 'One exchange for every token',
image: '/images/dapps/easytrade.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 3,
},
rate: 82345,
},
{
metadata: {
name: 'slow.trade',
url: 'https://slow.trade/',
description:
'Trade fairly priced crypto assets on the first platform built with the DutchX protocol',
image: '/images/dapps/slowtrade.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 92345,
},
{
metadata: {
name: 'Expo Trading',
url: 'https://expotrading.com/trade/',
description: 'The simplest way to margin trade cryptocurrency',
image: '/images/dapps/expotrading.png',
category: Categories.EXCHANGES,
dateAdded: '2019-04-11',
categoryPosition: 1,
},
rate: 102345,
},
{
metadata: {
name: 'Bidali',
url: 'https://commerce.bidali.com/dapp',
description: 'Buy from top brands with crypto',
image: '/images/dapps/bidali.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-05-01',
},
rate: 10246,
},
{
metadata: {
name: 'blockimmo',
url: 'https://blockimmo.ch',
description:
'blockimmo is a blockchain powered, regulated platform enabling shared property investments and ownership',
image: '/images/dapps/blockimmo.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'CryptoCribs',
url: 'https://cryptocribs.com',
description: 'Travel the globe. Pay in crypto',
image: '/images/dapps/cryptocribs.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Ethlance',
url: 'https://ethlance.com',
description:
'The future of work is now. Hire people or work yourself in return for ETH',
image: '/images/dapps/ethlance.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'OpenSea',
url: 'https://opensea.io',
description: 'The largest decentralized marketplace for cryptogoods',
image: '/images/dapps/opensea.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'KnownOrigin',
url: 'https://dapp.knownorigin.io/gallery',
description: 'Discover, buy and collect digital artwork',
image: '/images/dapps/knownorigin.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'dBay',
url: 'https://dbay.ai',
description: 'Buy from all your favorite DApps in one place',
image: '/images/dapps/dBay.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-23',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Name Bazaar',
url: 'https://namebazaar.io',
description: 'ENS name marketplace',
image: '/images/dapps/name-bazaar.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'The Bounties Network',
url: 'https://bounties.network/',
description: 'Bounties on any task, paid in any token',
image: '/images/dapps/bounties-network.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Emoon',
url: 'https://www.emoon.io/',
description:
'A decentralized marketplace for buying & selling crypto assets',
image: '/images/dapps/emoon.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Astro Ledger',
url: 'https://www.astroledger.org/#/onSale',
description: 'Funding space grants with blockchain star naming',
image: '/images/dapps/astroledger.svg',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'SuperRare',
url: 'https://superrare.co/market',
description:
'Buy, sell and collect unique digital creations by artists around the world',
image: '/images/dapps/superrare.png',
category: Categories.MARKETPLACES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'CryptoCare',
url: 'https://cryptocare.tech',
description:
'Give your Ether some heart! Collectibles that make the world a better place',
image: '/images/dapps/cryptocare.jpg',
category: Categories.COLLECTIBLES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'CryptoKitties',
url: 'https://www.cryptokitties.co',
description: 'Collect and breed adorable digital cats',
image: '/images/dapps/cryptokitties.png',
category: Categories.COLLECTIBLES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Cryptographics',
url: 'https://cryptographics.app/',
description:
'A digital art hub for creation, trading, and collecting unique items',
image: '/images/dapps/cryptographics.png',
category: Categories.COLLECTIBLES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'CryptoPunks',
url: 'https://www.larvalabs.com/cryptopunks',
description: '10,000 unique collectible punks',
image: '/images/dapps/cryptopunks.png',
category: Categories.COLLECTIBLES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Crypto Takeovers',
url: 'https://cryptotakeovers.com/',
description: 'Predict and conquer the world. Make a crypto fortune',
image: '/images/dapps/cryptotakeovers.png',
category: Categories.GAMES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'CryptoFighters',
url: 'https://cryptofighters.io',
description: 'Collect train and fight digital fighters',
image: '/images/dapps/cryptofighters.png',
category: Categories.GAMES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Decentraland',
url: 'https://market.decentraland.org/',
description:
'A virtual reality platform powered by the Ethereum blockchain',
image: '/images/dapps/decentraland.png',
category: Categories.GAMES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Dragonereum',
url: 'https://dapp.dragonereum.io',
description: 'Own and trade dragons, fight with other players',
image: '/images/dapps/dragonereum.png',
category: Categories.GAMES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Etherbots',
url: 'https://etherbots.io/',
description: 'Robot wars on Ethereum',
image: '/images/dapps/etherbots.png',
category: Categories.GAMES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Etheremon',
url: 'https://www.etheremon.com/',
description: 'Decentralized World of Ether Monsters',
image: '/images/dapps/etheremon.png',
category: Categories.GAMES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'CryptoStrikers',
url: 'https://www.cryptostrikers.com/',
description: 'The Beautiful (card) Game',
image: '/images/dapps/cryptostrikers.png',
category: Categories.GAMES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
// {
// metadata: {
// name: 'FairHouse',
// url: 'https://fairhouse.io',
// description: 'Fair and transparent entertainment games.',
// image: '/images/dapps/fairhouse.png',
// category: Categories.GAMES,
// dateAdded: '2019-04-11',
// categoryPosition: 2,
// },
// rate: 12345,
// },
{
metadata: {
name: 'Cent',
url: 'https://beta.cent.co/',
description: 'Get wisdom, get money',
image: '/images/dapps/cent.png',
category: Categories.SOCIAL_NETWORKS,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Kickback',
url: 'https://kickback.events/',
description:
'Event no shows? No problem. Kickback asks event attendees to put skin in the game with Ethereum',
image: '/images/dapps/kickback.png',
category: Categories.SOCIAL_NETWORKS,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Peepeth',
url: 'https://peepeth.com/',
description: 'Blockchain-powered microblogging',
image: '/images/dapps/peepeth.png',
category: Categories.SOCIAL_NETWORKS,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'livepeer.tv',
url: 'http://livepeer.tv/',
description: 'Decentralized video broadcasting',
image: '/images/dapps/livepeer.png',
category: Categories.OTHER,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Aragon',
url: 'https://mainnet.aragon.org/',
description: 'Build unstoppable organizations on Ethereum',
image: '/images/dapps/aragon.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Compound Finance',
url: 'https://app.compound.finance/',
description:
'An open-source protocol for algorithmic, efficient Money Markets on Ethereum',
image: '/images/dapps/compoundfinance.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'InstaDApp',
url: 'https://instadapp.io/',
description: 'Decentralized Banking',
image: '/images/dapps/instadapp.jpg',
category: Categories.UTILITIES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Livepeer',
url: 'https://explorer.livepeer.org/',
description: 'Decentralized video broadcasting',
image: '/images/dapps/livepeer.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'ETHLend',
url: 'https://app.ethlend.io',
description: 'Decentralized lending on Ethereum',
image: '/images/dapps/ethlend.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Civitas',
url: 'https://communities.colu.com/',
description: 'Blockchain-powered local communities',
image: '/images/dapps/civitas.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: '3Box',
url: 'https://3box.io/',
description: 'Create and manage your Ethereum Profile',
image: '/images/dapps/3Box.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Hexel',
url: 'https://www.onhexel.com/',
description: 'Create your own cryptocurrency',
image: '/images/dapps/hexel.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-11',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'Smartz',
url: 'https://smartz.io',
description: 'Easy smart contract management',
image: '/images/dapps/smartz.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
{
metadata: {
name: 'SNT Voting DApp',
url: 'https://vote.status.im',
description:
'Let your SNT be heard! Vote on decisions exclusive to SNT holders, or create a poll of your own.',
image: '/images/dapps/snt-voting.png',
category: Categories.UTILITIES,
dateAdded: '2019-04-05',
categoryPosition: 2,
},
rate: 12345,
},
]
export default Dapps

@ -4,6 +4,8 @@ const vote = {
isUpvote: false,
sntValue: '0',
afterVoteRating: null,
learnMoreUpVote: false,
learnMoreDownVote: false,
}
export default vote

@ -3,11 +3,13 @@ import { withRouter } from 'react-router-dom'
import Profile from './Profile'
import { showWithdrawAction } from '../Withdraw/Withdraw.reducer'
import { showSubmitAction } from '../Submit/Submit.reducer';
const mapStateToProps = state => ({ dappState: state.dapps })
const mapDispatchToProps = dispatch => ({
onClickWithdraw: dapp => dispatch(showWithdrawAction(dapp)),
onClickUpdateMetadata: dapp => dispatch(showSubmitAction(dapp)),
})
export default withRouter(

@ -17,6 +17,7 @@ const ProfileContent = ({
highestRankedPosition,
categoryPosition,
onClickWithdraw,
onClickUpdateMetadata,
}) => {
return (
<>
@ -83,7 +84,7 @@ const ProfileContent = ({
</div>
</div>
<div className={styles.actions}>
<div className={styles.button}>
<div className={styles.button} onClick={onClickUpdateMetadata}>
Edit metadata
</div>
<div className={styles.button} onClick={onClickWithdraw}>
@ -114,6 +115,14 @@ class Profile extends Component {
}, 1)
}
onClickUpdateMetadata(dapp) {
const { onClickUpdateMetadata } = this.props
this.onClickClose()
setTimeout(() => {
onClickUpdateMetadata(dapp)
}, 1)
}
render() {
const { match, dappState } = this.props
const { dapps } = dappState
@ -151,7 +160,8 @@ class Profile extends Component {
<ProfileContent {...dapp}
highestRankedPosition={highestRankedPosition}
categoryPosition={categoryPosition}
onClickWithdraw={this.onClickWithdraw.bind(this, dapp)} />
onClickWithdraw={this.onClickWithdraw.bind(this, dapp)}
onClickUpdateMetadata={this.onClickUpdateMetadata.bind(this, dapp)} />
</Modal>
)
}
@ -160,6 +170,7 @@ class Profile extends Component {
Profile.propTypes = {
dappState: PropTypes.instanceOf(DappState),
onClickWithdraw: PropTypes.func.isRequired,
onClickUpdateMetadata: PropTypes.func.isRequired,
}
export default Profile

@ -17,6 +17,7 @@ import {
submitAction,
switchToRatingAction,
onInputSntValueAction,
updateAction,
} from './Submit.reducer'
const mapStateToProps = state =>
@ -33,6 +34,7 @@ const mapDispatchToProps = dispatch => ({
onImgCancel: () => dispatch(onImgCancelAction()),
onImgDone: imgBase64 => dispatch(onImgDoneAction(imgBase64)),
onSubmit: (dapp, sntValue) => dispatch(submitAction(dapp, sntValue)),
onUpdate: (dappId, metadata) => dispatch(updateAction(dappId, metadata)),
onClickTerms: () => dispatch(push('/terms')),
switchToRating: () => dispatch(switchToRatingAction()),
onInputSntValue: sntValue => dispatch(onInputSntValueAction(sntValue)),

@ -151,8 +151,8 @@ class Submit extends React.Component {
}
onSubmit() {
const { onSubmit, name, desc, url, img, category, sntValue } = this.props
const dapp = {
const { onSubmit, onUpdate, id, name, desc, url, img, category, sntValue } = this.props
const metadata = {
name,
url,
img,
@ -160,7 +160,10 @@ class Submit extends React.Component {
desc,
}
onSubmit(dapp, parseInt(sntValue, 10))
if (id === '')
onSubmit(metadata, parseInt(sntValue, 10))
else
onUpdate(id, metadata)
}
handleSNTChange(e) {
@ -187,6 +190,7 @@ class Submit extends React.Component {
visible_submit,
visible_rating,
onClickClose,
id,
name,
desc,
url,
@ -316,7 +320,7 @@ class Submit extends React.Component {
className={styles.submitButton}
type="submit"
disabled={!canSubmit}
onClick={switchToRating}
onClick={id === '' ? switchToRating : this.onSubmit}
>
Continue
</button>
@ -468,6 +472,7 @@ Submit.propTypes = {
onImgCancel: PropTypes.func.isRequired,
onImgDone: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
onUpdate: PropTypes.func.isRequired,
onInputSntValue: PropTypes.func.isRequired,
onClickTerms: PropTypes.func.isRequired,
switchToRating: PropTypes.func.isRequired,

@ -6,7 +6,7 @@ import {
onStartProgressAction,
hideAction,
} from '../TransactionStatus/TransactionStatus.recuder'
import { TYPE_SUBMIT } from '../TransactionStatus/TransactionStatus.utilities'
import { TYPE_SUBMIT, TYPE_UPDATE } from '../TransactionStatus/TransactionStatus.utilities'
import { showAlertAction } from '../Alert/Alert.reducer'
import BlockchainSDK from '../../common/blockchain'
@ -27,15 +27,15 @@ const ON_IMG_DONE = 'SUBMIT_ON_IMG_DONE'
const SWITCH_TO_RATING = 'SUBMIT_SWITCH_TO_RATING'
const ON_INPUT_SNT_VALUE = 'SUBMIT_ON_INPUT_SNT_VALUE'
export const showSubmitActionAfterCheck = () => {
const showSubmitAfterCheckAction = dapp => {
window.location.hash = 'submit'
return {
type: SHOW_SUBMIT_AFTER_CHECK,
payload: null,
payload: dapp,
}
}
export const showSubmitAction = () => {
export const showSubmitAction = dapp => {
return (dispatch, getState) => {
const state = getState()
if (
@ -47,7 +47,26 @@ export const showSubmitAction = () => {
'There is an active transaction. Please wait for it to finish and then you could be able to create your Ðapp',
),
)
} else dispatch(showSubmitActionAfterCheck())
} else if (dapp !== undefined) {
// convert dapp's image from url ot base64
const toDataUrl = (url, callback) => {
const xhr = new XMLHttpRequest()
xhr.onload = () => {
const reader = new FileReader()
reader.onloadend = () => {
callback(reader.result)
}
reader.readAsDataURL(xhr.response)
}
xhr.open('GET', url)
xhr.responseType = 'blob'
xhr.send()
}
toDataUrl(dapp.image, base64 => {
dapp.image = base64
dispatch(showSubmitAfterCheckAction(dapp))
})
} else dispatch(showSubmitAfterCheckAction(dapp))
}
}
@ -138,6 +157,29 @@ export const submitAction = (dapp, sntValue) => {
}
}
export const updateAction = (dappId, metadata) => {
return async dispatch => {
dispatch(closeSubmitAction())
dispatch(
onStartProgressAction(
metadata.name,
metadata.img,
'Status is an open source mobile DApp browser and messenger build for #Etherium',
TYPE_UPDATE,
),
)
try {
const blockchain = await BlockchainSDK.getInstance()
const tx = await blockchain.DiscoverService.setMetadata(dappId, metadata)
dispatch(onReceiveTransactionInfoAction(dappId, tx))
dispatch(checkTransactionStatusAction(tx))
} catch (e) {
dispatch(hideAction())
dispatch(showAlertAction(e.message))
}
}
}
export const switchToRatingAction = () => ({
type: SWITCH_TO_RATING,
paylaod: null,
@ -148,16 +190,16 @@ export const onInputSntValueAction = sntValue => ({
payload: sntValue,
})
const showSubmitAfterCheck = state => {
const showSubmitAfterCheck = (state, dapp) => {
return Object.assign({}, state, {
visible_submit: true,
visible_rating: false,
id: '',
name: '',
desc: '',
url: '',
img: '',
category: '',
id: dapp !== undefined ? dapp.id : '',
name: dapp !== undefined ? dapp.name : '',
desc: dapp !== undefined ? dapp.desc : '',
url: dapp !== undefined ? dapp.url : '',
img: dapp !== undefined ? dapp.image : '',
category: dapp !== undefined ? dapp.category : '',
imgControl: false,
imgControlZoom: 0,
imgControlMove: false,

@ -5,6 +5,7 @@ export const TYPE_SUBMIT = 1
export const TYPE_UPVOTE = 2
export const TYPE_DOWNVOTE = 3
export const TYPE_WITHDRAW = 4
export const TYPE_UPDATE = 5
class TransactionStatus {
constructor() {

@ -9,6 +9,9 @@ import {
fetchVoteRatingAction,
upVoteAction,
downVoteAction,
learnMoreUpVoteAction,
learnMoreDownVoteAction,
closeLearnMoreAction,
} from './Vote.reducer'
const mapStateToProps = state =>
@ -23,6 +26,9 @@ const mapDispatchToProps = dispatch => ({
},
upVote: (dapp, amount) => dispatch(upVoteAction(dapp, amount)),
downVote: (dapp, amount) => dispatch(downVoteAction(dapp, amount)),
onClickLearnMoreUpVote: () => dispatch(learnMoreUpVoteAction()),
onClickLearnMoreDownVote: () => dispatch(learnMoreDownVoteAction()),
onClickCloseLearnMore: () => dispatch(closeLearnMoreAction())
})
export default withRouter(

@ -63,6 +63,11 @@ class Vote extends Component {
dappState,
sntValue,
afterVoteRating,
learnMoreUpVote,
learnMoreDownVote,
onClickLearnMoreUpVote,
onClickLearnMoreDownVote,
onClickCloseLearnMore,
} = this.props
if (dapp === null) {
@ -99,123 +104,159 @@ class Vote extends Component {
windowClassName={styles.modalWindow}
contentClassName={styles.modalContent}
>
<div className={styles.tabs}>
<button
className={isUpvote ? styles.active : ''}
type="button"
onClick={this.onClickUpvote}
>
UPVOTE
</button>
<button
className={!isUpvote ? styles.active : ''}
type="button"
onClick={this.onClickDownvote}
>
DOWNVOTE
</button>
</div>
<div className={styles.dapp}>
<ReactImageFallback
className={styles.image}
src={dapp.image}
fallbackImage={icon}
alt="App icon"
width={24}
height={24}
/>
{dapp.name}
</div>
<div className={styles.items}>
<div className={styles.itemRow}>
<span className={styles.item}>
<img src={sntIcon} alt="SNT" width="24" height="24" />
{currentSNTamount.toLocaleString()}
</span>
{isUpvote && afterVoteRating !== null && (
<span className={styles.greenBadge}>
{`${(dapp.sntValue + afterVoteRating).toLocaleString()}`}
</span>
)}
{!isUpvote && afterVoteRating !== null && (
<span className={styles.redBadge}>
{`${(dapp.sntValue - afterVoteRating).toLocaleString()}`}
</span>
)}
{(!learnMoreUpVote && !learnMoreDownVote && (
<>
<div className={styles.tabs}>
<button
className={isUpvote ? styles.active : ''}
type="button"
onClick={this.onClickUpvote}
>
UPVOTE
</button>
<button
className={!isUpvote ? styles.active : ''}
type="button"
onClick={this.onClickDownvote}
>
DOWNVOTE
</button>
</div>
<div className={styles.itemRow}>
<span className={styles.item}>
<img
src={CategoriesUtils(dapp.category)}
alt={getCategoryName(dapp.category)}
width="24"
height="24"
/>
{`${getCategoryName(dapp.category)}${catPosition}`}
</span>
{isUpvote &&
afterVoteCategoryPosition !== null &&
afterVoteCategoryPosition !== catPosition && (
<span className={styles.greenBadge}>
{`${afterVoteCategoryPosition}`}
</span>
)}
{!isUpvote &&
afterVoteCategoryPosition !== null &&
afterVoteCategoryPosition !== catPosition && (
<span className={styles.redBadge}>
{`${afterVoteCategoryPosition}`}
</span>
)}
</div>
</div>
{!isUpvote && (
<div
className={styles.inputArea}
style={{ opacity: sntValue !== '0' ? 1 : 0 }}
>
<span>{sntValue}</span>
</div>
)}
{isUpvote && (
<div className={`${styles.inputArea} ${styles.inputAreaBorder}`}>
<input
type="text"
value={sntValue}
onChange={this.handleChange}
style={{ width: `${21 * Math.max(1, sntValue.length)}px` }}
<div className={styles.dapp}>
<ReactImageFallback
className={styles.image}
src={dapp.image}
fallbackImage={icon}
alt="App icon"
width={24}
height={24}
/>
{dapp.name}
</div>
<div className={styles.items}>
<div className={styles.itemRow}>
<span className={styles.item}>
<img src={sntIcon} alt="SNT" width="24" height="24" />
{currentSNTamount.toLocaleString()}
</span>
{isUpvote && afterVoteRating !== null && (
<span className={styles.greenBadge}>
{`${(dapp.sntValue + afterVoteRating).toLocaleString()}`}
</span>
)}
{!isUpvote && afterVoteRating !== null && (
<span className={styles.redBadge}>
{`${(dapp.sntValue - afterVoteRating).toLocaleString()}`}
</span>
)}
</div>
<div className={styles.itemRow}>
<span className={styles.item}>
<img
src={CategoriesUtils(dapp.category)}
alt={getCategoryName(dapp.category)}
width="24"
height="24"
/>
{`${getCategoryName(dapp.category)}${catPosition}`}
</span>
{isUpvote &&
afterVoteCategoryPosition !== null &&
afterVoteCategoryPosition !== catPosition && (
<span className={styles.greenBadge}>
{`${afterVoteCategoryPosition}`}
</span>
)}
{!isUpvote &&
afterVoteCategoryPosition !== null &&
afterVoteCategoryPosition !== catPosition && (
<span className={styles.redBadge}>
{`${afterVoteCategoryPosition}`}
</span>
)}
</div>
</div>
{!isUpvote && (
<div
className={styles.inputArea}
style={{ opacity: sntValue !== '0' ? 1 : 0 }}
>
<span>{sntValue}</span>
</div>
)}
{isUpvote && (
<div className={`${styles.inputArea} ${styles.inputAreaBorder}`}>
<input
type="text"
value={sntValue}
onChange={this.handleChange}
style={{ width: `${21 * Math.max(1, sntValue.length)}px` }}
/>
</div>
)}
<div className={styles.footer}>
{isUpvote && (
<p className={styles.disclaimer}>
SNT you spend to upvote is locked in the contract and contributes
directly to {dapp.name}'s ranking.{' '}
<a onClick={onClickLearnMoreUpVote}>
Learn more
</a>
</p>
)}
{!isUpvote && (
<p className={styles.disclaimer}>
SNT you spend to downvote goes directly back to {dapp.name}.
Downvoting moves their DApp down by 1% of the current ranking. The
cost is fixed by our unique bonded curve.{' '}
<a onClick={onClickLearnMoreDownVote}>
Learn more
</a>
</p>
)}
<button
type="submit"
disabled={(!sntValue || sntValue === '0') && isUpvote}
onClick={this.onClickVote}
>
{isUpvote ? 'Upvote' : 'Downvote'}
</button>
</div>
</>
))}
{learnMoreUpVote && (
<div className={styles.learnMoreCnt}>
<div className={styles.title}>How to submit a ÐApp</div>
<div className={styles.spacing}>
<img src='/images/learn-more-curve.png' />
<p>This is what the curve you're using really looks like. The more SNT staked on a DApp, the cheaper it becomes for anyone to downvote it.</p>
<p>However, you can upvote this DApp by any amount of SNT you wish. SNT you spend is sent directly to the contract and locked up there. It does not</p>
<p>go to Status, the developer of the DApp, or any other middleman. There are no fees, but once the SNT is spent, you cannot get it back.</p>
<p>What you spend is added directly to the DApp's balance, and the effect this will have on it's ranking is shown in the previous screen.</p>
<p>Welcome to the future of decentralised curation!</p>
</div>
<div className={styles.backButtonCnt}>
<button type="submit" onClick={onClickCloseLearnMore} className={styles.backButton}>Back</button>
</div>
</div>
)}
{learnMoreDownVote && (
<div className={styles.learnMoreCnt}>
<div className={styles.title}>How to submit a ÐApp</div>
<div className={styles.spacing}>
<img src='/images/learn-more-curve.png' />
<p>This is what the curve you're using really looks like. The more SNT staked on a DApp, the cheaper it becomes for anyone to downvote it.</p>
<p>You can downvote this DApp, and each downvote will move it 1% of its current value down the rankings. </p>
<p>SNT you spend is sent directly to the developer of the DApp, so we can be sure you aren't just trolling them and that, even if you are, you are required to pay for the privilege. It does not go to Status or any other middleman. There are no fees, but once the SNT is spent, you cannot get it back.</p>
<p>What you spend is dictated by how much SNT the DApp has already staked, and the exact numerical effect of moving 1% down in the rankings is shown in the previous screen.</p>
<p>Welcome to the future of decentralised curation!</p>
</div>
<div className={styles.backButtonCnt}>
<button type="submit" onClick={onClickCloseLearnMore} className={styles.backButton}>Back</button>
</div>
</div>
)}
<div className={styles.footer}>
{isUpvote && (
<p className={styles.disclaimer}>
SNT you spend to upvote is locked in the contract and contributes
directly to {dapp.name}'s ranking.{' '}
<a href="#" target="_blank">
Learn more
</a>
</p>
)}
{!isUpvote && (
<p className={styles.disclaimer}>
SNT you spend to downvote goes directly back to {dapp.name}.
Downvoting moves their DApp down by 1% of the current ranking. The
cost is fixed by our unique bonded curve.{' '}
<a href="#" target="_blank">
Learn more
</a>
</p>
)}
<button
type="submit"
disabled={(!sntValue || sntValue === '0') && isUpvote}
onClick={this.onClickVote}
>
{isUpvote ? 'Upvote' : 'Downvote'}
</button>
</div>
</Modal>
)
}
@ -232,6 +273,8 @@ Vote.propTypes = {
visible: PropTypes.bool.isRequired,
sntValue: PropTypes.string.isRequired,
afterVoteRating: PropTypes.number,
learnMoreDownVote: PropTypes.bool.isRequired,
learnMoreUpVote: PropTypes.bool.isRequired,
onClickClose: PropTypes.func.isRequired,
onClickUpvote: PropTypes.func.isRequired,
onClickDownvote: PropTypes.func.isRequired,
@ -240,6 +283,9 @@ Vote.propTypes = {
upVote: PropTypes.func.isRequired,
downVote: PropTypes.func.isRequired,
dappState: PropTypes.instanceOf(DappState).isRequired,
onClickLearnMoreUpVote: PropTypes.func.isRequired,
onClickLearnMoreDownVote: PropTypes.func.isRequired,
onClickCloseLearnMore: PropTypes.func.isRequired,
}
export default Vote

@ -213,4 +213,60 @@
.footer .disclaimer a {
text-decoration: none;
color: $link-color;
cursor: pointer;
}
.learnMoreCnt {
display: flex; flex-direction: column;
font-family: $font;
.title {
line-height: 40px;
text-align: center;
text-transform: uppercase;
font-weight: 600;
font-size: 17px;
border-bottom: 1px solid #f7f7f7;
}
.spacing {
margin: 14px 16px;
img {
width:100%;
flex:0 0 auto;
}
p {
line-height: 24px;
text-indent: 32px;
margin: 0;
}
}
.backButtonCnt {
height: 64px;
display: flex; flex:0 0 auto;
align-items: center;
justify-content: center;
border-top: 1px solid #f7f7f7;
margin-top: auto;
.backButton {
background: $link-color;
border-radius: 8px;
color: #fff;
border: none;
font-family: $font;
padding: calculateRem(11) calculateRem(38);
font-size: calculateRem(15);
cursor: pointer;
}
}
}
@media (min-width: $desktop) {
.learnMoreCnt {
min-height: 512px;
}
}

@ -21,6 +21,9 @@ const SWITCH_TO_DOWNVOTE = 'VOTE_SWITCH_TO_DOWNVOTE'
const ON_INPUT_SNT_VALUE = 'VOTE_ON_INPUT_SNT_VALUE'
const UPDATE_AFTER_UP_VOTING_VALUES = 'VOTE_UPDATE_AFTER_UP_VOTING_VALUES'
const UPDATE_AFTER_DOWN_VOTING_VALUES = 'VOTE_UPDATE_AFTER_DOWN_VOTING_VALUES'
const LEARN_MORE_UPVOTE = 'VOTE_LEARN_MORE_UPVOTE'
const LEARN_MORE_DOWNVOTE = 'VOTE_LEARN_MORE_DOWNVOTE'
const CLOSE_LEARN_MORE = 'VOTE_CLOSE_LEARN_MORE'
export const showUpVoteActionAfterCheck = dapp => {
window.location.hash = 'vote'
@ -57,7 +60,10 @@ export const showUpVoteAction = dapp => {
export const showDownVoteAction = dapp => {
return (dispatch, getState) => {
const state = getState()
if (state.transactionStatus.progress) {
if (
state.transactionStatus.progress &&
state.transactionStatus.dappTx !== ''
) {
dispatch(
showAlertAction(
'There is an active transaction. Please wait for it to finish and then you could be able to vote',
@ -190,6 +196,21 @@ export const downVoteAction = (dapp, amount) => {
}
}
export const learnMoreUpVoteAction = () => ({
type: LEARN_MORE_UPVOTE,
payload: null,
})
export const learnMoreDownVoteAction = () => ({
type: LEARN_MORE_DOWNVOTE,
payload: null,
})
export const closeLearnMoreAction = () => ({
type: CLOSE_LEARN_MORE,
payload: null,
})
const showUpVoteAfterCheck = (state, dapp) => {
return Object.assign({}, state, {
visible: true,
@ -197,6 +218,8 @@ const showUpVoteAfterCheck = (state, dapp) => {
sntValue: '0',
isUpvote: true,
afterVoteRating: null,
learnMoreUpVote: false,
learnMoreDownVote: false,
})
}
@ -207,6 +230,8 @@ const showDownVoteAfterCheck = (state, dapp) => {
sntValue: '0',
isUpvote: false,
afterVoteRating: null,
learnMoreUpVote: false,
learnMoreDownVote: false,
})
}
@ -214,6 +239,8 @@ const closeVote = state => {
return Object.assign({}, state, {
visible: false,
dapp: null,
learnMoreUpVote: false,
learnMoreDownVote: false,
})
}
@ -253,6 +280,27 @@ const updateAfterDownVotingValues = (state, payload) => {
})
}
const learnMoreUpVote = state => {
return Object.assign({}, state, {
learnMoreUpVote: true,
learnMoreDownVote: false,
})
}
const learnMoreDownVote = state => {
return Object.assign({}, state, {
learnMoreUpVote: false,
learnMoreDownVote: true,
})
}
const closeLearnMore = state => {
return Object.assign({}, state, {
learnMoreUpVote: false,
learnMoreDownVote: false,
})
}
const map = {
[SHOW_UP_VOTE_AFTER_CHECK]: showUpVoteAfterCheck,
[SHOW_DOWN_VOTE_AFTER_CHEECK]: showDownVoteAfterCheck,
@ -262,6 +310,9 @@ const map = {
[ON_INPUT_SNT_VALUE]: onInputSntValue,
[UPDATE_AFTER_UP_VOTING_VALUES]: updateAfterUpVotingValues,
[UPDATE_AFTER_DOWN_VOTING_VALUES]: updateAfterDownVotingValues,
[LEARN_MORE_UPVOTE]: learnMoreUpVote,
[LEARN_MORE_DOWNVOTE]: learnMoreDownVote,
[CLOSE_LEARN_MORE]: closeLearnMore,
}
export default reducerUtil(map, voteInitialState)