Skip to content

Commit

Permalink
feat: account selector on wallet connect
Browse files Browse the repository at this point in the history
  • Loading branch information
akalogerakisunicorn committed Jan 20, 2025
1 parent f09d3e5 commit 6714ad0
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 110 deletions.
23 changes: 20 additions & 3 deletions src/composables/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import { tg } from '@/popup/plugins/i18n';
import migrateAccountsVuexToComposable from '@/migrations/001-accounts-vuex-to-composable';

import { ProtocolAdapterFactory } from '@/lib/ProtocolAdapterFactory';
import { useStorageRef, useAuth, useModals } from '@/composables';

import { useStorageRef } from './storageRef';
import { useAuth } from './auth';
import { useModals } from './modals';
import AirGapIcon from '@/icons/air-gap.svg?vue-component';
import PrivateKeyIcon from '@/icons/private-key.svg?vue-component';

const {
addCallback: onAccountChange,
Expand Down Expand Up @@ -206,6 +206,10 @@ export const useAccounts = createCustomScopedComposable(() => {
return accounts.value.find((acc) => acc.globalIdx === globalIdx);
}

function getAccountsSelectOptionsByProtocol(protocol: Protocol): IFormSelectOption[] {
return prepareAccountSelectOptions(accounts.value.filter((acc) => acc.protocol === protocol));
}

/**
* Access last used (or current) account of the protocol when accessing features
* related to protocol different than the current account is using.
Expand Down Expand Up @@ -311,6 +315,17 @@ export const useAccounts = createCustomScopedComposable(() => {
}
}

function getAccountIcon(type: AccountType) {
switch (type) {
case ACCOUNT_TYPES.airGap:
return AirGapIcon;
case ACCOUNT_TYPES.privateKey:
return PrivateKeyIcon;
default:
return null;
}
}

function resetAccounts() {
mnemonic.value = '';
accountsRaw.value = [];
Expand Down Expand Up @@ -347,6 +362,8 @@ export const useAccounts = createCustomScopedComposable(() => {
getAccountByAddress,
getAccountByGlobalIdx,
getLastActiveProtocolAccount,
getAccountsSelectOptionsByProtocol,
getAccountIcon,
onAccountChange,
setActiveAccountByAddress,
setActiveAccountByGlobalIdx,
Expand Down
26 changes: 0 additions & 26 deletions src/popup/components/AccountCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@
<template #bottom-left>
<AccountCardTotalTokens :account="account" />
</template>

<template #bottom-right>
<Component
:is="accountIcon"
v-if="accountIcon"
class="account-type-icon"
/>
</template>
</AccountCardBase>
</template>

Expand All @@ -41,24 +33,18 @@ import {
} from 'vue';
import type { IAccount } from '@/types';
import { useBalances } from '@/composables';
import { ACCOUNT_TYPES } from '@/constants';
import AccountInfo from './AccountInfo.vue';
import BalanceInfo from './BalanceInfo.vue';
import AccountCardTotalTokens from './AccountCardTotalTokens.vue';
import AccountCardBase, { accountCardBaseCommonProps } from './AccountCardBase.vue';
import AirGapIcon from '../../icons/air-gap.svg?vue-component';
import PrivateKeyIcon from '../../icons/private-key.svg?vue-component';
export default defineComponent({
components: {
AccountCardBase,
AccountCardTotalTokens,
AccountInfo,
BalanceInfo,
AirGapIcon,
PrivateKeyIcon,
},
props: {
account: { type: Object as PropType<IAccount>, required: true },
Expand All @@ -67,21 +53,9 @@ export default defineComponent({
setup(props) {
const { getAccountBalance } = useBalances();
const accountIcon = computed(() => {
switch (props.account.type) {
case ACCOUNT_TYPES.airGap:
return AirGapIcon;
case ACCOUNT_TYPES.privateKey:
return PrivateKeyIcon;
default:
return null;
}
});
const numericBalance = computed(() => getAccountBalance(props.account.address).toNumber());
return {
accountIcon,
numericBalance,
};
},
Expand Down
68 changes: 46 additions & 22 deletions src/popup/components/AccountInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,31 @@
class="account-details"
:class="{ 'list-name': isListName }"
>
<div
v-if="isMultisig"
class="account-name"
v-text="$t('multisig.multisigVault')"
/>
<div
v-else-if="name"
class="account-name"
>
<ion-skeleton-text v-if="isLoading" animated />
<Truncate v-if="!isLoading" :str="name" />
<div class="account-with-icons">
<Component
:is="type && getAccountIcon(type)"
class="account-type-icon"
/>
<div
v-if="isMultisig"
class="account-name"
v-text="$t('multisig.multisigVault')"
/>
<div
v-else-if="name"
class="account-name"
>
<ion-skeleton-text v-if="isLoading" animated />
<Truncate v-if="!isLoading" :str="name" />
</div>
<Truncate
v-else
data-cy="account-name-number"
class="account-name"
:str="getDefaultAccountLabel(account)"
/>
<slot name="after-address" />
</div>
<Truncate
v-else
data-cy="account-name-number"
class="account-name"
:str="getDefaultAccountLabel(account)"
/>

<slot name="address">
<CopyText
v-if="address?.length"
Expand Down Expand Up @@ -72,11 +78,12 @@ import type { IAccount } from '@/types';
import { getDefaultAccountLabel } from '@/utils';
import { ProtocolAdapterFactory } from '@/lib/ProtocolAdapterFactory';
import { useAeNames } from '@/protocols/aeternity/composables/aeNames';
import { useAccounts } from '@/composables';
import Avatar, { type AvatarSize } from './Avatar.vue';
import CopyText from './CopyText.vue';
import Truncate from './Truncate.vue';
import AddressTruncated from './AddressTruncated.vue';
import Avatar, { type AvatarSize } from '@/popup/components/Avatar.vue';
import CopyText from '@/popup/components/CopyText.vue';
import Truncate from '@/popup/components/Truncate.vue';
import AddressTruncated from '@/popup/components/AddressTruncated.vue';
export default defineComponent({
components: {
Expand All @@ -102,6 +109,7 @@ export default defineComponent({
},
setup(props) {
const { getName, getNameByNameHash } = useAeNames();
const { getAccountIcon, getAccountByAddress } = useAccounts();
const isLoading = ref(true);
const resolvedChainName = ref('');
Expand All @@ -111,6 +119,7 @@ export default defineComponent({
|| props.customName
|| getName(address.value).value
));
const type = computed(() => getAccountByAddress(props.account.address!)?.type);
const explorerUrl = computed(
() => (props.account.protocol)
Expand All @@ -136,8 +145,10 @@ export default defineComponent({
return {
name: resolvedChainName.value || name,
type,
address,
explorerUrl,
getAccountIcon,
getDefaultAccountLabel,
isLoading,
};
Expand Down Expand Up @@ -171,11 +182,18 @@ export default defineComponent({
max-width: var(--maxWidth);
font-weight: 500;
.account-with-icons {
display: flex;
align-items: center;
max-width: 100%;
}
.account-name {
@extend %face-sans-16-medium;
line-height: 20px; // Avoid cutting off bottom part of some letters, e.g.: "g"
max-width: 100%;
flex: 1;
}
&.list-name {
Expand Down Expand Up @@ -213,5 +231,11 @@ export default defineComponent({
height: 16px;
margin: 0 0 4px 0;
}
.account-type-icon {
width: 18px;
height: 18px;
margin-right: 4px;
}
}
</style>
19 changes: 13 additions & 6 deletions src/popup/components/AccountSelectOptionsItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
avatar-borderless
is-list-name
:show-protocol-icon="!hideProtocolIcon"
/>
>
<template #after-address>
<slot name="after-address" />
</template>
</AccountInfo>
<TokenAmount
v-if="!hideBalance"
:amount="balance"
Expand Down Expand Up @@ -80,23 +84,25 @@ export default defineComponent({
const { getAccountBalance } = useBalances();
const { getAccountByAddress } = useAccounts();
const account = props.customAccount ?? getAccountByAddress(props.option.value as string);
const account = computed(() => (
props.customAccount ?? getAccountByAddress(props.option.value as string)
));
const bgColorStyle = computed(() => ({ '--bg-color': getAddressColor(account.address) }));
const bgColorStyle = computed(() => ({ '--bg-color': getAddressColor(account.value.address) }));
const balance = computed(() => {
switch (true) {
case !!props.outsideBalance:
return props.outsideBalance;
case !!account:
return getAccountBalance(account.address.toString()).toNumber();
case !!account.value:
return getAccountBalance(account.value.address.toString()).toNumber();
default:
return 0;
}
});
const tokenSymbol = computed(
() => ProtocolAdapterFactory.getAdapter(account!.protocol).coinSymbol,
() => ProtocolAdapterFactory.getAdapter(account.value.protocol).coinSymbol,
);
return {
Expand Down Expand Up @@ -125,6 +131,7 @@ export default defineComponent({
padding: 6px 8px;
border-radius: 10px;
width: 100%;
gap: 4px;
&::before {
top: 0;
Expand Down
42 changes: 8 additions & 34 deletions src/popup/components/AddressBook/AddressBookList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
protocol,
isOwnAddress,
nameAddress,
type,
}, index) in accountsFiltered"
:key="address"
:to="
Expand All @@ -42,23 +41,17 @@
: { name: ROUTE_ADDRESS_BOOK_EDIT, params: { id: address } }
"
class="address-book-item"
:style="bgColorStyle(isOwnAddress, nameAddress, address)"
:style="bgColorStyle(isOwnAddress, address)"
:idx="index"
data-cy="address-book-item"
@click="selectAddress(nameAddress, address)"
@click="selectAddress(nameAddress!, address)"
>
<AccountInfo
:account="{ address, protocol }"
:custom-name="name"
:name-address="nameAddress"
show-protocol-icon
/>
<template v-if="accountIcon(type) && isSelector" #bottom-right-icon>
<Component
:is="accountIcon(type)"
class="account-type-icon"
/>
</template>
</PanelItem>
</div>
<p
Expand All @@ -83,12 +76,12 @@ import { IonContent, IonHeader } from '@ionic/vue';
import { Encoded } from '@aeternity/aepp-sdk';
import { useRoute } from 'vue-router';
import type { AccountType, ComponentRef } from '@/types';
import { ACCOUNT_SELECT_TYPE_FILTER, ACCOUNT_TYPES } from '@/constants';
import type { ComponentRef } from '@/types';
import { ACCOUNT_SELECT_TYPE_FILTER } from '@/constants';
import { ROUTE_ADDRESS_BOOK, ROUTE_ADDRESS_BOOK_EDIT } from '@/popup/router/routeNames';
import { getAddressColor } from '@/utils';
import { ProtocolAdapterFactory } from '@/lib/ProtocolAdapterFactory';
import { useAccountSelector } from '@/composables';
import { useAccountSelector, useAccounts } from '@/composables';
import { useAeNames } from '@/protocols/aeternity/composables/aeNames';
Expand All @@ -97,18 +90,9 @@ import InputSearch from '@/popup/components/InputSearch.vue';
import AccountInfo from '@/popup/components/AccountInfo.vue';
import AddressBookFilters from '@/popup/components/AddressBook/AddressBookFilters.vue';
import PanelItem from '@/popup/components/PanelItem.vue';
import BtnBase from '@/popup/components/buttons/BtnBase.vue';
import BtnMain from '@/popup/components/buttons/BtnMain.vue';
import IconWrapper from '@/popup/components/IconWrapper.vue';
import AirGapIcon from '@/icons/air-gap.svg?vue-component';
import PrivateKeyIcon from '@/icons/private-key.svg?vue-component';
export default defineComponent({
components: {
IconWrapper,
BtnMain,
BtnBase,
IonHeader,
IonContent,
AccountInfo,
Expand Down Expand Up @@ -137,6 +121,7 @@ export default defineComponent({
showBookmarked,
setAccountSelectType,
} = useAccountSelector();
const { getAccountIcon } = useAccounts();
const route = useRoute();
const noRecordsMessage = computed(() => {
Expand Down Expand Up @@ -174,18 +159,7 @@ export default defineComponent({
emit('update:hideButtons', hideOuterButtons.value);
}, 100);
function accountIcon(type: AccountType) {
switch (type) {
case ACCOUNT_TYPES.airGap:
return AirGapIcon;
case ACCOUNT_TYPES.privateKey:
return PrivateKeyIcon;
default:
return null;
}
}
function bgColorStyle(isOwnAddress: boolean, nameAddress: String, address: String) {
function bgColorStyle(isOwnAddress: boolean, address: String) {
return isOwnAddress ? { '--bg-color': getAddressColor(address) } : {};
}
Expand Down Expand Up @@ -229,7 +203,7 @@ export default defineComponent({
noRecordsMessage,
protocolName,
bgColorStyle,
accountIcon,
getAccountIcon,
selectAddress,
};
},
Expand Down
Loading

0 comments on commit 6714ad0

Please sign in to comment.