import { defineStore } from 'pinia' import { ref } from 'vue' import { NostrClient } from '@/lib/nostr/client' import { config } from '@/lib/config' import { pushService, type PushSubscriptionData } from '@/lib/notifications/push' // Define an interface for the account object interface NostrAccount { privkey: string pubkey: string } export const useNostrStore = defineStore('nostr', () => { // Connection state const isConnected = ref(false) const isConnecting = ref(false) const error = ref(null) // Configuration const relayUrls = ref(config.nostr.relays) const account = ref(null) // Push notifications const pushSubscription = ref(null) const notificationsEnabled = ref(false) // Singleton client instance let client: NostrClient | null = null // Get or create client instance function getClient(): NostrClient { if (!client) { client = new NostrClient({ relays: relayUrls.value }) } return client } // Connection management async function connect(): Promise { try { error.value = null isConnecting.value = true const nostrClient = getClient() await nostrClient.connect() isConnected.value = nostrClient.isConnected } catch (err) { error.value = err instanceof Error ? err : new Error('Failed to connect') isConnected.value = false throw err } finally { isConnecting.value = false } } function disconnect(): void { if (client) { client.disconnect() client = null } isConnected.value = false isConnecting.value = false error.value = null } // Configuration setters function setConnected(value: boolean) { isConnected.value = value } function setRelayUrls(urls: string[]) { relayUrls.value = urls // Recreate client with new relays if (client) { client.disconnect() client = null } } function setAccount(nostrAccount: NostrAccount | null) { account.value = nostrAccount } // Push notification management async function enablePushNotifications(): Promise { try { const subscription = await pushService.subscribe() pushSubscription.value = subscription notificationsEnabled.value = true // Store subscription in localStorage for persistence localStorage.setItem('push-subscription', JSON.stringify(subscription)) localStorage.setItem('notifications-enabled', 'true') return subscription } catch (error) { console.error('Failed to enable push notifications:', error) throw error } } async function disablePushNotifications(): Promise { try { await pushService.unsubscribe() pushSubscription.value = null notificationsEnabled.value = false // Remove from localStorage localStorage.removeItem('push-subscription') localStorage.removeItem('notifications-enabled') } catch (error) { console.error('Failed to disable push notifications:', error) throw error } } async function checkPushNotificationStatus(): Promise { try { // Check localStorage first const storedEnabled = localStorage.getItem('notifications-enabled') === 'true' const storedSubscription = localStorage.getItem('push-subscription') if (storedEnabled && storedSubscription) { pushSubscription.value = JSON.parse(storedSubscription) notificationsEnabled.value = true } // Verify with push service const currentSubscription = await pushService.getSubscription() if (currentSubscription) { pushSubscription.value = currentSubscription notificationsEnabled.value = true } else if (storedEnabled) { // Stored state says enabled but no actual subscription - clear stored state await disablePushNotifications() } } catch (error) { console.error('Failed to check push notification status:', error) } } // Send test notification async function sendTestNotification(): Promise { await pushService.showLocalNotification({ title: '🚨 Test Admin Announcement', body: 'This is a test notification to verify push notifications are working correctly.', icon: '/pwa-192x192.png', tag: 'test-notification', data: { url: '/', type: 'admin-announcement' } }) } return { // State isConnected, isConnecting, error, relayUrls, account, pushSubscription, notificationsEnabled, // Actions connect, disconnect, getClient, setConnected, setRelayUrls, setAccount, enablePushNotifications, disablePushNotifications, checkPushNotificationStatus, sendTestNotification, } })