Skip to content

Commit

Permalink
TWPAPP-960: Change pegin flow according to the new design
Browse files Browse the repository at this point in the history
  • Loading branch information
lserra-iov committed Oct 28, 2024
1 parent 19448f2 commit a7ec12a
Show file tree
Hide file tree
Showing 11 changed files with 478 additions and 150 deletions.
12 changes: 12 additions & 0 deletions src/common/styles/_cards.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,15 @@
border-color: rgba(var(--v-border-color), 1);
}
}

.not-available {
position: relative;
.not-available-text {
position: absolute;
inset: 0;
background-color: rgba(var(--v-theme-background), 0.5);
backdrop-filter: blur(4px);
opacity: 1;
z-index: 1;
}
}
1 change: 1 addition & 0 deletions src/common/styles/_inputs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ input[type=number].v-field__input, .v-select__selection, .amount-input input[typ
font-size: 1.5rem;
font-weight: 700;
line-height: 1;
padding-block: 0;
}

.v-field--focused {
Expand Down
5 changes: 5 additions & 0 deletions src/common/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ a:hover {
--v-avatar-height: 16px;
}
}

.v-tooltip > .v-overlay__content {
background-color: rgb(var(--v-theme-bw-700));
color: white;
}
4 changes: 2 additions & 2 deletions src/pegin/components/create/BtcFeeSelect.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<v-row class="align-start mx-0">
<v-col class="px-0 py-6">
<v-row no-gutters>
<v-col class="pa-0">
<span class="d-inline-block font-weight-bold">
Select transaction fee
</span>
Expand Down
169 changes: 169 additions & 0 deletions src/pegin/components/create/BtcInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<template>
<v-col class="d-flex flex-column ga-2">
<span class="font-weight-bold">
Amount to send
</span>
<v-text-field
hide-details
hide-spin-buttons
flat
variant="solo"
density="comfortable"
rounded="lg"
:class="(!isValidAmount && isInputFilled) && 'input-error'"
class="text-h4 flex-grow-0 amount-input"
v-model="bitcoinAmountModel"
type="text"
:readonly="isComposing"
@compositionstart="isComposing = true"
@keydown="blockLetterKeyDown"
@wheel.prevent
@focus="focus = true"
@blur="focus = false"
>
<template #prepend-inner>
<v-chip density="comfortable" :prepend-icon="mdiBitcoin" class="btc-icon">
{{ environmentContext.getBtcTicker() }}
</v-chip>
</template>
<template #append-inner>
<div class="d-flex px-2 ga-1">
<v-chip variant="outlined" density="compact" @click="setMin">
{{ boundaries.minValue.toBTCString().slice(0,5) }} MIN
</v-chip>
</div>
</template>
</v-text-field>
<div>
<v-alert v-if="!isValidAmount && isInputFilled" :text="amountErrorMessage"
density="compact" type="warning" color="orange"/>
</div>
</v-col>
</template>

