Skip to content

Commit

Permalink
Add multi token display functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mikozet committed Sep 22, 2023
1 parent 3eb5c94 commit 9d5abf7
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 8 deletions.
4 changes: 4 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@
"TextVerification": {
"noteInvalid": "You cannot write special symbols like {}<br>^ or more than 100 characters."
},
"Tokens": {
"headingTokens": "Your Circles",
"descriptionTokens": "All circles you hold was originally issued as someone's basic income. These users are the original issuers of the circles you hold. Each of these circles can be sent directly to other wallets that trust these users."
},
"TransferInfoBalanceCard": {
"bodyTotalBalance": "Your total balance: {balance}",
"tooltipTotalBalance": "This is the current balance of all Circles you have on your account"
Expand Down
9 changes: 7 additions & 2 deletions src/components/BalanceDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { Box, Tooltip, Typography } from '@mui/material';
import makeStyles from '@mui/styles/makeStyles';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';

import { TOKENS_PATH } from '~/routes';

import { useUpdateLoop } from '~/hooks/update';
import translate from '~/services/locale';
Expand Down Expand Up @@ -56,8 +59,10 @@ const BalanceDisplay = () => {
<CircularProgress />
) : (
<Typography variant="balance1">
<IconCircles className={classes.balanceIcon} />
{tokenBalance}
<Link to={TOKENS_PATH}>
<IconCircles className={classes.balanceIcon} />
{tokenBalance}
</Link>
</Typography>
)}
</Box>
Expand Down
1 change: 0 additions & 1 deletion src/components/Finder.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ function filterToQuery(filterName) {
const useStyles = makeStyles((theme) => ({
searchItem: {
cursor: 'pointer',
boxShadow: theme.custom.shadows.gray,
},
noSearchResultContainer: {
marginTop: '80px',
Expand Down
28 changes: 25 additions & 3 deletions src/components/ProfileMini.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Typography,
} from '@mui/material';
import makeStyles from '@mui/styles/makeStyles';
import clsx from 'clsx';
import PropTypes from 'prop-types';
import React, { Fragment, useState } from 'react';
import { useDispatch } from 'react-redux';
Expand All @@ -28,6 +29,16 @@ import { addSafeOwner } from '~/store/safe/actions';
import { IconFriends, IconSend, IconTrust } from '~/styles/icons';

const useStyles = makeStyles((theme) => ({
cardContainer: {
boxShadow: theme.custom.shadows.navigationFloating,
'&:hover': {
background: theme.custom.colors.blackSqueeze,

'& .MuiCardHeader-root': {
background: theme.custom.colors.blackSqueeze,
},
},
},
cardHeader: {
padding: theme.spacing(1),
},
Expand Down Expand Up @@ -64,6 +75,7 @@ const ProfileMini = ({
className,
hasActions = false,
isSharedWalletCreation,
value,
...props
}) => {
const classes = useStyles();
Expand Down Expand Up @@ -160,18 +172,27 @@ const ProfileMini = ({
onConfirm={handleClose}
/>
)}
<Card {...props} className={className}>
<Card {...props} className={clsx(className, classes.cardContainer)}>
<CardHeader
action={
hasActions && (
(hasActions && (
<ProfileMiniActions
address={address}
connection={connection}
isSharedWalletCreation={isSharedWalletCreation}
onSend={handleSend}
onTrust={handleTrust}
/>
)
)) ||
(value && (
<Typography
classes={{ root: 'h1_blue' }}
component="span"
variant="h1"
>
{value}
</Typography>
))
}
avatar={<Avatar address={address} />}
classes={{
Expand Down Expand Up @@ -258,6 +279,7 @@ ProfileMini.propTypes = {
className: PropTypes.string,
hasActions: PropTypes.bool,
isSharedWalletCreation: PropTypes.bool,
value: PropTypes.string,
};

ProfileMiniActions.propTypes = {
Expand Down
3 changes: 3 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Send from '~/views/Send';
import SendConfirm from '~/views/SendConfirm';
import Settings from '~/views/Settings';
import Share from '~/views/Share';
import Tokens from '~/views/Tokens';
import TutorialOnboarding from '~/views/TutorialOnboarding';
import Validation from '~/views/Validation';
import ValidationLock from '~/views/ValidationLock';
Expand All @@ -43,6 +44,7 @@ export const ORGANIZATION_PATH = '/organization';
export const PROFILE_PATH = '/profile/:address';
export const QR_GENERATOR_PATH = '/sharedwallet/qr';
export const SEARCH_PATH = '/search';
export const TOKENS_PATH = '/tokens';
export const SEED_PHRASE_PATH = '/seedphrase';
export const SEND_CONFIRM_PATH = '/send/:address(0x[0-9a-fA-f]{40})';
export const SEND_PATH = '/send';
Expand Down Expand Up @@ -265,6 +267,7 @@ const Routes = () => {
<TrustedRoute component={EditProfile} exact path={EDIT_PROFILE_PATH} />
<TrustedRoute component={QRGenerator} exact path={QR_GENERATOR_PATH} />
<TrustedRoute component={Search} exact path={SEARCH_PATH} />
<TrustedRoute component={Tokens} exact path={TOKENS_PATH} />
<OrganizationRoute
component={OrganizationMembersAdd}
exact
Expand Down
68 changes: 66 additions & 2 deletions src/store/token/actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { tcToCrc } from '@circles/timecircles';
import { Typography } from '@mui/material';
import { DateTime } from 'luxon';
import React from 'react';

import core from '~/services/core';
import translate from '~/services/locale';
Expand All @@ -9,7 +11,8 @@ import { addPendingActivity } from '~/store/activity/actions';
import notify, { NotificationsTypes } from '~/store/notifications/actions';
import ActionTypes from '~/store/token/types';
import { PATHFINDER_HOPS_DEFAULT, ZERO_ADDRESS } from '~/utils/constants';
import logError from '~/utils/debug';
import logError, { translateErrorForUser } from '~/utils/debug';
import { formatCirclesValue } from '~/utils/format';
import { isTokenDeployed, waitAndRetryOnFail } from '~/utils/stateChecks';

const { ActivityTypes } = core.activity;
Expand Down Expand Up @@ -139,7 +142,7 @@ export function checkTokenState() {

export function checkCurrentBalance() {
return async (dispatch, getState) => {
const { safe, token } = getState();
const { token, safe } = getState();

// No token address given yet
if (!token.address && !safe.isOrganization) {
Expand Down Expand Up @@ -167,6 +170,67 @@ export function checkCurrentBalance() {
};
}

export function checkOtherTokens() {
return async (dispatch, getState) => {
const { safe } = getState();

try {
const otherTokens = await core.token.listAllTokens(safe.currentAccount);

const filterOrderedOtherTokens = otherTokens
.filter(
(item) =>
formatCirclesValue(item.amount, Date.now(), 2, false) > 0.005,
)
.reverse();
dispatch({
type: ActionTypes.TOKEN_UPDATE_OTHER_TOKENS,
meta: {
otherTokens: filterOrderedOtherTokens,
},
});
dispatch({
type: ActionTypes.TOKEN_UPDATE_OTHER_TOKENS_SUCCESS,
});
} catch (error) {
dispatch({
type: ActionTypes.TOKEN_UPDATE_OTHER_TOKENS_LOADING,
meta: {
isLoading: false,
},
});
dispatch({
type: ActionTypes.TOKEN_UPDATE_OTHER_TOKENS_ERROR,
meta: {
isError: true,
},
});
logError(error);
dispatch(
notify({
text: (
<Typography classes={{ root: 'body4_white' }} variant="body4">
{translateErrorForUser(error)}
</Typography>
),
type: NotificationsTypes.ERROR,
}),
);
}
};
}

export function checkOtherTokensLoading(isLoading) {
return async (dispatch) => {
dispatch({
type: ActionTypes.TOKEN_UPDATE_OTHER_TOKENS_LOADING,
meta: {
isLoading,
},
});
};
}

export function requestUBIPayout(payout) {
return async (dispatch, getState) => {
const { safe, token } = getState();
Expand Down
23 changes: 23 additions & 0 deletions src/store/token/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ const initialState = {
isLoading: false,
lastPayoutAt: null,
lastUpdateAt: null,
otherTokens: {
isLoading: true,
isError: false,
otherTokens: [],
},
};

const tokenReducer = (state = initialState, action) => {
Expand All @@ -23,6 +28,24 @@ const tokenReducer = (state = initialState, action) => {
address: { $set: action.meta.address },
lastPayoutAt: { $set: action.meta.lastPayoutAt },
});
case ActionTypes.TOKEN_UPDATE_OTHER_TOKENS:
return update(state, {
otherTokens: {
otherTokens: { $set: action.meta.otherTokens },
},
});
case ActionTypes.TOKEN_UPDATE_OTHER_TOKENS_LOADING:
return update(state, {
otherTokens: {
isLoading: { $set: action.meta.isLoading },
},
});
case ActionTypes.TOKEN_UPDATE_OTHER_TOKENS_ERROR:
return update(state, {
otherTokens: {
isError: { $set: action.meta.isError },
},
});
case ActionTypes.TOKEN_BALANCE_UPDATE:
return update(state, {
isLoading: { $set: true },
Expand Down
4 changes: 4 additions & 0 deletions src/store/token/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ export default createTypes(
'TOKEN_UPDATE',
'TOKEN_UPDATE_ERROR',
'TOKEN_UPDATE_SUCCESS',
'TOKEN_UPDATE_OTHER_TOKENS',
'TOKEN_UPDATE_OTHER_TOKENS_LOADING',
'TOKEN_UPDATE_OTHER_TOKENS_ERROR',
'TOKEN_UPDATE_OTHER_TOKENS_SUCCESS',
);
6 changes: 6 additions & 0 deletions src/styles/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ export default createTheme({
background: gradients.violetCurved,
backgroundClip: 'text',
textFillColor: 'transparent',
'& svg': {
fill: colors.violet,
},
'& a': {
textDecoration: 'none',
},
},
poster: {
fontSize: '4rem',
Expand Down
Loading

0 comments on commit 9d5abf7

Please sign in to comment.