feat: friend lastSeen + offline directory

This commit is contained in:
Raven Scott
2026-07-13 00:42:40 -04:00
parent ff720efef8
commit 698f2c98bb
+31 -3
View File
@@ -335,8 +335,14 @@ class PearcordContacts extends EventEmitter {
const row = presenceGossipRow(payload)
const prev = this._friendPresence.get(payload.userId)
if (prev && (prev.at || 0) > (row.at || 0)) return prev
this._friendPresence.set(payload.userId, row)
this.emit('friend-presence', row)
// Durable offline directory: keep lastSeen when peer goes offline or updates.
const lastSeen =
row.status && row.status !== 'offline'
? row.at || Date.now()
: prev?.lastSeen || prev?.at || row.at || Date.now()
const enriched = { ...row, lastSeen }
this._friendPresence.set(payload.userId, enriched)
this.emit('friend-presence', enriched)
if (row.username || row.displayName) {
this.emit('user', {
id: row.userId,
@@ -346,7 +352,7 @@ class PearcordContacts extends EventEmitter {
avatarHash: row.avatarHash
})
}
return row
return enriched
}
async broadcastPresence (payload) {
@@ -418,6 +424,28 @@ class PearcordContacts extends EventEmitter {
return out
}
/** Offline-directory snapshot for accepted friends (last-seen when presence cold). */
getOfflineDirectory (acceptedPeerIds = []) {
const ids = Array.isArray(acceptedPeerIds) ? acceptedPeerIds : []
const out = []
for (const peerUserId of ids) {
if (!peerUserId || this._blockedPeerIds.has(peerUserId)) continue
const row = this._friendPresence.get(peerUserId)
const status = row?.status || 'offline'
if (status === 'online' || status === 'idle' || status === 'dnd') continue
out.push({
peerUserId,
status: status || 'offline',
lastSeen: row?.lastSeen || row?.at || null,
activity: row?.activity || null,
avatarHash: row?.avatarHash || null,
displayName: row?.displayName || null,
username: row?.username || null
})
}
return out.sort((a, b) => (b.lastSeen || 0) - (a.lastSeen || 0))
}
_onGossip (method, payload) {
if (method === RPC.USER_UPSERT) {
if (payload?.id) this.emit('user', payload)