1
1
import * as Progress from "@radix-ui/react-progress"
2
- import { useStateObservable } from "@react-rxjs/core"
3
- import { useEffect , useState } from "react"
4
- import { senderChainId$ , submitTransfer$ , transferStatus$ } from "./send"
5
- import { state } from "@react-rxjs/core"
6
- import { allChains , ChainId } from "@/api"
7
- import { of , merge } from "rxjs"
2
+ import { state , useStateObservable , withDefault } from "@react-rxjs/core"
3
+ import { map , of , switchMap , withLatestFrom } from "rxjs"
4
+ import {
5
+ senderChainId$ ,
6
+ submitTransfer$ ,
7
+ TransactionStatus ,
8
+ transferStatus$ ,
9
+ } from "./send"
10
+ import { allChains } from "@/api"
11
+ import { twMerge } from "tailwind-merge"
12
+
13
+ transferStatus$ . subscribe ( )
8
14
9
15
const finalizedBlock$ = state (
10
- ( chainId : ChainId | "" ) =>
11
- chainId === "" ? of ( null ) : allChains [ chainId ] . client . finalizedBlock$ ,
16
+ senderChainId$ . pipe (
17
+ switchMap ( ( chain ) =>
18
+ chain ? allChains [ chain ] . client . finalizedBlock$ : of ( null ) ,
19
+ ) ,
20
+ ) ,
12
21
null ,
13
22
)
14
23
15
- const subscriptions = state ( merge ( transferStatus$ ) ) . subscribe ( )
24
+ const progress$ = transferStatus$ . pipeState (
25
+ withLatestFrom ( finalizedBlock$ ) ,
26
+ switchMap ( ( [ v , finalized ] ) => {
27
+ if ( ! v ) return [ null ]
16
28
17
- export default function Submit ( ) {
18
- const txStatus = useStateObservable ( transferStatus$ )
19
- const selectedChain = useStateObservable ( senderChainId$ ) !
20
- const finalizedBlock = useStateObservable ( finalizedBlock$ ( selectedChain ) )
29
+ if (
30
+ v . status === TransactionStatus . BestBlock &&
31
+ "number" in v &&
32
+ v . number &&
33
+ finalized
34
+ ) {
35
+ const start = finalized . number
36
+ const end = v . number
37
+ return finalizedBlock$ . pipe (
38
+ map ( ( finalized ) => ( {
39
+ ok : v . ok ,
40
+ value : v . status ,
41
+ subProgress : {
42
+ value : finalized ! . number - start ,
43
+ total : end - start ,
44
+ } ,
45
+ } ) ) ,
46
+ )
47
+ }
21
48
22
- const [ isSubmitting , setSubmitting ] = useState ( false )
23
- const [ isTransacting , setIsTransacting ] = useState ( false )
24
- const [ statusLabel , setStatusLabel ] = useState ( "" )
49
+ return [
50
+ {
51
+ ok : v . ok ,
52
+ value : v . status ,
53
+ } ,
54
+ ]
55
+ } ) ,
56
+ withDefault ( null ) ,
57
+ )
25
58
26
- const [ progress , setProgress ] = useState ( 2 )
59
+ const transactionStatusLabel : Record < TransactionStatus , string > = {
60
+ [ TransactionStatus . Signing ] : "Signing" ,
61
+ [ TransactionStatus . Broadcasted ] :
62
+ "Broadcasting complete. Sending to best blocks" ,
63
+ [ TransactionStatus . BestBlock ] : "In best block state: " ,
64
+ [ TransactionStatus . Finalized ] : "Transaction completed successfully!" ,
65
+ }
27
66
28
- useEffect ( ( ) => {
29
- setProgress ( 5 )
30
- } , [ isSubmitting ] )
67
+ export default function Submit ( ) {
68
+ const selectedChain = useStateObservable ( senderChainId$ )
31
69
32
- useEffect ( ( ) => {
33
- switch ( txStatus ?. type ) {
34
- case "signed" : {
35
- setProgress ( 25 )
36
- setIsTransacting ( true )
37
- setStatusLabel ( "Transaction Signed successfully. Broadcasting..." )
38
- break
39
- }
40
- case "broadcasted" :
41
- setProgress ( 50 )
42
- setStatusLabel ( "Broadcasting complete. Sending to best blocks" )
43
- break
44
- case "txBestBlocksState" :
45
- setProgress ( 75 )
46
- setStatusLabel ( "In best blocks state: " )
47
- // set micro progress per block
48
- break
49
- case "finalized" :
50
- setProgress ( 100 )
51
- setStatusLabel ( "Transaction completed successfully!" )
70
+ const txProgress = useStateObservable ( progress$ )
71
+ const isTransacting =
72
+ txProgress && txProgress . value > TransactionStatus . Signing
73
+ const isSigning = ! ! txProgress && ! isTransacting
74
+ const progress =
75
+ ( txProgress ?. value ?? 0 ) +
76
+ ( txProgress && "subProgress" in txProgress
77
+ ? ( 50 * txProgress . subProgress . value ) / txProgress . subProgress . total
78
+ : 0 )
52
79
53
- // setTimeout(() => )
54
- break
55
- }
56
- } , [ txStatus ] )
80
+ if ( ! selectedChain ) return null
57
81
58
82
return (
59
83
< div className = "mb-5" >
60
84
{ isTransacting ? (
61
85
< >
62
- < div className = "mb-4 text-pink font-semibold flex flex-col" >
63
- < span > { statusLabel } </ span >
64
- { txStatus ?. type === "txBestBlocksState" && txStatus . found === true
65
- ? `${ finalizedBlock ?. number } /${ txStatus . block . number } `
86
+ < div
87
+ className = { twMerge (
88
+ "mb-4 text-pink font-semibold flex flex-col" ,
89
+ txProgress . ok ? "" : "text-orange-500" ,
90
+ ) }
91
+ >
92
+ < span > { transactionStatusLabel [ txProgress . value ] } </ span >
93
+ { "subProgress" in txProgress
94
+ ? `${ txProgress . subProgress . value } /${ txProgress . subProgress . total } `
66
95
: null }
67
96
</ div >
68
97
< Progress . Root
@@ -81,14 +110,11 @@ export default function Submit() {
81
110
) : (
82
111
< >
83
112
< button
84
- className = { `rounded mb-10 bg-pink p-2 text-white w-40 ${ ! selectedChain || isSubmitting ? "opacity-80" : "" } ` }
85
- disabled = { ! selectedChain || isSubmitting }
86
- onClick = { ( ) => {
87
- submitTransfer$ ( )
88
- setSubmitting ( true )
89
- } }
113
+ className = { `rounded mb-10 bg-pink p-2 text-white w-40 ${ isSigning ? "opacity-80" : "" } ` }
114
+ disabled = { isSigning }
115
+ onClick = { submitTransfer$ }
90
116
>
91
- { isSubmitting ? "Sign transaction" : "Send Transaction" }
117
+ { isSigning ? "Sign transaction" : "Send Transaction" }
92
118
</ button >
93
119
</ >
94
120
) }
0 commit comments