Skip to content

Commit

Permalink
Merge pull request #13 from polkadot-api/send-progress
Browse files Browse the repository at this point in the history
Add progress bar
  • Loading branch information
hannahredler authored Aug 20, 2024
2 parents 0feff91 + 3a21fdd commit a9165c9
Show file tree
Hide file tree
Showing 15 changed files with 228 additions and 40 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@headlessui/react": "^2.1.2",
"@polkadot-api/descriptors": "file:.papi/descriptors",
"@radix-ui/react-progress": "^1.1.0",
"@react-rxjs/core": "^0.10.7",
"@react-rxjs/utils": "^0.9.7",
"@remix-run/router": "^1.19.1",
Expand Down
94 changes: 94 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/AccountSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const AccountSelector: React.FC = () => {
<div>
<button
className={twMerge(
"border border-[#ff007b] rounded-full px-4 hover:bg-gray-200",
"border border-pink rounded-full px-4 hover:bg-pink hover:text-white",
buttonStyles,
)}
onClick={() => setAccountPickerOpen(true)}
Expand Down
84 changes: 71 additions & 13 deletions src/actions/send/Submit.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,83 @@
import { useStateObservable } from "@react-rxjs/core"
import { useStateObservable, state } from "@react-rxjs/core"
import { submitTransfer$, transferStatus$, senderChainId$ } from "./send"
import { useState } from "react"
import { useEffect, useState } from "react"
import * as Progress from "@radix-ui/react-progress"
import { allChains, ChainId } from "@/api"
import { of } from "rxjs"

const subscriptions = transferStatus$.subscribe()

// const finalizedBlock$ = state((chainId: ChainId | "") =>
// chainId === "" ? of(null) : allChains[chainId].client.finalizedBlock$,
// )

export default function Submit() {
const txStatus = useStateObservable(transferStatus$)
const selectedChain = useStateObservable(senderChainId$)
const selectedChain = useStateObservable(senderChainId$)!
// const finalizedBlock = useStateObservable(finalizedBlock$(selectedChain))
// const [firstBestBlock, setFirstBestBlock] = useState<number | null>(null)

const [isSubmitting, setSubmitting] = useState(false)
const [isTransacting, setIsTransacting] = useState(false)

const [progress, setProgress] = useState(2)

useEffect(() => {
setProgress(5)
}, [isSubmitting])

useEffect(() => {
switch (txStatus?.type) {
case "signed": {
setProgress(25)
setIsTransacting(true)
break
}
case "broadcasted":
setProgress(50)
break
case "txBestBlocksState":
setProgress(75)
// set micro progress per block
break
case "finalized":
setProgress(100)
break
}
}, [txStatus])

return (
<button
className={`rounded bg-pink-500 p-2 text-white w-40 ${!selectedChain || isSubmitting ? "opacity-80" : ""}`}
disabled={!selectedChain || isSubmitting}
onClick={() => {
submitTransfer$()
setSubmitting(true)
}}
>
{isSubmitting ? "Sending..." : "Send Transaction"}
</button>
<div>
{isTransacting ? (
<>
<Progress.Root
value={progress}
className="bg-pink w-[350px] h-4 relative overflow-hidden rounded-xl"
>
<Progress.Indicator
className="bg-purple-600 w-full h-full"
style={{
transition: "transform 660ms cubic-bezier(0.65, 0, 0.35, 1)",
transform: `translateX(-${100 - progress}%)`,
}}
/>
</Progress.Root>
{txStatus?.type}
</>
) : (
<>
<button
className={`rounded mb-10 bg-pink p-2 text-white w-40 ${!selectedChain || isSubmitting ? "opacity-80" : ""}`}
disabled={!selectedChain || isSubmitting}
onClick={() => {
submitTransfer$()
setSubmitting(true)
}}
>
{isSubmitting ? "Sign transaction" : "Send Transaction"}
</button>
</>
)}
</div>
)
}
33 changes: 27 additions & 6 deletions src/api/allChains.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,86 @@
import { ChainDefinition, TypedApi } from "polkadot-api"
import { ChainDefinition, PolkadotClient, TypedApi } from "polkadot-api"
import { ChainSpec } from "./chainspec"
import { decodedPolkadotSpec, polkadotApi } from "./polkadot"
import { decodedPolkadotSpec, polkadotApi, polkadotClient } from "./polkadot"
import {
decodedPolkadotAssetHubSpec,
polkadotAssetHubApi,
polkadotAssetHubClient,
} from "./polkadotAssetHub"
import {
decodedPolkadotBridgeHubSpec,
polkadotBridgeHubApi,
polkadotBridgeHubClient,
} from "./polkadotBridgeHub"
import {
decodedPolkadotCollectivesSpec,
polkadotCollectivesApi,
polkadotCollectivesClient,
} from "./polkadotCollectives"
import { decodedPolkadotPeopleSpec, polkadotPeopleApi } from "./polkadotPeople"
import { decodedRococoSpec, rococoApi } from "./rococo"
import { decodedRococoAssetHubSpec, rococoAssetHubApi } from "./rococoAssetHub"
import { decodedWestendSpec, westendApi } from "./westend"
import {
decodedPolkadotPeopleSpec,
polkadotPeopleApi,
polkadotPeopleClient,
} from "./polkadotPeople"
import { decodedRococoSpec, rococoApi, rococoClient } from "./rococo"
import {
decodedRococoAssetHubSpec,
rococoAssetHubApi,
rococoAssetHubClient,
} from "./rococoAssetHub"
import { decodedWestendSpec, westendApi, westendClient } from "./westend"
import { decodedWestendAssetHubSpec } from "./westendAssetHub"

export interface Chain<T extends ChainDefinition> {
chainSpec: Promise<ChainSpec>
api: TypedApi<T>
client: PolkadotClient
}

export const allChains = {
polkadot: {
chainSpec: decodedPolkadotSpec,
api: polkadotApi,
client: polkadotClient,
},
polkadotAssetHub: {
chainSpec: decodedPolkadotAssetHubSpec,
api: polkadotAssetHubApi,
client: polkadotAssetHubClient,
},
polkadotBridgeHub: {
chainSpec: decodedPolkadotBridgeHubSpec,
api: polkadotBridgeHubApi,
client: polkadotBridgeHubClient,
},
polkadotCollectives: {
chainSpec: decodedPolkadotCollectivesSpec,
api: polkadotCollectivesApi,
client: polkadotCollectivesClient,
},
polkadotPeople: {
chainSpec: decodedPolkadotPeopleSpec,
api: polkadotPeopleApi,
client: polkadotPeopleClient,
},
rococo: {
chainSpec: decodedRococoSpec,
api: rococoApi,
client: rococoClient,
},
rococoAssetHub: {
chainSpec: decodedRococoAssetHubSpec,
api: rococoAssetHubApi,
client: rococoAssetHubClient,
},
westend: {
chainSpec: decodedWestendSpec,
api: westendApi,
client: westendClient,
},
westendAssetHub: {
chainSpec: decodedWestendAssetHubSpec,
api: westendApi,
client: westendClient,
},
} satisfies Record<string, Chain<ChainDefinition>>

Expand Down
4 changes: 2 additions & 2 deletions src/api/polkadot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export const decodedPolkadotSpec = polkadotSpec.then(
)

export const polkadotChain = polkadotSpec.then(smoldot.addChain)
const client = createClient(getSmProvider(polkadotChain))
export const polkadotClient = createClient(getSmProvider(polkadotChain))

export const polkadotApi = client.getTypedApi(polkadot)
export const polkadotApi = polkadotClient.getTypedApi(polkadot)
5 changes: 3 additions & 2 deletions src/api/polkadotAssetHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const decodedPolkadotAssetHubSpec = polkadotAssetHubSpec.then(
)

const chain = addParachain(polkadotChain, polkadotAssetHubSpec)
const client = createClient(getSmProvider(chain))
export const polkadotAssetHubClient = createClient(getSmProvider(chain))

export const polkadotAssetHubApi = client.getTypedApi(polkadot_asset_hub)
export const polkadotAssetHubApi =
polkadotAssetHubClient.getTypedApi(polkadot_asset_hub)
5 changes: 3 additions & 2 deletions src/api/polkadotBridgeHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const decodedPolkadotBridgeHubSpec = polkadotBridgeHubSpec.then(
)

const chain = addParachain(polkadotChain, polkadotBridgeHubSpec)
const client = createClient(getSmProvider(chain))
export const polkadotBridgeHubClient = createClient(getSmProvider(chain))

export const polkadotBridgeHubApi = client.getTypedApi(polkadot_bridge_hub)
export const polkadotBridgeHubApi =
polkadotBridgeHubClient.getTypedApi(polkadot_bridge_hub)
5 changes: 3 additions & 2 deletions src/api/polkadotCollectives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const decodedPolkadotCollectivesSpec = polkadotCollectivesSpec.then(
)

const chain = addParachain(polkadotChain, polkadotCollectivesSpec)
const client = createClient(getSmProvider(chain))
export const polkadotCollectivesClient = createClient(getSmProvider(chain))

export const polkadotCollectivesApi = client.getTypedApi(polkadot_collectives)
export const polkadotCollectivesApi =
polkadotCollectivesClient.getTypedApi(polkadot_collectives)
5 changes: 3 additions & 2 deletions src/api/polkadotPeople.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const decodedPolkadotPeopleSpec = polkadotPeopleSpec.then(
)

const chain = addParachain(polkadotChain, polkadotPeopleSpec)
const client = createClient(getSmProvider(chain))
export const polkadotPeopleClient = createClient(getSmProvider(chain))

export const polkadotPeopleApi = client.getTypedApi(polkadot_people)
export const polkadotPeopleApi =
polkadotPeopleClient.getTypedApi(polkadot_people)
4 changes: 2 additions & 2 deletions src/api/rococo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export const decodedRococoSpec = rococoSpec.then(
)

export const rococoChain = rococoSpec.then(smoldot.addChain)
const client = createClient(getSmProvider(rococoChain))
export const rococoClient = createClient(getSmProvider(rococoChain))

export const rococoApi = client.getTypedApi(rococo)
export const rococoApi = rococoClient.getTypedApi(rococo)
7 changes: 5 additions & 2 deletions src/api/rococoAssetHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export const decodedRococoAssetHubSpec = rococoAssetHubSpec.then(
)

const rococoAssetHubChain = addParachain(rococoChain, rococoAssetHubSpec)
const client = createClient(getSmProvider(rococoAssetHubChain))
export const rococoAssetHubClient = createClient(
getSmProvider(rococoAssetHubChain),
)

export const rococoAssetHubApi = client.getTypedApi(rococoAssetHub)
export const rococoAssetHubApi =
rococoAssetHubClient.getTypedApi(rococoAssetHub)
Loading

0 comments on commit a9165c9

Please sign in to comment.