fix(contacts): improve friend requests and relay DM channel invites
Use server+client ephemeral joins with longer flush for CONTACT_REQUEST delivery. Forward DM_CHANNEL_UPSERT to peers on the contacts mesh. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -110,6 +110,12 @@ class PearcordContacts extends EventEmitter {
|
||||
return row
|
||||
}
|
||||
|
||||
async sendDmChannelInvite (peerUserId, channel) {
|
||||
if (!peerUserId || !channel?.id) return null
|
||||
await this._gossipToPeer(peerUserId, RPC.DM_CHANNEL_UPSERT, channel)
|
||||
return channel
|
||||
}
|
||||
|
||||
async acceptRequest (peerUserId) {
|
||||
const row = await this.get(peerUserId)
|
||||
if (!row || row.status !== CONTACT_STATUS.PENDING_IN) {
|
||||
@@ -231,6 +237,7 @@ class PearcordContacts extends EventEmitter {
|
||||
id: blocked?.id || id(),
|
||||
ownerId: this.userId,
|
||||
peerUserId: from,
|
||||
peerUsername: payload.fromUsername || null,
|
||||
peerDisplayName: payload.fromDisplayName || payload.fromUsername || from.slice(0, 8),
|
||||
status: mutual ? CONTACT_STATUS.ACCEPTED : CONTACT_STATUS.PENDING_IN,
|
||||
requestedAt: payload.at || now(),
|
||||
@@ -343,6 +350,10 @@ class PearcordContacts extends EventEmitter {
|
||||
this.emit('profile-cosmetic', payload)
|
||||
return
|
||||
}
|
||||
if (method === RPC.DM_CHANNEL_UPSERT) {
|
||||
this.emit('dm-channel', payload)
|
||||
return
|
||||
}
|
||||
if (method === RPC.CONTACT_REQUEST) {
|
||||
this.ingestRequest(payload).catch(() => {})
|
||||
} else if (method === RPC.CONTACT_ACCEPT) {
|
||||
@@ -359,6 +370,10 @@ class PearcordContacts extends EventEmitter {
|
||||
}
|
||||
|
||||
async simulateGossip (method, payload) {
|
||||
if (method === RPC.DM_CHANNEL_UPSERT) {
|
||||
this.emit('dm-channel', payload)
|
||||
return payload
|
||||
}
|
||||
if (method === RPC.PRESENCE_UPDATE) return this.ingestFriendPresence(payload)
|
||||
if (method === RPC.PROFILE_COSMETIC_UPDATE) {
|
||||
this.emit('profile-cosmetic', payload)
|
||||
@@ -413,13 +428,15 @@ class PearcordContacts extends EventEmitter {
|
||||
const persistent = this._friendTopics.has(topic)
|
||||
const wasEphemeral = this._ephemeralTopics.has(topic)
|
||||
if (!persistent && !wasEphemeral) {
|
||||
await this.swarm.join(buf, { server: false, client: true })
|
||||
await this.swarm.join(buf, { server: true, client: true })
|
||||
this._ephemeralTopics.add(topic)
|
||||
}
|
||||
await this._flushSwarm()
|
||||
await this._flushSwarm(6000)
|
||||
await broadcastContactsGossip(this, method, payload)
|
||||
if (!persistent && !wasEphemeral) {
|
||||
await new Promise((r) => setTimeout(r, 350))
|
||||
await new Promise((r) => setTimeout(r, 1200))
|
||||
await broadcastContactsGossip(this, method, payload).catch(() => {})
|
||||
await new Promise((r) => setTimeout(r, 400))
|
||||
await this.swarm.leave(buf).catch(() => {})
|
||||
this._ephemeralTopics.delete(topic)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
const Protomux = require('protomux')
|
||||
const b4a = require('b4a')
|
||||
const { encodeRpc, decodeRpc } = require('pearcord-shared')
|
||||
const { encodeRpc, decodeRpc, wireSwarmConnection } = require('pearcord-shared')
|
||||
const { openWireChannel, wireReady } = require('pearcord-drive/mux-wire')
|
||||
|
||||
const CONTACTS_PROTOCOL = 'pearcord-contacts-v1'
|
||||
|
||||
function attachContactsMesh (contacts, conn) {
|
||||
wireSwarmConnection(conn)
|
||||
const mux = Protomux.from(conn)
|
||||
return openWireChannel(mux, {
|
||||
protocol: CONTACTS_PROTOCOL,
|
||||
|
||||
Reference in New Issue
Block a user