@@ -143,13 +143,7 @@ class MessageCollector
143143 }
144144 }
145145
146- val isFavorite =
147- try {
148- announceRepository.getAnnounce(sourceHash)?.isFavorite ? : false
149- } catch (e: Exception ) {
150- Log .w(TAG , " Could not check if peer is favorite" , e)
151- false
152- }
146+ val isFavorite = isSavedPeer(sourceHash)
153147
154148 // Only notify if the message hasn't been read yet
155149 // This prevents duplicate notifications after service restart
@@ -274,13 +268,7 @@ class MessageCollector
274268 Log .d(TAG , " Message saved to database for peer ${sourceHash.take(16 )} (hasPublicKey=${publicKey != null } )" )
275269
276270 // Check if sender is a saved peer (favorite)
277- val isFavorite =
278- try {
279- announceRepository.getAnnounce(sourceHash)?.isFavorite ? : false
280- } catch (e: Exception ) {
281- Log .w(TAG , " Could not check if peer is favorite" , e)
282- false
283- }
271+ val isFavorite = isSavedPeer(sourceHash)
284272
285273 // Show notification for received message
286274 try {
@@ -458,6 +446,39 @@ class MessageCollector
458446 return PeerNameResolver .formatHashAsFallback(peerHash)
459447 }
460448
449+ /* *
450+ * Determine whether [sourceHash] is a "saved peer" for notification purposes.
451+ *
452+ * A peer is considered saved if it is either:
453+ * - flagged as a favorite on its announce row (legacy "Save Peer" via the
454+ * announce stream star), OR
455+ * - present in the active identity's contacts table (written by the
456+ * "Save to Contacts" flows in Chats/Messaging, QR import, manual entry,
457+ * and propagation-node relay setup, which do not touch the announce flag).
458+ *
459+ * Both signals must be checked: the contacts table is the source of truth for
460+ * "saved" as the user experiences it, and the legacy flag is kept so peers saved
461+ * before the contacts table existed continue to notify. Either signal being true
462+ * is sufficient.
463+ */
464+ private suspend fun isSavedPeer (sourceHash : String ): Boolean {
465+ val favoriteFlag =
466+ try {
467+ announceRepository.getAnnounce(sourceHash)?.isFavorite ? : false
468+ } catch (e: Exception ) {
469+ Log .w(TAG , " Could not check if peer is favorite" , e)
470+ false
471+ }
472+ if (favoriteFlag) return true
473+
474+ return try {
475+ contactRepository.hasContact(sourceHash)
476+ } catch (e: Exception ) {
477+ Log .w(TAG , " Could not check if peer is a saved contact" , e)
478+ false
479+ }
480+ }
481+
461482 /* *
462483 * Get peer name with fallback - uses PeerNameResolver for consistent lookup across the app
463484 */
0 commit comments