fix: clarify Web5 connection actions and remove cosmetic wallet polling

This commit is contained in:
archipelago
2026-10-05 19:53:05 -04:00
parent 9a041bed18
commit eaecab16ca
6 changed files with 9 additions and 93 deletions
+1 -1
View File
@@ -392,7 +392,7 @@
"manageDomains": "Manage Domains",
"relaysConnected": "{count} connected",
"peersKnown": "{count} peer(s) known",
"findNodes": "Find Nodes",
"findNodes": "Connect with Nodes",
"sendMessage": "Send Message",
"sendMessageTitle": "Send Message (over Tor)",
"to": "To",
+1 -1
View File
@@ -390,7 +390,7 @@
"manageDomains": "Administrar dominios",
"relaysConnected": "{count} conectados",
"peersKnown": "{count} par(es) conocido(s)",
"findNodes": "Buscar nodos",
"findNodes": "Conectar con nodos",
"sendMessage": "Enviar mensaje",
"sendMessageTitle": "Enviar mensaje (a trav\u00e9s de Tor)",
"to": "Para",
+2 -62
View File
@@ -12,8 +12,6 @@
:dhtDid="dhtDid"
:dhtDidCopied="dhtDidCopied"
:publishingDht="publishingDht"
:walletConnected="walletConnected"
:connectingWallet="connectingWallet"
:nostrRelayStats="nostrRelaysRef?.nostrRelayStats ?? null"
:connectedNodesCount="connectedNodesRef?.peers?.length ?? 0"
:detectedHwWallets="detectedHwWallets"
@@ -23,7 +21,6 @@
@copyDhtDid="copyDhtDid"
@refreshDhtDid="refreshDhtDid"
@publishDhtDid="publishDhtDid"
@connectWallet="connectWallet"
@manageRelays="nostrRelaysRef?.openRelaysModal()"
/>
@@ -90,7 +87,7 @@ let web5AnimationDone = false
</script>
<script setup lang="ts">
import { ref, computed, onActivated, onDeactivated, onMounted, onUnmounted } from 'vue'
import { ref, computed, onActivated, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { rpcClient } from '@/api/rpc-client'
import { useCachedResource } from '@/composables/useCachedResource'
@@ -288,41 +285,9 @@ async function copyDidDocument() {
setTimeout(() => { didDocCopied.value = false }, 2000)
}
// --- Wallet / LND Balances ---
// Cached: balances/transactions paint instantly on revisit and revalidate
// behind the cached value; errors keep the last-known data.
const lndInfoRes = useCachedResource<{
balance_sats: number
channel_balance_sats: number
synced_to_chain: boolean
}>({
key: 'web5.lnd-info',
fetcher: (signal) => rpcClient.call({ method: 'lnd.getinfo', signal, dedup: true, maxRetries: 1 }),
persist: false, // wallet balance — must never land in sessionStorage (T-02-01)
})
// connectWallet() can still "disconnect" the (hidden) wallet card UI-side.
const walletManuallyDisconnected = ref(false)
const walletConnected = computed(() =>
!walletManuallyDisconnected.value && lndInfoRes.data.value !== null && !lndInfoRes.error.value)
const connectingWallet = ref(false)
// Ecash/transaction/balance display lives in the hidden wallet card — when it
// returns, add cached resources for wallet.ecash-balance / lnd.gettransactions
// here rather than reviving the old eager loaders.
// Hardware wallets
const detectedHwWallets = ref<HwWalletDevice[]>([])
async function connectWallet() {
if (walletConnected.value) {
walletManuallyDisconnected.value = true
} else {
connectingWallet.value = true
walletManuallyDisconnected.value = false
await lndInfoRes.refresh()
connectingWallet.value = false
}
}
async function detectHardwareWallets() {
try {
const res = await rpcClient.detectUsbDevices()
@@ -332,10 +297,6 @@ async function detectHardwareWallets() {
}
}
// Auto-refresh wallet data every 30s while mounted (B5 will move this to
// WS-push invalidation; the store dedups overlapping refreshes).
let walletRefreshInterval: ReturnType<typeof setInterval> | null = null
// Every-entry: none of these child components use useCachedResource
// internally (confirmed by reading Web5ConnectedNodes.vue/Web5Identities.vue/
// Web5NodeVisibility.vue/Web5NostrRelays.vue — all are plain functions
@@ -353,20 +314,12 @@ function armWeb5Live() {
// credentialsRef.value?.loadCredentials() // hidden for now
// sharedContentRef.value?.loadContentItems() // hidden for now
// Wallet/profits resources fetch themselves on first use (and skip the
// Profits resources fetch themselves on first use (and skip the
// fetch entirely when the cached value is still fresh).
detectHardwareWallets()
// Shared content loaded by the component itself via expose
// The SharedContent component manages its own loadContentItems
// Only-while-visible: the 30s force-refresh interval bypasses
// useCachedResource's own TTL gate for lndInfoRes, so it must not keep
// running while Web5 is off screen.
if (walletRefreshInterval) clearInterval(walletRefreshInterval)
walletRefreshInterval = setInterval(() => {
void lndInfoRes.refresh()
}, 30000)
}
// Vue fires onActivated immediately after onMounted on a KeepAlive-wrapped
// component's first mount, which would otherwise double every load in
@@ -400,17 +353,4 @@ onMounted(() => {
armWeb5Live()
})
onDeactivated(() => {
if (walletRefreshInterval) {
clearInterval(walletRefreshInterval)
walletRefreshInterval = null
}
})
onUnmounted(() => {
if (walletRefreshInterval) {
clearInterval(walletRefreshInterval)
walletRefreshInterval = null
}
})
</script>
+2 -2
View File
@@ -15,7 +15,7 @@
</div>
<div class="web5-card-actions-top items-center gap-2">
<RouterLink to="/dashboard/server/federation" class="glass-button glass-button-sm px-3 rounded-lg text-sm font-medium inline-flex items-center gap-2 no-underline">
Find Nodes
Connect with Nodes
</RouterLink>
<RouterLink to="/dashboard/fleet" class="glass-button glass-button-sm px-3 rounded-lg text-sm font-medium inline-flex items-center gap-2 no-underline">
Fleet
@@ -74,7 +74,7 @@
<div class="web5-card-actions-bottom-grid mt-6 grid-cols-2 gap-3">
<RouterLink to="/dashboard/server/federation" class="mobile-card-action glass-button rounded-lg text-sm font-medium text-white/90 hover:text-white transition-colors no-underline">
Find Nodes
Connect with Nodes
</RouterLink>
<RouterLink to="/dashboard/fleet" class="mobile-card-action glass-button rounded-lg text-sm font-medium text-white/90 hover:text-white transition-colors no-underline">
Fleet
+1 -25
View File
@@ -1,7 +1,7 @@
<template>
<!-- Quick Actions Container -->
<div class="glass-card p-6 mb-6">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-6 gap-4 stagger-grid">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 gap-4 stagger-grid">
<!-- Networking Profits -->
<div data-controller-container tabindex="0" :class="{ 'card-stagger': showStagger }" class="flex flex-col gap-3 p-4 bg-white/5 rounded-lg min-w-0" style="--stagger-index: 0">
<div class="flex items-center gap-3 min-w-0">
@@ -113,27 +113,6 @@
</button>
</div>
<!-- Wallet Connection -->
<div data-controller-container tabindex="0" :class="{ 'card-stagger': showStagger }" class="flex flex-col gap-3 p-4 bg-white/5 rounded-lg min-w-0" style="--stagger-index: 2">
<div class="flex items-center gap-3 min-w-0">
<div class="relative shrink-0">
<div class="w-3 h-3 rounded-full" :class="walletConnected ? 'bg-green-400' : 'bg-red-400'"></div>
<div v-if="walletConnected" class="absolute inset-0 w-3 h-3 rounded-full bg-green-400 animate-ping opacity-75"></div>
</div>
<div class="min-w-0">
<p class="text-sm font-medium text-white">{{ t('web5.wallet') }}</p>
<p class="text-xs text-white/60">{{ walletConnected ? t('common.connected') : t('common.disconnected') }}</p>
</div>
</div>
<button
@click="$emit('connectWallet')"
class="w-full mt-auto px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors disabled:opacity-50"
:disabled="connectingWallet"
>
{{ connectingWallet ? t('common.connecting') : walletConnected ? t('common.disconnect') : t('common.connect') }}
</button>
</div>
<!-- Nostr Relay Status -->
<div data-controller-container tabindex="0" :class="{ 'card-stagger': showStagger }" class="flex flex-col gap-3 p-4 bg-white/5 rounded-lg min-w-0" style="--stagger-index: 3">
<div class="flex items-center gap-3 min-w-0">
@@ -225,8 +204,6 @@ defineProps<{
dhtDid: string | null
dhtDidCopied: boolean
publishingDht: boolean
walletConnected: boolean
connectingWallet: boolean
nostrRelayStats: NostrRelayStatsData | null
connectedNodesCount: number
detectedHwWallets: HwWalletDevice[]
@@ -239,7 +216,6 @@ defineEmits<{
copyDhtDid: []
refreshDhtDid: []
publishDhtDid: []
connectWallet: []
manageRelays: []
}>()
</script>
@@ -34,13 +34,13 @@ function mountFederation() {
}
describe('Web5Federation', () => {
it('surfaces Find Nodes and Fleet routes', () => {
it('surfaces Connect with Nodes and Fleet routes', () => {
const wrapper = mountFederation()
const links = wrapper.findAll('a').map(link => link.attributes('href'))
expect(links).toContain('/dashboard/server/federation')
expect(links).toContain('/dashboard/fleet')
expect(wrapper.text()).toContain('Find Nodes')
expect(wrapper.text()).toContain('Connect with Nodes')
expect(wrapper.text()).toContain('Fleet')
})