Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bridge] UI improvements #1222

Merged
merged 15 commits into from
Nov 21, 2023
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/mixins/TranslationMixin.ts
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ const TranslationConsts = {
APR: 'APR', // Annual percentage rate
TVL: 'TVL',
EVM: 'EVM',
Substrate: 'Substrate',
Kusama: 'Kusama',
ROI: 'ROI', // Return of investment
mbps: 'mbps',
58 changes: 58 additions & 0 deletions src/components/pages/Bridge/AccountPanel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<div class="account-panel">
<slot name="icon">
<wallet-avatar :address="address" :size="18" class="account-gravatar" />
</slot>
<span v-if="name" class="account-panel-name">
{{ name }}
</span>
<formatted-address :value="address" :symbols="12" :tooltip-text="tooltip" />
</div>
</template>

<script lang="ts">
import { components, mixins } from '@soramitsu/soraneo-wallet-web';
import { Component, Mixins, Prop } from 'vue-property-decorator';

import TranslationMixin from '@/components/mixins/TranslationMixin';

@Component({
components: {
WalletAvatar: components.WalletAvatar,
FormattedAddress: components.FormattedAddress,
},
})
export default class BridgeAccountPanel extends Mixins(mixins.CopyAddressMixin, TranslationMixin) {
@Prop({ default: '', type: String }) readonly address!: string;
@Prop({ default: '', type: String }) readonly name!: string;
@Prop({ default: '', type: String }) readonly tooltip!: string;
}
</script>

<style lang="scss">
.account-panel {
.account-gravatar {
border: none;
border-radius: 50%;

& > circle:first-child {
fill: var(--s-color-utility-surface);
}
}
}
</style>

<style lang="scss" scoped>
.account-panel {
display: flex;
align-items: center;
gap: $inner-spacing-mini;

&-name {
max-width: 80px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
</style>
8 changes: 5 additions & 3 deletions src/components/pages/Bridge/SelectAccount.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<dialog-base :visible.sync="visibility" :title="t('connection.selectAccount')" custom-class="account-select-dialog">
<div class="account-select">
<address-book-input v-model="address" :is-valid="validAddress" />
<address-book-input v-model="address" :is-valid="validAddress" ref="input" />

<s-button
class="s-typography-button--large account-select-button"
@@ -32,7 +32,7 @@ export default class BridgeSelectAccount extends Mixins(mixins.LoadingMixin, Tra
@state.web3.subAddress private subAddress!: string;
@state.web3.selectAccountDialogVisibility private selectAccountDialogVisibility!: boolean;
@mutation.web3.setSelectAccountDialogVisibility private setSelectAccountDialogVisibility!: (flag: boolean) => void;
@mutation.web3.setSubAddress private setSubAddress!: (address: string) => Promise<void>;
@mutation.web3.setSubAddress private setSubAddress!: (opts: { address: string; name: string }) => Promise<void>;

address = '';

@@ -60,7 +60,9 @@ export default class BridgeSelectAccount extends Mixins(mixins.LoadingMixin, Tra
}

handleSelectAddress(): void {
this.setSubAddress(this.address);
// [TODO] emit name from address-book-input
const name = this.address ? (this.$refs.input as any).name : '';
this.setSubAddress({ address: this.address, name });
this.visibility = false;
}
}
6 changes: 2 additions & 4 deletions src/components/pages/Bridge/SelectNetwork.vue
Original file line number Diff line number Diff line change
@@ -83,13 +83,11 @@ export default class BridgeSelectNetwork extends Mixins(NetworkFormatterMixin) {
let content = '';
let link = false;

if (type === BridgeNetworkType.Eth) {
content = this.t('hashiBridgeText');
} else if (id === SubNetwork.Polkadot) {
if (id === SubNetwork.Polkadot) {
content = 'https://parachains.info/details/sora_polkadot';
link = true;
} else if (disabled) {
content = `${this.t('comingSoonText')} (2024)`;
content = this.t('comingSoonText');
}

if (available) {
9 changes: 7 additions & 2 deletions src/components/shared/Dialog/SelectProvider.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<dialog-base :visible.sync="visibility" :title="t('connectEthereumWalletText')">
<dialog-base :visible.sync="visibility" :title="t('connectEthereumWalletText')" append-to-body>
<connection-items :size="providers.length">
<account-card
v-button
@@ -17,6 +17,7 @@
<s-button v-if="provider.connected" size="small" disabled>
{{ t('connection.wallet.connected') }}
</s-button>
<s-icon v-else-if="provider.loading" name="el-icon-loading" size="16" class="provider-loading-icon" />
</template>
</account-card>
</connection-items>
@@ -35,6 +36,7 @@ type WalletProvider = {
name: Provider;
icon: any;
connected: boolean;
loading: boolean;
};

@Component({
@@ -46,6 +48,8 @@ type WalletProvider = {
})
export default class SelectProviderDialog extends Mixins(WalletConnectMixin) {
@state.web3.selectProviderDialogVisibility private selectProviderDialogVisibility!: boolean;
@state.web3.evmProvider private evmProvider!: Nullable<Provider>;
@state.web3.evmProviderLoading private evmProviderLoading!: Nullable<Provider>;

get visibility(): boolean {
return this.selectProviderDialogVisibility;
@@ -63,13 +67,14 @@ export default class SelectProviderDialog extends Mixins(WalletConnectMixin) {
name: provider,
icon: this.getEvmProviderIcon(provider),
connected: provider === this.evmProvider,
loading: provider === this.evmProviderLoading,
};
});
}

handleProviderClick(provider: Provider): void {
this.visibility = false;
this.connectEvmProvider(provider);
this.visibility = false;
}
}
</script>
1 change: 1 addition & 0 deletions src/consts/index.ts
Original file line number Diff line number Diff line change
@@ -190,6 +190,7 @@ export enum Components {
BridgeSelectAccount = 'pages/Bridge/SelectAccount',
BridgeLinksDropdown = 'pages/Bridge/LinksDropdown',
BridgeLimitCard = 'pages/Bridge/LimitCard',
BridgeAccountPanel = 'pages/Bridge/AccountPanel',
// Moonpay Page
Moonpay = 'pages/Moonpay/Moonpay',
MoonpayNotification = 'pages/Moonpay/Notification',
16 changes: 16 additions & 0 deletions src/store/bridge/getters.ts
Original file line number Diff line number Diff line change
@@ -94,6 +94,14 @@ const getters = defineGetters<BridgeState>()({
return state.isSoraToEvm ? soraAddress : evmAddress;
},

senderName(...args): string {
const { state, rootState, getters } = bridgeGetterContext(args);
if (getters.isSubBridge) {
return rootState.wallet.account.name;
}
return state.isSoraToEvm ? rootState.wallet.account.name : '';
},

recipient(...args): string {
const { state, rootState, getters } = bridgeGetterContext(args);
const { address: soraAddress } = rootState.wallet.account;
@@ -106,6 +114,14 @@ const getters = defineGetters<BridgeState>()({
return state.isSoraToEvm ? evmAddress : soraAddress;
},

recipientName(...args): string {
const { state, rootState, getters } = bridgeGetterContext(args);
if (getters.isSubBridge) {
return rootState.web3.subAddressName;
}
return state.isSoraToEvm ? '' : rootState.wallet.account.name;
},

isEthBridge(...args): boolean {
const { rootState } = bridgeGetterContext(args);

7 changes: 4 additions & 3 deletions src/store/web3/actions.ts
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ const actions = defineActions({
async selectEvmProvider(context, provider: Provider): Promise<void> {
const { commit, dispatch, state } = web3ActionContext(context);
try {
commit.setEvmProviderLoading(true);
commit.setEvmProviderLoading(provider);
// reset prev connection
dispatch.resetEvmProviderConnection();
// create new connection
@@ -77,15 +77,16 @@ const actions = defineActions({
optionalChains: [...state.evmNetworkApps],
});
// if we have address - we are connected
if (address) {
// if provider not changed - continue
if (address && provider === state.evmProviderLoading) {
// set new provider data
commit.setEvmAddress(address);
commit.setEvmProvider(provider);
await updateProvidedEvmNetwork(context);
await subscribeOnEvm(context);
}
} finally {
commit.setEvmProviderLoading(false);
commit.setEvmProviderLoading();
}
},

7 changes: 4 additions & 3 deletions src/store/web3/mutations.ts
Original file line number Diff line number Diff line change
@@ -19,8 +19,9 @@ const mutations = defineMutations<Web3State>()({
ethersUtil.removeEvmUserAddress();
},

setSubAddress(state, address: string): void {
setSubAddress(state, { address, name }: { address: string; name: string }): void {
state.subAddress = address;
state.subAddressName = name;
},

setSubSS58(state, prefix: number) {
@@ -42,8 +43,8 @@ const mutations = defineMutations<Web3State>()({
resetEvmProvider(state): void {
state.evmProvider = null;
},
setEvmProviderLoading(state, flag: boolean): void {
state.evmProviderLoading = flag;
setEvmProviderLoading(state, provider: Nullable<Provider> = null): void {
state.evmProviderLoading = provider;
},
// by provider
setProvidedEvmNetwork(state, networkId: BridgeNetworkId | null): void {
3 changes: 2 additions & 1 deletion src/store/web3/state.ts
Original file line number Diff line number Diff line change
@@ -7,14 +7,15 @@ export function initialState(): Web3State {
return {
evmAddress: '', // external evm address
subAddress: '', // external sub address
subAddressName: '',
subSS58: 69, // external sub network ss58 prefix (sora by default)

networkType: null, // network type for selected network
networkSelected: null, // network selected by user

evmProvider: null,
evmProviderLoading: null,
evmProviderNetwork: null, // evm network in provider
evmProviderLoading: false,
evmProviderSubscription: null, // provider event listeners

evmNetworkApps: [], // evm networks from app config
3 changes: 2 additions & 1 deletion src/store/web3/types.ts
Original file line number Diff line number Diff line change
@@ -30,14 +30,15 @@ export type AvailableNetwork = {
export type Web3State = {
evmAddress: string;
subAddress: string;
subAddressName: string;
subSS58: number;

networkType: Nullable<BridgeNetworkType>;
networkSelected: Nullable<BridgeNetworkId>;

evmProvider: Nullable<Provider>;
evmProviderLoading: Nullable<Provider>;
evmProviderNetwork: Nullable<BridgeNetworkId>;
evmProviderLoading: boolean;
evmProviderSubscription: Nullable<FnWithoutArgs>;

evmNetworkApps: EvmNetwork[];
1 change: 1 addition & 0 deletions src/styles/common.scss
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ $networks: 'sora', 'ethereum', 'ethereum-classic', 'avalanche', 'klaytn', 'polyg
background-size: contain;
background-repeat: no-repeat;
background-position: center;
border-radius: 50%;

@each $network in $networks {
&--#{$network} {
Loading