feat(nostr): Add connecting state to Nostr connection management
- Introduce `isConnecting` state in useNostr composable - Update ConnectionStatus component to handle connecting state - Add warning variant to Badge for connecting status - Implement dynamic status text, color, and animation for connection states - Modify App.vue to pass new isConnecting prop to ConnectionStatus
This commit is contained in:
parent
0923731ee9
commit
18ece1e3e7
5 changed files with 52 additions and 12 deletions
3
.env
3
.env
|
|
@ -1,5 +1,4 @@
|
|||
# Support agent's public key in npub format
|
||||
VITE_SUPPORT_NPUB=npub1tm42jkmdn54zncjcylp34e85jagmgndr0skw4v0rsg8rucmu7r5swayth3
|
||||
|
||||
VITE_NOSTR_RELAYS=["wss://relay.damus.io","wss://relay.nostr.info"]
|
||||
|
||||
VITE_NOSTR_RELAYS=["wss://nostr.atitlan.io"]
|
||||
|
|
|
|||
10
src/App.vue
10
src/App.vue
|
|
@ -1,12 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import Navbar from '@/components/layout/Navbar.vue'
|
||||
import Footer from '@/components/layout/Footer.vue'
|
||||
import ConnectionStatus from '@/components/nostr/ConnectionStatus.vue'
|
||||
import { useNostr } from '@/composables/useNostr'
|
||||
|
||||
const relays = JSON.parse(import.meta.env.VITE_NOSTR_RELAYS as string)
|
||||
const { isConnected, error, connect, disconnect } = useNostr({ relays })
|
||||
const { isConnected, isConnecting, error, connect, disconnect } = useNostr({ relays })
|
||||
|
||||
onMounted(async () => {
|
||||
await connect()
|
||||
|
|
@ -25,7 +25,11 @@ onUnmounted(() => {
|
|||
class="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<nav class="container flex h-14 items-center justify-between">
|
||||
<Navbar />
|
||||
<ConnectionStatus :is-connected="isConnected" :error="error" />
|
||||
<ConnectionStatus
|
||||
:is-connected="isConnected"
|
||||
:is-connecting="isConnecting"
|
||||
:error="error"
|
||||
/>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,51 @@
|
|||
<script setup lang="ts">
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
isConnected: boolean
|
||||
isConnecting: boolean
|
||||
error?: Error | null
|
||||
}>()
|
||||
|
||||
function getStatusVariant() {
|
||||
if (props.isConnecting) return 'warning'
|
||||
return props.isConnected ? 'success' : 'destructive'
|
||||
}
|
||||
|
||||
function getStatusText() {
|
||||
if (props.isConnecting) return 'Connecting'
|
||||
return props.isConnected ? 'Online' : 'Offline'
|
||||
}
|
||||
|
||||
function getStatusColor() {
|
||||
if (props.isConnecting) return 'bg-yellow-400'
|
||||
return props.isConnected ? 'bg-green-400' : 'bg-red-400'
|
||||
}
|
||||
|
||||
function getStatusColorSolid() {
|
||||
if (props.isConnecting) return 'bg-yellow-500'
|
||||
return props.isConnected ? 'bg-green-500' : 'bg-red-500'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center gap-2">
|
||||
<Badge :variant="isConnected ? 'success' : 'destructive'" class="flex items-center gap-1">
|
||||
<Badge :variant="getStatusVariant()" class="flex items-center gap-1">
|
||||
<span class="relative flex h-2 w-2">
|
||||
<span class="absolute inline-flex h-full w-full animate-ping rounded-full opacity-75"
|
||||
:class="isConnected ? 'bg-green-400' : 'bg-red-400'" />
|
||||
<span class="relative inline-flex h-2 w-2 rounded-full"
|
||||
:class="isConnected ? 'bg-green-500' : 'bg-red-500'" />
|
||||
<span
|
||||
class="absolute inline-flex h-full w-full rounded-full opacity-75"
|
||||
:class="[
|
||||
getStatusColor(),
|
||||
{ 'animate-ping': !props.isConnecting },
|
||||
{ 'animate-pulse': props.isConnecting }
|
||||
]"
|
||||
/>
|
||||
<span
|
||||
class="relative inline-flex h-2 w-2 rounded-full"
|
||||
:class="getStatusColorSolid()"
|
||||
/>
|
||||
</span>
|
||||
<span class="text-[10px]">{{ isConnected ? 'Online' : 'Offline' }}</span>
|
||||
<span class="text-[10px]">{{ getStatusText() }}</span>
|
||||
</Badge>
|
||||
<p v-if="error" class="text-xs text-destructive">
|
||||
{{ error.message }}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ export const badgeVariants = cva(
|
|||
'border-transparent bg-destructive/10 text-destructive hover:bg-destructive/20',
|
||||
success:
|
||||
'border-transparent bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
|
||||
warning:
|
||||
'border-transparent bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
|
||||
outline: 'border-border text-foreground hover:bg-accent hover:text-accent-foreground',
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,27 +4,33 @@ import { NostrClient, type NostrClientConfig } from '@/lib/nostr/client'
|
|||
export function useNostr(config: NostrClientConfig) {
|
||||
const client = new NostrClient(config)
|
||||
const isConnected = ref(false)
|
||||
const isConnecting = ref(false)
|
||||
const error = ref<Error | null>(null)
|
||||
|
||||
async function connect() {
|
||||
try {
|
||||
error.value = null
|
||||
isConnecting.value = true
|
||||
await client.connect()
|
||||
isConnected.value = client.isConnected
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err : new Error('Failed to connect')
|
||||
isConnected.value = false
|
||||
} finally {
|
||||
isConnecting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
client.disconnect()
|
||||
isConnected.value = false
|
||||
isConnecting.value = false
|
||||
error.value = null
|
||||
}
|
||||
|
||||
return {
|
||||
isConnected,
|
||||
isConnecting,
|
||||
error,
|
||||
connect,
|
||||
disconnect
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue