debug: Add comprehensive logging to diagnose live message delivery

Added detailed logging throughout gift-wrap service to trace:
- Timeline subscription firing
- Gift wrap detection (symbol vs persisted)
- Conversation updates
- Rumor extraction

Also fixed updateConversations to check persistedIds in addition to
in-memory symbol, ensuring gift wraps are processed correctly even
after persistence.

This will help identify why messages don't appear live and require
manual sync.
This commit is contained in:
Alejandro Gómez
2026-01-16 14:02:40 +01:00
parent ae46088333
commit b6dad2429c

View File

@@ -363,15 +363,29 @@ class GiftWrapService {
};
// Use timeline observable for reactive updates
console.log(
`[GiftWrap] Setting up timeline subscription for user ${this.userPubkey?.slice(0, 8)}`,
);
const sub = eventStore
.timeline(reqFilter)
.pipe(map((events) => events.sort((a, b) => b.created_at - a.created_at)))
.subscribe((giftWraps) => {
console.log(
`[GiftWrap] 📬 Timeline subscription fired with ${giftWraps.length} gift wraps`,
);
// Find new gift wraps that we haven't seen before
const newGiftWraps = giftWraps.filter(
(gw) => !this.giftWraps.some((existing) => existing.id === gw.id),
);
if (newGiftWraps.length > 0) {
console.log(
`[GiftWrap] Found ${newGiftWraps.length} new gift wraps:`,
newGiftWraps.map((gw) => gw.id.slice(0, 8)),
);
}
this.giftWraps = giftWraps;
this.giftWraps$.next(giftWraps);
@@ -380,8 +394,14 @@ class GiftWrapService {
if (!this.decryptStates.has(gw.id)) {
// Check both in-memory unlock state and persisted IDs
// Persisted IDs indicate content was decrypted in a previous session
const isUnlocked =
isGiftWrapUnlocked(gw) || this.persistedIds.has(gw.id);
const hasSymbol = isGiftWrapUnlocked(gw);
const hasPersisted = this.persistedIds.has(gw.id);
const isUnlocked = hasSymbol || hasPersisted;
console.log(
`[GiftWrap] Gift wrap ${gw.id.slice(0, 8)}: symbol=${hasSymbol}, persisted=${hasPersisted}, unlocked=${isUnlocked}`,
);
this.decryptStates.set(gw.id, {
status: isUnlocked ? "success" : "pending",
decryptedAt: isUnlocked ? Date.now() : undefined,
@@ -442,14 +462,32 @@ class GiftWrapService {
* preserving all fields (id, pubkey, created_at, kind, tags, content).
*/
private updateConversations() {
console.log(
`[GiftWrap] Updating conversations from ${this.giftWraps.length} gift wraps`,
);
const conversationMap = new Map<string, Conversation>();
const allRumors: Array<{ giftWrap: NostrEvent; rumor: Rumor }> = [];
for (const gw of this.giftWraps) {
if (!isGiftWrapUnlocked(gw)) continue;
// Check both in-memory unlock state AND persisted IDs
// This is critical: gift wraps we just sent have the symbol,
// but after reload they only have persisted IDs
const isUnlocked = isGiftWrapUnlocked(gw) || this.persistedIds.has(gw.id);
if (!isUnlocked) {
console.log(
`[GiftWrap] Skipping locked gift wrap ${gw.id.slice(0, 8)}`,
);
continue;
}
const rumor = getGiftWrapRumor(gw);
if (!rumor) continue;
if (!rumor) {
console.log(
`[GiftWrap] Gift wrap ${gw.id.slice(0, 8)} has no rumor (might need to load from cache)`,
);
continue;
}
// Collect all decrypted rumors (any kind) for future use
allRumors.push({ giftWrap: gw, rumor });
@@ -482,6 +520,10 @@ class GiftWrapService {
(b.lastMessage?.created_at ?? 0) - (a.lastMessage?.created_at ?? 0),
);
console.log(
`[GiftWrap] 💬 Updated conversations: ${conversations.length} conversations, ${allRumors.length} total rumors`,
);
this.conversations$.next(conversations);
}