diff --git a/src/composables/useNostrChat.ts b/src/composables/useNostrChat.ts index 718fe9a..c8674e5 100644 --- a/src/composables/useNostrChat.ts +++ b/src/composables/useNostrChat.ts @@ -24,6 +24,7 @@ export interface NostrRelayConfig { interface UnreadMessageData { lastReadTimestamp: number unreadCount: number + processedMessageIds: Set // Track which messages we've already counted as unread } const UNREAD_MESSAGES_KEY = 'nostr-chat-unread-messages' @@ -32,17 +33,30 @@ const UNREAD_MESSAGES_KEY = 'nostr-chat-unread-messages' const getUnreadData = (peerPubkey: string): UnreadMessageData => { try { const stored = localStorage.getItem(`${UNREAD_MESSAGES_KEY}-${peerPubkey}`) - return stored ? JSON.parse(stored) : { lastReadTimestamp: 0, unreadCount: 0 } + if (stored) { + const data = JSON.parse(stored) + // Convert the array back to a Set for processedMessageIds + return { + ...data, + processedMessageIds: new Set(data.processedMessageIds || []) + } + } + return { lastReadTimestamp: 0, unreadCount: 0, processedMessageIds: new Set() } } catch (error) { console.warn('Failed to load unread data for peer:', peerPubkey, error) - return { lastReadTimestamp: 0, unreadCount: 0 } + return { lastReadTimestamp: 0, unreadCount: 0, processedMessageIds: new Set() } } } // Save unread message data for a peer const saveUnreadData = (peerPubkey: string, data: UnreadMessageData): void => { try { - localStorage.setItem(`${UNREAD_MESSAGES_KEY}-${peerPubkey}`, JSON.stringify(data)) + // Convert Set to array for localStorage serialization + const serializableData = { + ...data, + processedMessageIds: Array.from(data.processedMessageIds) + } + localStorage.setItem(`${UNREAD_MESSAGES_KEY}-${peerPubkey}`, JSON.stringify(serializableData)) } catch (error) { console.warn('Failed to save unread data for peer:', peerPubkey, error) } @@ -99,10 +113,11 @@ export function useNostrChat() { const currentTimestamp = Math.floor(Date.now() / 1000) const unreadData = getUnreadData(peerPubkey) - // Update last read timestamp and reset unread count + // Update last read timestamp, reset unread count, and clear processed message IDs const updatedData: UnreadMessageData = { lastReadTimestamp: currentTimestamp, - unreadCount: 0 + unreadCount: 0, + processedMessageIds: new Set() // Clear processed messages when marking as read } saveUnreadData(peerPubkey, updatedData) @@ -116,9 +131,17 @@ export function useNostrChat() { key.startsWith(`${UNREAD_MESSAGES_KEY}-`) ) + console.log('Loading unread counts from localStorage. Found keys:', keys) + for (const key of keys) { const peerPubkey = key.replace(`${UNREAD_MESSAGES_KEY}-`, '') const unreadData = getUnreadData(peerPubkey) + console.log(`Peer ${peerPubkey}:`, { + lastReadTimestamp: unreadData.lastReadTimestamp, + unreadCount: unreadData.unreadCount, + processedMessageIdsCount: unreadData.processedMessageIds.size + }) + if (unreadData.unreadCount > 0) { unreadCounts.value.set(peerPubkey, unreadData.unreadCount) } @@ -150,6 +173,36 @@ export function useNostrChat() { } } + // Clear processed message IDs for a specific peer (useful for debugging) + const clearProcessedMessageIds = (peerPubkey: string): void => { + try { + const unreadData = getUnreadData(peerPubkey) + const updatedData: UnreadMessageData = { + ...unreadData, + processedMessageIds: new Set() + } + saveUnreadData(peerPubkey, updatedData) + console.log(`Cleared processed message IDs for peer: ${peerPubkey}`) + } catch (error) { + console.warn('Failed to clear processed message IDs for peer:', peerPubkey, error) + } + } + + // Debug function to show current state of unread data for a peer + const debugUnreadData = (peerPubkey: string): void => { + try { + const unreadData = getUnreadData(peerPubkey) + console.log(`Debug unread data for ${peerPubkey}:`, { + lastReadTimestamp: unreadData.lastReadTimestamp, + unreadCount: unreadData.unreadCount, + processedMessageIds: Array.from(unreadData.processedMessageIds), + processedMessageIdsCount: unreadData.processedMessageIds.size + }) + } catch (error) { + console.warn('Failed to debug unread data for peer:', peerPubkey, error) + } + } + // Get relays from config - requires VITE_NOSTR_RELAYS to be set const getRelays = (): NostrRelayConfig[] => { const configuredRelays = config.nostr.relays @@ -536,22 +589,37 @@ export function useNostrChat() { if (!isSentByMe) { const unreadData = getUnreadData(peerPubkey) - // Check if this message is newer than the last read timestamp - if (message.created_at > unreadData.lastReadTimestamp) { + console.log(`Processing unread message logic for ${peerPubkey}:`, { + messageId: event.id, + messageTimestamp: message.created_at, + lastReadTimestamp: unreadData.lastReadTimestamp, + currentUnreadCount: unreadData.unreadCount, + alreadyProcessed: unreadData.processedMessageIds.has(event.id), + processedMessageIdsCount: unreadData.processedMessageIds.size + }) + + // Check if this message is newer than the last read timestamp AND we haven't already counted it + if (message.created_at > unreadData.lastReadTimestamp && !unreadData.processedMessageIds.has(event.id)) { + // Add this message ID to the processed set + unreadData.processedMessageIds.add(event.id) + const updatedUnreadData: UnreadMessageData = { lastReadTimestamp: unreadData.lastReadTimestamp, - unreadCount: unreadData.unreadCount + 1 + unreadCount: unreadData.unreadCount + 1, + processedMessageIds: unreadData.processedMessageIds } saveUnreadData(peerPubkey, updatedUnreadData) updateUnreadCount(peerPubkey, updatedUnreadData.unreadCount) - console.log(`New unread message from ${peerPubkey}. Total unread: ${updatedUnreadData.unreadCount}`) + console.log(`✅ New unread message from ${peerPubkey}. Total unread: ${updatedUnreadData.unreadCount}`) + } else if (unreadData.processedMessageIds.has(event.id)) { + console.log(`⏭️ Message ${event.id} from ${peerPubkey} already counted as unread. Skipping.`) } else { - console.log(`Message from ${peerPubkey} is older than last read timestamp. Skipping unread count.`) + console.log(`⏰ Message from ${peerPubkey} is older than last read timestamp. Skipping unread count.`) } } else { - console.log(`Message from ${peerPubkey} was sent by current user. Skipping unread count.`) + console.log(`📤 Message from ${peerPubkey} was sent by current user. Skipping unread count.`) } // Trigger callback if set @@ -723,6 +791,8 @@ export function useNostrChat() { getUnreadCount, getAllUnreadCounts, getTotalUnreadCount, - clearAllUnreadCounts + clearAllUnreadCounts, + clearProcessedMessageIds, + debugUnreadData } } \ No newline at end of file