-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
458 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { useEffect } from 'react'; | ||
import { Blocks } from 'lucide-react'; | ||
import { useComputed } from '@preact-signals/safe-react'; | ||
import { Popover } from '@penumbra-zone/ui/Popover'; | ||
import { Button } from '@penumbra-zone/ui/Button'; | ||
import { Density } from '@penumbra-zone/ui/Density'; | ||
import { Pill } from '@penumbra-zone/ui/Pill'; | ||
import { Text } from '@penumbra-zone/ui/Text'; | ||
import { penumbraStatus, penumbraStatusError, streamPenumbraStatus } from '@/state/status'; | ||
import { useConnect } from '@/utils/penumbra/useConnect.ts'; | ||
|
||
export const StatusPopover = () => { | ||
const { connected } = useConnect(); | ||
|
||
// a ReactNode displaying the sync status in form of a pill | ||
const pill = useComputed(() => { | ||
if (penumbraStatusError.value) { | ||
return <Pill context='technical-destructive'>Block Sync Error</Pill>; | ||
} | ||
|
||
if (!penumbraStatus.value) { | ||
return null; | ||
} | ||
|
||
if (!penumbraStatus.value.syncing) { | ||
return <Pill context='technical-success'>Blocks Synced</Pill>; | ||
} | ||
|
||
return <Pill context='technical-caution'>Block Syncing</Pill>; | ||
}); | ||
|
||
useEffect(() => { | ||
if (connected) { | ||
void streamPenumbraStatus(); | ||
} | ||
}, [connected]); | ||
|
||
return ( | ||
<Popover> | ||
<Popover.Trigger> | ||
<Button icon={Blocks} iconOnly> | ||
Status | ||
</Button> | ||
</Popover.Trigger> | ||
<Popover.Content align='end' side='bottom'> | ||
<Density compact> | ||
<div className='flex flex-col gap-4'> | ||
<div className='flex flex-col gap-2'> | ||
<Text technical>Status</Text> | ||
{pill.value} | ||
{penumbraStatusError.value} | ||
</div> | ||
{penumbraStatus.value && ( | ||
<div className='flex flex-col gap-2'> | ||
<Text technical>Block Height</Text> | ||
<Pill context='technical-default'> | ||
{penumbraStatus.value.latestKnownBlockHeight !== penumbraStatus.value.fullSyncHeight | ||
? `${penumbraStatus.value.fullSyncHeight} of ${penumbraStatus.value.latestKnownBlockHeight}` | ||
: `${penumbraStatus.value.latestKnownBlockHeight}`} | ||
</Pill> | ||
</div> | ||
)} | ||
</div> | ||
</Density> | ||
</Popover.Content> | ||
</Popover> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Progress } from '@penumbra-zone/ui/Progress'; | ||
import { penumbraStatus, penumbraStatusError } from '@/state/status'; | ||
|
||
export const SyncBar = () => { | ||
return ( | ||
<div className='fixed left-0 top-0 h-1 w-full'> | ||
{!penumbraStatus.value ? ( | ||
<Progress value={0} loading /> | ||
) : ( | ||
<Progress | ||
value={penumbraStatus.value.syncPercent ?? 0} | ||
loading={penumbraStatus.value.updating} | ||
error={Boolean(penumbraStatusError.value)} | ||
/> | ||
)} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export const getSyncPercent = ( | ||
fullSyncHeight: bigint, | ||
latestKnownBlockHeight: bigint, | ||
): { syncPercent: number, syncPercentStringified: string } => { | ||
let percentSyncedNumber = 0; | ||
if (latestKnownBlockHeight) { | ||
percentSyncedNumber = Number(fullSyncHeight) / Number(latestKnownBlockHeight); | ||
if (percentSyncedNumber > 1) { | ||
percentSyncedNumber = 1; | ||
} | ||
} | ||
|
||
// Round down to ensure whole numbers | ||
const roundedPercentSyncedNumber = Math.floor(percentSyncedNumber * 100); | ||
|
||
return { | ||
syncPercent: roundedPercentSyncedNumber / 100, | ||
syncPercentStringified: `${roundedPercentSyncedNumber}%`, | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { signal } from '@preact-signals/safe-react'; | ||
import { ViewService } from '@penumbra-zone/protobuf'; | ||
import { penumbra } from '@/utils/penumbra/penumbra'; | ||
import { getSyncPercent } from '@/state/status/getSyncPercent'; | ||
|
||
interface StatusState { | ||
/** Indicates that the account needs syncing with the blockchain */ | ||
syncing: boolean; | ||
/** Indicates that the account is almost in sync with the blockchain (amount of unsynced blocks is less than 10) */ | ||
updating?: boolean; | ||
/** The amount of synced blocks */ | ||
fullSyncHeight: bigint; | ||
/** The total amount of blocks in the blockchain */ | ||
latestKnownBlockHeight?: bigint; | ||
/** A number between 0 and 1 indicating the sync progress */ | ||
syncPercent: number; | ||
/** A stringified sync percentage, e.g. '100%' or '17%' */ | ||
syncPercentStringified: string; | ||
} | ||
|
||
export const penumbraStatus = signal<StatusState>(); | ||
export const penumbraStatusError = signal<string>(); | ||
|
||
/** | ||
* Initial status request doesn't return `latestKnownBlockHeight`. | ||
* Instead, it returns `catchingUp` to know if the sync is in progress | ||
*/ | ||
const getPenumbraStatus = async (): Promise<StatusState> => { | ||
const status = await penumbra.service(ViewService).status({}); | ||
return { | ||
syncing: status.catchingUp, | ||
fullSyncHeight: status.fullSyncHeight, | ||
latestKnownBlockHeight: status.catchingUp ? undefined : status.fullSyncHeight, | ||
syncPercent: status.catchingUp ? 0 : 1, | ||
syncPercentStringified: status.catchingUp ? '0%' : '100%', | ||
}; | ||
}; | ||
|
||
/** | ||
* Receives the status stream from the view service | ||
* and stores it in the `penumbraStatus` signal. | ||
*/ | ||
export const streamPenumbraStatus = async () => { | ||
try { | ||
penumbraStatus.value = await getPenumbraStatus(); | ||
penumbraStatusError.value = undefined; | ||
|
||
const stream = penumbra.service(ViewService).statusStream({}); | ||
for await (const status of stream) { | ||
const syncPercents = getSyncPercent(status.fullSyncHeight, status.latestKnownBlockHeight); | ||
|
||
penumbraStatusError.value = undefined; | ||
penumbraStatus.value = { | ||
syncing: status.fullSyncHeight !== status.latestKnownBlockHeight, | ||
fullSyncHeight: status.fullSyncHeight, | ||
latestKnownBlockHeight: status.latestKnownBlockHeight, | ||
...syncPercents, | ||
}; | ||
} | ||
} catch (error) { | ||
penumbraStatus.value = undefined; | ||
penumbraStatusError.value = error instanceof Error ? `${error.name}: ${error.message}` : 'Streaming error'; | ||
setTimeout(() => void streamPenumbraStatus(), 1000); | ||
} | ||
}; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,3 +17,8 @@ a { | |
* { | ||
box-sizing: border-box; | ||
} | ||
|
||
body > section { | ||
position: relative; | ||
z-index: 0; | ||
} |