Skip to content

Commit

Permalink
Merge pull request #10997 from hassnian/issue-10952
Browse files Browse the repository at this point in the history
feat: early success in offer modals
  • Loading branch information
vikiival authored Sep 19, 2024
2 parents 15317ef + 76aba7a commit 0a367cc
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 68 deletions.
18 changes: 18 additions & 0 deletions components/common/Notification.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@
<NeoIcon :icon="action.icon" />
</a>
</div>

<template
v-if="footer"
#footer
>
<div
class="flex items-center gap-2"
>
<NeoIcon :icon="footer.icon" />

<p class="text-xs">
{{ footer.label }}
</p>
</div>
</template>
</NeoMessage>
</template>

Expand All @@ -56,6 +71,7 @@ const props = withDefaults(
action?: MaybeRef<NotificationAction | undefined>
holdTimer?: Ref<boolean>
icon?: Ref<NeoMessageIconVariant | undefined>
footer?: Ref<Omit<NotificationAction, 'url'> | undefined>
}>(),
{
variant: 'success',
Expand All @@ -64,6 +80,7 @@ const props = withDefaults(
state: undefined,
holdTimer: undefined,
icon: undefined,
footer: undefined,
},
)
Expand All @@ -72,5 +89,6 @@ const message = computed(() => unref(props.message))
const action = computed(() => unref(props.action))
const holdTimer = computed(() => unref(props.holdTimer))
const icon = computed(() => unref(props.icon))
const footer = computed(() => unref(props.footer))
const variant = computed(() => unref(props.variant))
</script>
68 changes: 28 additions & 40 deletions components/offer/MakeOffer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:title="$t('transaction.offer')"
:is-loading="isLoading"
:status="status"
close-in-block
close-at-signed
@try-again="submitOffer"
/>

