Skip to content

Commit

Permalink
Merge d407d03 into c1256f0
Browse files Browse the repository at this point in the history
  • Loading branch information
bpierre committed Apr 5, 2019
2 parents c1256f0 + d407d03 commit bbea3fa
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 210 deletions.
3 changes: 2 additions & 1 deletion apps/token-manager/app/package.json
Expand Up @@ -5,9 +5,10 @@
"license": "AGPL-3.0-or-later",
"dependencies": {
"@aragon/api": "^1.0.0",
"@aragon/api-react": "^1.0.0-beta.2",
"@aragon/ui": "^0.33.0",
"bn.js": "^4.11.6",
"prop-types": "^15.6.0",
"prop-types": "^15.7.2",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-spring": "^7.2.10",
Expand Down
107 changes: 26 additions & 81 deletions apps/token-manager/app/src/App.js
@@ -1,15 +1,13 @@
import React from 'react'
import PropTypes from 'prop-types'
import BN from 'bn.js'
import { map } from 'rxjs/operators'
import { Badge, Main, SidePanel, observe } from '@aragon/ui'
import { useAragonApi } from '@aragon/api-react'
import EmptyState from './screens/EmptyState'
import Holders from './screens/Holders'
import AssignVotePanelContent from './components/Panels/AssignVotePanelContent'
import AssignTokensIcon from './components/AssignTokensIcon'
import AppLayout from './components/AppLayout'
import { networkContextType } from './provide-network'
import { hasLoadedTokenSettings } from './token-settings'
import { addressesEqual } from './web3-utils'
import { IdentityProvider } from './components/IdentityManager/IdentityManager'

Expand All @@ -18,34 +16,20 @@ const initialAssignTokensConfig = {
holderAddress: '',
}

class App extends React.Component {
class App extends React.PureComponent {
static propTypes = {
app: PropTypes.object.isRequired,
sendMessageToWrapper: PropTypes.func.isRequired,
api: PropTypes.object,
}
static defaultProps = {
appStateReady: false,
holders: [],
network: {},
userAccount: '',
connectedAccount: '',
groupMode: false,
}
state = {
assignTokensConfig: initialAssignTokensConfig,
sidepanelOpened: false,
}
static childContextTypes = {
network: networkContextType,
}
getChildContext() {
const { network } = this.props

return {
network: {
type: network.type,
},
}
}
getHolderBalance = address => {
const { holders } = this.props
const holder = holders.find(holder =>
Expand All @@ -54,13 +38,13 @@ class App extends React.Component {
return holder ? holder.balance : new BN('0')
}
handleUpdateTokens = ({ amount, holder, mode }) => {
const { app } = this.props
const { api } = this.props

if (mode === 'assign') {
app.mint(holder, amount)
api.mint(holder, amount)
}
if (mode === 'remove') {
app.burn(holder, amount)
api.burn(holder, amount)
}

this.handleSidepanelClose()
Expand All @@ -80,9 +64,6 @@ class App extends React.Component {
sidepanelOpened: true,
})
}
handleMenuPanelOpen = () => {
this.props.sendMessageToWrapper('menuPanel', true)
}
handleSidepanelClose = () => {
this.setState({ sidepanelOpened: false })
}
Expand All @@ -92,10 +73,10 @@ class App extends React.Component {
}
}
handleResolveLocalIdentity = address => {
return this.props.app.resolveAddressIdentity(address).toPromise()
return this.props.api.resolveAddressIdentity(address).toPromise()
}
handleShowLocalIdentityModal = address => {
return this.props.app
return this.props.api
.requestAddressIdentityModification(address)
.toPromise()
}
Expand All @@ -113,7 +94,8 @@ class App extends React.Component {
tokenSupply,
tokenSymbol,
tokenTransfersEnabled,
userAccount,
connectedAccount,
requestMenu,
} = this.props
const { assignTokensConfig, sidepanelOpened } = this.state
return (
Expand All @@ -126,9 +108,9 @@ class App extends React.Component {
<AppLayout
title="Token Manager"
afterTitle={tokenSymbol && <Badge.App>{tokenSymbol}</Badge.App>}
onMenuOpen={this.handleMenuPanelOpen}
onMenuOpen={requestMenu}
mainButton={{
label: 'Assign tokens',
label: 'Add tokens',
icon: <AssignTokensIcon />,
onClick: this.handleLaunchAssignTokensNoHolder,
}}
Expand All @@ -145,7 +127,7 @@ class App extends React.Component {
tokenSupply={tokenSupply}
tokenSymbol={tokenSymbol}
tokenTransfersEnabled={tokenTransfersEnabled}
userAccount={userAccount}
userAccount={connectedAccount}
onAssignTokens={this.handleLaunchAssignTokens}
onRemoveTokens={this.handleLaunchRemoveTokens}
/>
Expand All @@ -158,7 +140,7 @@ class App extends React.Component {
<SidePanel
title={
assignTokensConfig.mode === 'assign'
? 'Assign tokens'
? 'Add tokens'
: 'Remove tokens'
}
opened={sidepanelOpened}
Expand All @@ -184,51 +166,14 @@ class App extends React.Component {
}
}

export default observe(
// Convert tokenSupply and holders balances to BNs,
// and calculate tokenDecimalsBase.
observable =>
observable.pipe(
map(state => {
const appStateReady = hasLoadedTokenSettings(state)
if (!appStateReady) {
return {
...state,
appStateReady,
}
}

const {
holders,
maxAccountTokens,
tokenDecimals,
tokenSupply,
tokenTransfersEnabled,
} = state

const tokenDecimalsBase = new BN(10).pow(new BN(tokenDecimals))

return {
...state,
appStateReady,
tokenDecimalsBase,
// Note that numbers in `numData` are not safe for accurate computations
// (but are useful for making divisions easier)
numData: {
tokenDecimals: parseInt(tokenDecimals, 10),
tokenSupply: parseInt(tokenSupply, 10),
},
holders: holders
? holders
.map(holder => ({ ...holder, balance: new BN(holder.balance) }))
.sort((a, b) => b.balance.cmp(a.balance))
: [],
tokenDecimals: new BN(tokenDecimals),
tokenSupply: new BN(tokenSupply),
maxAccountTokens: new BN(maxAccountTokens),
groupMode: tokenTransfersEnabled && maxAccountTokens === '1',
}
})
),
{}
)(App)
export default () => {
const { api, appState, connectedAccount, requestMenu } = useAragonApi()
return (
<App
api={api}
connectedAccount={connectedAccount}
requestMenu={requestMenu}
{...appState}
/>
)
}
49 changes: 49 additions & 0 deletions apps/token-manager/app/src/app-state-reducer.js
@@ -0,0 +1,49 @@
import BN from 'bn.js'
import { map } from 'rxjs/operators'
import { hasLoadedTokenSettings } from './token-settings'

// Convert tokenSupply and holders balances to BNs,
// and calculate tokenDecimalsBase.
function appStateReducer(state) {
const appStateReady = hasLoadedTokenSettings(state)
if (!appStateReady) {
return {
...state,
appStateReady,
}
}

const {
holders,
maxAccountTokens,
tokenDecimals,
tokenSupply,
tokenTransfersEnabled,
} = state

const tokenDecimalsBase = new BN(10).pow(new BN(tokenDecimals))

return {
...state,
appStateReady,
tokenDecimalsBase,

// Note that numbers in `numData` are not safe for accurate computations
// (but are useful for making divisions easier)
numData: {
tokenDecimals: parseInt(tokenDecimals, 10),
tokenSupply: parseInt(tokenSupply, 10),
},
holders: holders
? holders
.map(holder => ({ ...holder, balance: new BN(holder.balance) }))
.sort((a, b) => b.balance.cmp(a.balance))
: [],
tokenDecimals: new BN(tokenDecimals),
tokenSupply: new BN(tokenSupply),
maxAccountTokens: new BN(maxAccountTokens),
groupMode: tokenTransfersEnabled && maxAccountTokens === '1',
}
}

export default appStateReducer
18 changes: 12 additions & 6 deletions apps/token-manager/app/src/components/AppLayout.js
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { AppBar, AppView, Button, ButtonIcon, Viewport, font } from '@aragon/ui'
import { useAragonApi } from '@aragon/api-react'
import MenuButton from './MenuButton/MenuButton'

const AppLayout = ({
Expand All @@ -10,9 +11,9 @@ const AppLayout = ({
afterTitle,
smallViewPadding,
largeViewPadding,
onMenuOpen,
mainButton,
}) => {
const { requestMenu, displayMenuButton } = useAragonApi()
return (
<Viewport>
{({ below }) => (
Expand All @@ -21,18 +22,24 @@ const AppLayout = ({
appBar={
<AppBar>
<AppBarContainer
style={{ padding: below('medium') ? '0' : '0 30px' }}
style={{ padding: below('medium') ? '0' : '0 30px 0 10px' }}
>
<Title>
{below('medium') && <MenuButton onClick={onMenuOpen} />}
<TitleLabel>{title}</TitleLabel>
{displayMenuButton && <MenuButton onClick={requestMenu} />}
<TitleLabel
css={`
margin-left: ${displayMenuButton ? '0' : '20px'};
`}
>
{title}
</TitleLabel>
{afterTitle}
</Title>
{mainButton &&
(below('medium') ? (
<ButtonIcon
onClick={mainButton.onClick}
title={mainButton.label}
label={mainButton.label}
css={`
width: auto;
height: 100%;
Expand Down Expand Up @@ -67,7 +74,6 @@ AppLayout.propTypes = {
children: PropTypes.node,
title: PropTypes.node.isRequired,
afterTitle: PropTypes.node,
onMenuOpen: PropTypes.func.isRequired,
smallViewPadding: PropTypes.number,
largeViewPadding: PropTypes.number,
mainButton: PropTypes.shape({
Expand Down
9 changes: 6 additions & 3 deletions apps/token-manager/app/src/components/HolderRow.js
Expand Up @@ -9,8 +9,8 @@ import {
TableRow,
theme,
} from '@aragon/ui'
import { useNetwork } from '@aragon/api-react'
import LocalIdentityBadge from './LocalIdentityBadge/LocalIdentityBadge'
import provideNetwork from '../provide-network'
import { formatBalance } from '../utils'
import You from './You'

Expand Down Expand Up @@ -69,7 +69,7 @@ class HolderRow extends React.Component {
<IconWrapper>
<IconAdd />
</IconWrapper>
<ActionLabel>Assign Tokens</ActionLabel>
<ActionLabel>Add Tokens</ActionLabel>
</ContextMenuItem>
)}
<ContextMenuItem onClick={this.handleRemoveTokens}>
Expand Down Expand Up @@ -114,4 +114,7 @@ const IconWrapper = styled.span`
color: ${theme.textSecondary};
`

export default provideNetwork(HolderRow)
export default props => {
const network = useNetwork()
return <HolderRow network={network} {...props} />
}
Expand Up @@ -11,6 +11,7 @@ export default props => (
padding: 0 10px 0 20px;
margin-right: 8px;
`}
label="Open menu"
>
<IconMenu />
</ButtonIcon>
Expand Down

0 comments on commit bbea3fa

Please sign in to comment.