feat(contacts): unblockContact with CONTACT_UNBLOCK P2P gossip

Users can remove blocks locally and notify peers via CONTACT_UNBLOCK.
ingestUnblock clears blocked rows when a remote device unblocks you.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-21 20:41:35 -04:00
co-authored by Cursor
parent fef965beb3
commit dfab588145
+24
View File
@@ -176,6 +176,27 @@ class PearcordContacts extends EventEmitter {
return rows.filter((r) => r.status === CONTACT_STATUS.BLOCKED)
}
async unblockContact (peerUserId) {
if (!peerUserId) throw new Error('peerUserId required')
const row = await this.get(peerUserId)
if (!row || row.status !== CONTACT_STATUS.BLOCKED) return null
await this.store.delete(CONTACTS_COLLECTION, contactKey(this.userId, peerUserId))
await this._gossipToPeer(peerUserId, RPC.CONTACT_UNBLOCK, {
...this._profilePayload(),
toUserId: peerUserId
}).catch(() => {})
this.emit('contact', null)
return row
}
async ingestUnblock (payload) {
const from = payload?.fromUserId
if (!from || from === this.userId) return null
await this.store.delete(CONTACTS_COLLECTION, contactKey(this.userId, from))
this.emit('contact', null)
return null
}
async ingestBlock (payload) {
const from = payload?.fromUserId
if (!from || from === this.userId) return null
@@ -273,6 +294,8 @@ class PearcordContacts extends EventEmitter {
this.ingestRemove(payload).catch(() => {})
} else if (method === RPC.CONTACT_BLOCK) {
this.ingestBlock(payload).catch(() => {})
} else if (method === RPC.CONTACT_UNBLOCK) {
this.ingestUnblock(payload).catch(() => {})
}
}
@@ -282,6 +305,7 @@ class PearcordContacts extends EventEmitter {
if (method === RPC.CONTACT_DECLINE) return this.ingestDecline(payload)
if (method === RPC.CONTACT_REMOVE) return this.ingestRemove(payload)
if (method === RPC.CONTACT_BLOCK) return this.ingestBlock(payload)
if (method === RPC.CONTACT_UNBLOCK) return this.ingestUnblock(payload)
this._onGossip(method, payload)
return null
}