Skip to content

Commit

Permalink
feat: walletd resubscribe
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Apr 5, 2024
1 parent 0f3b9f0 commit 1fc2113
Show file tree
Hide file tree
Showing 25 changed files with 686 additions and 129 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-trees-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'walletd': minor
---

Address generation and addition dialogs now have an option to rescan from a specified height. Closes https://github.com/SiaFoundation/walletd/issues/96
5 changes: 5 additions & 0 deletions .changeset/mighty-days-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/design-system': patch
---

Fixed an issue where Dialog and useDialogFormHelpers were not calling onOpenChange on open events.
5 changes: 5 additions & 0 deletions .changeset/plenty-ligers-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'walletd': minor
---

There is now a dedicated rescan dialog that can be opened from the wallet list and wallet context menus. Closes https://github.com/SiaFoundation/walletd/issues/96
5 changes: 5 additions & 0 deletions .changeset/rare-bags-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'walletd': minor
---

Rescan progress and status including errors is now shown in a sticky status bar. Closes https://github.com/SiaFoundation/walletd/issues/96
5 changes: 5 additions & 0 deletions .changeset/wicked-buses-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@siafoundation/react-walletd': minor
---

Added useRescanStart, useRescanStatus.
76 changes: 76 additions & 0 deletions apps/walletd/components/RescanStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {
Panel,
ProgressBar,
Separator,
Text,
} from '@siafoundation/design-system'
import { useRescanStatus } from '@siafoundation/react-walletd'
import { useSyncStatus } from '../hooks/useSyncStatus'
import { formatRelative } from 'date-fns'
import { defaultDatasetRefreshInterval } from '../config/swr'

export function RescanStatus() {
const syncStatus = useSyncStatus()
const rescanStatus = useRescanStatus({
config: {
swr: {
refreshInterval: defaultDatasetRefreshInterval,
},
},
})

if (!rescanStatus.data) {
return null
}

const isScanning = rescanStatus.data.index.height < syncStatus.nodeBlockHeight

if (!isScanning) {
return null
}

return (
<div className="z-20 fixed bottom-5 left-1/2 -translate-x-1/2 flex justify-center">
<Panel className="px-2 py-2 w-[400px] overflow-hidden">
<Text weight="medium" className="pb-2">
Rescanning the blockchain
</Text>
<div className="flex flex-col gap-1">
<ProgressBar
variant="accent"
value={rescanStatus.data.index.height}
max={syncStatus.nodeBlockHeight}
/>
<div className="flex justify-between gap-3">
<Text color="verySubtle" size="12" ellipsis>
{rescanStatus.data.error ? 'Stopped' : 'Scanning...'}
</Text>
<Text color="verySubtle" size="12" noWrap>
{`${rescanStatus.data.index.height.toLocaleString()} / ${syncStatus.nodeBlockHeight.toLocaleString()}`}
</Text>
</div>
</div>
<Separator className="w-full mt-2 mb-1" />
<div className="flex justify-between items-center">
{rescanStatus.data.error && (
<Text color="red" size="12">
Error rescanning the blockchain
</Text>
)}
<div className="flex-1" />
<Text color="subtle" size="12">
Started{' '}
{formatRelative(new Date(rescanStatus.data.startTime), new Date())}
</Text>
</div>
{rescanStatus.data.error && (
<div className="flex flex-col gap-1 overflow-hidden pt-1">
<Text color="contrast" size="12">
{rescanStatus.data.error}
</Text>
</div>
)}
</Panel>
</div>
)
}
10 changes: 10 additions & 0 deletions apps/walletd/components/WalletContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Unlocked16,
Edit16,
Delete16,
Scan16,
} from '@siafoundation/react-icons'
import { useDialog } from '../contexts/dialog'
import { WalletData } from '../contexts/wallets/types'
Expand Down Expand Up @@ -66,6 +67,15 @@ export function WalletContextMenu({
</DropdownMenuLeftSlot>
Delete wallet
</DropdownMenuItem>
<DropdownMenuItem
onClick={(e) => e.stopPropagation()}
onSelect={() => openDialog('walletsRescan')}
>
<DropdownMenuLeftSlot>
<Scan16 />
</DropdownMenuLeftSlot>
Rescan blockchain
</DropdownMenuItem>
</DropdownMenu>
)
}
28 changes: 28 additions & 0 deletions apps/walletd/components/WalletsContextMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
DropdownMenu,
DropdownMenuItem,
DropdownMenuLeftSlot,
DropdownMenuLabel,
} from '@siafoundation/design-system'
import { Scan16 } from '@siafoundation/react-icons'
import { useDialog } from '../contexts/dialog'

