Skip to content

Commit

Permalink
improve transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
zlayine committed Aug 18, 2023
1 parent 6e96404 commit e923227
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 172 deletions.
27 changes: 22 additions & 5 deletions resources/js/components/SignTransaction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
</Btn>
<Modal :is-open="showAccountsModal" :close="closeModal" width="max-w-lg">
<DialogTitle as="h3" class="text-lg font-medium leading-6 text-gray-900 text-center">
Select an account to sign
Select an account to sign the transaction
</DialogTitle>
<div class="flex flex-col space-y-2 mt-4">
<div>Transaction fee: {{ feeCost }}</div>
<div
v-for="account in useAppStore().accounts"
:key="account.address"
Expand All @@ -32,6 +33,7 @@ import Btn from './Btn.vue';
import Modal from './Modal.vue';
import { addressShortHex } from '~/util/address';
import { useAppStore } from '~/store';
import { useTransactionStore } from '~/store/transaction';
import { ref } from 'vue';
import LoadingCircle from './LoadingCircle.vue';
import snackbar from '~/util/snackbar';
Expand All @@ -45,10 +47,25 @@ const emit = defineEmits(['success']);
const isLoading = ref(false);
const showAccountsModal = ref(false);
const feeCost = ref(0);
const appStore = useAppStore();
const transactionStore = useTransactionStore();
const signTransaction = async () => {
useAppStore().getAccounts();
showAccountsModal.value = true;
try {
if (!appStore.provider) {
snackbar.error({ title: 'Please connect your wallet to sign' });
return;
}
appStore.getAccounts();
await transactionStore.init();
feeCost.value = await transactionStore.getTransactionCost(props.transaction);
showAccountsModal.value = true;
} catch (e) {
console.log(e)
snackbar.error({ title: 'Failed to sign transaction' });
}
};
const closeModal = () => {
Expand All @@ -58,9 +75,9 @@ const closeModal = () => {
const selectAccount = async (account) => {
try {
isLoading.value = true;
useAppStore().setAccount(account);
appStore.setAccount(account);
showAccountsModal.value = false;
const res = await useAppStore().signTransaction(props.transaction);
const res = await transactionStore.signTransaction(props.transaction);
if (res) {
emit('success');
}
Expand Down
7 changes: 6 additions & 1 deletion resources/js/components/Slideover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
@close="emit('close')"
@update="($event) => emit('update', $event)"
/>
<XMarkIcon
class="absolute top-0 right-0 w-6 h-6 mt-4 mr-6 text-black cursor-pointer hover:text-gray-500 transition-all"
@click="emit('close')"
/>
</DialogPanel>
</TransitionChild>
</div>
Expand All @@ -33,6 +37,7 @@

<script setup lang="ts">
import { Dialog, DialogPanel, TransitionChild, TransitionRoot } from '@headlessui/vue';
import { XMarkIcon } from '@heroicons/vue/20/solid';
import { defineAsyncComponent, shallowRef, watch } from 'vue';
const emit = defineEmits(['close', 'update']);
Expand All @@ -53,7 +58,7 @@ const props = withDefaults(
const loadComponent = () => {
component.value = defineAsyncComponent({
loader: () => import(`~/components/slideovers/${props.item.componentPath}/${props.item.componentName}.vue`),
loader: () => import(`~/components/slideovers/${props.item?.componentPath}/${props.item?.componentName}.vue`),
timeout: 3000,
suspensible: false,
});
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/beam/BeamsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ import Slideover from '~/components/Slideover.vue';
import debounce from 'lodash/debounce';
import snackbar, { events } from '~/util/snackbar';
import FormInput from '~/components/FormInput.vue';
import { CodeType } from '~/types/types.enums';
import { CodeType, TransactionState } from '~/types/types.enums';
import { shortCode } from '~/util/address';
import NoItems from '~/components/NoItems.vue';
import Btn from '~/components/Btn.vue';
Expand Down Expand Up @@ -421,7 +421,7 @@ const openTransactionSlide = async (transactionId: string) => {
if (modalSlide.value) closeModalSlide();
setTimeout(() => {
openModalSlide('DetailsTransactionSlideover', { transactionId });
openModalSlide('DetailsTransactionSlideover', { id: transactionId, state: TransactionState.PENDING });
}, 600);
};
Expand Down
3 changes: 2 additions & 1 deletion resources/js/components/pages/Collections.vue
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ import FormInput from '~/components/FormInput.vue';
import NoItems from '~/components/NoItems.vue';
import { snackbarErrors } from '~/util';
import Btn from '~/components/Btn.vue';
import { TransactionState } from '~/types/types.enums';

const isLoading = ref(true);
const isPaginationLoading = ref(false);
Expand Down Expand Up @@ -283,7 +284,7 @@ const openTransactionSlide = async (transactionId: string) => {
if (modalSlide.value) closeModalSlide();

setTimeout(() => {
openModalSlide('DetailsTransactionSlideover', { transactionId });
openModalSlide('DetailsTransactionSlideover', { id: transactionId, state: TransactionState.PENDING });
}, 600);
};

Expand Down
3 changes: 2 additions & 1 deletion resources/js/components/pages/FuelTanks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ import NoItems from '~/components/NoItems.vue';
import { FuelTankApi } from '~/api/fueltank';
import { formatData } from '~/util';
import Btn from '../Btn.vue';
import { TransactionState } from '~/types/types.enums';
const isLoading = ref(true);
const isPaginationLoading = ref(false);
Expand Down Expand Up @@ -288,7 +289,7 @@ const openTransactionSlide = async (transactionId: string) => {
if (modalSlide.value) closeModalSlide();
setTimeout(() => {
openModalSlide('DetailsTransactionSlideover', { transactionId });
openModalSlide('DetailsTransactionSlideover', { id: transactionId, state: TransactionState.PENDING });
}, 600);
};
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/pages/Tokens.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ import LoadingContent from '~/components/LoadingContent.vue';
import Slideover from '~/components/Slideover.vue';
import debounce from 'lodash/debounce';
import { formatTokens, snackbarErrors } from '~/util';
import { TokenIdSelectType } from '~/types/types.enums';
import { TokenIdSelectType, TransactionState } from '~/types/types.enums';
import TokenIdInput from '~/components/TokenIdInput.vue';
import snackbar, { events } from '~/util/snackbar';
import FormInput from '~/components/FormInput.vue';
Expand Down Expand Up @@ -302,7 +302,7 @@ const openTransactionSlide = async (transactionId: string) => {
if (modalSlide.value) closeModalSlide();
setTimeout(() => {
openModalSlide('DetailsTransactionSlideover', { transactionId });
openModalSlide('DetailsTransactionSlideover', { id: transactionId, state: TransactionState.PENDING });
}, 600);
};
Expand Down
3 changes: 3 additions & 0 deletions resources/js/components/pages/Transactions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,11 @@ const onSuccess = async (id) => {
p.result = res.result;
p.transactionId = res.transactionId;
}
return p;
});
openModalSlide('DetailsTransactionSlideover', res);
};
const getTransaction = async (id) => {
Expand Down
3 changes: 2 additions & 1 deletion resources/js/components/pages/Wallets.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import { formatData, snackbarErrors } from '~/util';
import snackbar, { events } from '~/util/snackbar';
import FormInput from '~/components/FormInput.vue';
import NoItems from '~/components/NoItems.vue';
import { TransactionState } from '~/types/types.enums';
const isLoading = ref(false);
const isPaginationLoading = ref(false);
Expand Down Expand Up @@ -215,7 +216,7 @@ const openTransactionSlide = async (transactionId: string) => {
if (modalSlide.value) closeModalSlide();
setTimeout(() => {
openModalSlide('DetailsTransactionSlideover', { transactionId });
openModalSlide('DetailsTransactionSlideover', { id: transactionId, state: TransactionState.PENDING });
}, 600);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
<template>
<div class="flex h-full flex-col divide-y divide-gray-200 bg-white shadow-xl">
<h3 class="text-xl font-semibold px-4 sm:px-6 py-4 text-gray-900">
Transaction Details for {{ item?.transactionId ?? item?.id }}
Transaction Details for {{ transaction?.transactionId ?? transaction?.id }}
</h3>
<div class="h-0 flex-1 overflow-y-auto">
<div class="flex flex-1 flex-col justify-between">
<div class="px-4 sm:px-6 divide-y divide-gray-200">
<div>
<div v-if="!webSocketEvents && !transaction?.state">
<LoadingCircle :size="40" class="pt-10" />
<p class="text-center pt-2">Waiting for transaction...</p>
</div>
<div
v-else-if="webSocketEvents || transaction.state !== TransactionState.FINALIZED"
class="py-4"
>
<div class="space-y-2 pt-2 pb-2" v-for="(event, idx) in webSocketEvents" :key="idx">
<dt class="text-base font-medium text-gray-500">{{ event.title }}</dt>
<dd class="mt-1 text-sm text-gray-900">{{ event.value }}</dd>
<template v-if="transaction?.state === TransactionState.PENDING">
<div class="flex justify-center py-4">
<SignTransaction :transaction="transaction" @success="signedTransaction" />
</div>
</template>

<Btn
v-if="transaction?.state !== TransactionState.FINALIZED"
class="!mx-auto !flex"
primary
:loading="isLoading"
:disabled="isLoading"
@click="getTransaction"
>
Get More Transaction Details
</Btn>
<div class="text-xs text-center mx-auto mt-4">
Usually it takes few seconds to finilize the transaction
<template v-if="transaction?.state !== TransactionState.FINALIZED">
<div v-if="!webSocketEvents && webSocket">
<LoadingCircle :size="40" class="pt-10" />
<p class="text-center py-4">Waiting for the transaction details...</p>
</div>
</div>
<div v-else-if="webSocketEvents" class="py-4">
<div class="space-y-2 pt-2 pb-2" v-for="(event, idx) in webSocketEvents" :key="idx">
<dt class="text-base font-medium text-gray-500">{{ event.title }}</dt>
<dd class="mt-1 text-sm text-gray-900">{{ event.value }}</dd>
</div>

<Btn
v-if="transaction?.state !== TransactionState.FINALIZED"
class="!mx-auto !flex"
primary
:loading="isLoading"
:disabled="isLoading"
@click="getTransaction"
>
Get More Transaction Details
</Btn>
<div class="text-xs text-center mx-auto mt-4" v-if="!webSocketEvents.length">
Usually it takes few seconds to finilize the transaction
</div>
</div>
</template>
</div>

<div v-if="transaction" class="animate-fade-in" as="div">
Expand Down Expand Up @@ -69,8 +74,8 @@
</dd>
</div>

<h3 class="text-xl font-semibold pt-4 text-gray-900" v-if="events.length">Events</h3>
<div class="space-y-2 pb-3 divide divide-y divide-gray-300" v-if="events.length">
<h3 class="text-xl font-semibold pt-4 text-gray-900" v-if="events?.length">Events</h3>
<div class="space-y-2 pb-3 divide divide-y divide-gray-300" v-if="events?.length">
<div class="" v-for="event in events" :key="event">
<div class="space-y-2 pt-4 pb-3">
<dt class="text-base font-medium text-gray-500">Event ID</dt>
Expand All @@ -91,7 +96,7 @@
</div>
</div>

<template v-if="useAppStore().advanced && advancedEvents.length">
<template v-if="useAppStore().advanced && advancedEvents?.length">
<h3 class="text-xl font-semibold pt-4 text-gray-900">Advanced Events</h3>
<div class="space-y-2 pb-3 divide divide-y divide-gray-300" v-if="advancedEvents.length">
<div class="" v-for="event in advancedEvents" :key="event">
Expand Down Expand Up @@ -122,13 +127,15 @@
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { ref, computed, watch } from 'vue';
import { TransactionApi } from '~/api/transaction';
import Address from '~/components/Address.vue';
import Btn from '~/components/Btn.vue';
import CopyTextIcon from '~/components/CopyTextIcon.vue';
import LoadingCircle from '~/components/LoadingCircle.vue';
import SignTransaction from '~/components/SignTransaction.vue';
import TransactionResultChip from '~/components/TransactionResultChip.vue';
import { DTOTransactionFactory } from '~/factory/transaction';
import { useAppStore } from '~/store';
import { TransactionState } from '~/types/types.enums';

Expand Down Expand Up @@ -166,13 +173,13 @@ const isAddressKey = (key) => ['who', 'operator', 'account', 'owner'].includes(k
const getTransaction = async () => {
try {
isLoading.value = true;
const res = await TransactionApi.getTransaction(props.item?.transactionId ?? props.item?.id ?? '');
const transactionData = res.data.GetTransaction;
transaction.value = transactionData;
if (transactionData.state === TransactionState.FINALIZED) {
emit('update', transactionData);
const res = await TransactionApi.getTransaction(props.item?.id ?? '');
transaction.value = DTOTransactionFactory.forTransaction(res);
if (transaction.value.state === TransactionState.FINALIZED) {
emit('update', transaction.value);
}
} catch (error) {
console.log(error);
// Do notihing
}
isLoading.value = false;
Expand All @@ -187,7 +194,6 @@ const parseWSMessage = (e) => {
value,
};
});
webSocket.value.close();
}
};

Expand All @@ -199,7 +205,7 @@ const connectWebSocket = () => {
const payload = {
event: 'pusher:subscribe',
data: {
channel: appStore.user?.account,
channel: 'platform',
},
};
webSocket.value.send(JSON.stringify(payload));
Expand All @@ -210,17 +216,32 @@ const connectWebSocket = () => {
};
};

const closeWebSocket = () => {
webSocket.value?.close();
};

const signedTransaction = () => {
transaction.value.state = TransactionState.BROADCAST;
};

(async () => {
if (props.item?.id) {
transaction.value = props.item;
} else {
connectWebSocket();
setTimeout(() => {
if (!webSocketEvents.value) {
if (webSocket.value) webSocket.value.close();
getTransaction();
}
}, 25000);
}
await getTransaction();
setTimeout(() => {
if (!webSocketEvents.value) {
if (webSocket.value) webSocket.value.close();
getTransaction();
}
}, 25000);
})();

watch(
() => transaction.value?.state,
() => {
if (transaction.value.state === TransactionState.BROADCAST) {
connectWebSocket();
} else if (transaction.value.state === TransactionState.FINALIZED) {
closeWebSocket();
}
}
);
</script>
5 changes: 1 addition & 4 deletions resources/js/factory/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ export class DTOTransactionFactory {
public static forTransaction(transactionData: any): any {
const transaction = transactionData.data.GetTransaction;

return {
items: [DTOTransactionFactory.buildTransaction(transaction)],
cursor: null,
};
return DTOTransactionFactory.buildTransaction(transaction);
}
}
Loading

0 comments on commit e923227

Please sign in to comment.