Expand Down Expand Up @@ -83,9 +83,7 @@ const {
} = useTransaction({
disableSuccessNotification: true,
})
const offerSession = ref<{ state: LoadingNotificationState, closeNotification?: () => void }>({
state: 'loading',
})
const { notification, lastSessionId, updateSession } = useLoadingNotfication()
const { itemsInChain, hasInvalidOfferPrices, count } = storeToRefs(offerStore)
const { decimals } = useChain()
Expand Down Expand Up @@ -180,27 +178,6 @@ const onClose = () => {
}
const closeMakingOfferModal = () => (preferencesStore.makeOfferModalOpen = false)
const showOfferCreationNotification = (session) => {
const isSessionState = (state: LoadingNotificationState) =>
session.value?.state === state
session.value.closeNotification = loadingMessage({
title: ref($i18n.t('offer.offerCreation')),
state: computed(() => session?.value.state as LoadingNotificationState),
action: computed<NotificationAction | undefined>(() => {
if (isSessionState('succeeded')) {
return {
label: $i18n.t('offer.manageOffers'),
icon: 'arrow-up-right',
url: `/${urlPrefix.value}/u/${accountId.value}`,
}
}
return undefined
}),
})
}
watch(
() => count.value,
() => {
Expand All @@ -217,21 +194,32 @@ useModalIsOpenTracker({
},
})
watch(isError, (error) => {
if (error) {
offerSession.value.closeNotification?.()
}
})
watch(status, (status) => {
switch (status) {
case TransactionStatus.Block:
showOfferCreationNotification(offerSession)
break
case TransactionStatus.Finalized:
offerSession.value.state = 'succeeded'
break
}
useTransactionNotification({
status,
isError,
sessionId: lastSessionId,
autoTeleport,
updateSession,
init: () => {
return notification(({ isSessionState, notify, session }) => {
return notify({
title: ref($i18n.t('offer.offerCreation')),
state: computed(() => session?.value.state as LoadingNotificationState),
action: computed<NotificationAction | undefined>(() => {
if (isSessionState('succeeded')) {
return {
label: $i18n.t('offer.manageOffers'),
icon: 'arrow-up-right',
url: `/${urlPrefix.value}/u/${accountId.value}?tab=offers&filter=outgoing`,
}
}
return undefined
}),
showIndexerDelayMessage: true,
})
})
},
})
onBeforeMount(closeMakingOfferModal)
Expand Down
34 changes: 12 additions & 22 deletions components/offer/OfferOverviewModal.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
<template>
<div>
<SigningModal
:title="details.signingTitle"
:is-loading="isLoading"
:status="status"
close-at-signed
@try-again="execTransaction"
/>

<NeoModal
:value="modelValue"
append-to-body
Expand Down Expand Up @@ -77,7 +85,6 @@
>
<OfferOwnerButton
class="!w-full"
:loading="starting"
:offer="offer"
@click="execTransaction"
/>
Expand Down Expand Up @@ -109,14 +116,13 @@ const vModel = useVModel(props, 'modelValue')
const { accountId } = useAuth()
const { urlPrefix, client } = usePrefix()
const { decimals, chainSymbol } = useChain()
const { transaction, status, isError } = useTransaction({ disableSuccessNotification: true })
const { transaction, status, isError, isLoading } = useTransaction({ disableSuccessNotification: true })
const { isOwnerOfNft } = useIsOffer(computed(() => props.offer), accountId)
const { $i18n } = useNuxtApp()
const { notification, lastSessionId, updateSession } = useLoadingNotfication()
const { $i18n: { t } } = useNuxtApp()
const offeredItem = ref<number>()
const starting = ref(false)
const subscription = ref(() => {})
const nftId = computed(() => props.offer?.desired.id)
Expand Down Expand Up @@ -195,7 +201,7 @@ const execTransaction = () => {
return
}
starting.value = true
vModel.value = false
if (isMyOffer.value) {
transaction({
Expand Down Expand Up @@ -234,23 +240,6 @@ watch(() => props.offer, () => {
}
})
useTransactionTracker({
transaction: {
isError,
status,
},
onCancel: () => {
starting.value = false
},
})
useModalIsOpenTracker({
isOpen: vModel,
onChange: () => {
starting.value = false
},
})
useTransactionNotification({
status,
isError,
Expand All @@ -267,11 +256,12 @@ useTransactionNotification({
return {
label: t('offer.manageOffers'),
icon: 'arrow-up-right',
url: `/${urlPrefix.value}/u/${accountId.value}`,
url: `/${urlPrefix.value}/u/${accountId.value}?tab=offers&filter=outgoing`,
}
}
return undefined
}),
showIndexerDelayMessage: true,
})
})
},
Expand Down
3 changes: 3 additions & 0 deletions components/shared/SigningModal/SigningModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ const props = withDefaults(
title: string
isError?: boolean
closeInBlock?: boolean
closeAtSigned?: boolean
}>(),
{
isError: false,
closeInBlock: false,
closeAtSigned: false,
},
)
Expand Down Expand Up @@ -84,6 +86,7 @@ watch(
if (
(props.closeInBlock && succeded)
|| (props.closeAtSigned && isLoading.value)
|| status === TransactionStatus.Finalized
) {
isModalActive.value = false
Expand Down
10 changes: 5 additions & 5 deletions composables/useTransactionNotification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@ type TransactionNotification = {
init: () => () => void
updateSession: ReturnType<typeof useLoadingNotfication>['updateSession']
initOn?: TransactionStatus[]
autoTeleport?: Ref<boolean>
}

export default function ({ status, isError, sessionId, init, updateSession, initOn = [TransactionStatus.Broadcast] }: TransactionNotification) {
export default function ({ status, isError, sessionId, init, updateSession, initOn = [TransactionStatus.Broadcast], autoTeleport = ref(false) }: TransactionNotification) {
const closeModal = ref(() => {})

watchEffect(() => {
if (initOn.includes(status.value)) {
if (initOn.includes(status.value) && !autoTeleport.value) {
closeModal.value = init()
}
})

useTransactionTracker({
successStatus: [TransactionStatus.Finalized],
transaction: {
isError,
status,
},
onSuccess: () => {
if (sessionId.value) {
if (sessionId.value && !autoTeleport.value) {
updateSession(sessionId.value, {
state: 'succeeded',
})
}
},
onError: () => {
if (sessionId.value) {
if (sessionId.value && !autoTeleport.value) {
closeModal.value?.()
}
},
Expand Down
7 changes: 7 additions & 0 deletions libs/ui/src/components/NeoMessage/NeoMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
</div>
</div>

<div
v-if="$slots.footer"
class="mt-3 mb-1"
>
<slot name="footer" />
</div>

<div
v-if="showProgressBar"
class="w-full h-1 message-progress absolute left-0 bottom-0 transition-all ease-linear"
Expand Down
3 changes: 2 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,8 @@
"finishingTouches": "Finishing Touches",
"almostThere": "Almost There",
"pleaseWait": "Please wait",
"copy": "Copy"
"copy": "Copy",
"updateOnWebsiteSoon": "Update on website visible soon"
},
"fiatOnRamp": {
"agree": "I agree to the",
Expand Down
8 changes: 8 additions & 0 deletions utils/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const showNotification = ({
variant,
holdTimer,
icon,
footer,
params = notificationTypes.info,
duration = 10000,
}: {
Expand All @@ -49,6 +50,7 @@ export const showNotification = ({
action?: MaybeRef<NotificationAction | undefined>
holdTimer?: Ref<boolean>
icon?: Ref<NeoMessageIconVariant | undefined>
footer?: Ref<Omit<NotificationAction, 'url'> | undefined>
}) => {
if (params === notificationTypes.danger) {
consola.error('[Notification Error]', message)
Expand All @@ -65,6 +67,7 @@ export const showNotification = ({
action: action,
holdTimer: holdTimer,
icon: icon,
footer: footer,
}),
variant: 'component',
duration: 50000, // child component will trigger close when the real duration is ended
Expand Down Expand Up @@ -174,13 +177,15 @@ export type LoadingMessageParams = {
message?: MaybeRef<string | undefined>
state: Ref<LoadingNotificationState>
action?: Ref<NotificationAction | undefined>
showIndexerDelayMessage?: boolean
}

export const loadingMessage = ({
title,
message,
state,
action,
showIndexerDelayMessage: showIndexerDelayMesasge = false,
}: LoadingMessageParams) => {
const { $i18n } = useNuxtApp()
const stateMessage = ref(unref(message) ?? `${$i18n.t('mint.progress')}...`)
Expand Down Expand Up @@ -214,5 +219,8 @@ export const loadingMessage = ({
icon: computed(() =>
isLoadingState.value ? { icon: 'spinner-third', spin: true } : undefined,
),
footer: computed(() =>
state.value === 'succeeded' && showIndexerDelayMesasge ? { icon: 'circle-info', label: $i18n.t('general.updateOnWebsiteSoon') } : undefined,
),
})
}

0 comments on commit 0a367cc

Please sign in to comment.