feat(platform): avatar mesh, DM video/screen-share, rekey prefs v0.8.635

Peer avatar image IPC, live screen-share on video calls, toggleDmVideoCall,
readPeerAvatarPreview, and dismissed rekey channel id persistence.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-06-02 01:23:41 -04:00
co-authored by Cursor
parent 8671f1e250
commit 63c1cef962
+103 -2
View File
@@ -142,6 +142,7 @@ const {
const { PearcordContacts } = require('pearcord-contacts')
const { PearcordNotifications } = require('pearcord-notifications')
const { PearcordSettings } = require('pearcord-settings')
const { UserPrefsMirrorStore } = require('pearcord-settings/prefs-store')
const { PearcordProfileCosmetics } = require('pearcord-profile-cosmetics')
const {
enrichProfileCosmeticGossip,
@@ -331,6 +332,8 @@ class PearcordPlatform extends EventEmitter {
this.dm = null
this.dmVoice = null
this._dmVoiceMedia = null
this._dmScreenShare = null
this._prefsMirrorStore = null
this.attachments = null
this.moderation = null
this.voice = null
@@ -921,6 +924,7 @@ class PearcordPlatform extends EventEmitter {
storagePath: this.storagePath,
userId: snap.user.id
})
this.userSettings._prefsMirror = await this._ensurePrefsMirrorStore()
await this.userSettings.ready()
const sessionPrefs = await this.userSettings.getPrefs()
this._ingestGuildPresenceCacheFromPrefs(sessionPrefs)
@@ -1137,8 +1141,11 @@ class PearcordPlatform extends EventEmitter {
})
this.userSettings = new PearcordSettings({
storagePath: this.storagePath,
userId: user.id
userId: user.id,
prefsMirror: null
})
const prefsMirror = await this._ensurePrefsMirrorStore()
this.userSettings._prefsMirror = prefsMirror
this.profileCosmetics = new PearcordProfileCosmetics({
storagePath: this.storagePath,
userId: user.id
@@ -1646,6 +1653,16 @@ class PearcordPlatform extends EventEmitter {
})
}
async _ensurePrefsMirrorStore () {
if (this._prefsMirrorStore) return this._prefsMirrorStore
this._prefsMirrorStore = new UserPrefsMirrorStore({
db: this.db,
storagePath: this.storagePath
})
await this._prefsMirrorStore.ready()
return this._prefsMirrorStore
}
async _ensureDmMetaStore () {
if (this._dmMetaStore) return this._dmMetaStore
this._dmMetaStore = new DmChannelMetaStore({
@@ -1848,7 +1865,20 @@ class PearcordPlatform extends EventEmitter {
}
clearDmSessionRekeyNotice () {
const notice = this._dmSessionRekeyNotice
this._dmSessionRekeyNotice = null
if (notice?.channelId && this.userSettings) {
void this.userSettings.getPrefs().then(async (prefs) => {
const dismissed = [...(prefs.dismissedDmRekeyChannelIds || [])]
if (!dismissed.includes(notice.channelId)) {
dismissed.push(notice.channelId)
await this.userSettings.setPrefs(
{ dismissedDmRekeyChannelIds: dismissed.slice(-48) },
{ gossip: false }
)
}
}).catch(() => {})
}
return true
}
@@ -1998,6 +2028,7 @@ class PearcordPlatform extends EventEmitter {
channelId: ch.id,
peerUserId,
isGroup: !!ch.isGroup,
participantIds: ch.isGroup ? (ch.participantIds || []) : undefined,
voiceMediaHub: media
})
this.emit('dm-voice')
@@ -2024,7 +2055,42 @@ class PearcordPlatform extends EventEmitter {
}
}
async _ensureDmScreenShare () {
const user = this.identity?.user
if (!user?.id) throw new Error('register first')
if (!this._dmScreenShare) {
this._dmScreenShare = new ScreenShareHub({
storagePath: this.storagePath,
guildId: DM_GUILD_ID,
userId: user.id,
displayFeed: this.displayCapture
})
await this._dmScreenShare.ready()
this._dmScreenShare.on('frame', () => this.emit('screen-share'))
}
return this._dmScreenShare
}
async _resolvePeerAvatarHash (userId) {
if (!userId) return null
const presenceMap = this.contacts?.getFriendPresenceMap?.() || {}
if (presenceMap[userId]?.avatarHash) return presenceMap[userId].avatarHash
const user = await this.db.get(COLLECTIONS.USERS, { id: userId }).catch(() => null)
return user?.avatarHash || null
}
async readPeerAvatarPreview (userId) {
if (!userId) throw new Error('userId required')
const hash = await this._resolvePeerAvatarHash(userId)
if (!hash) return null
await this._ensureBannerAttachmentReady(hash, userId).catch(() => {})
return this.readAttachmentPreview(hash)
}
async endDmVoiceCall (reason = 'ended') {
if (this._dmScreenShare?.active) {
await this._dmScreenShare.stopShare().catch(() => {})
}
const voice = await this._ensureDmVoice()
if (!voice || voice.state === 'idle') return { ended: false }
const span = this.log.time('dm.voice.hangup', {
@@ -2130,6 +2196,11 @@ class PearcordPlatform extends EventEmitter {
peerUserId,
voiceMediaHub: media
})
const screen = await this._ensureDmScreenShare().catch(() => null)
if (screen) {
await screen.startShare(ch.id, 'DM Video').catch(() => {})
}
this.emit('screen-share')
this.emit('dm-voice')
this.emit('voice-media')
span.end({
@@ -2153,6 +2224,20 @@ class PearcordPlatform extends EventEmitter {
}
}
async toggleDmVideoCall () {
const voice = await this._ensureDmVoice()
if (voice?.snapshot?.()?.videoActive) {
await voice.stopVideo()
if (this._dmScreenShare?.active) {
await this._dmScreenShare.stopShare().catch(() => {})
}
this.emit('dm-voice')
this.emit('screen-share')
return { videoActive: false, toggled: true }
}
return this.startDmVideoCall()
}
async createGroupDM ({ peerUserIds, name }) {
const ids = peerUserIds || []
const span = this.log.time('dm.group.create', {
@@ -20037,12 +20122,27 @@ class PearcordPlatform extends EventEmitter {
peers: []
}
let dmMetaEngine = 'json'
let userPrefsEngine = 'json'
try {
const metaStore = await this._ensureDmMetaStore()
dmMetaEngine = metaStore.engine || 'json'
} catch {
dmMetaEngine = 'json'
}
try {
const prefsMirror = await this._ensurePrefsMirrorStore()
userPrefsEngine = prefsMirror.engine || 'json'
} catch {
userPrefsEngine = 'json'
}
const dismissedRekeys = new Set(
(await this.userSettings?.getPrefs?.().catch(() => null))?.dismissedDmRekeyChannelIds || []
)
const dmSessionRekey =
this._dmSessionRekeyNotice &&
!dismissedRekeys.has(this._dmSessionRekeyNotice.channelId)
? this._dmSessionRekeyNotice
: null
const activityFeed = buildActivityFeed({
selfUserId: user?.id,
presence: this.presence?.snapshot() || null,
@@ -20101,6 +20201,7 @@ class PearcordPlatform extends EventEmitter {
permissionMeta: PERMISSION_META,
dmConversations,
dmMetaEngine,
userPrefsEngine,
globalPresence,
dmCall: this.dmVoice?.snapshot?.() || {
state: 'idle',
@@ -20108,7 +20209,7 @@ class PearcordPlatform extends EventEmitter {
connected: false,
peerCount: 0
},
dmSessionRekey: this._dmSessionRekeyNotice,
dmSessionRekey,
dmPeer: this._dmPeerId(),
dmTitle: this.dm?.channel?.name || null,
dmIsGroup: !!this.dm?.channel?.isGroup,