<script lang="ts">
import EnvironmentContextProviderService from '@/common/providers/EnvironmentContextProvider';
import {
computed, defineComponent, ref, watch,
} from 'vue';
import SatoshiBig from '@/common/types/SatoshiBig';
import {
PeginConfiguration,
} from '@/common/types/pegInTx';
import { useAction, useGetter, useStateAttribute } from '@/common/store/helper';
import { mdiBitcoin } from '@mdi/js';
import * as constants from '@/common/store/constants';
import { isBTCAmountValidRegex } from '@/common/utils';
export default defineComponent({
name: 'BtcInput',
setup(props, context) {
const environmentContext = EnvironmentContextProviderService.getEnvironmentContext();
const peginConfiguration = useStateAttribute<PeginConfiguration>('pegInTx', 'peginConfiguration');
const boundaries = computed(() => {
const minValue: SatoshiBig = new SatoshiBig(peginConfiguration.value.minValue, 'btc');
return {
minValue,
};
});
const isComposing = ref(false);
watch(isComposing, () => {
const timeout = setTimeout(() => { isComposing.value = false; }, 200);
return () => clearTimeout(timeout);
});
const bitcoinAmount = ref('');
function blockLetterKeyDown(e: KeyboardEvent) {
const allowedKeys = ['Backspace', 'Delete', 'Home', 'End', 'ArrowRight', 'ArrowLeft'];
if (allowedKeys.includes(e.key)) return;
if (e.key === '.' && (bitcoinAmount.value && !bitcoinAmount.value.includes('.'))) return;
const decimals = bitcoinAmount.value.split('.').pop() ?? '';
if (decimals.length >= 8 || Number.isNaN(Number(e.key)) || e.key === ' ') {
e.preventDefault();
}
}
const setBtcAmountPeginTx = useAction('pegInTx', constants.PEGIN_TX_ADD_AMOUNT_TO_TRANSFER);
const setBtcAmountFlyover = useAction('flyoverPegin', constants.FLYOVER_PEGIN_ADD_AMOUNT);
function setBtcAmount(amount: SatoshiBig) {
setBtcAmountPeginTx(amount);
setBtcAmountFlyover(amount);
}
const safeTxFee = useGetter<SatoshiBig>('pegInTx', constants.PEGIN_TX_GET_SAFE_TX_FEE);
const safeAmount = useStateAttribute<SatoshiBig>('pegInTx', 'amountToTransfer');
const selectedAccountBalance = useGetter<SatoshiBig>('pegInTx', constants.PEGIN_TX_GET_SELECTED_BALANCE);
const insufficientAmount = computed(() => {
const feePlusAmount: SatoshiBig = safeAmount.value.plus(safeTxFee.value);
const { minValue } = boundaries.value;
if (safeAmount.value.lte('0')
|| feePlusAmount.gt(selectedAccountBalance.value)
|| safeAmount.value.lt(minValue)) {
return true;
}
if (safeAmount.value.gt('0') && feePlusAmount.lte(selectedAccountBalance.value)) {
return false;
}
return false;
});
const amountErrorMessage = computed(() => {
const { minValue } = boundaries.value;
if (safeAmount.value.lt(minValue)) {
return `The minimum accepted value is ${minValue.toBTCTrimmedString()} ${environmentContext.getBtcTicker()}`;
}
const feePlusAmount: SatoshiBig = safeAmount.value.plus(safeTxFee.value);
if (feePlusAmount.gte(selectedAccountBalance.value)) {
return 'You don\'t have the balance for this amount';
}
if (isBTCAmountValidRegex(bitcoinAmount.value)) {
return 'The amount must be a valid Bitcoin value';
}
return '';
});
const isInputFilled = computed(() => bitcoinAmount.value !== '');
const isValidAmount = computed(() => !insufficientAmount.value
&& isBTCAmountValidRegex(bitcoinAmount.value));
function emitIsValidAmount() {
const amount = new SatoshiBig(Number(bitcoinAmount.value), 'btc');
setBtcAmount(amount);
context.emit('validAmount', isValidAmount.value, bitcoinAmount.value);
}
const timeOutId = ref(0);
const bitcoinAmountModel = computed({
get() {
return bitcoinAmount.value;
},
set(amount: string) {
window.clearTimeout(timeOutId.value);
bitcoinAmount.value = amount;
timeOutId.value = window.setTimeout(emitIsValidAmount, 300);
},
});
function setMin() {
const { minValue } = boundaries.value;
bitcoinAmountModel.value = minValue.toBTCTrimmedString();
}
return {
environmentContext,
boundaries,
mdiBitcoin,
isComposing,
blockLetterKeyDown,
bitcoinAmountModel,
isValidAmount,
isInputFilled,
amountErrorMessage,
setMin,
};
},
});
</script>
Loading

0 comments on commit a7ec12a

Please sign in to comment.