Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
743700b82c | ||
|
|
8953596194 |
@@ -4,7 +4,7 @@ export default {
|
|||||||
app: {
|
app: {
|
||||||
name: 'koins',
|
name: 'koins',
|
||||||
identifier: 'koins.tzgyn.com',
|
identifier: 'koins.tzgyn.com',
|
||||||
version: '0.0.10',
|
version: '0.0.11',
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
// Vite builds to dist/, we copy from there
|
// Vite builds to dist/, we copy from there
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export const createMoneroWallet = () => {
|
|||||||
let refreshInFlight: Promise<void> | null = null
|
let refreshInFlight: Promise<void> | null = null
|
||||||
let syncing = $state(false)
|
let syncing = $state(false)
|
||||||
let syncRetryTimer: ReturnType<typeof setTimeout> | null = null
|
let syncRetryTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
|
let autoRefreshTimer: ReturnType<typeof setInterval> | null = null
|
||||||
let price = $state<string | null>(null)
|
let price = $state<string | null>(null)
|
||||||
let priceInFlight = false
|
let priceInFlight = false
|
||||||
|
|
||||||
@@ -408,6 +409,31 @@ export const createMoneroWallet = () => {
|
|||||||
}, 15000)
|
}, 15000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stopAutoRefresh = () => {
|
||||||
|
if (autoRefreshTimer) {
|
||||||
|
clearInterval(autoRefreshTimer)
|
||||||
|
autoRefreshTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh runs in the store so the dashboard's connection/sync state
|
||||||
|
// stays live regardless of which page is mounted.
|
||||||
|
const startAutoRefresh = () => {
|
||||||
|
if (autoRefreshTimer || !walletOpen) return
|
||||||
|
autoRefreshTimer = setInterval(() => {
|
||||||
|
if (walletOpen && !loading) refresh()
|
||||||
|
}, 30000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// $effect needs a root outside a component; the root lives for the
|
||||||
|
// lifetime of the singleton store.
|
||||||
|
$effect.root(() => {
|
||||||
|
$effect(() => {
|
||||||
|
if (walletOpen && !loading) startAutoRefresh()
|
||||||
|
else if (!walletOpen) stopAutoRefresh()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
const rpc = electrobun.rpc
|
const rpc = electrobun.rpc
|
||||||
if (!rpc) return
|
if (!rpc) return
|
||||||
|
|||||||
@@ -47,6 +47,16 @@
|
|||||||
const hasXmr = $derived(moneroWallet.wallets.length > 0)
|
const hasXmr = $derived(moneroWallet.wallets.length > 0)
|
||||||
const noWallets = $derived(!hasXrp && !hasXmr)
|
const noWallets = $derived(!hasXrp && !hasXmr)
|
||||||
|
|
||||||
|
const moneroDot = $derived(
|
||||||
|
!moneroWallet.running
|
||||||
|
? 'bg-muted'
|
||||||
|
: !moneroWallet.connected
|
||||||
|
? 'bg-red-500'
|
||||||
|
: moneroWallet.syncing || moneroWallet.height < moneroWallet.daemonHeight
|
||||||
|
? 'bg-yellow-500 animate-pulse'
|
||||||
|
: 'bg-emerald-500',
|
||||||
|
)
|
||||||
|
|
||||||
const fmtUsd = (v: number) =>
|
const fmtUsd = (v: number) =>
|
||||||
v.toLocaleString(undefined, {
|
v.toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
@@ -154,9 +164,7 @@
|
|||||||
<img src="/icons/xrp.png" alt="" class="size-5 rounded-full" />
|
<img src="/icons/xrp.png" alt="" class="size-5 rounded-full" />
|
||||||
<CardTitle class="text-base">XRP</CardTitle>
|
<CardTitle class="text-base">XRP</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
<CardDescription class="text-xs">
|
<CardDescription class="text-xs">XRP Ledger</CardDescription>
|
||||||
{xrpWallet.wallets.length} wallet{xrpWallet.wallets.length !== 1 ? 's' : ''}
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="flex flex-1 flex-col justify-center">
|
<CardContent class="flex flex-1 flex-col justify-center">
|
||||||
{#if !xrpWallet.ready || (xrpWallet.wallets.length > 0 && Object.keys(xrpWallet.balances).length === 0)}
|
{#if !xrpWallet.ready || (xrpWallet.wallets.length > 0 && Object.keys(xrpWallet.balances).length === 0)}
|
||||||
@@ -185,20 +193,21 @@
|
|||||||
<img src="/icons/monero.png" alt="" class="size-5 rounded-full" />
|
<img src="/icons/monero.png" alt="" class="size-5 rounded-full" />
|
||||||
<CardTitle class="text-base">Monero</CardTitle>
|
<CardTitle class="text-base">Monero</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
<CardDescription class="text-xs">
|
<CardDescription class="flex items-center gap-1.5 text-xs">
|
||||||
{moneroWallet.walletOpen
|
<span class="size-2 shrink-0 rounded-full {moneroDot}"></span>
|
||||||
? moneroWallet.walletName || 'Wallet open'
|
{#if !moneroWallet.running}
|
||||||
: moneroWallet.wallets.length > 0
|
Server offline
|
||||||
? `${moneroWallet.wallets.length} wallet${moneroWallet.wallets.length !== 1 ? 's' : ''}`
|
{:else if !moneroWallet.connected}
|
||||||
: 'Not set up'}
|
Connecting to daemon…
|
||||||
|
{:else}
|
||||||
|
{fmtBal(moneroWallet.height, 0)} / {fmtBal(moneroWallet.daemonHeight, 0)}
|
||||||
|
{/if}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="flex flex-1 flex-col justify-center">
|
<CardContent class="flex flex-1 flex-col justify-center">
|
||||||
{#if moneroWallet.walletOpen}
|
{#if moneroWallet.walletOpen}
|
||||||
<p class="font-mono text-xl tabular-nums">{fmtBal(xmrBalance, 4)}</p>
|
<p class="font-mono text-xl tabular-nums">{fmtBal(xmrBalance, 4)}</p>
|
||||||
{#if moneroWallet.syncing}
|
{#if !moneroWallet.syncing && moneroWallet.price}
|
||||||
<p class="mt-0.5 text-xs text-muted-foreground">Syncing…</p>
|
|
||||||
{:else if moneroWallet.price}
|
|
||||||
<p class="mt-0.5 text-sm text-muted-foreground tabular-nums">
|
<p class="mt-0.5 text-sm text-muted-foreground tabular-nums">
|
||||||
${fmtUsd(xmrTotalUsd)}
|
${fmtUsd(xmrTotalUsd)}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -154,7 +154,6 @@
|
|||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (w.walletOpen && !autoRefreshTimer) {
|
if (w.walletOpen && !autoRefreshTimer) {
|
||||||
autoRefreshTimer = setInterval(() => {
|
autoRefreshTimer = setInterval(() => {
|
||||||
w.refresh()
|
|
||||||
electrobun.rpc?.request
|
electrobun.rpc?.request
|
||||||
.fetchMoneroPrice({})
|
.fetchMoneroPrice({})
|
||||||
.then((p) => (moneroPrice = p))
|
.then((p) => (moneroPrice = p))
|
||||||
|
|||||||
Reference in New Issue
Block a user