fix: Auto-initialize gift wrap subscriptions on login

CRITICAL FIX: Gift wrap service was only initialized when opening the
inbox viewer, meaning users wouldn't receive DMs unless they had the
inbox window open. This caused the issue where sent messages appeared
but received messages didn't.

**Root Cause:**

1. Gift wrap service init only happened in InboxViewer component
2. Default settings had enabled=false
3. Subscription only started if enabled=true
4. Result: No subscription → no incoming messages

**Solution:**

Moved gift wrap service initialization to useAccountSync hook, which runs
globally whenever a user is logged in. This ensures DM subscriptions are
always active.

**Changes:**

1. src/hooks/useAccountSync.ts:
   * Added gift wrap service initialization when account changes
   * Auto-enables inbox sync on first login (enabled=true)
   * Properly cleans up on logout/account change
   * Runs globally in AppShell, not just in inbox viewer

2. src/components/InboxViewer.tsx:
   * Removed redundant service initialization
   * Added comment explaining global init
   * Kept signer update effect for account switching

**Expected Behavior:**

-  User logs in → gift wrap subscription starts automatically
-  DMs received in real-time even when inbox viewer closed
-  Both sent and received messages appear live in chat
-  Works with self-chat and group chats
-  Proper cleanup on logout

**Testing:**

1. Login to account
2. Console should show: '[useAccountSync] Initializing gift wrap service'
3. Open chat with someone (don't open inbox viewer)
4. Have them send you a message
5. Message should appear automatically within 500ms
6. Send a message back
7. Both messages visible without manual sync

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Alejandro Gómez
2026-01-16 14:31:41 +01:00
parent 024be8d7ea
commit cb98fc129b
2 changed files with 43 additions and 7 deletions

View File

@@ -48,14 +48,10 @@ function InboxViewer() {
const [isDecryptingAll, setIsDecryptingAll] = useState(false);
// Initialize service when account changes
useEffect(() => {
if (account) {
giftWrapService.init(account.pubkey, account.signer ?? null);
}
}, [account]);
// Note: Gift wrap service is now initialized globally in useAccountSync
// This ensures DM subscriptions are active even when inbox viewer isn't open
// Update signer when it changes
// Update signer when it changes (in case user switches signers)
useEffect(() => {
if (account?.signer) {
giftWrapService.setSigner(account.signer);

View File

@@ -6,6 +6,7 @@ import { addressLoader } from "@/services/loaders";
import type { RelayInfo } from "@/types/app";
import { normalizeRelayURL } from "@/lib/relay-url";
import { getServersFromEvent } from "@/services/blossom";
import giftWrapService from "@/services/gift-wrap";
/**
* Hook that syncs active account with Grimoire state and fetches relay lists and blossom servers
@@ -125,4 +126,43 @@ export function useAccountSync() {
storeSubscription.unsubscribe();
};
}, [activeAccount?.pubkey, eventStore, setActiveAccountBlossomServers]);
// Initialize gift wrap service for NIP-17 DM subscriptions when account changes
useEffect(() => {
if (!activeAccount?.pubkey) {
console.log(
"[useAccountSync] No active account, cleaning up gift wrap service",
);
giftWrapService.cleanup();
return;
}
const pubkey = activeAccount.pubkey;
const signer = activeAccount.signer ?? null;
console.log(
`[useAccountSync] Initializing gift wrap service for user ${pubkey.slice(0, 8)}`,
);
// Initialize the service (loads inbox relays, sets up subscriptions)
giftWrapService.init(pubkey, signer);
// Auto-enable inbox sync if not already set
// This ensures users receive DMs without manually enabling inbox
const currentSettings = giftWrapService.settings$.value;
if (!currentSettings.enabled) {
console.log(
"[useAccountSync] Auto-enabling inbox sync for NIP-17 DM subscriptions",
);
giftWrapService.updateSettings({ enabled: true });
}
// Cleanup on account change or logout
return () => {
console.log(
`[useAccountSync] Cleaning up gift wrap service for user ${pubkey.slice(0, 8)}`,
);
giftWrapService.cleanup();
};
}, [activeAccount?.pubkey, activeAccount?.signer]);
}