From 2dec184c420d9b4c6eda46ee345f15da1a46ccc4 Mon Sep 17 00:00:00 2001 From: padreug Date: Sat, 9 Aug 2025 15:19:52 +0200 Subject: [PATCH] refactor: Replace Nostr chat preloader with a singleton pattern for improved state management - Remove the useNostrChatPreloader composable and integrate its functionality into the useNostrChat composable, streamlining chat data handling. - Update App.vue and ChatComponent to utilize the new singleton instance for managing chat connections and peer subscriptions. - Enhance Navbar and ChatComponent to reflect changes in unread message tracking and peer management, improving user experience. - Ensure proper error handling and logging during chat connection and peer loading processes. --- src/App.vue | 37 +++-- src/components/layout/Navbar.vue | 7 +- src/components/nostr/ChatComponent.vue | 60 ++++---- src/composables/useNostrChat.ts | 99 +++++++++++++- src/composables/useNostrChatPreloader.ts | 166 ----------------------- 5 files changed, 160 insertions(+), 209 deletions(-) delete mode 100644 src/composables/useNostrChatPreloader.ts diff --git a/src/App.vue b/src/App.vue index fae0885..cd68390 100644 --- a/src/App.vue +++ b/src/App.vue @@ -8,28 +8,39 @@ import { Toaster } from '@/components/ui/sonner' import 'vue-sonner/style.css' import { auth } from '@/composables/useAuth' import { useMarketPreloader } from '@/composables/useMarketPreloader' -import { useNostrChatPreloader } from '@/composables/useNostrChatPreloader' +import { nostrChat } from '@/composables/useNostrChat' import { toast } from 'vue-sonner' const route = useRoute() const showLoginDialog = ref(false) -// Initialize preloaders +// Initialize preloader const marketPreloader = useMarketPreloader() -const chatPreloader = useNostrChatPreloader() // Hide navbar on login page const showNavbar = computed(() => { return route.path !== '/login' }) -function handleLoginSuccess() { +async function handleLoginSuccess() { showLoginDialog.value = false toast.success('Welcome back!') // Trigger preloading after successful login marketPreloader.preloadMarket() - chatPreloader.preloadChat() + + // Connect to chat + if (!nostrChat.isConnected.value) { + try { + await nostrChat.connect() + + // Load peers and subscribe to all for notifications + const peers = await nostrChat.loadPeers() + await nostrChat.subscribeToAllPeersForNotifications(peers) + } catch (error) { + console.error('Failed to initialize chat:', error) + } + } } onMounted(async () => { @@ -42,15 +53,23 @@ onMounted(async () => { }) // Watch for authentication changes and trigger preloading -watch(() => auth.isAuthenticated.value, (isAuthenticated) => { +watch(() => auth.isAuthenticated.value, async (isAuthenticated) => { if (isAuthenticated) { if (!marketPreloader.isPreloaded.value) { console.log('User authenticated, triggering market preload...') marketPreloader.preloadMarket() } - if (!chatPreloader.isPreloaded.value) { - console.log('User authenticated, triggering chat preload...') - chatPreloader.preloadChat() + if (!nostrChat.isConnected.value) { + console.log('User authenticated, connecting to chat...') + try { + await nostrChat.connect() + + // Load peers and subscribe to all for notifications + const peers = await nostrChat.loadPeers() + await nostrChat.subscribeToAllPeersForNotifications(peers) + } catch (error) { + console.error('Failed to initialize chat:', error) + } } } }, { immediate: true }) diff --git a/src/components/layout/Navbar.vue b/src/components/layout/Navbar.vue index 926a833..1c887da 100644 --- a/src/components/layout/Navbar.vue +++ b/src/components/layout/Navbar.vue @@ -13,7 +13,7 @@ import ProfileDialog from '@/components/auth/ProfileDialog.vue' import CurrencyDisplay from '@/components/ui/CurrencyDisplay.vue' import { auth } from '@/composables/useAuth' import { useMarketPreloader } from '@/composables/useMarketPreloader' -import { useNostrChatPreloader } from '@/composables/useNostrChatPreloader' +import { nostrChat } from '@/composables/useNostrChat' interface NavigationItem { name: string @@ -27,7 +27,6 @@ const isOpen = ref(false) const showLoginDialog = ref(false) const showProfileDialog = ref(false) const marketPreloader = useMarketPreloader() -const chatPreloader = useNostrChatPreloader() const navigation = computed(() => [ { name: t('nav.home'), href: '/' }, @@ -45,9 +44,9 @@ const totalBalance = computed(() => { }, 0) }) -// Compute total unread messages +// Compute total unread messages (reactive) const totalUnreadMessages = computed(() => { - return chatPreloader.getTotalUnreadCount() + return nostrChat.totalUnreadCount.value }) const toggleMenu = () => { diff --git a/src/components/nostr/ChatComponent.vue b/src/components/nostr/ChatComponent.vue index bb35210..d971451 100644 --- a/src/components/nostr/ChatComponent.vue +++ b/src/components/nostr/ChatComponent.vue @@ -13,8 +13,8 @@ Disconnected - - {{ getTotalUnreadCount() }} unread + + {{ totalUnreadCount }} unread