type Props = Omit<React.ComponentProps<typeof DropdownMenu>, 'children'>

export function WalletsContextMenu({ ...props }: Props) {
const { openDialog } = useDialog()
return (
<DropdownMenu {...props}>
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem
onClick={(e) => e.stopPropagation()}
onSelect={() => openDialog('walletsRescan')}
>
<DropdownMenuLeftSlot>
<Scan16 />
</DropdownMenuLeftSlot>
Rescan blockchain
</DropdownMenuItem>
</DropdownMenu>
)
}
18 changes: 17 additions & 1 deletion apps/walletd/components/WalletsList/WalletsActionsMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Button } from '@siafoundation/design-system'
import { Add16, Locked16 } from '@siafoundation/react-icons'
import { Add16, Locked16, Settings16 } from '@siafoundation/react-icons'
import { useWallets } from '../../contexts/wallets'
import { useDialog } from '../../contexts/dialog'
import { WalletsViewDropdownMenu } from './WalletsViewDropdownMenu'
import { WalletsContextMenu } from '../WalletsContextMenu'

export function WalletsActionsMenu() {
const { lockAllWallets, unlockedCount } = useWallets()
Expand All @@ -24,6 +25,21 @@ export function WalletsActionsMenu() {
Add wallet
</Button>
<WalletsViewDropdownMenu />
<WalletsContextMenu
trigger={
<Button
size="small"
tip="Wallet settings"
tipAlign="end"
tipSide="bottom"
>
<Settings16 />
</Button>
}
contentProps={{
align: 'end',
}}
/>
</div>
)
}
2 changes: 2 additions & 0 deletions apps/walletd/config/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AddressesProvider } from '../contexts/addresses'
import { EventsProvider } from '../contexts/events'
import { LedgerProvider } from '../contexts/ledger'
import { AppProvider } from '../contexts/app'
import { RescanStatus } from '../components/RescanStatus'

