feat: Implement push notification system for admin announcements
- Add a notification manager to handle push notifications and integrate with Nostr events. - Create a push notification service to manage subscription and permission requests. - Introduce components for notification settings and permission prompts in the UI. - Update Nostr store to manage push notification state and enable/disable functionality. - Enhance NostrFeed to send notifications for new admin announcements. - Implement test notification functionality for development purposes.
This commit is contained in:
parent
6c1caac84b
commit
c05f40f1ec
17 changed files with 1316 additions and 13 deletions
|
|
@ -2,6 +2,7 @@ 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 {
|
||||
|
|
@ -19,6 +20,10 @@ export const useNostrStore = defineStore('nostr', () => {
|
|||
const relayUrls = ref<string[]>(config.nostr.relays)
|
||||
const account = ref<NostrAccount | null>(null)
|
||||
|
||||
// Push notifications
|
||||
const pushSubscription = ref<PushSubscriptionData | null>(null)
|
||||
const notificationsEnabled = ref(false)
|
||||
|
||||
// Singleton client instance
|
||||
let client: NostrClient | null = null
|
||||
|
||||
|
|
@ -77,6 +82,78 @@ export const useNostrStore = defineStore('nostr', () => {
|
|||
account.value = nostrAccount
|
||||
}
|
||||
|
||||
// Push notification management
|
||||
async function enablePushNotifications(): Promise<PushSubscriptionData> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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,
|
||||
|
|
@ -84,6 +161,8 @@ export const useNostrStore = defineStore('nostr', () => {
|
|||
error,
|
||||
relayUrls,
|
||||
account,
|
||||
pushSubscription,
|
||||
notificationsEnabled,
|
||||
|
||||
// Actions
|
||||
connect,
|
||||
|
|
@ -92,5 +171,9 @@ export const useNostrStore = defineStore('nostr', () => {
|
|||
setConnected,
|
||||
setRelayUrls,
|
||||
setAccount,
|
||||
enablePushNotifications,
|
||||
disablePushNotifications,
|
||||
checkPushNotificationStatus,
|
||||
sendTestNotification,
|
||||
}
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue