OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon / lib / dm-shares.js

80 lines · javascript ref:
/**
 * dm-shares.js — _hs:room-share messages in DM rooms
 *
 * Share rooms with DM contacts as structured messages.
 * Each share is one editable message — update invite token by editing,
 * unshare by deleting.
 *
 * Usage:
 *   const shares = new DmShares(backend)
 *   await shares.share(dmRoomId, { roomId, title, topics, inviteToken })
 *   await shares.list(dmRoomId) → [{ roomId, title, ... , messageId }]
 */

import { createHsMessage, parseHsMessage } from './room-meta.js'

export class DmShares {
  constructor (backend) {
    this.backend = backend
  }

  /**
   * Share a room in a DM conversation.
   * Posts an _hs:room-share message.
   */
  async share (dmRoomId, { roomId, title, topics, inviteToken }) {
    if (!dmRoomId) throw new Error('Missing dmRoomId')
    if (!roomId) throw new Error('Missing roomId')

    const payload = createHsMessage('room-share', {
      roomId,
      title: title || '',
      topics: topics || [],
      inviteToken: inviteToken || '',
      sharedAt: Date.now()
    })

    const result = await this.backend.api.core.addChatMessage(dmRoomId, payload, {})
    return result || { ok: true }
  }

  /**
   * List rooms shared in a DM conversation.
   * Scans message history for _hs:room-share messages.
   * Returns array of shares with messageId for edit/delete.
   */
  async list (dmRoomId) {
    if (!dmRoomId) throw new Error('Missing dmRoomId')

    const result = await this.backend.api.core.getChatMessages(dmRoomId, {
      limit: 200,
      reverse: true
    })
    const messages = Array.isArray(result) ? result : (result?.messages || result?.data || [])

    const shares = []
    const seen = new Set() // dedupe by roomId (latest share wins)

    for (const msg of messages) {
      if (msg.deleted) continue
      const text = msg.chat?.text || msg.text || msg.message?.text || ''
      const parsed = parseHsMessage(text)
      if (!parsed || parsed._hs !== 'room-share') continue
      if (seen.has(parsed.roomId)) continue
      seen.add(parsed.roomId)

      shares.push({
        roomId: parsed.roomId,
        title: parsed.title || '',
        topics: parsed.topics || [],
        inviteToken: parsed.inviteToken || '',
        sharedAt: parsed.sharedAt || null,
        messageId: msg.id || null,
        sharedBy: msg.memberId || null
      })
    }

    return shares
  }
}