diff --git a/src/components/ConnectionStatus.vue b/src/components/ConnectionStatus.vue
index 6d76609..96faa89 100644
--- a/src/components/ConnectionStatus.vue
+++ b/src/components/ConnectionStatus.vue
@@ -1,21 +1,122 @@
-
-
{{ status }}
+
+
+ {{ status }}
+
+ (1)
+
+
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/stores/nostr.ts b/src/stores/nostr.ts
index 026dca8..d4f1f0a 100644
--- a/src/stores/nostr.ts
+++ b/src/stores/nostr.ts
@@ -50,6 +50,10 @@ async function withTimeout(promise: Promise, timeoutMs: number = 10000): P
// Add to state
const connectionStatus = ref<'connected' | 'connecting' | 'disconnected'>('disconnected')
+const hasUnreadMessages = ref(false)
+const viewedMessageIds = ref>(new Set(
+ JSON.parse(localStorage.getItem('nostr_viewed_messages') || '[]')
+))
// Update in connect function
async function connectToRelay(url: string) {
@@ -224,6 +228,10 @@ export const useNostrStore = defineStore('nostr', () => {
activeChat.value = null
localStorage.removeItem('nostr_messages')
localStorage.removeItem('nostr_account')
+ hasUnreadMessages.value = false
+ localStorage.removeItem('nostr_unread_messages')
+ viewedMessageIds.value.clear()
+ localStorage.removeItem('nostr_viewed_messages')
}
const addMessage = async (pubkey: string, message: DirectMessage) => {
@@ -232,25 +240,28 @@ export const useNostrStore = defineStore('nostr', () => {
return
}
- // Add message ID to processed set
processedMessageIds.value.add(message.id)
-
- // Add message to the map
const userMessages = messages.value.get(pubkey) || []
- // Check for duplicates by content and timestamp (backup check)
+ // Check for duplicates
const isDuplicate = userMessages.some(msg =>
msg.content === message.content &&
Math.abs(msg.created_at - message.created_at) < 1
)
if (!isDuplicate) {
- messages.value.set(pubkey, [...userMessages, message])
+ messages.value.set(pubkey, [...userMessages, message].sort((a, b) =>
+ a.created_at - b.created_at
+ ))
- // Sort messages by timestamp
- const sortedMessages = messages.value.get(pubkey) || []
- sortedMessages.sort((a, b) => a.created_at - b.created_at)
- messages.value.set(pubkey, sortedMessages)
+ // Only set unread if:
+ // 1. Message came from websocket (not storage)
+ // 2. Not from current chat
+ // 3. Not sent by us
+ if (!message.fromStorage && pubkey !== activeChat.value && !message.sent) {
+ console.log('New unread message received:', { pubkey, messageId: message.id })
+ hasUnreadMessages.value = true
+ }
}
}
@@ -340,11 +351,11 @@ export const useNostrStore = defineStore('nostr', () => {
pubkey: event.pubkey,
content: decrypted,
created_at: event.created_at,
- sent: false
+ sent: false,
+ fromStorage: false // Mark as not from storage
}
await addMessage(event.pubkey, dm)
- processedMessageIds.value.add(event.id)
} catch (err) {
console.error('Failed to decrypt received message:', err)
}
@@ -374,7 +385,6 @@ export const useNostrStore = defineStore('nostr', () => {
}
await addMessage(targetPubkey, dm)
- processedMessageIds.value.add(event.id)
} catch (err) {
console.error('Failed to decrypt sent message:', err)
}
@@ -564,6 +574,30 @@ export const useNostrStore = defineStore('nostr', () => {
window.addEventListener('focus', handleVisibilityChange)
}
+ // Add function to clear unread state
+ function clearUnreadMessages() {
+ hasUnreadMessages.value = false
+ localStorage.setItem('nostr_unread_messages', 'false')
+
+ // Mark all current chat messages as viewed
+ if (activeChat.value) {
+ const chatMessages = messages.value.get(activeChat.value) || []
+ chatMessages.forEach(msg => {
+ viewedMessageIds.value.add(msg.id)
+ })
+ // Persist viewed message IDs
+ localStorage.setItem('nostr_viewed_messages',
+ JSON.stringify(Array.from(viewedMessageIds.value))
+ )
+ }
+ }
+
+ // Add to watch section
+ watch(activeChat, () => {
+ // Clear unread messages when changing to a chat
+ clearUnreadMessages()
+ })
+
return {
account,
profiles,
@@ -580,5 +614,7 @@ export const useNostrStore = defineStore('nostr', () => {
loadProfiles,
connectionStatus,
hasActiveSubscription,
+ hasUnreadMessages,
+ clearUnreadMessages,
}
})
\ No newline at end of file
diff --git a/src/types/nostr.ts b/src/types/nostr.ts
index b34905c..091392d 100644
--- a/src/types/nostr.ts
+++ b/src/types/nostr.ts
@@ -34,4 +34,5 @@ export interface DirectMessage {
content: string
created_at: number
sent: boolean
+ fromStorage?: boolean
}
\ No newline at end of file