- Refactor useNostr composable to utilize a centralized Pinia store for connection state and client management. - Update NostrFeed and App components to leverage the new store-based approach for relay configuration and client instantiation. - Remove direct relay URL handling from components, improving maintainability and consistency across the application.
88 lines
2.6 KiB
Vue
88 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
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 PasswordDialog from '@/components/nostr/PasswordDialog.vue'
|
|
import { Toaster } from 'vue-sonner'
|
|
import { useNostr } from '@/composables/useNostr'
|
|
import { identity } from '@/composables/useIdentity'
|
|
import { toast } from 'vue-sonner'
|
|
import { config } from '@/lib/config'
|
|
|
|
const { isConnected, isConnecting, error, connect, disconnect } = useNostr()
|
|
|
|
const showPasswordDialog = ref(false)
|
|
|
|
async function handlePasswordUnlock(password: string) {
|
|
try {
|
|
await identity.loadWithPassword(password)
|
|
showPasswordDialog.value = false
|
|
toast.success('Identity unlocked successfully')
|
|
} catch (error) {
|
|
toast.error('Failed to unlock identity. Please check your password.')
|
|
}
|
|
}
|
|
|
|
function handlePasswordCancel() {
|
|
showPasswordDialog.value = false
|
|
}
|
|
|
|
onMounted(async () => {
|
|
// Check if we have an encrypted identity that needs password
|
|
if (identity.hasStoredIdentity() && identity.isStoredIdentityEncrypted()) {
|
|
showPasswordDialog.value = true
|
|
} else {
|
|
// Initialize identity system for non-encrypted identities
|
|
try {
|
|
await identity.initialize()
|
|
} catch (error) {
|
|
console.error('Failed to initialize identity:', error)
|
|
}
|
|
}
|
|
|
|
// Connect to Nostr relays
|
|
await connect()
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
disconnect()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="min-h-screen bg-background font-sans antialiased">
|
|
<div class="relative flex min-h-screen flex-col"
|
|
style="padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom)">
|
|
<header
|
|
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"
|
|
:is-connecting="isConnecting"
|
|
:error="error"
|
|
/>
|
|
</nav>
|
|
</header>
|
|
|
|
<main class="flex-1">
|
|
<router-view />
|
|
</main>
|
|
|
|
<Footer />
|
|
</div>
|
|
|
|
<!-- Toast notifications -->
|
|
<Toaster />
|
|
|
|
<!-- Password unlock dialog -->
|
|
<PasswordDialog
|
|
v-model:is-open="showPasswordDialog"
|
|
title="Unlock Identity"
|
|
description="Your Nostr identity is encrypted. Enter your password to unlock it."
|
|
@password="handlePasswordUnlock"
|
|
@cancel="handlePasswordCancel"
|
|
/>
|
|
</div>
|
|
</template>
|