Skip to content

Commit

Permalink
feat: change icon of account (#335)
Browse files Browse the repository at this point in the history
* feat: add account icon types

* chore: squash

* feat: add utility function to parse account icon and add icon to account avatar

* feat: add icon selection to the edit account page

* feat: add ability to change account background color

* feat: add algorand and voi icons to the account icon list

* feat: add currency icons to the account icons

* feat: update whats new modal

* feat: add option to show scroll bars on scroll container

* refactor: use thin scroll bars on chrome

* feat: re-add color to account icons
  • Loading branch information
kieranroneill authored Oct 2, 2024
1 parent 7ac79c5 commit 0174529
Show file tree
Hide file tree
Showing 40 changed files with 1,140 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';

// components
import AccountItem from '@extension/components/AccountItem';
import Button from '@extension/components/Button';
import EmptyState from '@extension/components/EmptyState';
import NewAccountItem from '@extension/components/NewAccountItem';

// constants
import {
Expand Down Expand Up @@ -216,7 +216,7 @@ const ARC0300AccountImportModalContent: FC<
py={DEFAULT_GAP / 3}
w="full"
>
<AccountItem
<NewAccountItem
address={convertPublicKeyToAVMAddress(keyPair.publicKey)}
{...(name && { name })}
/>
Expand Down
47 changes: 42 additions & 5 deletions src/extension/components/AccountAvatar/AccountAvatar.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,57 @@
import { Avatar, Icon } from '@chakra-ui/react';
import React, { FC, PropsWithChildren } from 'react';
import { IoWalletOutline } from 'react-icons/io5';
import React, { type FC } from 'react';

// hooks
import usePrimaryButtonTextColor from '@extension/hooks/usePrimaryButtonTextColor';
import usePrimaryColor from '@extension/hooks/usePrimaryColor';

const AccountAvatar: FC<PropsWithChildren> = ({ children }) => {
// types
import type { IProps } from './types';

// utils
import parseAccountIcon from '@extension/utils/parseAccountIcon';

const AccountAvatar: FC<IProps> = ({ account, children }) => {
// hooks
const primaryButtonTextColor = usePrimaryButtonTextColor();
const primaryColor = usePrimaryColor();
// misc
let iconColor = primaryButtonTextColor;

switch (account.color) {
case 'yellow.300':
case 'yellow.500':
case 'orange.300':
case 'orange.500':
case 'red.300':
case 'red.500':
iconColor = 'gray.800';
break;
case 'black':
case 'blue.300':
case 'blue.500':
case 'green.300':
case 'green.500':
case 'teal.300':
case 'teal.500':
iconColor = 'white';
break;
case 'primary':
default:
break;
}

return (
<Avatar
bg={primaryColor}
icon={<Icon as={IoWalletOutline} color={primaryButtonTextColor} />}
bg={
!account.color || account.color === 'primary'
? primaryColor
: account.color
}
icon={parseAccountIcon({
accountIcon: account.icon,
color: iconColor,
})}
size="sm"
>
{children}
Expand Down
10 changes: 10 additions & 0 deletions src/extension/components/AccountAvatar/types/IProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { PropsWithChildren } from 'react';

// types
import type { IAccountWithExtendedProps } from '@extension/types';

interface IProps extends PropsWithChildren {
account: IAccountWithExtendedProps;
}

export default IProps;
1 change: 1 addition & 0 deletions src/extension/components/AccountAvatar/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { default as IProps } from './IProps';
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const AccountAvatarWithBadges: FC<IProps> = ({
};

return (
<AccountAvatar>
<AccountAvatar account={account}>
{/*polis account badge*/}
{systemInfo && systemInfo.polisAccountID === account.id && (
<AvatarBadge
Expand Down
16 changes: 7 additions & 9 deletions src/extension/components/AccountItem/AccountItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,23 @@ import type { IProps } from './types';

// utils
import ellipseAddress from '@extension/utils/ellipseAddress';
import convertPublicKeyToAVMAddress from '@extension/utils/convertPublicKeyToAVMAddress';

const AccountItem: FC<IProps> = ({
address,
name,
subTextColor,
textColor,
}) => {
const AccountItem: FC<IProps> = ({ account, subTextColor, textColor }) => {
// hooks
const defaultSubTextColor = useSubTextColor();
const defaultTextColor = useDefaultTextColor();
// misc
const address = convertPublicKeyToAVMAddress(account.publicKey);

return (
<HStack m={0} p={0} spacing={DEFAULT_GAP / 3} w="full">
{/*avatar*/}
<Center>
<AccountAvatar />
<AccountAvatar account={account} />
</Center>

{name ? (
{account.name ? (
<VStack
alignItems="flex-start"
flexGrow={1}
Expand All @@ -48,7 +46,7 @@ const AccountItem: FC<IProps> = ({
noOfLines={1}
textAlign="left"
>
{name}
{account.name}
</Text>

<Text
Expand Down
6 changes: 4 additions & 2 deletions src/extension/components/AccountItem/types/IProps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// types
import type { IAccountWithExtendedProps } from '@extension/types';

interface IProps {
address: string;
name?: string;
account: IAccountWithExtendedProps;
subTextColor?: string;
textColor?: string;
}
Expand Down
6 changes: 1 addition & 5 deletions src/extension/components/AccountSelect/AccountSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import type { IProps } from './types';

// utils
import calculateIconSize from '@extension/utils/calculateIconSize';
import convertPublicKeyToAVMAddress from '@extension/utils/convertPublicKeyToAVMAddress';

const AccountSelect: FC<IProps> = ({
_context,
Expand Down Expand Up @@ -117,10 +116,7 @@ const AccountSelect: FC<IProps> = ({
w="full"
>
<Stack flexGrow={1} justifyContent="center" w="full">
<AccountItem
address={convertPublicKeyToAVMAddress(value.publicKey)}
{...(value.name && { name: value.name })}
/>
<AccountItem account={value} />
</Stack>
</ChakraButton>
</VStack>
Expand Down
88 changes: 88 additions & 0 deletions src/extension/components/NewAccountItem/NewAccountItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Avatar, Center, HStack, Icon, Text, VStack } from '@chakra-ui/react';
import React, { type FC } from 'react';
import { IoWalletOutline } from 'react-icons/io5';

// constants
import { DEFAULT_GAP } from '@extension/constants';

// hooks
import useDefaultTextColor from '@extension/hooks/useDefaultTextColor';
import usePrimaryColor from '@extension/hooks/usePrimaryColor';
import usePrimaryButtonTextColor from '@extension/hooks/usePrimaryButtonTextColor';
import useSubTextColor from '@extension/hooks/useSubTextColor';

// types
import type { IProps } from './types';

// utils
import ellipseAddress from '@extension/utils/ellipseAddress';

const NewAccountItem: FC<IProps> = ({
address,
name,
subTextColor,
textColor,
}) => {
// hooks
const defaultSubTextColor = useSubTextColor();
const defaultTextColor = useDefaultTextColor();
const primaryButtonTextColor = usePrimaryButtonTextColor();
const primaryColor = usePrimaryColor();

return (
<HStack m={0} p={0} spacing={DEFAULT_GAP / 3} w="full">
{/*avatar*/}
<Center>
<Avatar
bg={primaryColor}
icon={<Icon as={IoWalletOutline} color={primaryButtonTextColor} />}
size="sm"
/>
</Center>

{name ? (
<VStack
alignItems="flex-start"
flexGrow={1}
justifyContent="space-evenly"
spacing={0}
>
<Text
color={textColor || defaultTextColor}
fontSize="sm"
maxW={195}
noOfLines={1}
textAlign="left"
>
{name}
</Text>

<Text
color={subTextColor || defaultSubTextColor}
fontSize="xs"
textAlign="left"
>
{ellipseAddress(address, {
end: 10,
start: 10,
})}
</Text>
</VStack>
) : (
<Text
color={textColor || defaultTextColor}
flexGrow={1}
fontSize="sm"
textAlign="left"
>
{ellipseAddress(address, {
end: 10,
start: 10,
})}
</Text>
)}
</HStack>
);
};

export default NewAccountItem;
1 change: 1 addition & 0 deletions src/extension/components/NewAccountItem/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './NewAccountItem';
8 changes: 8 additions & 0 deletions src/extension/components/NewAccountItem/types/IProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface IProps {
address: string;
name?: string;
subTextColor?: string;
textColor?: string;
}

export default IProps;
1 change: 1 addition & 0 deletions src/extension/components/NewAccountItem/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { default as IProps } from './IProps';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { IProps } from './types';
const ScrollableContainer: FC<IProps> = ({
children,
onScrollEnd,
showScrollBars = false,
...stackProps
}) => {
const scrollContainerRef = useRef<HTMLDivElement | null>(null);
Expand All @@ -32,6 +33,15 @@ const ScrollableContainer: FC<IProps> = ({
ref={scrollContainerRef}
spacing={0}
w="full"
{...(showScrollBars && {
sx: {
scrollbarWidth: __TARGET__ === 'chrome' ? 'thin' : 'auto',
msOverflowStyle: 'auto',
['::-webkit-scrollbar']: {
display: 'contents',
},
},
})}
>
<Stack {...stackProps}>{children}</Stack>
</Stack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { StackProps } from '@chakra-ui/react';

interface IProps extends StackProps {
onScrollEnd?: () => void;
showScrollBars?: boolean;
}

export default IProps;
13 changes: 13 additions & 0 deletions src/extension/components/VoiIcon/VoiIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Icon, type IconProps } from '@chakra-ui/react';
import React, { type FC } from 'react';

const VoiIcon: FC<IconProps> = (props: IconProps) => (
<Icon viewBox="0 0 38.231651 34.998402" {...props}>
<path
d="m 19.1157,35.4984 c -2.6714,0 -5.1412,-1.4216 -6.4824,-3.7317 L 1.01431,11.7568 C -1.06415,8.17804 0.153903,3.59172 3.73356,1.5138 7.314,-0.56412 11.9007,0.653619 13.9792,4.23234 l 5.1365,8.84566 5.1366,-8.84566 c 2.0784,-3.578721 6.6652,-4.79646 10.2456,-2.71854 3.5805,2.07792 4.7977,6.66345 2.7193,10.243 l -11.619,20.0099 c -1.3412,2.3101 -3.8111,3.7317 -6.4825,3.7317 z"
fill="currentColor"
/>
</Icon>
);

export default VoiIcon;
1 change: 1 addition & 0 deletions src/extension/components/VoiIcon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './VoiIcon';
2 changes: 1 addition & 1 deletion src/extension/features/accounts/enums/ThunkEnum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ enum ThunkEnum {
RemoveAccountById = 'accounts/removeAccountById',
RemoveARC0200AssetHoldings = 'accounts/removeARC0200AssetHoldings',
RemoveStandardAssetHoldings = 'accounts/removeStandardAssetHoldings',
SaveAccountName = 'accounts/saveAccountName',
SaveAccountDetails = 'accounts/saveAccountDetails',
SaveAccounts = 'accounts/saveAccounts',
SaveActiveAccountDetails = 'accounts/saveActiveAccountDetails',
SaveNewAccounts = 'accounts/saveNewAccounts',
Expand Down
28 changes: 16 additions & 12 deletions src/extension/features/accounts/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
removeAccountByIdThunk,
removeARC0200AssetHoldingsThunk,
removeStandardAssetHoldingsThunk,
saveAccountNameThunk,
saveAccountDetailsThunk,
saveAccountsThunk,
saveActiveAccountDetails,
saveNewAccountsThunk,
Expand Down Expand Up @@ -221,20 +221,24 @@ const slice = createSlice({
);
}
);
/** save account name **/
builder.addCase(saveAccountNameThunk.fulfilled, (state: IState, action) => {
if (action.payload) {
state.items = upsertItemsById<IAccountWithExtendedProps>(state.items, [
action.payload,
]);
}
/** save account details **/
builder.addCase(
saveAccountDetailsThunk.fulfilled,
(state: IState, action) => {
if (action.payload) {
state.items = upsertItemsById<IAccountWithExtendedProps>(
state.items,
[action.payload]
);
}

state.saving = false;
});
builder.addCase(saveAccountNameThunk.pending, (state: IState) => {
state.saving = false;
}
);
builder.addCase(saveAccountDetailsThunk.pending, (state: IState) => {
state.saving = true;
});
builder.addCase(saveAccountNameThunk.rejected, (state: IState) => {
builder.addCase(saveAccountDetailsThunk.rejected, (state: IState) => {
state.saving = false;
});
/** save accounts **/
Expand Down
2 changes: 1 addition & 1 deletion src/extension/features/accounts/thunks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export { default as fetchAccountsFromStorageThunk } from './fetchAccountsFromSto
export { default as removeAccountByIdThunk } from './removeAccountByIdThunk';
export { default as removeARC0200AssetHoldingsThunk } from './removeARC0200AssetHoldingsThunk';
export { default as removeStandardAssetHoldingsThunk } from './removeStandardAssetHoldingsThunk';
export { default as saveAccountNameThunk } from './saveAccountNameThunk';
export { default as saveAccountDetailsThunk } from './saveAccountDetailsThunk';
export { default as saveAccountsThunk } from './saveAccountsThunk';
export { default as saveActiveAccountDetails } from './saveActiveAccountDetails';
export { default as saveNewAccountsThunk } from './saveNewAccountsThunk';
Expand Down
Loading

0 comments on commit 0174529

Please sign in to comment.