type Props = {
children: React.ReactNode
Expand All @@ -21,6 +22,7 @@ export function Providers({ children }: Props) {
{/* this is here so that dialogs can use all the other providers,
and the other providers can trigger dialogs */}
<Dialogs />
<RescanStatus />
{children}
</EventsProvider>
</AddressesProvider>
Expand Down
52 changes: 43 additions & 9 deletions apps/walletd/contexts/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ import {
WalletAddressesGenerateLedgerDialog,
WalletAddressesGenerateLedgerDialogParams,
} from '../dialogs/WalletAddressesGenerateLedgerDialog'
import {
WalletsRescanDialogParams,
WalletsRescanDialog,
} from '../dialogs/WalletsRescanDialog'
// import { CmdKDialog } from '../components/CmdKDialog'

export type DialogParams = {
Expand All @@ -82,6 +86,7 @@ export type DialogParams = {
addressRemove?: AddressRemoveDialogParams
connectPeer?: SyncerConnectPeerDialogParams
confirm?: ConfirmDialogParams
walletsRescan?: WalletsRescanDialogParams
walletAddType?: WalletAddTypeDialogParams
walletAddNew?: WalletAddNewDialogParams
walletAddRecover?: WalletAddRecoverDialogParams
Expand Down Expand Up @@ -213,42 +218,69 @@ export function Dialogs() {
<WalletAddressesGenerateSeedDialog
open={dialog === 'walletAddressesGenerate'}
params={params['walletAddressesGenerate']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val
? openDialog(dialog, params['walletAddressesGenerate'])
: closeDialog()
}
/>
<WalletAddressesGenerateLedgerDialog
open={dialog === 'walletLedgerAddressGenerate'}
params={params['walletLedgerAddressGenerate']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val
? openDialog(dialog, params['walletLedgerAddressGenerate'])
: closeDialog()
}
/>
<WalletAddressesAddDialog
open={dialog === 'walletAddressesAdd'}
params={params['walletAddressesAdd']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['walletAddressesAdd']) : closeDialog()
}
/>
<WalletRemoveDialog
open={dialog === 'walletRemove'}
params={params['walletRemove']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['walletRemove']) : closeDialog()
}
/>
<WalletUpdateDialog
open={dialog === 'walletUpdate'}
params={params['walletUpdate']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['walletUpdate']) : closeDialog()
}
/>
<WalletUnlockDialog
open={dialog === 'walletUnlock'}
params={params['walletUnlock']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['walletUnlock']) : closeDialog()
}
/>
<WalletsRescanDialog
open={dialog === 'walletsRescan'}
params={params['walletsRescan']}
onOpenChange={(val) =>
val ? openDialog(dialog, params['walletsRescan']) : closeDialog()
}
/>
<AddressUpdateDialog
open={dialog === 'addressUpdate'}
params={params['addressUpdate']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['addressUpdate']) : closeDialog()
}
/>
<AddressRemoveDialog
open={dialog === 'addressRemove'}
params={params['addressRemove']}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['addressRemove']) : closeDialog()
}
/>
<SyncerConnectPeerDialog
open={dialog === 'connectPeer'}
Expand All @@ -258,7 +290,9 @@ export function Dialogs() {
payload: address,
})
}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
onOpenChange={(val) =>
val ? openDialog(dialog, params['connectPeer']) : closeDialog()
}
/>
<WalletSendSeedDialog
open={dialog === 'walletSendSeed'}
Expand Down
16 changes: 2 additions & 14 deletions apps/walletd/contexts/events/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ import {
useDatasetEmptyState,
useServerFilters,
} from '@siafoundation/design-system'
import {
useResubscribe,
useWalletEvents,
useWalletTxPool,
} from '@siafoundation/react-walletd'
import { createContext, useCallback, useContext, useMemo } from 'react'
import { useWalletEvents, useWalletTxPool } from '@siafoundation/react-walletd'
import { createContext, useContext, useMemo } from 'react'
import {
CellContext,
EventData,
Expand Down Expand Up @@ -56,13 +52,6 @@ export function useEventsMain() {
},
})

const _resubscribe = useResubscribe()
const resubscribe = useCallback(async () => {
_resubscribe.post({
payload: 0,
})
}, [_resubscribe])

const dataset = useMemo<EventData[] | null>(() => {
if (!responseEvents.data || !responseTxPool.data) {
return null
Expand Down Expand Up @@ -204,7 +193,6 @@ export function useEventsMain() {
removeFilter,
removeLastFilter,
resetFilters,
resubscribe,
offset,
limit,
}
Expand Down
25 changes: 25 additions & 0 deletions apps/walletd/dialogs/CalloutWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Alert, Text } from '@siafoundation/design-system'
import { Warning16 } from '@carbon/icons-react'

type Props = {
label: string
description: React.ReactNode
}

export function CalloutWarning({ label, description }: Props) {
return (
<Alert className="!p-2">
<div className="flex flex-col gap-1">
<div className="flex gap-2 items-center">
<Text>
<Warning16 />
</Text>
<Text weight="medium">{label}</Text>
</div>
<Text size="14" color="subtle">
{description}
</Text>
</div>
</Alert>
)
}
Loading

0 comments on commit 1fc2113

Please sign in to comment.