improve transaction ux

This commit is contained in:
Victor Oliva
2024-11-09 13:29:08 +07:00
parent e393661687
commit 2a5900b5f3
4 changed files with 38 additions and 14 deletions
+5 -3
View File
@@ -2,7 +2,7 @@ import { groupBy } from "@/lib/groupBy"
import type { SystemEvent } from "@polkadot-api/observable-client"
import { state } from "@react-rxjs/core"
import { combineKeys } from "@react-rxjs/utils"
import { filter, map, takeWhile } from "rxjs"
import { filter, map, takeWhile, tap } from "rxjs"
import { blockInfo$, BlockState, recordedBlocks$ } from "./block.state"
import { MAX_LENGTH } from "./BlockTable"
@@ -17,9 +17,11 @@ const blackList = new Set([
"TransactionPayment.TransactionFeePaid",
"Staking.Rewarded",
])
const whitelist = new Set(["System.Remarked"])
export const filterEvt = (evt: SystemEvent) =>
!blackList.has(`${evt.event.type}.*`) &&
!blackList.has(`${evt.event.type}.${evt.event.value.type}`)
whitelist.has(`${evt.event.type}.${evt.event.value.type}`) ||
(!blackList.has(`${evt.event.type}.*`) &&
!blackList.has(`${evt.event.type}.${evt.event.value.type}`))
export interface EventInfo {
status: BlockState
@@ -3,16 +3,19 @@ import { ActionButton } from "@/components/ActionButton"
import { onNexTx } from "@/pages/Transactions"
import { useStateObservable } from "@react-rxjs/core"
import { Binary } from "polkadot-api"
import { FC } from "react"
import { FC, useState } from "react"
import { noop } from "rxjs"
import { AccountProvider, selectedAccount$ } from "./AccountProvider"
import { ExtensionProvider } from "./ExtensionProvider"
import { Spinner } from "@/components/Icons"
import { twMerge } from "tailwind-merge"
const SignAndSubmit: FC<{ callData: string; onClose: () => void }> = ({
callData,
onClose,
}) => {
const account = useStateObservable(selectedAccount$)
const [isSigning, setIsSigning] = useState(false)
if (!account) return null
@@ -23,6 +26,7 @@ const SignAndSubmit: FC<{ callData: string; onClose: () => void }> = ({
const subscription = unsafeApi$.subscribe((client) => {
nClients++
if (nClients > 1) return subscription.unsubscribe()
setIsSigning(true)
client
.txFromCallData(Binary.fromHex(callData))
.then((x) => {
@@ -34,11 +38,16 @@ const SignAndSubmit: FC<{ callData: string; onClose: () => void }> = ({
}, noop)
.finally(() => {
subscription.unsubscribe()
setIsSigning(false)
})
})
}}
className="flex gap-2 items-center justify-center"
>
Sign and Submit
<span className={twMerge("ml-4", isSigning ? "" : "mr-6")}>
Sign and Submit
</span>
{isSigning && <Spinner size={16} />}
</ActionButton>
)
}
+12 -3
View File
@@ -5,9 +5,16 @@ import * as React from "react"
import { Link } from "react-router-dom"
import { onGoingEvents } from "./transactions.state"
export const Transaction: React.FC<
TxBroadcastEvent | { type: "invalid" | "error"; value: any; txHash: string }
> = (event) => {
export const Transaction: React.FC<{
event:
| TxBroadcastEvent
| {
type: "invalid" | "error"
value: any
txHash: string
}
onClose: () => void
}> = ({ event, onClose }) => {
const getStatus = () => {
const { type } = event
switch (event.type) {
@@ -26,6 +33,7 @@ export const Transaction: React.FC<
<Link
className="underline font-bold"
to={`/explorer/${event.block.hash}#tx=${event.block.index}`}
onClick={() => onClose()}
>
best block
</Link>
@@ -45,6 +53,7 @@ export const Transaction: React.FC<
<Link
className="underline font-bold"
to={`/explorer/${event.block.hash}#tx=${event.block.index}`}
onClick={() => onClose()}
>
{" "}
finalized block
+10 -6
View File
@@ -16,17 +16,15 @@ const txsSummary$ = grouppedTransactions$.pipeState(
)
const transactionList$ = grouppedTransactions$.pipeState(
map((x) =>
[...x.values()].map((props) => (
<Transaction key={props.txHash} {...props} />
)),
),
map((x) => [...x.values()]),
withDefault([]),
)
export function Transactions() {
const [isOpen, setIsOpen] = React.useState(false)
const { nTxs, nOngoing } = useStateObservable(txsSummary$)
const list = useStateObservable(transactionList$)
return !nTxs ? null : (
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
<Dialog.Trigger asChild>
@@ -54,7 +52,13 @@ export function Transactions() {
</Dialog.Close>
</div>
<div className="p-4 h-[calc(100%-4rem)] overflow-y-auto">
{transactionList$}
{list.map((event) => (
<Transaction
key={event.txHash}
event={event}
onClose={() => setIsOpen(false)}
/>
))}
</div>
</Dialog.Content>
</Dialog.Portal>