@chisquare-tech/yan-ngx-apps-messages 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,10 @@ import { firstValueFrom } from 'rxjs';
5
5
 
6
6
  /** Mounted at `messages`. `to/:userId` opens (or starts) the direct conversation with someone, then replaces itself. */
7
7
  const MESSAGES_ROUTES = [
8
- { path: '', pathMatch: 'full', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-messages.page-L0fDp0gv.mjs').then((m) => m.MessagesPage) },
9
- { path: 'requests', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-messages.page-L0fDp0gv.mjs').then((m) => m.MessagesPage) },
10
- { path: 'to/:userId', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-start.page-gJ1cJDfy.mjs').then((m) => m.StartPage) },
11
- { path: ':id', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-messages.page-L0fDp0gv.mjs').then((m) => m.MessagesPage) },
8
+ { path: '', pathMatch: 'full', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-messages.page-Dy0RhQwj.mjs').then((m) => m.MessagesPage) },
9
+ { path: 'requests', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-messages.page-Dy0RhQwj.mjs').then((m) => m.MessagesPage) },
10
+ { path: 'to/:userId', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-start.page-D97JIFrb.mjs').then((m) => m.StartPage) },
11
+ { path: ':id', loadComponent: () => import('./chisquare-tech-yan-ngx-apps-messages-messages.page-Dy0RhQwj.mjs').then((m) => m.MessagesPage) },
12
12
  ];
13
13
 
14
14
  // The `dm` channel of Yan's one WebSocket (/ws, cloud/server/realtime): auth with an access token in the first frame
@@ -1354,4 +1354,4 @@ function randomHex(n) {
1354
1354
  */
1355
1355
 
1356
1356
  export { E2EE_LABEL as E, MessagesStore as M, OLM as O, MESSAGES_HOST as a, personName as b, conversationName as c, errorText as d, expiresIn as e, errorCode as f, E2eeMachine as g, MEGOLM as h, MESSAGES_API_BASE as i, MESSAGES_E2EE_WASM as j, kindLabel as k, MESSAGES_ROUTES as l, MESSAGES_SOCIAL_BASE as m, MessagingApi as n, others as o, pendingFor as p, forget as q, requestsLine as r, seen as s };
1357
- //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BtQC73sF.mjs.map
1357
+ //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BYCxC81Q.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BtQC73sF.mjs","sources":["../../../projects/messages/src/lib/routes.ts","../../../projects/messages/src/lib/dm-socket.ts","../../../projects/messages/src/lib/e2ee.ts","../../../projects/messages/src/lib/idb-store.ts","../../../projects/messages/src/lib/labels.ts","../../../projects/messages/src/lib/tokens.ts","../../../projects/messages/src/lib/messaging-api.ts","../../../projects/messages/src/lib/messages.store.ts","../../../projects/messages/src/chisquare-tech-yan-ngx-apps-messages.ts"],"sourcesContent":["import { Routes } from '@angular/router';\n\n/** Mounted at `messages`. `to/:userId` opens (or starts) the direct conversation with someone, then replaces itself. */\nexport const MESSAGES_ROUTES: Routes = [\n { path: '', pathMatch: 'full', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n { path: 'requests', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n { path: 'to/:userId', loadComponent: () => import('./start.page').then((m) => m.StartPage) },\n { path: ':id', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n];\n","// The `dm` channel of Yan's one WebSocket (/ws, cloud/server/realtime): auth with an access token in the first frame\n// (never in the URL), subscribe, answer pings, and on a drop reconnect with backoff and resume from the last seq.\n// Frames carry ids, never content.\n\nexport interface DmEvent {\n t: 'message' | 'to-device' | 'receipt' | 'typing' | 'membership' | string;\n id?: string;\n d?: Record<string, unknown>;\n}\n\ninterface Frame {\n v?: number;\n ch?: string;\n t: string;\n id?: string;\n seq?: number;\n d?: Record<string, unknown>;\n}\n\nexport interface DmSocketOptions {\n url: () => string;\n token: () => Promise<string | null>;\n device: () => string;\n onEvent: (e: DmEvent) => void;\n /** after a reconnect that may have missed events (resync or a gap): reload what's on screen */\n onResync: () => void;\n}\n\nexport class DmSocket {\n private ws: WebSocket | null = null;\n private seq: number | undefined;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n private readonly o: DmSocketOptions;\n\n constructor(o: DmSocketOptions) {\n this.o = o;\n }\n\n start(): void {\n this.closed = false;\n void this.connect();\n }\n\n stop(): void {\n this.closed = true;\n if (this.timer) clearTimeout(this.timer);\n this.ws?.close();\n this.ws = null;\n }\n\n private async connect(): Promise<void> {\n if (this.closed) return;\n const token = await this.o.token().catch(() => null);\n if (!token || this.closed) return this.retry();\n let ws: WebSocket;\n try {\n ws = new WebSocket(this.o.url());\n } catch {\n return this.retry();\n }\n this.ws = ws;\n ws.onopen = () => ws.send(JSON.stringify({ v: 1, t: 'auth', token, device: this.o.device() }));\n ws.onmessage = (e) => {\n let f: Frame;\n try {\n f = JSON.parse(String(e.data)) as Frame;\n } catch {\n return;\n }\n if (f.t === 'ping') return ws.send(JSON.stringify({ v: 1, t: 'pong' }));\n if (f.t === 'ready') {\n const since = this.seq;\n return ws.send(JSON.stringify(since === undefined ? { v: 1, t: 'sub', ch: 'dm' } : { v: 1, t: 'sub', ch: 'dm', since }));\n }\n if (f.ch !== 'dm') return;\n if (f.t === 'subscribed') {\n this.attempt = 0;\n const cur = f.seq ?? 0;\n if (this.seq === undefined) this.seq = cur; // first time: from now on\n else if (cur < this.seq) {\n // the server restarted and its numbering with it: what we missed can't be replayed\n this.seq = cur;\n this.o.onResync();\n }\n // otherwise the frames after our seq are replayed next\n return;\n }\n if (f.t === 'resync') {\n this.seq = f.seq;\n return this.o.onResync();\n }\n if (f.t === 'error') return;\n if (typeof f.seq === 'number') {\n if (this.seq !== undefined && f.seq > this.seq + 1) this.o.onResync();\n this.seq = Math.max(this.seq ?? 0, f.seq);\n }\n this.o.onEvent({ t: f.t, id: f.id, d: f.d });\n };\n ws.onclose = () => {\n if (this.ws === ws) this.ws = null;\n this.retry();\n };\n }\n\n private retry(): void {\n if (this.closed || this.timer) return;\n const delay = Math.min(30_000, 1000 * 2 ** this.attempt) * (0.5 + Math.random() / 2);\n this.attempt = Math.min(this.attempt + 1, 6);\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.connect();\n }, delay);\n }\n}\n","// End-to-end encryption for Yan's DMs (PLAN P1.7, TRD §5.8; owner decision 2026-11-06: Olm/Megolm via vodozemac,\n// @chisquare-tech/yan-e2ee). Framework-free, so the same code runs in the browser and in node tests: the wasm module,\n// storage, the server API and the lock are all passed in.\n//\n// The model is Matrix's:\n// - Each device has an Olm account. It publishes signed identity keys, signed one-time keys and a fallback key.\n// - Each device sending to a conversation has a Megolm group session per epoch (the server bumps the epoch on every\n// membership change), rotated after ROTATE_AFTER messages. Its key goes to every member device over Olm, through\n// that device's to-device inbox, before the first message that device should read.\n// - Messages are Megolm ciphertext. The server stores and relays what it can't read.\n//\n// Envelopes (version 1). The Android and iOS clients must produce exactly these:\n// - to-device body: JSON {\"v\":1,\"type\":0|1,\"body\":\"<olm ciphertext>\"} (type 0 is a pre-key message)\n// - its plaintext: {\"t\":\"yan.room_key\",\"conversationId\",\"epoch\",\"sessionId\",\"sessionKey\",\n// \"sender\":{\"userId\",\"deviceId\",\"ed25519\"},\"recipient\":{\"userId\",\"deviceId\",\"ed25519\"}}\n// - a message's Megolm plaintext: {\"v\":1,\"conversationId\",\"kind\",\"text\"}\n// A room key is accepted only when it names this device as the recipient and its sender matches the device that\n// sent it (its keys as the server published them, signed by itself). A message is shown only when its session's\n// conversation and sender match the message's own.\n\nimport type * as YanE2ee from '@chisquare-tech/yan-e2ee';\n\nexport type Wasm = Pick<typeof YanE2ee, 'Account' | 'Session' | 'GroupSession' | 'InboundGroupSession' | 'verify_ed25519'>;\ntype Account = YanE2ee.Account;\ntype OlmSession = YanE2ee.Session;\n\nexport const OLM = 'm.olm.v1.curve25519-aes-sha2';\nexport const MEGOLM = 'm.megolm.v1.aes-sha2';\n/** One-time keys a device keeps on the server; topped up when it falls below half. */\nexport const KEY_TARGET = 50;\n/** Messages per group session before a new one (Matrix's default is 100 too). */\nexport const ROTATE_AFTER = 100;\n\n// ---- what the server says (yan-gox-apps/libs/messaging) ----\n\nexport interface DeviceKeys {\n userId: string;\n deviceId: string;\n curve25519: string;\n ed25519: string;\n signature: string;\n name?: string;\n}\n\nexport interface SignedKey {\n keyId: string;\n key: string;\n signature: string;\n}\n\nexport interface ClaimedKey extends SignedKey {\n userId: string;\n deviceId: string;\n fallback?: boolean;\n}\n\nexport interface ToDeviceOut {\n userId: string;\n deviceId: string;\n type: string;\n body: string;\n}\n\nexport interface ToDeviceIn {\n id: number;\n senderUserId: string;\n senderDeviceId: string;\n type: string;\n body: string;\n}\n\nexport interface KeyCount {\n oneTimeKeys: number;\n fallback: boolean;\n}\n\n/** The messaging API calls the machine needs. */\nexport interface E2eeTransport {\n /** Resolves false when the server refuses the device id (revoked, or other keys): the machine starts a new one. */\n registerDevice(deviceId: string, body: { curve25519: string; ed25519: string; signature: string; name: string }): Promise<boolean>;\n uploadKeys(deviceId: string, body: { oneTimeKeys: SignedKey[]; fallbackKey?: SignedKey }): Promise<KeyCount>;\n /** null when the server doesn't know the device (revoked: signed out from another device) */\n keyCount(deviceId: string): Promise<KeyCount | null>;\n devices(userId: string): Promise<DeviceKeys[]>;\n claim(devices: { userId: string; deviceId: string }[]): Promise<ClaimedKey[]>;\n sendToDevice(senderDevice: string, messages: ToDeviceOut[]): Promise<number>;\n inbox(deviceId: string, after: number): Promise<ToDeviceIn[]>;\n ackInbox(deviceId: string, upTo: number): Promise<void>;\n}\n\n/** String storage for one person on one device (IndexedDB in the browser). Pickles are already encrypted. */\nexport interface E2eeStore {\n get(key: string): Promise<string | undefined>;\n set(key: string, value: string): Promise<void>;\n del(key: string): Promise<void>;\n}\n\n/** Runs fn exclusively across everything sharing the store (navigator.locks across tabs in the browser). */\nexport type Lock = <T>(fn: () => Promise<T>) => Promise<T>;\n\n/** A lock for one process. */\nexport function localLock(): Lock {\n let tail: Promise<unknown> = Promise.resolve();\n return <T>(fn: () => Promise<T>) => {\n const run = tail.then(fn, fn);\n tail = run.catch(() => undefined);\n return run;\n };\n}\n\n// ---- what a conversation and a message look like to the machine ----\n\nexport interface ConversationKeys {\n id: string;\n epoch: number;\n /** Everyone who should read: active members and those with it in Requests. Left and declined ones get no keys. */\n members: { userId: string; state: string }[];\n}\n\nexport interface Encrypted {\n senderDevice: string;\n algorithm: string;\n sessionId: string;\n ciphertext: string;\n}\n\nexport interface SealedMessage {\n id: string;\n conversationId: string;\n senderId: string;\n senderDeviceId: string;\n algorithm: string;\n sessionId: string;\n ciphertext: string;\n}\n\nexport interface Plain {\n kind: string;\n text: string;\n}\n\nexport type Opened = ({ ok: true } & Plain) | { ok: false; reason: 'missing-key' | 'invalid' };\n\n// ---- pure rules (also used by tests) ----\n\nexport const deviceSigningText = (userId: string, deviceId: string, curve: string, ed: string) =>\n `yan.device.v1|${userId}|${deviceId}|${curve}|${ed}`;\n\nexport const keySigningText = (userId: string, deviceId: string, keyId: string, key: string, fallback: boolean) =>\n `yan.${fallback ? 'fallback' : 'otk'}.v1|${userId}|${deviceId}|${keyId}|${key}`;\n\ninterface Party {\n userId: string;\n deviceId: string;\n ed25519: string;\n}\n\nexport interface RoomKey {\n t: 'yan.room_key';\n conversationId: string;\n epoch: number;\n sessionId: string;\n sessionKey: string;\n sender: Party;\n recipient: Party;\n}\n\n/** A room key that arrived from `from` is for `me` and really from that device. */\nexport function roomKeyProblem(k: unknown, me: Party, from: Party): string | null {\n const r = k as RoomKey;\n if (!r || r.t !== 'yan.room_key') return 'not a room key';\n if (typeof r.conversationId !== 'string' || typeof r.sessionId !== 'string' || typeof r.sessionKey !== 'string') return 'malformed';\n if (!same(r.recipient, me)) return 'meant for another device';\n if (!same(r.sender, from)) return 'sender mismatch';\n return null;\n}\n\nconst same = (a: Party | undefined, b: Party) => !!a && a.userId === b.userId && a.deviceId === b.deviceId && a.ed25519 === b.ed25519;\n\n/** Keys to generate so the server holds about KEY_TARGET: none until it falls below half. */\nexport function keysToGenerate(onServer: number, target = KEY_TARGET): number {\n return onServer >= target / 2 ? 0 : target - onServer;\n}\n\n// ---- storage records ----\n\ninterface DeviceRecord {\n deviceId: string;\n account: string; // pickle\n registered: boolean;\n}\n\ninterface OutboundRecord {\n epoch: number;\n sessionId: string;\n pickle: string;\n sent: number;\n /** user|device|curve25519 of every device that has its key */\n shared: string[];\n}\n\ninterface InboundRecord {\n pickle: string;\n conversationId: string;\n senderUserId: string;\n senderDeviceId: string;\n firstIndex: number;\n}\n\ninterface OlmRecord {\n /** newest first */\n sessions: { id: string; pickle: string }[];\n}\n\nconst MAX_OLM_PER_PEER = 5;\n\nexport interface MachineOptions {\n wasm: Wasm;\n transport: E2eeTransport;\n store: E2eeStore;\n /** 32 bytes that never leave the device: every pickle is encrypted with it */\n pickleKey: Uint8Array;\n userId: string;\n deviceName: string;\n lock?: Lock;\n newDeviceId?: () => string;\n log?: (msg: string) => void;\n}\n\n/** One person's encryption on one device. */\nexport class E2eeMachine {\n private readonly w: Wasm;\n private readonly api: E2eeTransport;\n private readonly store: E2eeStore;\n private readonly key: Uint8Array;\n private readonly lock: Lock;\n private readonly log: (msg: string) => void;\n private readonly newId: () => string;\n readonly userId: string;\n private readonly deviceName: string;\n private dev!: DeviceRecord;\n private ed!: string;\n private curve!: string;\n /** devices as the server published them and we checked them, per user, for this page's life */\n private readonly deviceCache = new Map<string, Promise<DeviceKeys[]>>();\n /** sessionId → message index → message id: a reused index is a replay */\n private readonly seen = new Map<string, Map<number, string>>();\n\n private constructor(o: MachineOptions) {\n this.w = o.wasm;\n this.api = o.transport;\n this.store = o.store;\n this.key = o.pickleKey;\n this.lock = o.lock ?? localLock();\n this.log = o.log ?? (() => undefined);\n this.userId = o.userId;\n this.deviceName = o.deviceName;\n this.newId = o.newDeviceId ?? randomDeviceId;\n }\n\n /** Loads this device's account, or makes and publishes a new one; then makes sure the server has its keys. */\n static async open(o: MachineOptions): Promise<E2eeMachine> {\n const m = new E2eeMachine(o);\n await m.lock(() => m.boot());\n return m;\n }\n\n get deviceId(): string {\n return this.dev.deviceId;\n }\n\n get ed25519(): string {\n return this.ed;\n }\n\n private async boot(): Promise<void> {\n const raw = await this.store.get('device');\n this.dev = raw ? (JSON.parse(raw) as DeviceRecord) : this.fresh();\n for (let attempt = 0; ; attempt++) {\n const acct = this.account();\n this.ed = acct.ed25519;\n this.curve = acct.curve25519;\n if (!this.dev.registered) {\n const ok = await this.api.registerDevice(this.dev.deviceId, {\n curve25519: this.curve,\n ed25519: this.ed,\n signature: acct.sign(deviceSigningText(this.userId, this.dev.deviceId, this.curve, this.ed)),\n name: this.deviceName,\n });\n if (!ok) {\n acct.free();\n if (attempt > 0) throw new Error('the server refused this device');\n this.log('device refused; starting a new one');\n await this.wipe();\n this.dev = this.fresh();\n continue;\n }\n this.dev.registered = true;\n await this.saveDevice(acct);\n }\n acct.free();\n const count = await this.api.keyCount(this.dev.deviceId);\n if (!count) {\n if (attempt > 0) throw new Error('the server forgot this device');\n this.log('device unknown to the server; starting a new one');\n await this.wipe();\n this.dev = this.fresh();\n continue;\n }\n await this.topUp(count);\n break;\n }\n }\n\n private fresh(): DeviceRecord {\n const acct = new this.w.Account();\n const rec = { deviceId: this.newId(), account: acct.pickle(this.key), registered: false };\n acct.free();\n return rec;\n }\n\n private async wipe(): Promise<void> {\n await this.store.del('device');\n await this.store.del('inboxAfter');\n }\n\n private account(): Account {\n return this.w.Account.from_pickle(this.dev.account, this.key);\n }\n\n private async saveDevice(acct: Account): Promise<void> {\n this.dev.account = acct.pickle(this.key);\n await this.store.set('device', JSON.stringify(this.dev));\n }\n\n /** Publishes one-time keys when the server is running low, and a fallback key when it has none. */\n private async topUp(count?: KeyCount): Promise<void> {\n const c = count ?? (await this.api.keyCount(this.dev.deviceId));\n if (!c) return;\n const n = keysToGenerate(c.oneTimeKeys);\n if (!n && c.fallback) return;\n const acct = this.account();\n try {\n if (n) acct.generate_one_time_keys(Math.min(n, acct.max_one_time_keys()));\n if (!c.fallback) acct.generate_fallback_key();\n const sign = (fallback: boolean) => ([keyId, key]: [string, string]): SignedKey => ({\n keyId,\n key,\n signature: acct.sign(keySigningText(this.userId, this.dev.deviceId, keyId, key, fallback)),\n });\n const otks = Object.entries(acct.one_time_keys() as Record<string, string>).map(sign(false));\n const [fallbackKey] = Object.entries(acct.fallback_key() as Record<string, string>).map(sign(true));\n if (!otks.length && !fallbackKey) return;\n // saved before upload: if the upload is lost, the same keys go next time (the server ignores repeats)\n await this.saveDevice(acct);\n await this.api.uploadKeys(this.dev.deviceId, { oneTimeKeys: otks, fallbackKey });\n acct.mark_keys_as_published();\n await this.saveDevice(acct);\n } finally {\n acct.free();\n }\n }\n\n // ---- devices ----\n\n /** A user's devices whose keys are signed by themselves and match what this device saw before (trust on first use). */\n private devicesOf(userId: string): Promise<DeviceKeys[]> {\n let p = this.deviceCache.get(userId);\n if (!p) {\n p = this.loadDevices(userId);\n this.deviceCache.set(userId, p);\n p.catch(() => this.deviceCache.delete(userId));\n }\n return p;\n }\n\n private async loadDevices(userId: string): Promise<DeviceKeys[]> {\n const out: DeviceKeys[] = [];\n for (const d of await this.api.devices(userId)) {\n if (d.userId !== userId) continue;\n if (!this.w.verify_ed25519(d.ed25519, deviceSigningText(userId, d.deviceId, d.curve25519, d.ed25519), d.signature)) {\n this.log(`device ${userId}/${d.deviceId}: bad signature`);\n continue;\n }\n const pinKey = `pin:${userId}|${d.deviceId}`;\n const pinned = await this.store.get(pinKey);\n const now = `${d.curve25519}|${d.ed25519}`;\n if (pinned && pinned !== now) {\n this.log(`device ${userId}/${d.deviceId}: keys changed`);\n continue;\n }\n if (!pinned) await this.store.set(pinKey, now);\n out.push(d);\n }\n return out;\n }\n\n /** Forget cached device lists (someone signed in on a new device, or a membership changed). */\n forgetDevices(userId?: string): void {\n if (userId) this.deviceCache.delete(userId);\n else this.deviceCache.clear();\n }\n\n // ---- Olm sessions ----\n\n private async olmSessions(curve: string): Promise<OlmRecord> {\n const raw = await this.store.get(`olm:${curve}`);\n return raw ? (JSON.parse(raw) as OlmRecord) : { sessions: [] };\n }\n\n private async saveOlm(curve: string, s: OlmSession, rec?: OlmRecord): Promise<void> {\n const r = rec ?? (await this.olmSessions(curve));\n const id = s.session_id;\n const rest = r.sessions.filter((x) => x.id !== id);\n r.sessions = [{ id, pickle: s.pickle(this.key) }, ...rest].slice(0, MAX_OLM_PER_PEER);\n await this.store.set(`olm:${curve}`, JSON.stringify(r));\n }\n\n /** Olm sessions to each device, opening new ones from claimed one-time keys where there are none yet. */\n private async olmTo(devices: DeviceKeys[]): Promise<Map<string, OlmSession>> {\n const out = new Map<string, OlmSession>();\n const need: DeviceKeys[] = [];\n for (const d of devices) {\n const rec = await this.olmSessions(d.curve25519);\n if (rec.sessions.length) out.set(d.curve25519, this.w.Session.from_pickle(rec.sessions[0].pickle, this.key));\n else need.push(d);\n }\n if (!need.length) return out;\n const claimed = await this.api.claim(need.map((d) => ({ userId: d.userId, deviceId: d.deviceId })));\n const acct = this.account();\n try {\n for (const k of claimed) {\n const d = need.find((x) => x.userId === k.userId && x.deviceId === k.deviceId);\n if (!d) continue;\n if (!this.w.verify_ed25519(d.ed25519, keySigningText(d.userId, d.deviceId, k.keyId, k.key, !!k.fallback), k.signature)) {\n this.log(`claimed key for ${d.userId}/${d.deviceId}: bad signature`);\n continue;\n }\n const s = acct.create_outbound_session(d.curve25519, k.key);\n await this.saveOlm(d.curve25519, s);\n out.set(d.curve25519, s);\n }\n } finally {\n acct.free();\n }\n return out;\n }\n\n // ---- sending ----\n\n /** Encrypts a message for a conversation, first sending the group session's key to every device that lacks it. */\n encrypt(conv: ConversationKeys, plain: Plain): Promise<Encrypted> {\n return this.lock(async () => {\n const outKey = `out:${conv.id}`;\n const raw = await this.store.get(outKey);\n let rec = raw ? (JSON.parse(raw) as OutboundRecord) : null;\n if (!rec || rec.epoch !== conv.epoch || rec.sent >= ROTATE_AFTER) rec = await this.newOutbound(conv);\n const group = this.w.GroupSession.from_pickle(rec.pickle, this.key);\n try {\n await this.share(conv, group, rec);\n const ciphertext = group.encrypt(JSON.stringify({ v: 1, conversationId: conv.id, kind: plain.kind, text: plain.text }));\n rec.sent++;\n rec.pickle = group.pickle(this.key);\n await this.store.set(outKey, JSON.stringify(rec));\n return { senderDevice: this.dev.deviceId, algorithm: MEGOLM, sessionId: rec.sessionId, ciphertext };\n } finally {\n group.free();\n }\n });\n }\n\n private async newOutbound(conv: ConversationKeys): Promise<OutboundRecord> {\n const g = new this.w.GroupSession();\n // our own copy, so this device reads what it sent\n const ib = new this.w.InboundGroupSession(g.session_key);\n const mine: InboundRecord = { pickle: ib.pickle(this.key), conversationId: conv.id, senderUserId: this.userId, senderDeviceId: this.dev.deviceId, firstIndex: ib.first_known_index };\n await this.store.set(`in:${g.session_id}`, JSON.stringify(mine));\n const rec = { epoch: conv.epoch, sessionId: g.session_id, pickle: g.pickle(this.key), sent: 0, shared: [] };\n ib.free();\n g.free();\n return rec;\n }\n\n private async share(conv: ConversationKeys, group: YanE2ee.GroupSession, rec: OutboundRecord): Promise<void> {\n const readers = [...new Set(conv.members.filter((m) => m.state === 'active' || m.state === 'request').map((m) => m.userId))];\n if (!readers.includes(this.userId)) readers.push(this.userId); // our other devices\n const targets: DeviceKeys[] = [];\n for (const u of readers) {\n for (const d of await this.devicesOf(u)) {\n if (u === this.userId && d.deviceId === this.dev.deviceId) continue;\n if (!rec.shared.includes(`${u}|${d.deviceId}|${d.curve25519}`)) targets.push(d);\n }\n }\n if (!targets.length) return;\n const sessions = await this.olmTo(targets);\n const sessionKey = group.session_key; // from the current index: a new reader can't open what came before\n const messages: ToDeviceOut[] = [];\n const done: string[] = [];\n for (const d of targets) {\n const s = sessions.get(d.curve25519);\n if (!s) continue; // no keys to claim: that device reads nothing until it publishes some\n const k: RoomKey = {\n t: 'yan.room_key',\n conversationId: conv.id,\n epoch: conv.epoch,\n sessionId: rec.sessionId,\n sessionKey,\n sender: { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed },\n recipient: { userId: d.userId, deviceId: d.deviceId, ed25519: d.ed25519 },\n };\n const sealed = s.encrypt(JSON.stringify(k));\n await this.saveOlm(d.curve25519, s);\n s.free();\n messages.push({ userId: d.userId, deviceId: d.deviceId, type: OLM, body: JSON.stringify({ v: 1, type: sealed.message_type, body: sealed.body }) });\n done.push(`${d.userId}|${d.deviceId}|${d.curve25519}`);\n }\n for (let i = 0; i < messages.length; i += 200) await this.api.sendToDevice(this.dev.deviceId, messages.slice(i, i + 200));\n rec.shared.push(...done);\n }\n\n // ---- receiving ----\n\n /** Reads this device's to-device inbox: room keys from other devices. Answers how many new keys arrived. */\n sync(): Promise<number> {\n return this.lock(() => this.syncLocked());\n }\n\n private async syncLocked(): Promise<number> {\n let after = Number((await this.store.get('inboxAfter')) ?? 0);\n let added = 0;\n let usedOneTimeKey = false;\n for (;;) {\n const items = await this.api.inbox(this.dev.deviceId, after);\n if (!items.length) break;\n for (const it of items) {\n try {\n const r = await this.receive(it);\n added += r.added;\n usedOneTimeKey ||= r.newSession;\n } catch (e) {\n this.log(`to-device ${it.id} from ${it.senderUserId}/${it.senderDeviceId}: ${(e as Error).message}`);\n }\n after = Math.max(after, it.id);\n }\n await this.store.set('inboxAfter', String(after));\n await this.api.ackInbox(this.dev.deviceId, after);\n }\n if (usedOneTimeKey) await this.topUp();\n return added;\n }\n\n private async receive(it: ToDeviceIn): Promise<{ added: number; newSession: boolean }> {\n if (it.type !== OLM) return { added: 0, newSession: false };\n const env = JSON.parse(it.body) as { v: number; type: number; body: string };\n if (env.v !== 1) throw new Error('unknown envelope');\n const find = async () => (await this.devicesOf(it.senderUserId)).find((d) => d.deviceId === it.senderDeviceId);\n let from = await find();\n if (!from) {\n // a device that signed in after we last looked\n this.forgetDevices(it.senderUserId);\n from = await find();\n }\n if (!from) throw new Error('unknown sender device');\n\n let plaintext: string | null = null;\n let newSession = false;\n const rec = await this.olmSessions(from.curve25519);\n for (const s of rec.sessions) {\n const sess = this.w.Session.from_pickle(s.pickle, this.key);\n try {\n plaintext = sess.decrypt(env.type, env.body);\n await this.saveOlm(from.curve25519, sess, rec);\n break;\n } catch {\n // not this session\n } finally {\n sess.free();\n }\n }\n if (plaintext === null) {\n if (env.type !== 0) throw new Error('no session for this message');\n const acct = this.account();\n try {\n const inbound = acct.create_inbound_session(from.curve25519, env.type, env.body);\n plaintext = inbound.plaintext;\n const sess = inbound.take_session();\n await this.saveDevice(acct); // its one-time key is spent\n await this.saveOlm(from.curve25519, sess, rec);\n sess.free();\n newSession = true;\n } finally {\n acct.free();\n }\n }\n\n const k = JSON.parse(plaintext) as RoomKey;\n const problem = roomKeyProblem(k, { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed }, { userId: from.userId, deviceId: from.deviceId, ed25519: from.ed25519 });\n if (problem) throw new Error(problem);\n const ib = new this.w.InboundGroupSession(k.sessionKey);\n try {\n if (ib.session_id !== k.sessionId) throw new Error('session id mismatch');\n const existing = await this.store.get(`in:${k.sessionId}`);\n if (existing) {\n const e = JSON.parse(existing) as InboundRecord;\n if (e.senderUserId !== from.userId || e.senderDeviceId !== from.deviceId || e.conversationId !== k.conversationId) throw new Error('session claimed by another sender');\n if (e.firstIndex <= ib.first_known_index) return { added: 0, newSession };\n }\n const r: InboundRecord = { pickle: ib.pickle(this.key), conversationId: k.conversationId, senderUserId: from.userId, senderDeviceId: from.deviceId, firstIndex: ib.first_known_index };\n await this.store.set(`in:${k.sessionId}`, JSON.stringify(r));\n return { added: 1, newSession };\n } finally {\n ib.free();\n }\n }\n\n /** Decrypts a message; when its key hasn't arrived, reads the inbox once and tries again. */\n decrypt(msg: SealedMessage): Promise<Opened> {\n return this.lock(async () => {\n let raw = await this.store.get(`in:${msg.sessionId}`);\n if (!raw) {\n await this.syncLocked();\n raw = await this.store.get(`in:${msg.sessionId}`);\n }\n if (!raw) return { ok: false, reason: 'missing-key' };\n const rec = JSON.parse(raw) as InboundRecord;\n if (msg.algorithm !== MEGOLM || rec.conversationId !== msg.conversationId || rec.senderUserId !== msg.senderId || rec.senderDeviceId !== msg.senderDeviceId) {\n return { ok: false, reason: 'invalid' };\n }\n const ib = this.w.InboundGroupSession.from_pickle(rec.pickle, this.key);\n try {\n const d = ib.decrypt(msg.ciphertext);\n const seen = this.seen.get(msg.sessionId) ?? new Map<number, string>();\n this.seen.set(msg.sessionId, seen);\n const prior = seen.get(d.message_index);\n if (prior && prior !== msg.id) return { ok: false, reason: 'invalid' };\n seen.set(d.message_index, msg.id);\n const p = JSON.parse(d.plaintext) as { v: number; conversationId: string; kind: string; text: string };\n if (p.v !== 1 || p.conversationId !== msg.conversationId || typeof p.text !== 'string') return { ok: false, reason: 'invalid' };\n return { ok: true, kind: p.kind || 'text', text: p.text };\n } catch {\n return { ok: false, reason: 'invalid' };\n } finally {\n ib.free();\n }\n });\n }\n}\n\n/** web_ + 16 random hex characters. */\nexport function randomDeviceId(): string {\n const b = new Uint8Array(8);\n crypto.getRandomValues(b);\n return 'web_' + [...b].map((x) => x.toString(16).padStart(2, '0')).join('');\n}\n","import type { E2eeStore, Lock } from './e2ee';\n\n// The browser side of the encryption's storage: one IndexedDB database, keys prefixed by the person's id (several\n// people can use one browser). Every pickle is already encrypted by vodozemac with a 32-byte pickle key; that key is\n// stored wrapped by a non-extractable AES-GCM key, so its bytes never sit in storage in the clear.\n\nconst DB = 'yan-e2ee';\nconst KV = 'kv';\nconst KEYS = 'keys';\n\nlet dbp: Promise<IDBDatabase> | null = null;\n\nfunction db(): Promise<IDBDatabase> {\n dbp ??= new Promise((resolve, reject) => {\n const r = indexedDB.open(DB, 1);\n r.onupgradeneeded = () => {\n r.result.createObjectStore(KV);\n r.result.createObjectStore(KEYS);\n };\n r.onsuccess = () => resolve(r.result);\n r.onerror = () => reject(r.error);\n });\n dbp.catch(() => (dbp = null));\n return dbp;\n}\n\nfunction req<T>(store: string, mode: IDBTransactionMode, fn: (s: IDBObjectStore) => IDBRequest): Promise<T> {\n return db().then(\n (d) =>\n new Promise<T>((resolve, reject) => {\n const tx = d.transaction(store, mode);\n const r = fn(tx.objectStore(store));\n tx.oncomplete = () => resolve(r.result as T);\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n }),\n );\n}\n\n/** One person's encryption storage. */\nexport function idbStore(userId: string): E2eeStore {\n const k = (key: string) => `${userId}/${key}`;\n return {\n get: (key) => req<string | undefined>(KV, 'readonly', (s) => s.get(k(key))),\n set: (key, value) => req<void>(KV, 'readwrite', (s) => s.put(value, k(key))),\n del: (key) => req<void>(KV, 'readwrite', (s) => s.delete(k(key))),\n };\n}\n\ninterface WrappedKey {\n wrapper: CryptoKey;\n iv: Uint8Array;\n sealed: ArrayBuffer;\n}\n\n/** This person's pickle key on this browser, made on first use. */\nexport async function pickleKey(userId: string): Promise<Uint8Array> {\n const have = await req<WrappedKey | undefined>(KEYS, 'readonly', (s) => s.get(userId));\n if (have) return new Uint8Array(await crypto.subtle.decrypt({ name: 'AES-GCM', iv: have.iv as BufferSource }, have.wrapper, have.sealed));\n const raw = crypto.getRandomValues(new Uint8Array(32));\n const wrapper = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const sealed = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, wrapper, raw);\n await req<void>(KEYS, 'readwrite', (s) => s.put({ wrapper, iv, sealed } satisfies WrappedKey, userId));\n return raw;\n}\n\n/** Everything this browser holds for a person (signing out of messaging here). */\nexport async function forget(userId: string): Promise<void> {\n const d = await db();\n await new Promise<void>((resolve, reject) => {\n const tx = d.transaction([KV, KEYS], 'readwrite');\n tx.objectStore(KV).delete(IDBKeyRange.bound(`${userId}/`, `${userId}/￿`));\n tx.objectStore(KEYS).delete(userId);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/** One operation at a time across every tab of this person (a ratchet must never fork); in-tab only without Web Locks. */\nexport function tabLock(userId: string, fallback: Lock): Lock {\n const locks = (navigator as Navigator & { locks?: LockManager }).locks;\n if (!locks) return fallback;\n return <T>(fn: () => Promise<T>) => locks.request(`yan-e2ee:${userId}`, fn) as Promise<T>;\n}\n","// Pure display rules for Messages (prototype Messages screen, PRD DM-1–8). No Angular, so node tests run them.\n\nexport interface PersonLike {\n userId: string;\n username: string;\n displayName: string;\n}\n\nexport interface MemberLike {\n userId: string;\n state: string;\n lastReadMessageId?: string;\n}\n\nexport interface ConversationLike {\n kind: 'direct' | 'group';\n title?: string;\n members: MemberLike[];\n myState: string;\n}\n\n/** How a person is shown: display name, else @username, else \"Someone\". */\nexport function personName(p: PersonLike | undefined): string {\n if (!p) return 'Someone';\n return p.displayName || (p.username ? '@' + p.username : 'Someone');\n}\n\n/** The other people in a conversation who are still in it. */\nexport function others(c: ConversationLike, me: string): MemberLike[] {\n return c.members.filter((m) => m.userId !== me && (m.state === 'active' || m.state === 'request'));\n}\n\n/** A direct conversation is named after the other person; a group by its title, else its members. */\nexport function conversationName(c: ConversationLike, me: string, people: Record<string, PersonLike>): string {\n if (c.kind === 'group' && c.title) return c.title;\n const names = others(c, me).map((m) => personName(people[m.userId]));\n if (!names.length) return c.kind === 'group' ? 'Group' : 'Just you';\n if (c.kind === 'direct') return names[0];\n return names.length <= 3 ? names.join(', ') : `${names.slice(0, 2).join(', ')} and ${names.length - 2} others`;\n}\n\n/** The prototype's kind eyebrow. */\nexport function kindLabel(c: ConversationLike): string {\n return c.kind === 'group' ? 'Group' : 'Direct';\n}\n\n/** Every DM and group is end-to-end encrypted (the email and community rows, which aren't, come with P2). */\nexport const E2EE_LABEL = { cls: 'yan-security--e2ee', icon: 'shield-lock', text: 'End-to-end encrypted' } as const;\n\n/** The Requests row's second line. */\nexport function requestsLine(count: number, firstFrom: string | undefined): string {\n if (!count) return 'No requests';\n return `${count} waiting · ${firstFrom ?? 'Someone'}`;\n}\n\n/** Who will see your messages under Requests, until they accept (DM-3). */\nexport function pendingFor(c: ConversationLike, me: string, people: Record<string, PersonLike>): string | null {\n const waiting = c.members.filter((m) => m.userId !== me && m.state === 'request');\n if (!waiting.length) return null;\n if (c.kind === 'direct') return `${personName(people[waiting[0].userId])} isn't in your network yet. Your messages go to their Requests until they accept.`;\n return waiting.length === 1\n ? `${personName(people[waiting[0].userId])} hasn't accepted yet and sees this under Requests.`\n : `${waiting.length} people haven't accepted yet and see this under Requests.`;\n}\n\n/** Days left on a request (DM-3: 7), for \"Expires in 3 days\". */\nexport function expiresIn(until: string | undefined, now = Date.now()): string {\n if (!until) return '';\n const ms = new Date(until).getTime() - now;\n if (ms <= 0) return 'Expired';\n const h = Math.ceil(ms / 3_600_000);\n if (h < 24) return `Expires in ${h} hour${h === 1 ? '' : 's'}`;\n const d = Math.ceil(h / 24);\n return `Expires in ${d} day${d === 1 ? '' : 's'}`;\n}\n\n/**\n * \"Seen\" under your last message, when everyone else has read up to it or later. `order` is the thread's message\n * ids, oldest first.\n */\nexport function seen(c: ConversationLike, me: string, order: string[], lastMine: string | undefined): boolean {\n if (!lastMine) return false;\n const at = order.indexOf(lastMine);\n if (at < 0) return false;\n const rest = others(c, me).filter((m) => m.state === 'active');\n if (!rest.length) return false;\n return rest.every((m) => !!m.lastReadMessageId && order.indexOf(m.lastReadMessageId) >= at);\n}\n\n/** What a message that can't be shown says instead. */\nexport function unreadableText(reason: 'missing-key' | 'invalid'): string {\n return reason === 'missing-key' ? \"Can't be read on this device\" : \"Couldn't be verified, so it isn't shown\";\n}\n\n/** A preview line for the list: the text, else a word for the kind. */\nexport function previewText(kind: string, text: string): string {\n if (text) return text;\n const words: Record<string, string> = { image: 'Photo', video: 'Video', file: 'File', voice: 'Voice message', link: 'Link', reaction: 'Reaction' };\n return words[kind] ?? 'Message';\n}\n","import { InjectionToken } from '@angular/core';\n\n/** What the host app gives Messages: who is signed in, a fresh access token for the WebSocket, and where things are. */\nexport interface MessagesHost {\n /** current user id, or null for a guest */\n userId(): string | null;\n /** a usable access token (renewed when it's about to run out), or null when signed out */\n accessToken(): Promise<string | null>;\n /** send a guest to sign in, coming back to `next` */\n requestSignIn(next: string): void;\n /** the WebSocket address, e.g. wss://yansocial.com/ws */\n wsUrl(): string;\n /** this device's name as other devices list it, e.g. \"Chrome on Mac\" */\n deviceName(): string;\n}\n\nexport const MESSAGES_HOST = new InjectionToken<MessagesHost>('MESSAGES_HOST', {\n providedIn: 'root',\n factory: () => ({\n userId: () => null,\n accessToken: async () => null,\n requestSignIn: () => undefined,\n wsUrl: () => location.origin.replace(/^http/, 'ws') + '/ws',\n deviceName: () => 'Web',\n }),\n});\n\n/** Host-provided: base URL of the messaging API. */\nexport const MESSAGES_API_BASE = new InjectionToken<string>('MESSAGES_API_BASE', {\n providedIn: 'root',\n factory: () => '/api/apps/messaging',\n});\n\n/** Host-provided: base URL of the social API (names for people known only by id). */\nexport const MESSAGES_SOCIAL_BASE = new InjectionToken<string>('MESSAGES_SOCIAL_BASE', {\n providedIn: 'root',\n factory: () => '/api/apps/social',\n});\n\n/** Host-provided: where the encryption module (yan_e2ee_bg.wasm from @chisquare-tech/yan-e2ee) is served. */\nexport const MESSAGES_E2EE_WASM = new InjectionToken<string>('MESSAGES_E2EE_WASM', {\n providedIn: 'root',\n factory: () => '/e2ee/yan_e2ee_bg.wasm',\n});\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport type { ClaimedKey, DeviceKeys, E2eeTransport, KeyCount, SealedMessage, SignedKey, ToDeviceIn, ToDeviceOut } from './e2ee';\nimport { MESSAGES_API_BASE, MESSAGES_SOCIAL_BASE } from './tokens';\n\ninterface Envelope<T> {\n data: T;\n}\n\nexport interface Member {\n userId: string;\n role: 'owner' | 'admin' | 'member';\n state: 'active' | 'request' | 'declined' | 'left';\n lastReadMessageId?: string;\n lastReadAt?: string;\n}\n\nexport interface Conversation {\n id: string;\n kind: 'direct' | 'group';\n title?: string;\n epoch: number;\n members: Member[];\n myState: 'active' | 'request';\n myRole: string;\n unread: number;\n lastMessageId?: string;\n lastMessageAt?: string;\n requestUntil?: string;\n createdAt: string;\n}\n\nexport interface Message extends SealedMessage {\n clientMsgId: string;\n epoch: number;\n kind: string;\n replyToId?: string;\n createdAt: string;\n}\n\nexport interface Page<T> {\n items: T[];\n next?: string;\n}\n\nexport interface Person {\n userId: string;\n username: string;\n displayName: string;\n}\n\nexport interface SendBody {\n clientMsgId: string;\n senderDevice: string;\n algorithm: string;\n sessionId: string;\n kind: string;\n ciphertext: string;\n}\n\n/** yan-gox-apps/libs/messaging over HTTP: the conversation API, and the device-key API the encryption needs. */\n@Injectable({ providedIn: 'root' })\nexport class MessagingApi implements E2eeTransport {\n private readonly http = inject(HttpClient);\n private readonly base = inject(MESSAGES_API_BASE);\n private readonly social = inject(MESSAGES_SOCIAL_BASE);\n\n private async get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n const p: Record<string, string> = {};\n for (const [k, v] of Object.entries(params ?? {})) if (v !== undefined && v !== '') p[k] = String(v);\n return (await firstValueFrom(this.http.get<Envelope<T>>(this.base + path, { params: p }))).data;\n }\n\n private async send<T>(method: 'POST' | 'PUT' | 'DELETE', path: string, body?: unknown): Promise<T> {\n return (await firstValueFrom(this.http.request<Envelope<T>>(method, this.base + path, { body }))).data;\n }\n\n // ---- conversations ----\n\n conversations(box: 'inbox' | 'requests' = 'inbox'): Promise<Conversation[]> {\n return this.get('/conversations', { box: box === 'inbox' ? undefined : box });\n }\n\n conversation(id: string): Promise<Conversation> {\n return this.get(`/conversations/${encodeURIComponent(id)}`);\n }\n\n startDirect(userId: string): Promise<Conversation> {\n return this.send('POST', '/conversations', { kind: 'direct', userId });\n }\n\n accept(id: string): Promise<Conversation> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/accept`, {});\n }\n\n decline(id: string): Promise<unknown> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/decline`, {});\n }\n\n messages(id: string, before?: string, limit = 50): Promise<Page<Message>> {\n return this.get(`/conversations/${encodeURIComponent(id)}/messages`, { before, limit });\n }\n\n sendMessage(id: string, body: SendBody): Promise<Message> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/messages`, body);\n }\n\n markRead(id: string, messageId: string): Promise<unknown> {\n return this.send('PUT', `/conversations/${encodeURIComponent(id)}/read`, { messageId });\n }\n\n typing(id: string): Promise<unknown> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/typing`, {});\n }\n\n /** Names for people known only by id; an empty list asks nothing. */\n async people(ids: string[]): Promise<Person[]> {\n const unique = [...new Set(ids)].slice(0, 100);\n if (!unique.length) return [];\n return (await firstValueFrom(this.http.get<Envelope<Person[]>>(`${this.social}/people`, { params: { ids: unique.join(',') } }))).data;\n }\n\n // ---- E2eeTransport ----\n\n async registerDevice(deviceId: string, body: { curve25519: string; ed25519: string; signature: string; name: string }): Promise<boolean> {\n try {\n await this.send('PUT', `/devices/${encodeURIComponent(deviceId)}`, body);\n return true;\n } catch (e) {\n if (e instanceof HttpErrorResponse && e.status === 409) return false;\n throw e;\n }\n }\n\n uploadKeys(deviceId: string, body: { oneTimeKeys: SignedKey[]; fallbackKey?: SignedKey }): Promise<KeyCount> {\n return this.send('POST', `/devices/${encodeURIComponent(deviceId)}/keys`, body);\n }\n\n async keyCount(deviceId: string): Promise<KeyCount | null> {\n try {\n return await this.get<KeyCount>(`/devices/${encodeURIComponent(deviceId)}/keys/count`);\n } catch (e) {\n if (e instanceof HttpErrorResponse && e.status === 404) return null;\n throw e;\n }\n }\n\n devices(userId: string): Promise<DeviceKeys[]> {\n return this.get(`/users/${encodeURIComponent(userId)}/devices`);\n }\n\n claim(devices: { userId: string; deviceId: string }[]): Promise<ClaimedKey[]> {\n return this.send('POST', '/keys/claim', { devices });\n }\n\n async sendToDevice(senderDevice: string, messages: ToDeviceOut[]): Promise<number> {\n return (await this.send<{ sent: number }>('POST', '/to-device', { senderDevice, messages })).sent;\n }\n\n inbox(deviceId: string, after: number): Promise<ToDeviceIn[]> {\n return this.get(`/devices/${encodeURIComponent(deviceId)}/inbox`, { after, limit: 100 });\n }\n\n async ackInbox(deviceId: string, upTo: number): Promise<void> {\n await this.send('POST', `/devices/${encodeURIComponent(deviceId)}/inbox/ack`, { upTo });\n }\n}\n\n/** A server error's message for people, or a fallback. */\nexport function errorText(e: unknown, fallback: string): string {\n const m = (e as { error?: { message?: string } })?.error?.message;\n return m && m.length < 200 ? m : fallback;\n}\n\n/** An error's code from the server (e.g. cant_message), if any. */\nexport function errorCode(e: unknown): string | undefined {\n return (e as { error?: { code?: string } })?.error?.code;\n}\n","import { Injectable, NgZone, WritableSignal, computed, inject, signal } from '@angular/core';\nimport { DmSocket, type DmEvent } from './dm-socket';\nimport { E2eeMachine, localLock, type ConversationKeys, type Opened } from './e2ee';\nimport { idbStore, pickleKey, tabLock } from './idb-store';\nimport { previewText, unreadableText } from './labels';\nimport { MessagingApi, errorCode, errorText, type Conversation, type Message, type Person, type SendBody } from './messaging-api';\nimport { MESSAGES_E2EE_WASM, MESSAGES_HOST } from './tokens';\n\nexport type BubbleState = 'ok' | 'pending' | 'failed' | 'unreadable';\n\nexport interface Bubble {\n /** the server's id; a pending message has its clientMsgId here until it's sent */\n id: string;\n clientMsgId?: string;\n senderId: string;\n mine: boolean;\n kind: string;\n text: string;\n state: BubbleState;\n /** why an unreadable message can't be shown */\n unreadable?: 'missing-key' | 'invalid';\n /** why a message failed to send, for the retry line */\n error?: string;\n createdAt: string;\n sealed?: Message;\n /** a send that failed after encryption keeps its ciphertext, so the retry is the same message */\n outgoing?: { kind: string; text: string; body?: SendBody };\n}\n\nexport interface Thread {\n conv: Conversation | null;\n items: Bubble[];\n next?: string;\n loading: boolean;\n failed: boolean;\n missing: boolean;\n}\n\nexport type CryptoState = 'idle' | 'starting' | 'ready' | 'failed';\n\nconst PREVIEW_LIMIT = 30;\n\n/**\n * Messages for the signed-in person: the lists, each open thread (decrypted on this device), sending, Requests, and\n * live updates over the dm WebSocket channel. The server only ever sees ciphertext.\n */\n@Injectable({ providedIn: 'root' })\nexport class MessagesStore {\n private readonly api = inject(MessagingApi);\n private readonly host = inject(MESSAGES_HOST);\n private readonly wasmUrl = inject(MESSAGES_E2EE_WASM);\n private readonly zone = inject(NgZone);\n\n readonly inbox = signal<Conversation[]>([]);\n readonly requests = signal<Conversation[]>([]);\n readonly loaded = signal(false);\n readonly failed = signal(false);\n readonly people = signal<Record<string, Person>>({});\n readonly previews = signal<Record<string, string>>({});\n /** conversation id → who is typing there */\n readonly typing = signal<Record<string, string>>({});\n readonly crypto = signal<CryptoState>('idle');\n /** For the nav badge: unread conversations plus waiting requests. */\n readonly badge = computed(() => this.inbox().reduce((n, c) => n + (c.unread > 0 ? 1 : 0), 0) + this.requests().length);\n\n private readonly threads = new Map<string, WritableSignal<Thread>>();\n private machine: Promise<E2eeMachine> | null = null;\n private machineUser: string | null = null;\n private socket: DmSocket | null = null;\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly typingTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private lastTypingSent = new Map<string, number>();\n\n me(): string | null {\n return this.host.userId();\n }\n\n // ---- lifecycle ----\n\n /** Loads the lists (enough for the nav badge). */\n async loadLists(): Promise<void> {\n if (!this.me()) return;\n try {\n const [inbox, requests] = await Promise.all([this.api.conversations('inbox'), this.api.conversations('requests')]);\n this.inbox.set(inbox);\n this.requests.set(requests);\n this.failed.set(false);\n this.loaded.set(true);\n await this.loadPeople([...inbox, ...requests].flatMap((c) => c.members.map((m) => m.userId)));\n void this.loadPreviews([...requests, ...inbox]);\n } catch {\n this.failed.set(true);\n }\n }\n\n /** Everything Messages needs: the lists, this device's encryption, and live updates. */\n async start(): Promise<void> {\n const me = this.me();\n if (!me) return;\n if (this.machineUser && this.machineUser !== me) this.stop();\n void this.loadLists();\n void this.ensureMachine().then(\n () => this.openSocket(),\n () => undefined,\n );\n }\n\n /** Signing out, or another person signing in. */\n stop(): void {\n this.socket?.stop();\n this.socket = null;\n this.machine = null;\n this.machineUser = null;\n this.crypto.set('idle');\n this.threads.clear();\n this.inbox.set([]);\n this.requests.set([]);\n this.previews.set({});\n this.loaded.set(false);\n }\n\n /** This device's encryption: loads the wasm module, then opens (or makes and publishes) the device's keys. */\n ensureMachine(): Promise<E2eeMachine> {\n const me = this.me();\n if (!me) return Promise.reject(new Error('signed out'));\n if (this.machine && this.machineUser === me) return this.machine;\n this.machineUser = me;\n this.crypto.set('starting');\n this.machine = (async () => {\n const wasm = await import('@chisquare-tech/yan-e2ee');\n await wasm.default({ module_or_path: this.wasmUrl });\n return E2eeMachine.open({\n wasm,\n transport: this.api,\n store: idbStore(me),\n pickleKey: await pickleKey(me),\n userId: me,\n deviceName: this.host.deviceName(),\n lock: tabLock(me, localLock()),\n log: (m) => console.debug('[yan-e2ee]', m),\n });\n })();\n this.machine.then(\n () => this.crypto.set('ready'),\n (e) => {\n console.warn('[yan-e2ee] could not start', e);\n this.machine = null;\n this.crypto.set('failed');\n },\n );\n return this.machine;\n }\n\n retryCrypto(): void {\n void this.start();\n }\n\n private openSocket(): void {\n if (this.socket) return;\n const machine = this.machine;\n if (!machine) return;\n let device = '';\n void machine.then((m) => (device = m.deviceId));\n this.zone.runOutsideAngular(() => {\n this.socket = new DmSocket({\n url: () => this.host.wsUrl(),\n token: () => this.host.accessToken(),\n device: () => device,\n onEvent: (e) => this.zone.run(() => void this.onEvent(e)),\n onResync: () => this.zone.run(() => void this.resync()),\n });\n this.socket.start();\n });\n }\n\n // ---- people and previews ----\n\n private async loadPeople(ids: string[]): Promise<void> {\n const have = this.people();\n const missing = [...new Set(ids)].filter((id) => !have[id]);\n if (!missing.length) return;\n try {\n const got = await this.api.people(missing);\n this.people.update((p) => ({ ...p, ...Object.fromEntries(got.map((x) => [x.userId, x])) }));\n } catch {\n // names fall back to \"Someone\"\n }\n }\n\n private async loadPreviews(convs: Conversation[]): Promise<void> {\n let machine: E2eeMachine;\n try {\n machine = await this.ensureMachine();\n } catch {\n return;\n }\n const want = convs.filter((c) => c.lastMessageId && this.previews()[c.id + '|' + c.lastMessageId] === undefined).slice(0, PREVIEW_LIMIT);\n await Promise.all(\n want.map(async (c) => {\n try {\n const page = await this.api.messages(c.id, undefined, 1);\n const m = page.items[0];\n if (!m) return;\n const o = await machine.decrypt(m);\n const line = o.ok ? previewText(o.kind, o.text) : 'Encrypted message';\n const mine = m.senderId === this.me();\n this.previews.update((p) => ({ ...p, [c.id + '|' + c.lastMessageId]: (mine ? 'You: ' : '') + line }));\n } catch {\n // no preview\n }\n }),\n );\n }\n\n preview(c: Conversation): string {\n if (!c.lastMessageId) return 'No messages yet';\n return this.previews()[c.id + '|' + c.lastMessageId] ?? '';\n }\n\n // ---- threads ----\n\n thread(id: string): WritableSignal<Thread> {\n let t = this.threads.get(id);\n if (!t) {\n t = signal<Thread>({ conv: this.known(id), items: [], loading: true, failed: false, missing: false });\n this.threads.set(id, t);\n }\n return t;\n }\n\n private known(id: string): Conversation | null {\n return this.inbox().find((c) => c.id === id) ?? this.requests().find((c) => c.id === id) ?? null;\n }\n\n /** Loads a conversation and its newest messages, decrypted. */\n async openThread(id: string): Promise<void> {\n const t = this.thread(id);\n t.update((s) => ({ ...s, loading: true, failed: false }));\n try {\n const [conv, page] = await Promise.all([this.api.conversation(id), this.api.messages(id)]);\n void this.loadPeople(conv.members.map((m) => m.userId));\n const items = await this.open(page.items.slice().reverse());\n t.set({ conv, items: this.keepPending(t().items, items), next: page.next, loading: false, failed: false, missing: false });\n this.markRead(conv, items);\n } catch (e) {\n const status = (e as { status?: number }).status;\n t.update((s) => ({ ...s, loading: false, failed: status !== 404, missing: status === 404 }));\n }\n }\n\n async loadOlder(id: string): Promise<void> {\n const t = this.thread(id);\n const s = t();\n if (!s.next || s.loading) return;\n t.update((x) => ({ ...x, loading: true }));\n try {\n const page = await this.api.messages(id, s.next);\n const older = await this.open(page.items.slice().reverse());\n t.update((x) => ({ ...x, items: [...older, ...x.items], next: page.next, loading: false }));\n } catch {\n t.update((x) => ({ ...x, loading: false }));\n }\n }\n\n /** Pending sends survive a reload of the thread. */\n private keepPending(before: Bubble[], now: Bubble[]): Bubble[] {\n const sent = new Set(now.map((b) => b.sealed?.clientMsgId));\n return [...now, ...before.filter((b) => (b.state === 'pending' || b.state === 'failed') && !sent.has(b.clientMsgId))];\n }\n\n private async open(msgs: Message[]): Promise<Bubble[]> {\n let machine: E2eeMachine | null = null;\n try {\n machine = await this.ensureMachine();\n } catch {\n // shown as unreadable until encryption starts\n }\n const me = this.me();\n const out: Bubble[] = [];\n for (const m of msgs) {\n const o: Opened = machine ? await machine.decrypt(m) : { ok: false, reason: 'missing-key' };\n out.push({\n id: m.id,\n senderId: m.senderId,\n mine: m.senderId === me,\n kind: o.ok ? o.kind : m.kind,\n text: o.ok ? o.text : unreadableText(o.reason),\n state: o.ok ? 'ok' : 'unreadable',\n unreadable: o.ok ? undefined : o.reason,\n createdAt: m.createdAt,\n sealed: m,\n });\n }\n return out;\n }\n\n private markRead(conv: Conversation, items: Bubble[]): void {\n const last = [...items].reverse().find((b) => b.state !== 'pending' && b.state !== 'failed');\n if (!last || conv.myState !== 'active') return;\n const mine = conv.members.find((m) => m.userId === this.me());\n if (mine?.lastReadMessageId === last.id && !conv.unread) return;\n void this.api.markRead(conv.id, last.id).then(() => {\n this.inbox.update((l) => l.map((c) => (c.id === conv.id ? { ...c, unread: 0 } : c)));\n }, () => undefined);\n }\n\n // ---- sending ----\n\n async send(id: string, text: string): Promise<void> {\n const body = text.trim();\n if (!body) return;\n const t = this.thread(id);\n const conv = t().conv;\n if (!conv) return;\n const clientMsgId = 'c_' + randomHex(12);\n const bubble: Bubble = { id: clientMsgId, clientMsgId, senderId: this.me() ?? '', mine: true, kind: 'text', text: body, state: 'pending', createdAt: new Date().toISOString(), outgoing: { kind: 'text', text: body } };\n t.update((s) => ({ ...s, items: [...s.items, bubble] }));\n await this.deliver(id, bubble);\n }\n\n retry(id: string, b: Bubble): Promise<void> {\n this.thread(id).update((s) => ({ ...s, items: s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, state: 'pending' as const, error: undefined } : x)) }));\n return this.deliver(id, b);\n }\n\n private async deliver(id: string, b: Bubble): Promise<void> {\n const t = this.thread(id);\n const patch = (p: Partial<Bubble>) => t.update((s) => ({ ...s, items: s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, ...p } : x)) }));\n let body = b.outgoing?.body;\n try {\n if (!body) {\n // fresh members and epoch: someone added a moment ago must get this session's key\n const conv = await this.api.conversation(id);\n t.update((s) => ({ ...s, conv }));\n const machine = await this.ensureMachine();\n const enc = await machine.encrypt(keysOf(conv), { kind: b.outgoing?.kind ?? 'text', text: b.outgoing?.text ?? b.text });\n body = { clientMsgId: b.clientMsgId!, kind: b.outgoing?.kind ?? 'text', ...enc };\n patch({ outgoing: { ...b.outgoing!, body } });\n }\n const sent = await this.api.sendMessage(id, body);\n // the push for it may have arrived first\n t.update((s) => {\n const already = s.items.some((x) => x.id === sent.id && x.clientMsgId !== b.clientMsgId);\n const items = already\n ? s.items.filter((x) => x.clientMsgId !== b.clientMsgId)\n : s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, id: sent.id, state: 'ok' as const, sealed: sent, createdAt: sent.createdAt, outgoing: undefined } : x));\n return { ...s, items };\n });\n this.bump(id, sent.id, 'You: ' + previewText(body.kind, b.outgoing?.text ?? b.text));\n } catch (e) {\n const code = errorCode(e);\n patch({ state: 'failed', error: code === 'cant_message' ? \"You can't message this person.\" : this.crypto() === 'failed' ? \"Messages can't be encrypted in this browser.\" : errorText(e, 'Not sent.') });\n }\n }\n\n private bump(id: string, messageId: string, line: string): void {\n const now = new Date().toISOString();\n this.previews.update((p) => ({ ...p, [id + '|' + messageId]: line }));\n this.inbox.update((l) => {\n const c = l.find((x) => x.id === id);\n if (!c) return l;\n return [{ ...c, lastMessageId: messageId, lastMessageAt: now }, ...l.filter((x) => x.id !== id)];\n });\n }\n\n /** Starts (or finds) the direct conversation with someone. */\n async startDirect(userId: string): Promise<Conversation> {\n const c = await this.api.startDirect(userId);\n if (!this.inbox().some((x) => x.id === c.id)) this.inbox.update((l) => [c, ...l]);\n this.thread(c.id).update((s) => ({ ...s, conv: c }));\n void this.loadPeople(c.members.map((m) => m.userId));\n return c;\n }\n\n // ---- requests ----\n\n async accept(id: string): Promise<void> {\n const c = await this.api.accept(id);\n this.requests.update((l) => l.filter((x) => x.id !== id));\n this.inbox.update((l) => [c, ...l.filter((x) => x.id !== id)]);\n this.thread(id).update((s) => ({ ...s, conv: c }));\n }\n\n async decline(id: string): Promise<void> {\n await this.api.decline(id);\n this.requests.update((l) => l.filter((x) => x.id !== id));\n this.threads.delete(id);\n }\n\n // ---- typing ----\n\n typed(id: string): void {\n const now = Date.now();\n if (now - (this.lastTypingSent.get(id) ?? 0) < 4000) return;\n this.lastTypingSent.set(id, now);\n void this.api.typing(id).catch(() => undefined);\n }\n\n // ---- live ----\n\n private async onEvent(e: DmEvent): Promise<void> {\n const conv = typeof e.d?.['conversationId'] === 'string' ? (e.d['conversationId'] as string) : undefined;\n switch (e.t) {\n case 'message':\n if (conv) {\n // their message is here: they've stopped typing\n this.typing.update((t) => { const { [conv]: _, ...rest } = t; return rest; });\n await this.newer(conv);\n }\n this.refreshSoon();\n break;\n case 'to-device':\n await this.keysArrived();\n break;\n case 'membership':\n (await this.machine)?.forgetDevices();\n if (conv) await this.reloadConversation(conv);\n this.refreshSoon();\n break;\n case 'receipt':\n if (conv && e.d?.['userId'] !== this.me()) await this.reloadConversation(conv);\n break;\n case 'typing': {\n const who = e.d?.['userId'];\n if (!conv || typeof who !== 'string' || who === this.me()) break;\n this.typing.update((t) => ({ ...t, [conv]: who }));\n clearTimeout(this.typingTimers.get(conv));\n this.typingTimers.set(conv, setTimeout(() => this.typing.update((t) => { const { [conv]: _, ...rest } = t; return rest; }), 5000));\n break;\n }\n }\n }\n\n /** New messages in a loaded thread. */\n private async newer(id: string): Promise<void> {\n const t = this.threads.get(id);\n if (!t || t().loading && !t().items.length) return;\n try {\n const page = await this.api.messages(id, undefined, 20);\n const have = new Set(t().items.map((b) => b.id));\n const fresh = await this.open(page.items.filter((m) => !have.has(m.id)).reverse());\n if (!fresh.length) return;\n t.update((s) => {\n const byClient = new Map(fresh.filter((f) => f.mine).map((f) => [f.sealed?.clientMsgId, f]));\n const items = s.items.filter((b) => !(b.clientMsgId && byClient.has(b.clientMsgId)));\n const insertAt = items.findIndex((b) => b.state === 'pending' || b.state === 'failed');\n if (insertAt < 0) return { ...s, items: [...items, ...fresh] };\n return { ...s, items: [...items.slice(0, insertAt), ...fresh, ...items.slice(insertAt)] };\n });\n const c = t().conv;\n if (c) this.markRead(c, t().items);\n } catch {\n // the next event or a reload catches up\n }\n }\n\n /** Room keys arrived: messages that couldn't be read may open now. */\n private async keysArrived(): Promise<void> {\n const m = await this.machine?.catch(() => null);\n if (!m) return;\n await m.sync().catch(() => 0);\n for (const t of this.threads.values()) {\n if (!t().items.some((b) => b.state === 'unreadable')) continue;\n const items = await Promise.all(\n t().items.map(async (b) => {\n if (b.state !== 'unreadable' || !b.sealed) return b;\n const o = await m.decrypt(b.sealed);\n return o.ok ? { ...b, state: 'ok' as const, unreadable: undefined, kind: o.kind, text: o.text } : b;\n }),\n );\n t.update((s) => ({ ...s, items }));\n }\n void this.loadPreviews([...this.requests(), ...this.inbox()]);\n }\n\n private async reloadConversation(id: string): Promise<void> {\n const t = this.threads.get(id);\n if (!t) return;\n try {\n const conv = await this.api.conversation(id);\n t.update((s) => ({ ...s, conv }));\n } catch {\n // keep what we have\n }\n }\n\n private async resync(): Promise<void> {\n await this.loadLists();\n await this.keysArrived();\n for (const id of this.threads.keys()) await this.newer(id);\n }\n\n private refreshSoon(): void {\n if (this.refreshTimer) return;\n this.refreshTimer = setTimeout(() => {\n this.refreshTimer = null;\n void this.loadLists();\n }, 400);\n }\n}\n\n/** What the encryption needs to know about a conversation. */\nexport function keysOf(c: Conversation): ConversationKeys {\n return { id: c.id, epoch: c.epoch, members: c.members.map((m) => ({ userId: m.userId, state: m.state })) };\n}\n\nfunction randomHex(n: number): string {\n const b = new Uint8Array(Math.ceil(n / 2));\n crypto.getRandomValues(b);\n return [...b].map((x) => x.toString(16).padStart(2, '0')).join('').slice(0, n);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BYCxC81Q.mjs","sources":["../../../projects/messages/src/lib/routes.ts","../../../projects/messages/src/lib/dm-socket.ts","../../../projects/messages/src/lib/e2ee.ts","../../../projects/messages/src/lib/idb-store.ts","../../../projects/messages/src/lib/labels.ts","../../../projects/messages/src/lib/tokens.ts","../../../projects/messages/src/lib/messaging-api.ts","../../../projects/messages/src/lib/messages.store.ts","../../../projects/messages/src/chisquare-tech-yan-ngx-apps-messages.ts"],"sourcesContent":["import { Routes } from '@angular/router';\n\n/** Mounted at `messages`. `to/:userId` opens (or starts) the direct conversation with someone, then replaces itself. */\nexport const MESSAGES_ROUTES: Routes = [\n { path: '', pathMatch: 'full', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n { path: 'requests', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n { path: 'to/:userId', loadComponent: () => import('./start.page').then((m) => m.StartPage) },\n { path: ':id', loadComponent: () => import('./messages.page').then((m) => m.MessagesPage) },\n];\n","// The `dm` channel of Yan's one WebSocket (/ws, cloud/server/realtime): auth with an access token in the first frame\n// (never in the URL), subscribe, answer pings, and on a drop reconnect with backoff and resume from the last seq.\n// Frames carry ids, never content.\n\nexport interface DmEvent {\n t: 'message' | 'to-device' | 'receipt' | 'typing' | 'membership' | string;\n id?: string;\n d?: Record<string, unknown>;\n}\n\ninterface Frame {\n v?: number;\n ch?: string;\n t: string;\n id?: string;\n seq?: number;\n d?: Record<string, unknown>;\n}\n\nexport interface DmSocketOptions {\n url: () => string;\n token: () => Promise<string | null>;\n device: () => string;\n onEvent: (e: DmEvent) => void;\n /** after a reconnect that may have missed events (resync or a gap): reload what's on screen */\n onResync: () => void;\n}\n\nexport class DmSocket {\n private ws: WebSocket | null = null;\n private seq: number | undefined;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closed = false;\n private readonly o: DmSocketOptions;\n\n constructor(o: DmSocketOptions) {\n this.o = o;\n }\n\n start(): void {\n this.closed = false;\n void this.connect();\n }\n\n stop(): void {\n this.closed = true;\n if (this.timer) clearTimeout(this.timer);\n this.ws?.close();\n this.ws = null;\n }\n\n private async connect(): Promise<void> {\n if (this.closed) return;\n const token = await this.o.token().catch(() => null);\n if (!token || this.closed) return this.retry();\n let ws: WebSocket;\n try {\n ws = new WebSocket(this.o.url());\n } catch {\n return this.retry();\n }\n this.ws = ws;\n ws.onopen = () => ws.send(JSON.stringify({ v: 1, t: 'auth', token, device: this.o.device() }));\n ws.onmessage = (e) => {\n let f: Frame;\n try {\n f = JSON.parse(String(e.data)) as Frame;\n } catch {\n return;\n }\n if (f.t === 'ping') return ws.send(JSON.stringify({ v: 1, t: 'pong' }));\n if (f.t === 'ready') {\n const since = this.seq;\n return ws.send(JSON.stringify(since === undefined ? { v: 1, t: 'sub', ch: 'dm' } : { v: 1, t: 'sub', ch: 'dm', since }));\n }\n if (f.ch !== 'dm') return;\n if (f.t === 'subscribed') {\n this.attempt = 0;\n const cur = f.seq ?? 0;\n if (this.seq === undefined) this.seq = cur; // first time: from now on\n else if (cur < this.seq) {\n // the server restarted and its numbering with it: what we missed can't be replayed\n this.seq = cur;\n this.o.onResync();\n }\n // otherwise the frames after our seq are replayed next\n return;\n }\n if (f.t === 'resync') {\n this.seq = f.seq;\n return this.o.onResync();\n }\n if (f.t === 'error') return;\n if (typeof f.seq === 'number') {\n if (this.seq !== undefined && f.seq > this.seq + 1) this.o.onResync();\n this.seq = Math.max(this.seq ?? 0, f.seq);\n }\n this.o.onEvent({ t: f.t, id: f.id, d: f.d });\n };\n ws.onclose = () => {\n if (this.ws === ws) this.ws = null;\n this.retry();\n };\n }\n\n private retry(): void {\n if (this.closed || this.timer) return;\n const delay = Math.min(30_000, 1000 * 2 ** this.attempt) * (0.5 + Math.random() / 2);\n this.attempt = Math.min(this.attempt + 1, 6);\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.connect();\n }, delay);\n }\n}\n","// End-to-end encryption for Yan's DMs (PLAN P1.7, TRD §5.8; owner decision 2026-11-06: Olm/Megolm via vodozemac,\n// @chisquare-tech/yan-e2ee). Framework-free, so the same code runs in the browser and in node tests: the wasm module,\n// storage, the server API and the lock are all passed in.\n//\n// The model is Matrix's:\n// - Each device has an Olm account. It publishes signed identity keys, signed one-time keys and a fallback key.\n// - Each device sending to a conversation has a Megolm group session per epoch (the server bumps the epoch on every\n// membership change), rotated after ROTATE_AFTER messages. Its key goes to every member device over Olm, through\n// that device's to-device inbox, before the first message that device should read.\n// - Messages are Megolm ciphertext. The server stores and relays what it can't read.\n//\n// Envelopes (version 1). The Android and iOS clients must produce exactly these:\n// - to-device body: JSON {\"v\":1,\"type\":0|1,\"body\":\"<olm ciphertext>\"} (type 0 is a pre-key message)\n// - its plaintext: {\"t\":\"yan.room_key\",\"conversationId\",\"epoch\",\"sessionId\",\"sessionKey\",\n// \"sender\":{\"userId\",\"deviceId\",\"ed25519\"},\"recipient\":{\"userId\",\"deviceId\",\"ed25519\"}}\n// - a message's Megolm plaintext: {\"v\":1,\"conversationId\",\"kind\",\"text\"}\n// A room key is accepted only when it names this device as the recipient and its sender matches the device that\n// sent it (its keys as the server published them, signed by itself). A message is shown only when its session's\n// conversation and sender match the message's own.\n\nimport type * as YanE2ee from '@chisquare-tech/yan-e2ee';\n\nexport type Wasm = Pick<typeof YanE2ee, 'Account' | 'Session' | 'GroupSession' | 'InboundGroupSession' | 'verify_ed25519'>;\ntype Account = YanE2ee.Account;\ntype OlmSession = YanE2ee.Session;\n\nexport const OLM = 'm.olm.v1.curve25519-aes-sha2';\nexport const MEGOLM = 'm.megolm.v1.aes-sha2';\n/** One-time keys a device keeps on the server; topped up when it falls below half. */\nexport const KEY_TARGET = 50;\n/** Messages per group session before a new one (Matrix's default is 100 too). */\nexport const ROTATE_AFTER = 100;\n\n// ---- what the server says (yan-gox-apps/libs/messaging) ----\n\nexport interface DeviceKeys {\n userId: string;\n deviceId: string;\n curve25519: string;\n ed25519: string;\n signature: string;\n name?: string;\n}\n\nexport interface SignedKey {\n keyId: string;\n key: string;\n signature: string;\n}\n\nexport interface ClaimedKey extends SignedKey {\n userId: string;\n deviceId: string;\n fallback?: boolean;\n}\n\nexport interface ToDeviceOut {\n userId: string;\n deviceId: string;\n type: string;\n body: string;\n}\n\nexport interface ToDeviceIn {\n id: number;\n senderUserId: string;\n senderDeviceId: string;\n type: string;\n body: string;\n}\n\nexport interface KeyCount {\n oneTimeKeys: number;\n fallback: boolean;\n}\n\n/** The messaging API calls the machine needs. */\nexport interface E2eeTransport {\n /** Resolves false when the server refuses the device id (revoked, or other keys): the machine starts a new one. */\n registerDevice(deviceId: string, body: { curve25519: string; ed25519: string; signature: string; name: string }): Promise<boolean>;\n uploadKeys(deviceId: string, body: { oneTimeKeys: SignedKey[]; fallbackKey?: SignedKey }): Promise<KeyCount>;\n /** null when the server doesn't know the device (revoked: signed out from another device) */\n keyCount(deviceId: string): Promise<KeyCount | null>;\n devices(userId: string): Promise<DeviceKeys[]>;\n claim(devices: { userId: string; deviceId: string }[]): Promise<ClaimedKey[]>;\n sendToDevice(senderDevice: string, messages: ToDeviceOut[]): Promise<number>;\n inbox(deviceId: string, after: number): Promise<ToDeviceIn[]>;\n ackInbox(deviceId: string, upTo: number): Promise<void>;\n}\n\n/** String storage for one person on one device (IndexedDB in the browser). Pickles are already encrypted. */\nexport interface E2eeStore {\n get(key: string): Promise<string | undefined>;\n set(key: string, value: string): Promise<void>;\n del(key: string): Promise<void>;\n}\n\n/** Runs fn exclusively across everything sharing the store (navigator.locks across tabs in the browser). */\nexport type Lock = <T>(fn: () => Promise<T>) => Promise<T>;\n\n/** A lock for one process. */\nexport function localLock(): Lock {\n let tail: Promise<unknown> = Promise.resolve();\n return <T>(fn: () => Promise<T>) => {\n const run = tail.then(fn, fn);\n tail = run.catch(() => undefined);\n return run;\n };\n}\n\n// ---- what a conversation and a message look like to the machine ----\n\nexport interface ConversationKeys {\n id: string;\n epoch: number;\n /** Everyone who should read: active members and those with it in Requests. Left and declined ones get no keys. */\n members: { userId: string; state: string }[];\n}\n\nexport interface Encrypted {\n senderDevice: string;\n algorithm: string;\n sessionId: string;\n ciphertext: string;\n}\n\nexport interface SealedMessage {\n id: string;\n conversationId: string;\n senderId: string;\n senderDeviceId: string;\n algorithm: string;\n sessionId: string;\n ciphertext: string;\n}\n\nexport interface Plain {\n kind: string;\n text: string;\n}\n\nexport type Opened = ({ ok: true } & Plain) | { ok: false; reason: 'missing-key' | 'invalid' };\n\n// ---- pure rules (also used by tests) ----\n\nexport const deviceSigningText = (userId: string, deviceId: string, curve: string, ed: string) =>\n `yan.device.v1|${userId}|${deviceId}|${curve}|${ed}`;\n\nexport const keySigningText = (userId: string, deviceId: string, keyId: string, key: string, fallback: boolean) =>\n `yan.${fallback ? 'fallback' : 'otk'}.v1|${userId}|${deviceId}|${keyId}|${key}`;\n\ninterface Party {\n userId: string;\n deviceId: string;\n ed25519: string;\n}\n\nexport interface RoomKey {\n t: 'yan.room_key';\n conversationId: string;\n epoch: number;\n sessionId: string;\n sessionKey: string;\n sender: Party;\n recipient: Party;\n}\n\n/** A room key that arrived from `from` is for `me` and really from that device. */\nexport function roomKeyProblem(k: unknown, me: Party, from: Party): string | null {\n const r = k as RoomKey;\n if (!r || r.t !== 'yan.room_key') return 'not a room key';\n if (typeof r.conversationId !== 'string' || typeof r.sessionId !== 'string' || typeof r.sessionKey !== 'string') return 'malformed';\n if (!same(r.recipient, me)) return 'meant for another device';\n if (!same(r.sender, from)) return 'sender mismatch';\n return null;\n}\n\nconst same = (a: Party | undefined, b: Party) => !!a && a.userId === b.userId && a.deviceId === b.deviceId && a.ed25519 === b.ed25519;\n\n/** Keys to generate so the server holds about KEY_TARGET: none until it falls below half. */\nexport function keysToGenerate(onServer: number, target = KEY_TARGET): number {\n return onServer >= target / 2 ? 0 : target - onServer;\n}\n\n// ---- storage records ----\n\ninterface DeviceRecord {\n deviceId: string;\n account: string; // pickle\n registered: boolean;\n}\n\ninterface OutboundRecord {\n epoch: number;\n sessionId: string;\n pickle: string;\n sent: number;\n /** user|device|curve25519 of every device that has its key */\n shared: string[];\n}\n\ninterface InboundRecord {\n pickle: string;\n conversationId: string;\n senderUserId: string;\n senderDeviceId: string;\n firstIndex: number;\n}\n\ninterface OlmRecord {\n /** newest first */\n sessions: { id: string; pickle: string }[];\n}\n\nconst MAX_OLM_PER_PEER = 5;\n\nexport interface MachineOptions {\n wasm: Wasm;\n transport: E2eeTransport;\n store: E2eeStore;\n /** 32 bytes that never leave the device: every pickle is encrypted with it */\n pickleKey: Uint8Array;\n userId: string;\n deviceName: string;\n lock?: Lock;\n newDeviceId?: () => string;\n log?: (msg: string) => void;\n}\n\n/** One person's encryption on one device. */\nexport class E2eeMachine {\n private readonly w: Wasm;\n private readonly api: E2eeTransport;\n private readonly store: E2eeStore;\n private readonly key: Uint8Array;\n private readonly lock: Lock;\n private readonly log: (msg: string) => void;\n private readonly newId: () => string;\n readonly userId: string;\n private readonly deviceName: string;\n private dev!: DeviceRecord;\n private ed!: string;\n private curve!: string;\n /** devices as the server published them and we checked them, per user, for this page's life */\n private readonly deviceCache = new Map<string, Promise<DeviceKeys[]>>();\n /** sessionId → message index → message id: a reused index is a replay */\n private readonly seen = new Map<string, Map<number, string>>();\n\n private constructor(o: MachineOptions) {\n this.w = o.wasm;\n this.api = o.transport;\n this.store = o.store;\n this.key = o.pickleKey;\n this.lock = o.lock ?? localLock();\n this.log = o.log ?? (() => undefined);\n this.userId = o.userId;\n this.deviceName = o.deviceName;\n this.newId = o.newDeviceId ?? randomDeviceId;\n }\n\n /** Loads this device's account, or makes and publishes a new one; then makes sure the server has its keys. */\n static async open(o: MachineOptions): Promise<E2eeMachine> {\n const m = new E2eeMachine(o);\n await m.lock(() => m.boot());\n return m;\n }\n\n get deviceId(): string {\n return this.dev.deviceId;\n }\n\n get ed25519(): string {\n return this.ed;\n }\n\n private async boot(): Promise<void> {\n const raw = await this.store.get('device');\n this.dev = raw ? (JSON.parse(raw) as DeviceRecord) : this.fresh();\n for (let attempt = 0; ; attempt++) {\n const acct = this.account();\n this.ed = acct.ed25519;\n this.curve = acct.curve25519;\n if (!this.dev.registered) {\n const ok = await this.api.registerDevice(this.dev.deviceId, {\n curve25519: this.curve,\n ed25519: this.ed,\n signature: acct.sign(deviceSigningText(this.userId, this.dev.deviceId, this.curve, this.ed)),\n name: this.deviceName,\n });\n if (!ok) {\n acct.free();\n if (attempt > 0) throw new Error('the server refused this device');\n this.log('device refused; starting a new one');\n await this.wipe();\n this.dev = this.fresh();\n continue;\n }\n this.dev.registered = true;\n await this.saveDevice(acct);\n }\n acct.free();\n const count = await this.api.keyCount(this.dev.deviceId);\n if (!count) {\n if (attempt > 0) throw new Error('the server forgot this device');\n this.log('device unknown to the server; starting a new one');\n await this.wipe();\n this.dev = this.fresh();\n continue;\n }\n await this.topUp(count);\n break;\n }\n }\n\n private fresh(): DeviceRecord {\n const acct = new this.w.Account();\n const rec = { deviceId: this.newId(), account: acct.pickle(this.key), registered: false };\n acct.free();\n return rec;\n }\n\n private async wipe(): Promise<void> {\n await this.store.del('device');\n await this.store.del('inboxAfter');\n }\n\n private account(): Account {\n return this.w.Account.from_pickle(this.dev.account, this.key);\n }\n\n private async saveDevice(acct: Account): Promise<void> {\n this.dev.account = acct.pickle(this.key);\n await this.store.set('device', JSON.stringify(this.dev));\n }\n\n /** Publishes one-time keys when the server is running low, and a fallback key when it has none. */\n private async topUp(count?: KeyCount): Promise<void> {\n const c = count ?? (await this.api.keyCount(this.dev.deviceId));\n if (!c) return;\n const n = keysToGenerate(c.oneTimeKeys);\n if (!n && c.fallback) return;\n const acct = this.account();\n try {\n if (n) acct.generate_one_time_keys(Math.min(n, acct.max_one_time_keys()));\n if (!c.fallback) acct.generate_fallback_key();\n const sign = (fallback: boolean) => ([keyId, key]: [string, string]): SignedKey => ({\n keyId,\n key,\n signature: acct.sign(keySigningText(this.userId, this.dev.deviceId, keyId, key, fallback)),\n });\n const otks = Object.entries(acct.one_time_keys() as Record<string, string>).map(sign(false));\n const [fallbackKey] = Object.entries(acct.fallback_key() as Record<string, string>).map(sign(true));\n if (!otks.length && !fallbackKey) return;\n // saved before upload: if the upload is lost, the same keys go next time (the server ignores repeats)\n await this.saveDevice(acct);\n await this.api.uploadKeys(this.dev.deviceId, { oneTimeKeys: otks, fallbackKey });\n acct.mark_keys_as_published();\n await this.saveDevice(acct);\n } finally {\n acct.free();\n }\n }\n\n // ---- devices ----\n\n /** A user's devices whose keys are signed by themselves and match what this device saw before (trust on first use). */\n private devicesOf(userId: string): Promise<DeviceKeys[]> {\n let p = this.deviceCache.get(userId);\n if (!p) {\n p = this.loadDevices(userId);\n this.deviceCache.set(userId, p);\n p.catch(() => this.deviceCache.delete(userId));\n }\n return p;\n }\n\n private async loadDevices(userId: string): Promise<DeviceKeys[]> {\n const out: DeviceKeys[] = [];\n for (const d of await this.api.devices(userId)) {\n if (d.userId !== userId) continue;\n if (!this.w.verify_ed25519(d.ed25519, deviceSigningText(userId, d.deviceId, d.curve25519, d.ed25519), d.signature)) {\n this.log(`device ${userId}/${d.deviceId}: bad signature`);\n continue;\n }\n const pinKey = `pin:${userId}|${d.deviceId}`;\n const pinned = await this.store.get(pinKey);\n const now = `${d.curve25519}|${d.ed25519}`;\n if (pinned && pinned !== now) {\n this.log(`device ${userId}/${d.deviceId}: keys changed`);\n continue;\n }\n if (!pinned) await this.store.set(pinKey, now);\n out.push(d);\n }\n return out;\n }\n\n /** Forget cached device lists (someone signed in on a new device, or a membership changed). */\n forgetDevices(userId?: string): void {\n if (userId) this.deviceCache.delete(userId);\n else this.deviceCache.clear();\n }\n\n // ---- Olm sessions ----\n\n private async olmSessions(curve: string): Promise<OlmRecord> {\n const raw = await this.store.get(`olm:${curve}`);\n return raw ? (JSON.parse(raw) as OlmRecord) : { sessions: [] };\n }\n\n private async saveOlm(curve: string, s: OlmSession, rec?: OlmRecord): Promise<void> {\n const r = rec ?? (await this.olmSessions(curve));\n const id = s.session_id;\n const rest = r.sessions.filter((x) => x.id !== id);\n r.sessions = [{ id, pickle: s.pickle(this.key) }, ...rest].slice(0, MAX_OLM_PER_PEER);\n await this.store.set(`olm:${curve}`, JSON.stringify(r));\n }\n\n /** Olm sessions to each device, opening new ones from claimed one-time keys where there are none yet. */\n private async olmTo(devices: DeviceKeys[]): Promise<Map<string, OlmSession>> {\n const out = new Map<string, OlmSession>();\n const need: DeviceKeys[] = [];\n for (const d of devices) {\n const rec = await this.olmSessions(d.curve25519);\n if (rec.sessions.length) out.set(d.curve25519, this.w.Session.from_pickle(rec.sessions[0].pickle, this.key));\n else need.push(d);\n }\n if (!need.length) return out;\n const claimed = await this.api.claim(need.map((d) => ({ userId: d.userId, deviceId: d.deviceId })));\n const acct = this.account();\n try {\n for (const k of claimed) {\n const d = need.find((x) => x.userId === k.userId && x.deviceId === k.deviceId);\n if (!d) continue;\n if (!this.w.verify_ed25519(d.ed25519, keySigningText(d.userId, d.deviceId, k.keyId, k.key, !!k.fallback), k.signature)) {\n this.log(`claimed key for ${d.userId}/${d.deviceId}: bad signature`);\n continue;\n }\n const s = acct.create_outbound_session(d.curve25519, k.key);\n await this.saveOlm(d.curve25519, s);\n out.set(d.curve25519, s);\n }\n } finally {\n acct.free();\n }\n return out;\n }\n\n // ---- sending ----\n\n /** Encrypts a message for a conversation, first sending the group session's key to every device that lacks it. */\n encrypt(conv: ConversationKeys, plain: Plain): Promise<Encrypted> {\n return this.lock(async () => {\n const outKey = `out:${conv.id}`;\n const raw = await this.store.get(outKey);\n let rec = raw ? (JSON.parse(raw) as OutboundRecord) : null;\n if (!rec || rec.epoch !== conv.epoch || rec.sent >= ROTATE_AFTER) rec = await this.newOutbound(conv);\n const group = this.w.GroupSession.from_pickle(rec.pickle, this.key);\n try {\n await this.share(conv, group, rec);\n const ciphertext = group.encrypt(JSON.stringify({ v: 1, conversationId: conv.id, kind: plain.kind, text: plain.text }));\n rec.sent++;\n rec.pickle = group.pickle(this.key);\n await this.store.set(outKey, JSON.stringify(rec));\n return { senderDevice: this.dev.deviceId, algorithm: MEGOLM, sessionId: rec.sessionId, ciphertext };\n } finally {\n group.free();\n }\n });\n }\n\n private async newOutbound(conv: ConversationKeys): Promise<OutboundRecord> {\n const g = new this.w.GroupSession();\n // our own copy, so this device reads what it sent\n const ib = new this.w.InboundGroupSession(g.session_key);\n const mine: InboundRecord = { pickle: ib.pickle(this.key), conversationId: conv.id, senderUserId: this.userId, senderDeviceId: this.dev.deviceId, firstIndex: ib.first_known_index };\n await this.store.set(`in:${g.session_id}`, JSON.stringify(mine));\n const rec = { epoch: conv.epoch, sessionId: g.session_id, pickle: g.pickle(this.key), sent: 0, shared: [] };\n ib.free();\n g.free();\n return rec;\n }\n\n private async share(conv: ConversationKeys, group: YanE2ee.GroupSession, rec: OutboundRecord): Promise<void> {\n const readers = [...new Set(conv.members.filter((m) => m.state === 'active' || m.state === 'request').map((m) => m.userId))];\n if (!readers.includes(this.userId)) readers.push(this.userId); // our other devices\n const targets: DeviceKeys[] = [];\n for (const u of readers) {\n for (const d of await this.devicesOf(u)) {\n if (u === this.userId && d.deviceId === this.dev.deviceId) continue;\n if (!rec.shared.includes(`${u}|${d.deviceId}|${d.curve25519}`)) targets.push(d);\n }\n }\n if (!targets.length) return;\n const sessions = await this.olmTo(targets);\n const sessionKey = group.session_key; // from the current index: a new reader can't open what came before\n const messages: ToDeviceOut[] = [];\n const done: string[] = [];\n for (const d of targets) {\n const s = sessions.get(d.curve25519);\n if (!s) continue; // no keys to claim: that device reads nothing until it publishes some\n const k: RoomKey = {\n t: 'yan.room_key',\n conversationId: conv.id,\n epoch: conv.epoch,\n sessionId: rec.sessionId,\n sessionKey,\n sender: { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed },\n recipient: { userId: d.userId, deviceId: d.deviceId, ed25519: d.ed25519 },\n };\n const sealed = s.encrypt(JSON.stringify(k));\n await this.saveOlm(d.curve25519, s);\n s.free();\n messages.push({ userId: d.userId, deviceId: d.deviceId, type: OLM, body: JSON.stringify({ v: 1, type: sealed.message_type, body: sealed.body }) });\n done.push(`${d.userId}|${d.deviceId}|${d.curve25519}`);\n }\n for (let i = 0; i < messages.length; i += 200) await this.api.sendToDevice(this.dev.deviceId, messages.slice(i, i + 200));\n rec.shared.push(...done);\n }\n\n // ---- receiving ----\n\n /** Reads this device's to-device inbox: room keys from other devices. Answers how many new keys arrived. */\n sync(): Promise<number> {\n return this.lock(() => this.syncLocked());\n }\n\n private async syncLocked(): Promise<number> {\n let after = Number((await this.store.get('inboxAfter')) ?? 0);\n let added = 0;\n let usedOneTimeKey = false;\n for (;;) {\n const items = await this.api.inbox(this.dev.deviceId, after);\n if (!items.length) break;\n for (const it of items) {\n try {\n const r = await this.receive(it);\n added += r.added;\n usedOneTimeKey ||= r.newSession;\n } catch (e) {\n this.log(`to-device ${it.id} from ${it.senderUserId}/${it.senderDeviceId}: ${(e as Error).message}`);\n }\n after = Math.max(after, it.id);\n }\n await this.store.set('inboxAfter', String(after));\n await this.api.ackInbox(this.dev.deviceId, after);\n }\n if (usedOneTimeKey) await this.topUp();\n return added;\n }\n\n private async receive(it: ToDeviceIn): Promise<{ added: number; newSession: boolean }> {\n if (it.type !== OLM) return { added: 0, newSession: false };\n const env = JSON.parse(it.body) as { v: number; type: number; body: string };\n if (env.v !== 1) throw new Error('unknown envelope');\n const find = async () => (await this.devicesOf(it.senderUserId)).find((d) => d.deviceId === it.senderDeviceId);\n let from = await find();\n if (!from) {\n // a device that signed in after we last looked\n this.forgetDevices(it.senderUserId);\n from = await find();\n }\n if (!from) throw new Error('unknown sender device');\n\n let plaintext: string | null = null;\n let newSession = false;\n const rec = await this.olmSessions(from.curve25519);\n for (const s of rec.sessions) {\n const sess = this.w.Session.from_pickle(s.pickle, this.key);\n try {\n plaintext = sess.decrypt(env.type, env.body);\n await this.saveOlm(from.curve25519, sess, rec);\n break;\n } catch {\n // not this session\n } finally {\n sess.free();\n }\n }\n if (plaintext === null) {\n if (env.type !== 0) throw new Error('no session for this message');\n const acct = this.account();\n try {\n const inbound = acct.create_inbound_session(from.curve25519, env.type, env.body);\n plaintext = inbound.plaintext;\n const sess = inbound.take_session();\n await this.saveDevice(acct); // its one-time key is spent\n await this.saveOlm(from.curve25519, sess, rec);\n sess.free();\n newSession = true;\n } finally {\n acct.free();\n }\n }\n\n const k = JSON.parse(plaintext) as RoomKey;\n const problem = roomKeyProblem(k, { userId: this.userId, deviceId: this.dev.deviceId, ed25519: this.ed }, { userId: from.userId, deviceId: from.deviceId, ed25519: from.ed25519 });\n if (problem) throw new Error(problem);\n const ib = new this.w.InboundGroupSession(k.sessionKey);\n try {\n if (ib.session_id !== k.sessionId) throw new Error('session id mismatch');\n const existing = await this.store.get(`in:${k.sessionId}`);\n if (existing) {\n const e = JSON.parse(existing) as InboundRecord;\n if (e.senderUserId !== from.userId || e.senderDeviceId !== from.deviceId || e.conversationId !== k.conversationId) throw new Error('session claimed by another sender');\n if (e.firstIndex <= ib.first_known_index) return { added: 0, newSession };\n }\n const r: InboundRecord = { pickle: ib.pickle(this.key), conversationId: k.conversationId, senderUserId: from.userId, senderDeviceId: from.deviceId, firstIndex: ib.first_known_index };\n await this.store.set(`in:${k.sessionId}`, JSON.stringify(r));\n return { added: 1, newSession };\n } finally {\n ib.free();\n }\n }\n\n /** Decrypts a message; when its key hasn't arrived, reads the inbox once and tries again. */\n decrypt(msg: SealedMessage): Promise<Opened> {\n return this.lock(async () => {\n let raw = await this.store.get(`in:${msg.sessionId}`);\n if (!raw) {\n await this.syncLocked();\n raw = await this.store.get(`in:${msg.sessionId}`);\n }\n if (!raw) return { ok: false, reason: 'missing-key' };\n const rec = JSON.parse(raw) as InboundRecord;\n if (msg.algorithm !== MEGOLM || rec.conversationId !== msg.conversationId || rec.senderUserId !== msg.senderId || rec.senderDeviceId !== msg.senderDeviceId) {\n return { ok: false, reason: 'invalid' };\n }\n const ib = this.w.InboundGroupSession.from_pickle(rec.pickle, this.key);\n try {\n const d = ib.decrypt(msg.ciphertext);\n const seen = this.seen.get(msg.sessionId) ?? new Map<number, string>();\n this.seen.set(msg.sessionId, seen);\n const prior = seen.get(d.message_index);\n if (prior && prior !== msg.id) return { ok: false, reason: 'invalid' };\n seen.set(d.message_index, msg.id);\n const p = JSON.parse(d.plaintext) as { v: number; conversationId: string; kind: string; text: string };\n if (p.v !== 1 || p.conversationId !== msg.conversationId || typeof p.text !== 'string') return { ok: false, reason: 'invalid' };\n return { ok: true, kind: p.kind || 'text', text: p.text };\n } catch {\n return { ok: false, reason: 'invalid' };\n } finally {\n ib.free();\n }\n });\n }\n}\n\n/** web_ + 16 random hex characters. */\nexport function randomDeviceId(): string {\n const b = new Uint8Array(8);\n crypto.getRandomValues(b);\n return 'web_' + [...b].map((x) => x.toString(16).padStart(2, '0')).join('');\n}\n","import type { E2eeStore, Lock } from './e2ee';\n\n// The browser side of the encryption's storage: one IndexedDB database, keys prefixed by the person's id (several\n// people can use one browser). Every pickle is already encrypted by vodozemac with a 32-byte pickle key; that key is\n// stored wrapped by a non-extractable AES-GCM key, so its bytes never sit in storage in the clear.\n\nconst DB = 'yan-e2ee';\nconst KV = 'kv';\nconst KEYS = 'keys';\n\nlet dbp: Promise<IDBDatabase> | null = null;\n\nfunction db(): Promise<IDBDatabase> {\n dbp ??= new Promise((resolve, reject) => {\n const r = indexedDB.open(DB, 1);\n r.onupgradeneeded = () => {\n r.result.createObjectStore(KV);\n r.result.createObjectStore(KEYS);\n };\n r.onsuccess = () => resolve(r.result);\n r.onerror = () => reject(r.error);\n });\n dbp.catch(() => (dbp = null));\n return dbp;\n}\n\nfunction req<T>(store: string, mode: IDBTransactionMode, fn: (s: IDBObjectStore) => IDBRequest): Promise<T> {\n return db().then(\n (d) =>\n new Promise<T>((resolve, reject) => {\n const tx = d.transaction(store, mode);\n const r = fn(tx.objectStore(store));\n tx.oncomplete = () => resolve(r.result as T);\n tx.onerror = () => reject(tx.error);\n tx.onabort = () => reject(tx.error);\n }),\n );\n}\n\n/** One person's encryption storage. */\nexport function idbStore(userId: string): E2eeStore {\n const k = (key: string) => `${userId}/${key}`;\n return {\n get: (key) => req<string | undefined>(KV, 'readonly', (s) => s.get(k(key))),\n set: (key, value) => req<void>(KV, 'readwrite', (s) => s.put(value, k(key))),\n del: (key) => req<void>(KV, 'readwrite', (s) => s.delete(k(key))),\n };\n}\n\ninterface WrappedKey {\n wrapper: CryptoKey;\n iv: Uint8Array;\n sealed: ArrayBuffer;\n}\n\n/** This person's pickle key on this browser, made on first use. */\nexport async function pickleKey(userId: string): Promise<Uint8Array> {\n const have = await req<WrappedKey | undefined>(KEYS, 'readonly', (s) => s.get(userId));\n if (have) return new Uint8Array(await crypto.subtle.decrypt({ name: 'AES-GCM', iv: have.iv as BufferSource }, have.wrapper, have.sealed));\n const raw = crypto.getRandomValues(new Uint8Array(32));\n const wrapper = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const sealed = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, wrapper, raw);\n await req<void>(KEYS, 'readwrite', (s) => s.put({ wrapper, iv, sealed } satisfies WrappedKey, userId));\n return raw;\n}\n\n/** Everything this browser holds for a person (signing out of messaging here). */\nexport async function forget(userId: string): Promise<void> {\n const d = await db();\n await new Promise<void>((resolve, reject) => {\n const tx = d.transaction([KV, KEYS], 'readwrite');\n tx.objectStore(KV).delete(IDBKeyRange.bound(`${userId}/`, `${userId}/￿`));\n tx.objectStore(KEYS).delete(userId);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/** One operation at a time across every tab of this person (a ratchet must never fork); in-tab only without Web Locks. */\nexport function tabLock(userId: string, fallback: Lock): Lock {\n const locks = (navigator as Navigator & { locks?: LockManager }).locks;\n if (!locks) return fallback;\n return <T>(fn: () => Promise<T>) => locks.request(`yan-e2ee:${userId}`, fn) as Promise<T>;\n}\n","// Pure display rules for Messages (prototype Messages screen, PRD DM-1–8). No Angular, so node tests run them.\n\nexport interface PersonLike {\n userId: string;\n username: string;\n displayName: string;\n}\n\nexport interface MemberLike {\n userId: string;\n state: string;\n lastReadMessageId?: string;\n}\n\nexport interface ConversationLike {\n kind: 'direct' | 'group';\n title?: string;\n members: MemberLike[];\n myState: string;\n}\n\n/** How a person is shown: display name, else @username, else \"Someone\". */\nexport function personName(p: PersonLike | undefined): string {\n if (!p) return 'Someone';\n return p.displayName || (p.username ? '@' + p.username : 'Someone');\n}\n\n/** The other people in a conversation who are still in it. */\nexport function others(c: ConversationLike, me: string): MemberLike[] {\n return c.members.filter((m) => m.userId !== me && (m.state === 'active' || m.state === 'request'));\n}\n\n/** A direct conversation is named after the other person; a group by its title, else its members. */\nexport function conversationName(c: ConversationLike, me: string, people: Record<string, PersonLike>): string {\n if (c.kind === 'group' && c.title) return c.title;\n const names = others(c, me).map((m) => personName(people[m.userId]));\n if (!names.length) return c.kind === 'group' ? 'Group' : 'Just you';\n if (c.kind === 'direct') return names[0];\n return names.length <= 3 ? names.join(', ') : `${names.slice(0, 2).join(', ')} and ${names.length - 2} others`;\n}\n\n/** The prototype's kind eyebrow. */\nexport function kindLabel(c: ConversationLike): string {\n return c.kind === 'group' ? 'Group' : 'Direct';\n}\n\n/** Every DM and group is end-to-end encrypted (the email and community rows, which aren't, come with P2). */\nexport const E2EE_LABEL = { cls: 'yan-security--e2ee', icon: 'shield-lock', text: 'End-to-end encrypted' } as const;\n\n/** The Requests row's second line. */\nexport function requestsLine(count: number, firstFrom: string | undefined): string {\n if (!count) return 'No requests';\n return `${count} waiting · ${firstFrom ?? 'Someone'}`;\n}\n\n/** Who will see your messages under Requests, until they accept (DM-3). */\nexport function pendingFor(c: ConversationLike, me: string, people: Record<string, PersonLike>): string | null {\n const waiting = c.members.filter((m) => m.userId !== me && m.state === 'request');\n if (!waiting.length) return null;\n if (c.kind === 'direct') return `${personName(people[waiting[0].userId])} isn't in your network yet. Your messages go to their Requests until they accept.`;\n return waiting.length === 1\n ? `${personName(people[waiting[0].userId])} hasn't accepted yet and sees this under Requests.`\n : `${waiting.length} people haven't accepted yet and see this under Requests.`;\n}\n\n/** Days left on a request (DM-3: 7), for \"Expires in 3 days\". */\nexport function expiresIn(until: string | undefined, now = Date.now()): string {\n if (!until) return '';\n const ms = new Date(until).getTime() - now;\n if (ms <= 0) return 'Expired';\n const h = Math.ceil(ms / 3_600_000);\n if (h < 24) return `Expires in ${h} hour${h === 1 ? '' : 's'}`;\n const d = Math.ceil(h / 24);\n return `Expires in ${d} day${d === 1 ? '' : 's'}`;\n}\n\n/**\n * \"Seen\" under your last message, when everyone else has read up to it or later. `order` is the thread's message\n * ids, oldest first.\n */\nexport function seen(c: ConversationLike, me: string, order: string[], lastMine: string | undefined): boolean {\n if (!lastMine) return false;\n const at = order.indexOf(lastMine);\n if (at < 0) return false;\n const rest = others(c, me).filter((m) => m.state === 'active');\n if (!rest.length) return false;\n return rest.every((m) => !!m.lastReadMessageId && order.indexOf(m.lastReadMessageId) >= at);\n}\n\n/** What a message that can't be shown says instead. */\nexport function unreadableText(reason: 'missing-key' | 'invalid'): string {\n return reason === 'missing-key' ? \"Can't be read on this device\" : \"Couldn't be verified, so it isn't shown\";\n}\n\n/** A preview line for the list: the text, else a word for the kind. */\nexport function previewText(kind: string, text: string): string {\n if (text) return text;\n const words: Record<string, string> = { image: 'Photo', video: 'Video', file: 'File', voice: 'Voice message', link: 'Link', reaction: 'Reaction' };\n return words[kind] ?? 'Message';\n}\n","import { InjectionToken } from '@angular/core';\n\n/** What the host app gives Messages: who is signed in, a fresh access token for the WebSocket, and where things are. */\nexport interface MessagesHost {\n /** current user id, or null for a guest */\n userId(): string | null;\n /** a usable access token (renewed when it's about to run out), or null when signed out */\n accessToken(): Promise<string | null>;\n /** send a guest to sign in, coming back to `next` */\n requestSignIn(next: string): void;\n /** the WebSocket address, e.g. wss://yansocial.com/ws */\n wsUrl(): string;\n /** this device's name as other devices list it, e.g. \"Chrome on Mac\" */\n deviceName(): string;\n}\n\nexport const MESSAGES_HOST = new InjectionToken<MessagesHost>('MESSAGES_HOST', {\n providedIn: 'root',\n factory: () => ({\n userId: () => null,\n accessToken: async () => null,\n requestSignIn: () => undefined,\n wsUrl: () => location.origin.replace(/^http/, 'ws') + '/ws',\n deviceName: () => 'Web',\n }),\n});\n\n/** Host-provided: base URL of the messaging API. */\nexport const MESSAGES_API_BASE = new InjectionToken<string>('MESSAGES_API_BASE', {\n providedIn: 'root',\n factory: () => '/api/apps/messaging',\n});\n\n/** Host-provided: base URL of the social API (names for people known only by id). */\nexport const MESSAGES_SOCIAL_BASE = new InjectionToken<string>('MESSAGES_SOCIAL_BASE', {\n providedIn: 'root',\n factory: () => '/api/apps/social',\n});\n\n/** Host-provided: where the encryption module (yan_e2ee_bg.wasm from @chisquare-tech/yan-e2ee) is served. */\nexport const MESSAGES_E2EE_WASM = new InjectionToken<string>('MESSAGES_E2EE_WASM', {\n providedIn: 'root',\n factory: () => '/e2ee/yan_e2ee_bg.wasm',\n});\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport type { ClaimedKey, DeviceKeys, E2eeTransport, KeyCount, SealedMessage, SignedKey, ToDeviceIn, ToDeviceOut } from './e2ee';\nimport { MESSAGES_API_BASE, MESSAGES_SOCIAL_BASE } from './tokens';\n\ninterface Envelope<T> {\n data: T;\n}\n\nexport interface Member {\n userId: string;\n role: 'owner' | 'admin' | 'member';\n state: 'active' | 'request' | 'declined' | 'left';\n lastReadMessageId?: string;\n lastReadAt?: string;\n}\n\nexport interface Conversation {\n id: string;\n kind: 'direct' | 'group';\n title?: string;\n epoch: number;\n members: Member[];\n myState: 'active' | 'request';\n myRole: string;\n unread: number;\n lastMessageId?: string;\n lastMessageAt?: string;\n requestUntil?: string;\n createdAt: string;\n}\n\nexport interface Message extends SealedMessage {\n clientMsgId: string;\n epoch: number;\n kind: string;\n replyToId?: string;\n createdAt: string;\n}\n\nexport interface Page<T> {\n items: T[];\n next?: string;\n}\n\nexport interface Person {\n userId: string;\n username: string;\n displayName: string;\n}\n\nexport interface SendBody {\n clientMsgId: string;\n senderDevice: string;\n algorithm: string;\n sessionId: string;\n kind: string;\n ciphertext: string;\n}\n\n/** yan-gox-apps/libs/messaging over HTTP: the conversation API, and the device-key API the encryption needs. */\n@Injectable({ providedIn: 'root' })\nexport class MessagingApi implements E2eeTransport {\n private readonly http = inject(HttpClient);\n private readonly base = inject(MESSAGES_API_BASE);\n private readonly social = inject(MESSAGES_SOCIAL_BASE);\n\n private async get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n const p: Record<string, string> = {};\n for (const [k, v] of Object.entries(params ?? {})) if (v !== undefined && v !== '') p[k] = String(v);\n return (await firstValueFrom(this.http.get<Envelope<T>>(this.base + path, { params: p }))).data;\n }\n\n private async send<T>(method: 'POST' | 'PUT' | 'DELETE', path: string, body?: unknown): Promise<T> {\n return (await firstValueFrom(this.http.request<Envelope<T>>(method, this.base + path, { body }))).data;\n }\n\n // ---- conversations ----\n\n conversations(box: 'inbox' | 'requests' = 'inbox'): Promise<Conversation[]> {\n return this.get('/conversations', { box: box === 'inbox' ? undefined : box });\n }\n\n conversation(id: string): Promise<Conversation> {\n return this.get(`/conversations/${encodeURIComponent(id)}`);\n }\n\n startDirect(userId: string): Promise<Conversation> {\n return this.send('POST', '/conversations', { kind: 'direct', userId });\n }\n\n accept(id: string): Promise<Conversation> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/accept`, {});\n }\n\n decline(id: string): Promise<unknown> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/decline`, {});\n }\n\n messages(id: string, before?: string, limit = 50): Promise<Page<Message>> {\n return this.get(`/conversations/${encodeURIComponent(id)}/messages`, { before, limit });\n }\n\n sendMessage(id: string, body: SendBody): Promise<Message> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/messages`, body);\n }\n\n markRead(id: string, messageId: string): Promise<unknown> {\n return this.send('PUT', `/conversations/${encodeURIComponent(id)}/read`, { messageId });\n }\n\n typing(id: string): Promise<unknown> {\n return this.send('POST', `/conversations/${encodeURIComponent(id)}/typing`, {});\n }\n\n /** Names for people known only by id; an empty list asks nothing. */\n async people(ids: string[]): Promise<Person[]> {\n const unique = [...new Set(ids)].slice(0, 100);\n if (!unique.length) return [];\n return (await firstValueFrom(this.http.get<Envelope<Person[]>>(`${this.social}/people`, { params: { ids: unique.join(',') } }))).data;\n }\n\n // ---- E2eeTransport ----\n\n async registerDevice(deviceId: string, body: { curve25519: string; ed25519: string; signature: string; name: string }): Promise<boolean> {\n try {\n await this.send('PUT', `/devices/${encodeURIComponent(deviceId)}`, body);\n return true;\n } catch (e) {\n if (e instanceof HttpErrorResponse && e.status === 409) return false;\n throw e;\n }\n }\n\n uploadKeys(deviceId: string, body: { oneTimeKeys: SignedKey[]; fallbackKey?: SignedKey }): Promise<KeyCount> {\n return this.send('POST', `/devices/${encodeURIComponent(deviceId)}/keys`, body);\n }\n\n async keyCount(deviceId: string): Promise<KeyCount | null> {\n try {\n return await this.get<KeyCount>(`/devices/${encodeURIComponent(deviceId)}/keys/count`);\n } catch (e) {\n if (e instanceof HttpErrorResponse && e.status === 404) return null;\n throw e;\n }\n }\n\n devices(userId: string): Promise<DeviceKeys[]> {\n return this.get(`/users/${encodeURIComponent(userId)}/devices`);\n }\n\n claim(devices: { userId: string; deviceId: string }[]): Promise<ClaimedKey[]> {\n return this.send('POST', '/keys/claim', { devices });\n }\n\n async sendToDevice(senderDevice: string, messages: ToDeviceOut[]): Promise<number> {\n return (await this.send<{ sent: number }>('POST', '/to-device', { senderDevice, messages })).sent;\n }\n\n inbox(deviceId: string, after: number): Promise<ToDeviceIn[]> {\n return this.get(`/devices/${encodeURIComponent(deviceId)}/inbox`, { after, limit: 100 });\n }\n\n async ackInbox(deviceId: string, upTo: number): Promise<void> {\n await this.send('POST', `/devices/${encodeURIComponent(deviceId)}/inbox/ack`, { upTo });\n }\n}\n\n/** A server error's message for people, or a fallback. */\nexport function errorText(e: unknown, fallback: string): string {\n const m = (e as { error?: { message?: string } })?.error?.message;\n return m && m.length < 200 ? m : fallback;\n}\n\n/** An error's code from the server (e.g. cant_message), if any. */\nexport function errorCode(e: unknown): string | undefined {\n return (e as { error?: { code?: string } })?.error?.code;\n}\n","import { Injectable, NgZone, WritableSignal, computed, inject, signal } from '@angular/core';\nimport { DmSocket, type DmEvent } from './dm-socket';\nimport { E2eeMachine, localLock, type ConversationKeys, type Opened } from './e2ee';\nimport { idbStore, pickleKey, tabLock } from './idb-store';\nimport { previewText, unreadableText } from './labels';\nimport { MessagingApi, errorCode, errorText, type Conversation, type Message, type Person, type SendBody } from './messaging-api';\nimport { MESSAGES_E2EE_WASM, MESSAGES_HOST } from './tokens';\n\nexport type BubbleState = 'ok' | 'pending' | 'failed' | 'unreadable';\n\nexport interface Bubble {\n /** the server's id; a pending message has its clientMsgId here until it's sent */\n id: string;\n clientMsgId?: string;\n senderId: string;\n mine: boolean;\n kind: string;\n text: string;\n state: BubbleState;\n /** why an unreadable message can't be shown */\n unreadable?: 'missing-key' | 'invalid';\n /** why a message failed to send, for the retry line */\n error?: string;\n createdAt: string;\n sealed?: Message;\n /** a send that failed after encryption keeps its ciphertext, so the retry is the same message */\n outgoing?: { kind: string; text: string; body?: SendBody };\n}\n\nexport interface Thread {\n conv: Conversation | null;\n items: Bubble[];\n next?: string;\n loading: boolean;\n failed: boolean;\n missing: boolean;\n}\n\nexport type CryptoState = 'idle' | 'starting' | 'ready' | 'failed';\n\nconst PREVIEW_LIMIT = 30;\n\n/**\n * Messages for the signed-in person: the lists, each open thread (decrypted on this device), sending, Requests, and\n * live updates over the dm WebSocket channel. The server only ever sees ciphertext.\n */\n@Injectable({ providedIn: 'root' })\nexport class MessagesStore {\n private readonly api = inject(MessagingApi);\n private readonly host = inject(MESSAGES_HOST);\n private readonly wasmUrl = inject(MESSAGES_E2EE_WASM);\n private readonly zone = inject(NgZone);\n\n readonly inbox = signal<Conversation[]>([]);\n readonly requests = signal<Conversation[]>([]);\n readonly loaded = signal(false);\n readonly failed = signal(false);\n readonly people = signal<Record<string, Person>>({});\n readonly previews = signal<Record<string, string>>({});\n /** conversation id → who is typing there */\n readonly typing = signal<Record<string, string>>({});\n readonly crypto = signal<CryptoState>('idle');\n /** For the nav badge: unread conversations plus waiting requests. */\n readonly badge = computed(() => this.inbox().reduce((n, c) => n + (c.unread > 0 ? 1 : 0), 0) + this.requests().length);\n\n private readonly threads = new Map<string, WritableSignal<Thread>>();\n private machine: Promise<E2eeMachine> | null = null;\n private machineUser: string | null = null;\n private socket: DmSocket | null = null;\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly typingTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private lastTypingSent = new Map<string, number>();\n\n me(): string | null {\n return this.host.userId();\n }\n\n // ---- lifecycle ----\n\n /** Loads the lists (enough for the nav badge). */\n async loadLists(): Promise<void> {\n if (!this.me()) return;\n try {\n const [inbox, requests] = await Promise.all([this.api.conversations('inbox'), this.api.conversations('requests')]);\n this.inbox.set(inbox);\n this.requests.set(requests);\n this.failed.set(false);\n this.loaded.set(true);\n await this.loadPeople([...inbox, ...requests].flatMap((c) => c.members.map((m) => m.userId)));\n void this.loadPreviews([...requests, ...inbox]);\n } catch {\n this.failed.set(true);\n }\n }\n\n /** Everything Messages needs: the lists, this device's encryption, and live updates. */\n async start(): Promise<void> {\n const me = this.me();\n if (!me) return;\n if (this.machineUser && this.machineUser !== me) this.stop();\n void this.loadLists();\n void this.ensureMachine().then(\n () => this.openSocket(),\n () => undefined,\n );\n }\n\n /** Signing out, or another person signing in. */\n stop(): void {\n this.socket?.stop();\n this.socket = null;\n this.machine = null;\n this.machineUser = null;\n this.crypto.set('idle');\n this.threads.clear();\n this.inbox.set([]);\n this.requests.set([]);\n this.previews.set({});\n this.loaded.set(false);\n }\n\n /** This device's encryption: loads the wasm module, then opens (or makes and publishes) the device's keys. */\n ensureMachine(): Promise<E2eeMachine> {\n const me = this.me();\n if (!me) return Promise.reject(new Error('signed out'));\n if (this.machine && this.machineUser === me) return this.machine;\n this.machineUser = me;\n this.crypto.set('starting');\n this.machine = (async () => {\n const wasm = await import('@chisquare-tech/yan-e2ee');\n await wasm.default({ module_or_path: this.wasmUrl });\n return E2eeMachine.open({\n wasm,\n transport: this.api,\n store: idbStore(me),\n pickleKey: await pickleKey(me),\n userId: me,\n deviceName: this.host.deviceName(),\n lock: tabLock(me, localLock()),\n log: (m) => console.debug('[yan-e2ee]', m),\n });\n })();\n this.machine.then(\n () => this.crypto.set('ready'),\n (e) => {\n console.warn('[yan-e2ee] could not start', e);\n this.machine = null;\n this.crypto.set('failed');\n },\n );\n return this.machine;\n }\n\n retryCrypto(): void {\n void this.start();\n }\n\n private openSocket(): void {\n if (this.socket) return;\n const machine = this.machine;\n if (!machine) return;\n let device = '';\n void machine.then((m) => (device = m.deviceId));\n this.zone.runOutsideAngular(() => {\n this.socket = new DmSocket({\n url: () => this.host.wsUrl(),\n token: () => this.host.accessToken(),\n device: () => device,\n onEvent: (e) => this.zone.run(() => void this.onEvent(e)),\n onResync: () => this.zone.run(() => void this.resync()),\n });\n this.socket.start();\n });\n }\n\n // ---- people and previews ----\n\n private async loadPeople(ids: string[]): Promise<void> {\n const have = this.people();\n const missing = [...new Set(ids)].filter((id) => !have[id]);\n if (!missing.length) return;\n try {\n const got = await this.api.people(missing);\n this.people.update((p) => ({ ...p, ...Object.fromEntries(got.map((x) => [x.userId, x])) }));\n } catch {\n // names fall back to \"Someone\"\n }\n }\n\n private async loadPreviews(convs: Conversation[]): Promise<void> {\n let machine: E2eeMachine;\n try {\n machine = await this.ensureMachine();\n } catch {\n return;\n }\n const want = convs.filter((c) => c.lastMessageId && this.previews()[c.id + '|' + c.lastMessageId] === undefined).slice(0, PREVIEW_LIMIT);\n await Promise.all(\n want.map(async (c) => {\n try {\n const page = await this.api.messages(c.id, undefined, 1);\n const m = page.items[0];\n if (!m) return;\n const o = await machine.decrypt(m);\n const line = o.ok ? previewText(o.kind, o.text) : 'Encrypted message';\n const mine = m.senderId === this.me();\n this.previews.update((p) => ({ ...p, [c.id + '|' + c.lastMessageId]: (mine ? 'You: ' : '') + line }));\n } catch {\n // no preview\n }\n }),\n );\n }\n\n preview(c: Conversation): string {\n if (!c.lastMessageId) return 'No messages yet';\n return this.previews()[c.id + '|' + c.lastMessageId] ?? '';\n }\n\n // ---- threads ----\n\n thread(id: string): WritableSignal<Thread> {\n let t = this.threads.get(id);\n if (!t) {\n t = signal<Thread>({ conv: this.known(id), items: [], loading: true, failed: false, missing: false });\n this.threads.set(id, t);\n }\n return t;\n }\n\n private known(id: string): Conversation | null {\n return this.inbox().find((c) => c.id === id) ?? this.requests().find((c) => c.id === id) ?? null;\n }\n\n /** Loads a conversation and its newest messages, decrypted. */\n async openThread(id: string): Promise<void> {\n const t = this.thread(id);\n t.update((s) => ({ ...s, loading: true, failed: false }));\n try {\n const [conv, page] = await Promise.all([this.api.conversation(id), this.api.messages(id)]);\n void this.loadPeople(conv.members.map((m) => m.userId));\n const items = await this.open(page.items.slice().reverse());\n t.set({ conv, items: this.keepPending(t().items, items), next: page.next, loading: false, failed: false, missing: false });\n this.markRead(conv, items);\n } catch (e) {\n const status = (e as { status?: number }).status;\n t.update((s) => ({ ...s, loading: false, failed: status !== 404, missing: status === 404 }));\n }\n }\n\n async loadOlder(id: string): Promise<void> {\n const t = this.thread(id);\n const s = t();\n if (!s.next || s.loading) return;\n t.update((x) => ({ ...x, loading: true }));\n try {\n const page = await this.api.messages(id, s.next);\n const older = await this.open(page.items.slice().reverse());\n t.update((x) => ({ ...x, items: [...older, ...x.items], next: page.next, loading: false }));\n } catch {\n t.update((x) => ({ ...x, loading: false }));\n }\n }\n\n /** Pending sends survive a reload of the thread. */\n private keepPending(before: Bubble[], now: Bubble[]): Bubble[] {\n const sent = new Set(now.map((b) => b.sealed?.clientMsgId));\n return [...now, ...before.filter((b) => (b.state === 'pending' || b.state === 'failed') && !sent.has(b.clientMsgId))];\n }\n\n private async open(msgs: Message[]): Promise<Bubble[]> {\n let machine: E2eeMachine | null = null;\n try {\n machine = await this.ensureMachine();\n } catch {\n // shown as unreadable until encryption starts\n }\n const me = this.me();\n const out: Bubble[] = [];\n for (const m of msgs) {\n const o: Opened = machine ? await machine.decrypt(m) : { ok: false, reason: 'missing-key' };\n out.push({\n id: m.id,\n senderId: m.senderId,\n mine: m.senderId === me,\n kind: o.ok ? o.kind : m.kind,\n text: o.ok ? o.text : unreadableText(o.reason),\n state: o.ok ? 'ok' : 'unreadable',\n unreadable: o.ok ? undefined : o.reason,\n createdAt: m.createdAt,\n sealed: m,\n });\n }\n return out;\n }\n\n private markRead(conv: Conversation, items: Bubble[]): void {\n const last = [...items].reverse().find((b) => b.state !== 'pending' && b.state !== 'failed');\n if (!last || conv.myState !== 'active') return;\n const mine = conv.members.find((m) => m.userId === this.me());\n if (mine?.lastReadMessageId === last.id && !conv.unread) return;\n void this.api.markRead(conv.id, last.id).then(() => {\n this.inbox.update((l) => l.map((c) => (c.id === conv.id ? { ...c, unread: 0 } : c)));\n }, () => undefined);\n }\n\n // ---- sending ----\n\n async send(id: string, text: string): Promise<void> {\n const body = text.trim();\n if (!body) return;\n const t = this.thread(id);\n const conv = t().conv;\n if (!conv) return;\n const clientMsgId = 'c_' + randomHex(12);\n const bubble: Bubble = { id: clientMsgId, clientMsgId, senderId: this.me() ?? '', mine: true, kind: 'text', text: body, state: 'pending', createdAt: new Date().toISOString(), outgoing: { kind: 'text', text: body } };\n t.update((s) => ({ ...s, items: [...s.items, bubble] }));\n await this.deliver(id, bubble);\n }\n\n retry(id: string, b: Bubble): Promise<void> {\n this.thread(id).update((s) => ({ ...s, items: s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, state: 'pending' as const, error: undefined } : x)) }));\n return this.deliver(id, b);\n }\n\n private async deliver(id: string, b: Bubble): Promise<void> {\n const t = this.thread(id);\n const patch = (p: Partial<Bubble>) => t.update((s) => ({ ...s, items: s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, ...p } : x)) }));\n let body = b.outgoing?.body;\n try {\n if (!body) {\n // fresh members and epoch: someone added a moment ago must get this session's key\n const conv = await this.api.conversation(id);\n t.update((s) => ({ ...s, conv }));\n const machine = await this.ensureMachine();\n const enc = await machine.encrypt(keysOf(conv), { kind: b.outgoing?.kind ?? 'text', text: b.outgoing?.text ?? b.text });\n body = { clientMsgId: b.clientMsgId!, kind: b.outgoing?.kind ?? 'text', ...enc };\n patch({ outgoing: { ...b.outgoing!, body } });\n }\n const sent = await this.api.sendMessage(id, body);\n // the push for it may have arrived first\n t.update((s) => {\n const already = s.items.some((x) => x.id === sent.id && x.clientMsgId !== b.clientMsgId);\n const items = already\n ? s.items.filter((x) => x.clientMsgId !== b.clientMsgId)\n : s.items.map((x) => (x.clientMsgId === b.clientMsgId ? { ...x, id: sent.id, state: 'ok' as const, sealed: sent, createdAt: sent.createdAt, outgoing: undefined } : x));\n return { ...s, items };\n });\n this.bump(id, sent.id, 'You: ' + previewText(body.kind, b.outgoing?.text ?? b.text));\n } catch (e) {\n const code = errorCode(e);\n patch({ state: 'failed', error: code === 'cant_message' ? \"You can't message this person.\" : this.crypto() === 'failed' ? \"Messages can't be encrypted in this browser.\" : errorText(e, 'Not sent.') });\n }\n }\n\n private bump(id: string, messageId: string, line: string): void {\n const now = new Date().toISOString();\n this.previews.update((p) => ({ ...p, [id + '|' + messageId]: line }));\n this.inbox.update((l) => {\n const c = l.find((x) => x.id === id);\n if (!c) return l;\n return [{ ...c, lastMessageId: messageId, lastMessageAt: now }, ...l.filter((x) => x.id !== id)];\n });\n }\n\n /** Starts (or finds) the direct conversation with someone. */\n async startDirect(userId: string): Promise<Conversation> {\n const c = await this.api.startDirect(userId);\n if (!this.inbox().some((x) => x.id === c.id)) this.inbox.update((l) => [c, ...l]);\n this.thread(c.id).update((s) => ({ ...s, conv: c }));\n void this.loadPeople(c.members.map((m) => m.userId));\n return c;\n }\n\n // ---- requests ----\n\n async accept(id: string): Promise<void> {\n const c = await this.api.accept(id);\n this.requests.update((l) => l.filter((x) => x.id !== id));\n this.inbox.update((l) => [c, ...l.filter((x) => x.id !== id)]);\n this.thread(id).update((s) => ({ ...s, conv: c }));\n }\n\n async decline(id: string): Promise<void> {\n await this.api.decline(id);\n this.requests.update((l) => l.filter((x) => x.id !== id));\n this.threads.delete(id);\n }\n\n // ---- typing ----\n\n typed(id: string): void {\n const now = Date.now();\n if (now - (this.lastTypingSent.get(id) ?? 0) < 4000) return;\n this.lastTypingSent.set(id, now);\n void this.api.typing(id).catch(() => undefined);\n }\n\n // ---- live ----\n\n private async onEvent(e: DmEvent): Promise<void> {\n const conv = typeof e.d?.['conversationId'] === 'string' ? (e.d['conversationId'] as string) : undefined;\n switch (e.t) {\n case 'message':\n if (conv) {\n // their message is here: they've stopped typing\n this.typing.update((t) => { const { [conv]: _, ...rest } = t; return rest; });\n await this.newer(conv);\n }\n this.refreshSoon();\n break;\n case 'to-device':\n await this.keysArrived();\n break;\n case 'membership':\n (await this.machine)?.forgetDevices();\n if (conv) await this.reloadConversation(conv);\n this.refreshSoon();\n break;\n case 'receipt':\n if (conv && e.d?.['userId'] !== this.me()) await this.reloadConversation(conv);\n break;\n case 'typing': {\n const who = e.d?.['userId'];\n if (!conv || typeof who !== 'string' || who === this.me()) break;\n this.typing.update((t) => ({ ...t, [conv]: who }));\n clearTimeout(this.typingTimers.get(conv));\n this.typingTimers.set(conv, setTimeout(() => this.typing.update((t) => { const { [conv]: _, ...rest } = t; return rest; }), 5000));\n break;\n }\n }\n }\n\n /** New messages in a loaded thread. */\n private async newer(id: string): Promise<void> {\n const t = this.threads.get(id);\n if (!t || t().loading && !t().items.length) return;\n try {\n const page = await this.api.messages(id, undefined, 20);\n const have = new Set(t().items.map((b) => b.id));\n const fresh = await this.open(page.items.filter((m) => !have.has(m.id)).reverse());\n if (!fresh.length) return;\n t.update((s) => {\n const byClient = new Map(fresh.filter((f) => f.mine).map((f) => [f.sealed?.clientMsgId, f]));\n const items = s.items.filter((b) => !(b.clientMsgId && byClient.has(b.clientMsgId)));\n const insertAt = items.findIndex((b) => b.state === 'pending' || b.state === 'failed');\n if (insertAt < 0) return { ...s, items: [...items, ...fresh] };\n return { ...s, items: [...items.slice(0, insertAt), ...fresh, ...items.slice(insertAt)] };\n });\n const c = t().conv;\n if (c) this.markRead(c, t().items);\n } catch {\n // the next event or a reload catches up\n }\n }\n\n /** Room keys arrived: messages that couldn't be read may open now. */\n private async keysArrived(): Promise<void> {\n const m = await this.machine?.catch(() => null);\n if (!m) return;\n await m.sync().catch(() => 0);\n for (const t of this.threads.values()) {\n if (!t().items.some((b) => b.state === 'unreadable')) continue;\n const items = await Promise.all(\n t().items.map(async (b) => {\n if (b.state !== 'unreadable' || !b.sealed) return b;\n const o = await m.decrypt(b.sealed);\n return o.ok ? { ...b, state: 'ok' as const, unreadable: undefined, kind: o.kind, text: o.text } : b;\n }),\n );\n t.update((s) => ({ ...s, items }));\n }\n void this.loadPreviews([...this.requests(), ...this.inbox()]);\n }\n\n private async reloadConversation(id: string): Promise<void> {\n const t = this.threads.get(id);\n if (!t) return;\n try {\n const conv = await this.api.conversation(id);\n t.update((s) => ({ ...s, conv }));\n } catch {\n // keep what we have\n }\n }\n\n private async resync(): Promise<void> {\n await this.loadLists();\n await this.keysArrived();\n for (const id of this.threads.keys()) await this.newer(id);\n }\n\n private refreshSoon(): void {\n if (this.refreshTimer) return;\n this.refreshTimer = setTimeout(() => {\n this.refreshTimer = null;\n void this.loadLists();\n }, 400);\n }\n}\n\n/** What the encryption needs to know about a conversation. */\nexport function keysOf(c: Conversation): ConversationKeys {\n return { id: c.id, epoch: c.epoch, members: c.members.map((m) => ({ userId: m.userId, state: m.state })) };\n}\n\nfunction randomHex(n: number): string {\n const b = new Uint8Array(Math.ceil(n / 2));\n crypto.getRandomValues(b);\n return [...b].map((x) => x.toString(16).padStart(2, '0')).join('').slice(0, n);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, viewChild, signal, computed, effect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { Router, ActivatedRoute } from '@angular/router';
4
4
  import { ToastService, hueOf, initials, timeAgo } from '@chisquare-tech/yan-ngx-ui';
5
- import { M as MessagesStore, a as MESSAGES_HOST, E as E2EE_LABEL, r as requestsLine, s as seen, p as pendingFor, b as personName, c as conversationName, k as kindLabel, o as others, e as expiresIn, d as errorText } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BtQC73sF.mjs';
5
+ import { M as MessagesStore, a as MESSAGES_HOST, E as E2EE_LABEL, r as requestsLine, s as seen, p as pendingFor, b as personName, c as conversationName, k as kindLabel, o as others, e as expiresIn, d as errorText } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BYCxC81Q.mjs';
6
6
 
7
7
  /** The prototype's Messages layout (prototype.css .msg-list, .pane, .thread-head, .composer) on yan-design. */
8
8
  const MESSAGES_STYLES = `
@@ -190,7 +190,8 @@ class MessagesPage {
190
190
  async send() {
191
191
  const id = this.sel();
192
192
  const text = this.draft().trim();
193
- if (!id || id === 'requests' || !text || this.store.crypto() === 'starting')
193
+ // while encryption is still starting, the message waits as pending: the store sends it once it's ready
194
+ if (!id || id === 'requests' || !text)
194
195
  return;
195
196
  this.draft.set('');
196
197
  this.atBottom = true;
@@ -355,7 +356,7 @@ class MessagesPage {
355
356
  @if (pending(); as note) {<div class="yan-msgs__cap yan-msgs__note">{{ note }}</div>}
356
357
  <form class="yan-msgs__composer" (submit)="$event.preventDefault(); send()">
357
358
  <input class="yan-input" [value]="draft()" (input)="onDraft($event)" [placeholder]="placeholder()" [attr.aria-label]="placeholder()" maxlength="4000" autocomplete="off" />
358
- <button type="submit" class="yan-btn yan-btn--accent" aria-label="Send" [attr.aria-disabled]="!draft().trim() || store.crypto() === 'starting'"><span class="yi yi-send" style="--yi:18px" aria-hidden="true"></span></button>
359
+ <button type="submit" class="yan-btn yan-btn--accent" aria-label="Send" [attr.aria-disabled]="!draft().trim()"><span class="yi yi-send" style="--yi:18px" aria-hidden="true"></span></button>
359
360
  </form>
360
361
  }
361
362
  }
@@ -484,7 +485,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
484
485
  @if (pending(); as note) {<div class="yan-msgs__cap yan-msgs__note">{{ note }}</div>}
485
486
  <form class="yan-msgs__composer" (submit)="$event.preventDefault(); send()">
486
487
  <input class="yan-input" [value]="draft()" (input)="onDraft($event)" [placeholder]="placeholder()" [attr.aria-label]="placeholder()" maxlength="4000" autocomplete="off" />
487
- <button type="submit" class="yan-btn yan-btn--accent" aria-label="Send" [attr.aria-disabled]="!draft().trim() || store.crypto() === 'starting'"><span class="yi yi-send" style="--yi:18px" aria-hidden="true"></span></button>
488
+ <button type="submit" class="yan-btn yan-btn--accent" aria-label="Send" [attr.aria-disabled]="!draft().trim()"><span class="yi yi-send" style="--yi:18px" aria-hidden="true"></span></button>
488
489
  </form>
489
490
  }
490
491
  }
@@ -498,4 +499,4 @@ function firstName(n) {
498
499
  }
499
500
 
500
501
  export { MessagesPage };
501
- //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-messages.page-L0fDp0gv.mjs.map
502
+ //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-messages.page-Dy0RhQwj.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-messages.page-L0fDp0gv.mjs","sources":["../../../projects/messages/src/lib/styles.ts","../../../projects/messages/src/lib/messages.page.ts"],"sourcesContent":["/** The prototype's Messages layout (prototype.css .msg-list, .pane, .thread-head, .composer) on yan-design. */\nexport const MESSAGES_STYLES = `\n /* Messages fills the shell's main area: no content column, and the thread scrolls inside it */\n .yan-shell__scroller:has(> .yan-shell__col > yan-messages-page) { overflow: hidden; }\n .yan-shell__col:has(> yan-messages-page) { max-width: none; padding: 0; height: 100%; }\n yan-messages-page { display: block; height: 100%; }\n\n .yan-msgs { display: flex; height: 100%; }\n .yan-msgs__list { flex: none; width: 100%; overflow-y: auto; }\n .yan-msgs__pane { flex: 1; min-width: 0; display: none; flex-direction: column; }\n .yan-msgs--open .yan-msgs__list { display: none; }\n .yan-msgs--open .yan-msgs__pane { display: flex; }\n @media (min-width: 820px) {\n .yan-msgs__list { width: 340px; border-right: 1px solid var(--yan-color-border-default); }\n .yan-msgs--open .yan-msgs__list { display: block; }\n .yan-msgs__pane { display: flex; }\n .yan-msgs__back { display: none; }\n }\n\n .yan-msgs__title { font: var(--yan-text-title-lg); letter-spacing: var(--yan-text-title-lg-tracking); font-size: 22px; padding: 18px 16px 10px; margin: 0; }\n .yan-msgs__row { padding: 12px 16px; font: inherit; }\n .yan-msgs__line { display: flex; align-items: center; gap: 6px; min-width: 0; }\n .yan-msgs__name { font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .yan-msgs__last { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .yan-msgs__empty, .yan-msgs__err { margin: 16px; }\n .yan-msgs__sk1 { display: block; height: 12px; width: 40%; border-radius: 6px; margin-bottom: 6px; }\n .yan-msgs__sk2 { display: block; height: 10px; width: 70%; border-radius: 6px; }\n\n .yan-msgs__head { flex: none; display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--yan-color-border-default); }\n .yan-msgs__headname { font-weight: 600; }\n .yan-msgs__grow { flex: 1; min-width: 0; }\n .yan-msgs__scroll { flex: 1; min-height: 0; overflow-y: auto; }\n .yan-msgs__placeholder { margin: auto; max-width: 360px; padding: 24px; }\n .yan-msgs__older { align-self: center; }\n .yan-msgs__start { align-self: center; text-align: center; max-width: 360px; }\n .yan-msgs__lost { align-self: center; text-align: center; max-width: 420px; }\n .yan-msgs__from { font: var(--yan-text-micro); color: var(--yan-color-ink-muted); margin: 4px 0 -6px 4px; }\n .yan-msgs__unreadable { font-style: italic; color: var(--yan-color-ink-muted); }\n .yan-bubble--me.yan-msgs__unreadable { color: var(--yan-color-accent-on-accent); opacity: 0.8; }\n .yan-msgs__pending { opacity: 0.6; }\n .yan-msgs__failed { align-self: flex-end; font: var(--yan-text-caption); color: var(--yan-color-danger-default); margin-top: -6px; }\n .yan-msgs__seen { align-self: flex-end; font: var(--yan-text-micro); color: var(--yan-color-ink-muted); margin-top: -6px; }\n .yan-msgs__typing { align-self: flex-start; }\n .yan-msgs__skb { width: 50%; height: 36px; }\n .yan-msgs__cap { font: var(--yan-text-caption); color: var(--yan-color-ink-muted); }\n .yan-msgs__note { flex: none; padding: 8px 16px 0; }\n .yan-msgs__banner { flex: none; margin: 8px 16px 0; }\n .yan-msgs__reqbar { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--yan-color-border-default); }\n .yan-msgs__reqtext { display: block; width: 100%; margin: 10px 0; padding: 0; border: 0; background: none; text-align: left; font: inherit; color: inherit; cursor: pointer; overflow-wrap: anywhere; }\n .yan-msgs__reqacts { margin-top: 10px; }\n .yan-msgs__composer { flex: none; display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--yan-color-border-default); }\n .yan-msgs__composer .yan-input { flex: 1; min-width: 0; border-radius: var(--yan-radius-pill); }\n`;\n","import { ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, ViewEncapsulation, computed, effect, inject, signal, viewChild } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { ToastService, hueOf, initials, timeAgo } from '@chisquare-tech/yan-ngx-ui';\nimport { Subscription } from 'rxjs';\nimport { E2EE_LABEL, conversationName, expiresIn, kindLabel, others, pendingFor, personName, requestsLine, seen } from './labels';\nimport { errorText, type Conversation } from './messaging-api';\nimport { MessagesStore, type Bubble } from './messages.store';\nimport { MESSAGES_HOST } from './tokens';\nimport { MESSAGES_STYLES } from './styles';\n\n/**\n * `/messages`, `/messages/requests`, `/messages/:id`: the prototype's Messages screen. The list (Requests first, then\n * conversations) and the open thread side by side from 820 px; below that, push navigation. Every DM and group is\n * end-to-end encrypted on this device.\n */\n@Component({\n selector: 'yan-messages-page',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n styles: MESSAGES_STYLES,\n template: `\n <div class=\"yan-msgs\" [class.yan-msgs--open]=\"!!sel()\">\n <div class=\"yan-msgs__list\" [attr.aria-hidden]=\"null\">\n <h1 class=\"yan-msgs__title\">Messages</h1>\n @if (!signedIn()) {\n <div class=\"yan-empty yan-msgs__empty\">\n <span class=\"yi yi-messages\" style=\"--yi:28px\" aria-hidden=\"true\"></span>\n <div class=\"yan-empty__title\">Sign in to message people</div>\n <div>Direct messages and groups are end-to-end encrypted.</div>\n <button type=\"button\" class=\"yan-btn\" (click)=\"signIn()\">Sign in</button>\n </div>\n } @else if (store.failed() && !store.loaded()) {\n <div class=\"yan-error yan-msgs__err\" role=\"alert\"><span class=\"yi yi-alert-circle\" style=\"--yi:14px\" aria-hidden=\"true\"></span>We couldn't load your messages. <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--ghost\" (click)=\"store.loadLists()\">Try again</button></div>\n } @else if (!store.loaded()) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"yan-row yan-msgs__row\" aria-hidden=\"true\"><span class=\"yan-avatar yan-avatar--lg yan-skeleton\"></span><span class=\"yan-row__body\"><span class=\"yan-skeleton yan-msgs__sk1\"></span><span class=\"yan-skeleton yan-msgs__sk2\"></span></span></div>\n }\n } @else {\n <button type=\"button\" class=\"yan-row yan-row--interactive yan-msgs__row\" [class.yan-row--selected]=\"sel() === 'requests'\" (click)=\"go(['requests'])\">\n <span class=\"yan-avatar yan-avatar--lg yan-avatar--square\" style=\"--yan-avatar-hue:80\"><span class=\"yi yi-inbox\" aria-hidden=\"true\"></span></span>\n <span class=\"yan-row__body\">\n <span class=\"yan-msgs__line\"><b class=\"yan-msgs__name\">Requests</b><span class=\"yan-eyebrow\">Outside your network</span>@if (store.requests().length) {<span class=\"yan-badge\">{{ store.requests().length }}</span>}</span>\n <span class=\"yan-row__sub yan-msgs__last\">{{ requestsSub() }}</span>\n </span>\n </button>\n @for (c of store.inbox(); track c.id) {\n <button type=\"button\" class=\"yan-row yan-row--interactive yan-msgs__row\" [class.yan-row--selected]=\"sel() === c.id\" (click)=\"go([c.id])\">\n <span class=\"yan-avatar yan-avatar--lg\" [class.yan-avatar--square]=\"c.kind === 'group'\" [style.--yan-avatar-hue]=\"hueFor(c)\">{{ initialFor(c) }}</span>\n <span class=\"yan-row__body\">\n <span class=\"yan-msgs__line\"><b class=\"yan-msgs__name\">{{ name(c) }}</b><span class=\"yan-eyebrow\">{{ kind(c) }}</span>@if (c.unread) {<span class=\"yan-badge\" [attr.aria-label]=\"c.unread + ' unread'\">{{ c.unread }}</span>}</span>\n <span class=\"yan-row__sub yan-msgs__last\">{{ typingIn(c) || store.preview(c) }}</span>\n </span>\n </button>\n } @empty {\n <div class=\"yan-empty yan-msgs__empty\">\n <span class=\"yi yi-messages\" style=\"--yi:28px\" aria-hidden=\"true\"></span>\n <div class=\"yan-empty__title\">No messages yet</div>\n <div>Message someone from their profile. People outside your network see it under Requests first.</div>\n </div>\n }\n }\n </div>\n\n <div class=\"yan-msgs__pane\">\n @if (!sel()) {\n <div class=\"yan-empty yan-msgs__placeholder\">\n <span class=\"yi yi-shield-lock\" style=\"--yi:28px\" aria-hidden=\"true\"></span>\n <div class=\"yan-empty__title\">Your messages</div>\n <div>Pick a conversation. Only the people in it can read it, on their devices.</div>\n </div>\n } @else if (sel() === 'requests') {\n <div class=\"yan-msgs__head\">\n <button type=\"button\" class=\"yan-icon-btn yan-icon-btn--plain yan-msgs__back\" (click)=\"go([])\" aria-label=\"Back to messages\"><span class=\"yi yi-arrow-left\" aria-hidden=\"true\"></span></button>\n <div class=\"yan-msgs__grow\"><div class=\"yan-msgs__headname\">Requests</div><span class=\"yan-security yan-security--server\"><span class=\"yi yi-inbox\" style=\"--yi:14px\" aria-hidden=\"true\"></span>Requests from outside your network</span></div>\n </div>\n <div class=\"yan-thread yan-msgs__scroll\">\n @for (r of store.requests(); track r.id) {\n <div class=\"yan-card yan-card--tight\">\n <div class=\"yan-msgs__line\"><span class=\"yan-avatar\" [style.--yan-avatar-hue]=\"hueFor(r)\">{{ initialFor(r) }}</span><div class=\"yan-msgs__grow\"><b>{{ name(r) }}</b><div class=\"yan-msgs__cap\">Not in your network · {{ ago(r.lastMessageAt || r.createdAt) }} · {{ expires(r) }}</div></div></div>\n <button type=\"button\" class=\"yan-msgs__reqtext\" (click)=\"go([r.id])\">{{ store.preview(r) || 'Open to read' }}</button>\n <div class=\"yan-cluster yan-msgs__reqacts\">\n <button type=\"button\" class=\"yan-btn yan-btn--sm\" [attr.aria-disabled]=\"busy()\" (click)=\"accept(r)\">Accept</button>\n <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--secondary\" [attr.aria-disabled]=\"busy()\" (click)=\"decline(r)\">Decline</button>\n </div>\n </div>\n } @empty {\n <div class=\"yan-empty\"><span class=\"yi yi-inbox\" style=\"--yi:28px\" aria-hidden=\"true\"></span><div class=\"yan-empty__title\">No requests</div><div>Messages from people outside your network land here first.</div></div>\n }\n </div>\n } @else {\n @let t = thread();\n <div class=\"yan-msgs__head\">\n <button type=\"button\" class=\"yan-icon-btn yan-icon-btn--plain yan-msgs__back\" (click)=\"go(t.conv?.myState === 'request' ? ['requests'] : [])\" aria-label=\"Back to messages\"><span class=\"yi yi-arrow-left\" aria-hidden=\"true\"></span></button>\n <div class=\"yan-msgs__grow\">\n <div class=\"yan-msgs__headname\">{{ t.conv ? name(t.conv) : '' }}</div>\n <span class=\"yan-security {{ e2ee.cls }}\"><span class=\"yi yi-{{ e2ee.icon }}\" style=\"--yi:14px\" aria-hidden=\"true\"></span>{{ e2ee.text }}</span>\n </div>\n </div>\n @if (t.missing) {\n <div class=\"yan-empty yan-msgs__placeholder\"><span class=\"yi yi-messages\" style=\"--yi:28px\" aria-hidden=\"true\"></span><div class=\"yan-empty__title\">This conversation isn't available</div><div>It may have been declined, or you left it.</div></div>\n } @else {\n <div class=\"yan-thread yan-msgs__scroll\" #scroller (scroll)=\"onScroll()\">\n @if (t.next) {\n <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--ghost yan-msgs__older\" [attr.aria-disabled]=\"t.loading\" (click)=\"store.loadOlder(sel()!)\">Earlier messages</button>\n }\n @if (t.failed) {\n <div class=\"yan-error\" role=\"alert\"><span class=\"yi yi-alert-circle\" style=\"--yi:14px\" aria-hidden=\"true\"></span>We couldn't load this conversation. <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--ghost\" (click)=\"reload()\">Try again</button></div>\n } @else if (t.loading && !t.items.length) {\n <div class=\"yan-bubble yan-skeleton yan-msgs__skb\" aria-hidden=\"true\"></div>\n <div class=\"yan-bubble yan-bubble--me yan-skeleton yan-msgs__skb\" aria-hidden=\"true\"></div>\n } @else if (!t.items.length) {\n <div class=\"yan-msgs__cap yan-msgs__start\">Messages here are end-to-end encrypted. Only the people in this conversation can read them.</div>\n } @else if (hasUnreadable()) {\n <div class=\"yan-msgs__cap yan-msgs__lost\">Messages sent before you set up this device can't be read here. They're still on the devices you had then.</div>\n }\n @for (m of t.items; track m.clientMsgId || m.id) {\n @if (showSender(m, $index)) {<div class=\"yan-msgs__from\">{{ who(m.senderId) }}</div>}\n <div class=\"yan-bubble\" [class.yan-bubble--me]=\"m.mine\" [class.yan-msgs__unreadable]=\"m.state === 'unreadable'\" [class.yan-msgs__pending]=\"m.state === 'pending'\">{{ m.text }}</div>\n @if (m.state === 'failed') {\n <div class=\"yan-msgs__failed\" role=\"alert\">{{ m.error || 'Not sent.' }} <button type=\"button\" class=\"yan-btn yan-btn--link yan-btn--sm\" (click)=\"store.retry(sel()!, m)\">Try again</button></div>\n } @else if (m.id === seenOn()) {\n <div class=\"yan-msgs__seen\">Seen</div>\n }\n }\n @if (typingName(); as tn) {<div class=\"yan-msgs__cap yan-msgs__typing\" aria-live=\"polite\">{{ tn }} is typing…</div>}\n </div>\n @if (store.crypto() === 'failed') {\n <div class=\"yan-banner yan-banner--warning yan-msgs__banner\" role=\"alert\"><span class=\"yi yi-alert-triangle\" aria-hidden=\"true\"></span>Messages can't be set up in this browser: it needs storage and WebAssembly, which some private windows block. <button type=\"button\" class=\"yan-btn yan-btn--sm\" (click)=\"store.retryCrypto()\">Try again</button></div>\n }\n @if (t.conv?.myState === 'request') {\n <div class=\"yan-msgs__reqbar\">\n <div class=\"yan-msgs__cap\">{{ name(t.conv!) }} isn't in your network. Accept to reply; decline and it's removed. {{ expires(t.conv!) }}.</div>\n <div class=\"yan-cluster\"><button type=\"button\" class=\"yan-btn yan-btn--sm\" [attr.aria-disabled]=\"busy()\" (click)=\"accept(t.conv!)\">Accept</button><button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--secondary\" [attr.aria-disabled]=\"busy()\" (click)=\"decline(t.conv!)\">Decline</button></div>\n </div>\n } @else if (t.conv) {\n @if (pending(); as note) {<div class=\"yan-msgs__cap yan-msgs__note\">{{ note }}</div>}\n <form class=\"yan-msgs__composer\" (submit)=\"$event.preventDefault(); send()\">\n <input class=\"yan-input\" [value]=\"draft()\" (input)=\"onDraft($event)\" [placeholder]=\"placeholder()\" [attr.aria-label]=\"placeholder()\" maxlength=\"4000\" autocomplete=\"off\" />\n <button type=\"submit\" class=\"yan-btn yan-btn--accent\" aria-label=\"Send\" [attr.aria-disabled]=\"!draft().trim() || store.crypto() === 'starting'\"><span class=\"yi yi-send\" style=\"--yi:18px\" aria-hidden=\"true\"></span></button>\n </form>\n }\n }\n }\n </div>\n </div>\n `,\n})\nexport class MessagesPage implements OnInit, OnDestroy {\n protected readonly store = inject(MessagesStore);\n private readonly host = inject(MESSAGES_HOST);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly toast = inject(ToastService);\n private sub?: Subscription;\n private readonly scroller = viewChild<ElementRef<HTMLElement>>('scroller');\n private atBottom = true;\n\n protected readonly e2ee = E2EE_LABEL;\n readonly sel = signal<string | null>(null);\n readonly draft = signal('');\n readonly busy = signal(false);\n readonly signedIn = signal(false);\n\n readonly thread = computed(() => {\n const id = this.sel();\n return id && id !== 'requests' ? this.store.thread(id)() : { conv: null, items: [] as Bubble[], loading: false, failed: false, missing: false };\n });\n\n readonly requestsSub = computed(() => {\n const r = this.store.requests();\n return requestsLine(r.length, r[0] ? this.name(r[0]) : undefined);\n });\n\n /** The message that carries \"Seen\": your last one, once everyone else has read it. */\n readonly seenOn = computed(() => {\n const t = this.thread();\n const me = this.store.me();\n if (!t.conv || !me) return null;\n const ok = t.items.filter((b) => b.state === 'ok' || b.state === 'unreadable');\n const lastMine = [...ok].reverse().find((b) => b.mine)?.id;\n return seen(t.conv, me, ok.map((b) => b.id), lastMine) ? lastMine! : null;\n });\n\n readonly hasUnreadable = computed(() => this.thread().items.some((b) => b.state === 'unreadable' && b.unreadable === 'missing-key'));\n\n readonly pending = computed(() => {\n const t = this.thread();\n const me = this.store.me();\n return t.conv && me ? pendingFor(t.conv, me, this.store.people()) : null;\n });\n\n readonly typingName = computed(() => {\n const id = this.sel();\n const who = id ? this.store.typing()[id] : undefined;\n return who ? personName(this.store.people()[who]) : null;\n });\n\n readonly placeholder = computed(() => {\n const c = this.thread().conv;\n if (!c) return 'Message';\n return c.kind === 'group' ? 'Message group' : `Message ${firstName(this.name(c))}`;\n });\n\n constructor() {\n // keep the newest message in view as messages arrive, unless you've scrolled up to read\n effect(() => {\n const n = this.thread().items.length;\n if (!n) return;\n queueMicrotask(() => requestAnimationFrame(() => this.toBottom()));\n });\n }\n\n ngOnInit(): void {\n this.signedIn.set(!!this.store.me());\n if (this.signedIn()) void this.store.start();\n this.sub = this.route.paramMap.subscribe((p) => {\n const id = p.get('id') ?? (this.route.snapshot.url.at(-1)?.path === 'requests' ? 'requests' : null);\n this.sel.set(id);\n this.draft.set('');\n this.atBottom = true;\n if (id && id !== 'requests' && this.signedIn()) void this.store.openThread(id);\n });\n }\n\n ngOnDestroy(): void {\n this.sub?.unsubscribe();\n }\n\n go(path: string[]): void {\n void this.router.navigate(['/messages', ...path]);\n }\n\n signIn(): void {\n this.host.requestSignIn(this.router.url);\n }\n\n reload(): void {\n const id = this.sel();\n if (id && id !== 'requests') void this.store.openThread(id);\n }\n\n name(c: Conversation): string {\n return conversationName(c, this.store.me() ?? '', this.store.people());\n }\n\n kind(c: Conversation): string {\n return kindLabel(c);\n }\n\n who(userId: string): string {\n return personName(this.store.people()[userId]);\n }\n\n hueFor(c: Conversation): number {\n const o = others(c, this.store.me() ?? '');\n return c.kind === 'direct' && o[0] ? hueOf(o[0].userId) : hueOf(c.id);\n }\n\n initialFor(c: Conversation): string {\n return initials(this.name(c));\n }\n\n ago(iso: string): string {\n return timeAgo(iso);\n }\n\n expires(c: Conversation): string {\n return expiresIn(c.requestUntil);\n }\n\n typingIn(c: Conversation): string {\n const who = this.store.typing()[c.id];\n return who ? `${firstName(personName(this.store.people()[who]))} is typing…` : '';\n }\n\n /** Groups name the sender above a run of their messages. */\n showSender(m: Bubble, i: number): boolean {\n const t = this.thread();\n if (t.conv?.kind !== 'group' || m.mine) return false;\n const prev = t.items[i - 1];\n return !prev || prev.senderId !== m.senderId;\n }\n\n onDraft(e: Event): void {\n this.draft.set((e.target as HTMLInputElement).value);\n const id = this.sel();\n if (id && id !== 'requests' && this.draft().trim()) this.store.typed(id);\n }\n\n async send(): Promise<void> {\n const id = this.sel();\n const text = this.draft().trim();\n if (!id || id === 'requests' || !text || this.store.crypto() === 'starting') return;\n this.draft.set('');\n this.atBottom = true;\n await this.store.send(id, text);\n }\n\n async accept(c: Conversation): Promise<void> {\n if (this.busy()) return;\n this.busy.set(true);\n try {\n await this.store.accept(c.id);\n this.go([c.id]);\n } catch (e) {\n this.toast.show(errorText(e, \"Couldn't accept. Try again.\"));\n } finally {\n this.busy.set(false);\n }\n }\n\n async decline(c: Conversation): Promise<void> {\n if (this.busy()) return;\n this.busy.set(true);\n try {\n await this.store.decline(c.id);\n this.go(['requests']);\n } catch (e) {\n this.toast.show(errorText(e, \"Couldn't decline. Try again.\"));\n } finally {\n this.busy.set(false);\n }\n }\n\n onScroll(): void {\n const el = this.scroller()?.nativeElement;\n if (el) this.atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 80;\n }\n\n private toBottom(): void {\n const el = this.scroller()?.nativeElement;\n if (el && this.atBottom) el.scrollTop = el.scrollHeight;\n }\n}\n\nfunction firstName(n: string): string {\n return n.startsWith('@') ? n : n.split(' ')[0];\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-messages.page-Dy0RhQwj.mjs","sources":["../../../projects/messages/src/lib/styles.ts","../../../projects/messages/src/lib/messages.page.ts"],"sourcesContent":["/** The prototype's Messages layout (prototype.css .msg-list, .pane, .thread-head, .composer) on yan-design. */\nexport const MESSAGES_STYLES = `\n /* Messages fills the shell's main area: no content column, and the thread scrolls inside it */\n .yan-shell__scroller:has(> .yan-shell__col > yan-messages-page) { overflow: hidden; }\n .yan-shell__col:has(> yan-messages-page) { max-width: none; padding: 0; height: 100%; }\n yan-messages-page { display: block; height: 100%; }\n\n .yan-msgs { display: flex; height: 100%; }\n .yan-msgs__list { flex: none; width: 100%; overflow-y: auto; }\n .yan-msgs__pane { flex: 1; min-width: 0; display: none; flex-direction: column; }\n .yan-msgs--open .yan-msgs__list { display: none; }\n .yan-msgs--open .yan-msgs__pane { display: flex; }\n @media (min-width: 820px) {\n .yan-msgs__list { width: 340px; border-right: 1px solid var(--yan-color-border-default); }\n .yan-msgs--open .yan-msgs__list { display: block; }\n .yan-msgs__pane { display: flex; }\n .yan-msgs__back { display: none; }\n }\n\n .yan-msgs__title { font: var(--yan-text-title-lg); letter-spacing: var(--yan-text-title-lg-tracking); font-size: 22px; padding: 18px 16px 10px; margin: 0; }\n .yan-msgs__row { padding: 12px 16px; font: inherit; }\n .yan-msgs__line { display: flex; align-items: center; gap: 6px; min-width: 0; }\n .yan-msgs__name { font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .yan-msgs__last { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .yan-msgs__empty, .yan-msgs__err { margin: 16px; }\n .yan-msgs__sk1 { display: block; height: 12px; width: 40%; border-radius: 6px; margin-bottom: 6px; }\n .yan-msgs__sk2 { display: block; height: 10px; width: 70%; border-radius: 6px; }\n\n .yan-msgs__head { flex: none; display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--yan-color-border-default); }\n .yan-msgs__headname { font-weight: 600; }\n .yan-msgs__grow { flex: 1; min-width: 0; }\n .yan-msgs__scroll { flex: 1; min-height: 0; overflow-y: auto; }\n .yan-msgs__placeholder { margin: auto; max-width: 360px; padding: 24px; }\n .yan-msgs__older { align-self: center; }\n .yan-msgs__start { align-self: center; text-align: center; max-width: 360px; }\n .yan-msgs__lost { align-self: center; text-align: center; max-width: 420px; }\n .yan-msgs__from { font: var(--yan-text-micro); color: var(--yan-color-ink-muted); margin: 4px 0 -6px 4px; }\n .yan-msgs__unreadable { font-style: italic; color: var(--yan-color-ink-muted); }\n .yan-bubble--me.yan-msgs__unreadable { color: var(--yan-color-accent-on-accent); opacity: 0.8; }\n .yan-msgs__pending { opacity: 0.6; }\n .yan-msgs__failed { align-self: flex-end; font: var(--yan-text-caption); color: var(--yan-color-danger-default); margin-top: -6px; }\n .yan-msgs__seen { align-self: flex-end; font: var(--yan-text-micro); color: var(--yan-color-ink-muted); margin-top: -6px; }\n .yan-msgs__typing { align-self: flex-start; }\n .yan-msgs__skb { width: 50%; height: 36px; }\n .yan-msgs__cap { font: var(--yan-text-caption); color: var(--yan-color-ink-muted); }\n .yan-msgs__note { flex: none; padding: 8px 16px 0; }\n .yan-msgs__banner { flex: none; margin: 8px 16px 0; }\n .yan-msgs__reqbar { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--yan-color-border-default); }\n .yan-msgs__reqtext { display: block; width: 100%; margin: 10px 0; padding: 0; border: 0; background: none; text-align: left; font: inherit; color: inherit; cursor: pointer; overflow-wrap: anywhere; }\n .yan-msgs__reqacts { margin-top: 10px; }\n .yan-msgs__composer { flex: none; display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--yan-color-border-default); }\n .yan-msgs__composer .yan-input { flex: 1; min-width: 0; border-radius: var(--yan-radius-pill); }\n`;\n","import { ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, ViewEncapsulation, computed, effect, inject, signal, viewChild } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { ToastService, hueOf, initials, timeAgo } from '@chisquare-tech/yan-ngx-ui';\nimport { Subscription } from 'rxjs';\nimport { E2EE_LABEL, conversationName, expiresIn, kindLabel, others, pendingFor, personName, requestsLine, seen } from './labels';\nimport { errorText, type Conversation } from './messaging-api';\nimport { MessagesStore, type Bubble } from './messages.store';\nimport { MESSAGES_HOST } from './tokens';\nimport { MESSAGES_STYLES } from './styles';\n\n/**\n * `/messages`, `/messages/requests`, `/messages/:id`: the prototype's Messages screen. The list (Requests first, then\n * conversations) and the open thread side by side from 820 px; below that, push navigation. Every DM and group is\n * end-to-end encrypted on this device.\n */\n@Component({\n selector: 'yan-messages-page',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n styles: MESSAGES_STYLES,\n template: `\n <div class=\"yan-msgs\" [class.yan-msgs--open]=\"!!sel()\">\n <div class=\"yan-msgs__list\" [attr.aria-hidden]=\"null\">\n <h1 class=\"yan-msgs__title\">Messages</h1>\n @if (!signedIn()) {\n <div class=\"yan-empty yan-msgs__empty\">\n <span class=\"yi yi-messages\" style=\"--yi:28px\" aria-hidden=\"true\"></span>\n <div class=\"yan-empty__title\">Sign in to message people</div>\n <div>Direct messages and groups are end-to-end encrypted.</div>\n <button type=\"button\" class=\"yan-btn\" (click)=\"signIn()\">Sign in</button>\n </div>\n } @else if (store.failed() && !store.loaded()) {\n <div class=\"yan-error yan-msgs__err\" role=\"alert\"><span class=\"yi yi-alert-circle\" style=\"--yi:14px\" aria-hidden=\"true\"></span>We couldn't load your messages. <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--ghost\" (click)=\"store.loadLists()\">Try again</button></div>\n } @else if (!store.loaded()) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"yan-row yan-msgs__row\" aria-hidden=\"true\"><span class=\"yan-avatar yan-avatar--lg yan-skeleton\"></span><span class=\"yan-row__body\"><span class=\"yan-skeleton yan-msgs__sk1\"></span><span class=\"yan-skeleton yan-msgs__sk2\"></span></span></div>\n }\n } @else {\n <button type=\"button\" class=\"yan-row yan-row--interactive yan-msgs__row\" [class.yan-row--selected]=\"sel() === 'requests'\" (click)=\"go(['requests'])\">\n <span class=\"yan-avatar yan-avatar--lg yan-avatar--square\" style=\"--yan-avatar-hue:80\"><span class=\"yi yi-inbox\" aria-hidden=\"true\"></span></span>\n <span class=\"yan-row__body\">\n <span class=\"yan-msgs__line\"><b class=\"yan-msgs__name\">Requests</b><span class=\"yan-eyebrow\">Outside your network</span>@if (store.requests().length) {<span class=\"yan-badge\">{{ store.requests().length }}</span>}</span>\n <span class=\"yan-row__sub yan-msgs__last\">{{ requestsSub() }}</span>\n </span>\n </button>\n @for (c of store.inbox(); track c.id) {\n <button type=\"button\" class=\"yan-row yan-row--interactive yan-msgs__row\" [class.yan-row--selected]=\"sel() === c.id\" (click)=\"go([c.id])\">\n <span class=\"yan-avatar yan-avatar--lg\" [class.yan-avatar--square]=\"c.kind === 'group'\" [style.--yan-avatar-hue]=\"hueFor(c)\">{{ initialFor(c) }}</span>\n <span class=\"yan-row__body\">\n <span class=\"yan-msgs__line\"><b class=\"yan-msgs__name\">{{ name(c) }}</b><span class=\"yan-eyebrow\">{{ kind(c) }}</span>@if (c.unread) {<span class=\"yan-badge\" [attr.aria-label]=\"c.unread + ' unread'\">{{ c.unread }}</span>}</span>\n <span class=\"yan-row__sub yan-msgs__last\">{{ typingIn(c) || store.preview(c) }}</span>\n </span>\n </button>\n } @empty {\n <div class=\"yan-empty yan-msgs__empty\">\n <span class=\"yi yi-messages\" style=\"--yi:28px\" aria-hidden=\"true\"></span>\n <div class=\"yan-empty__title\">No messages yet</div>\n <div>Message someone from their profile. People outside your network see it under Requests first.</div>\n </div>\n }\n }\n </div>\n\n <div class=\"yan-msgs__pane\">\n @if (!sel()) {\n <div class=\"yan-empty yan-msgs__placeholder\">\n <span class=\"yi yi-shield-lock\" style=\"--yi:28px\" aria-hidden=\"true\"></span>\n <div class=\"yan-empty__title\">Your messages</div>\n <div>Pick a conversation. Only the people in it can read it, on their devices.</div>\n </div>\n } @else if (sel() === 'requests') {\n <div class=\"yan-msgs__head\">\n <button type=\"button\" class=\"yan-icon-btn yan-icon-btn--plain yan-msgs__back\" (click)=\"go([])\" aria-label=\"Back to messages\"><span class=\"yi yi-arrow-left\" aria-hidden=\"true\"></span></button>\n <div class=\"yan-msgs__grow\"><div class=\"yan-msgs__headname\">Requests</div><span class=\"yan-security yan-security--server\"><span class=\"yi yi-inbox\" style=\"--yi:14px\" aria-hidden=\"true\"></span>Requests from outside your network</span></div>\n </div>\n <div class=\"yan-thread yan-msgs__scroll\">\n @for (r of store.requests(); track r.id) {\n <div class=\"yan-card yan-card--tight\">\n <div class=\"yan-msgs__line\"><span class=\"yan-avatar\" [style.--yan-avatar-hue]=\"hueFor(r)\">{{ initialFor(r) }}</span><div class=\"yan-msgs__grow\"><b>{{ name(r) }}</b><div class=\"yan-msgs__cap\">Not in your network · {{ ago(r.lastMessageAt || r.createdAt) }} · {{ expires(r) }}</div></div></div>\n <button type=\"button\" class=\"yan-msgs__reqtext\" (click)=\"go([r.id])\">{{ store.preview(r) || 'Open to read' }}</button>\n <div class=\"yan-cluster yan-msgs__reqacts\">\n <button type=\"button\" class=\"yan-btn yan-btn--sm\" [attr.aria-disabled]=\"busy()\" (click)=\"accept(r)\">Accept</button>\n <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--secondary\" [attr.aria-disabled]=\"busy()\" (click)=\"decline(r)\">Decline</button>\n </div>\n </div>\n } @empty {\n <div class=\"yan-empty\"><span class=\"yi yi-inbox\" style=\"--yi:28px\" aria-hidden=\"true\"></span><div class=\"yan-empty__title\">No requests</div><div>Messages from people outside your network land here first.</div></div>\n }\n </div>\n } @else {\n @let t = thread();\n <div class=\"yan-msgs__head\">\n <button type=\"button\" class=\"yan-icon-btn yan-icon-btn--plain yan-msgs__back\" (click)=\"go(t.conv?.myState === 'request' ? ['requests'] : [])\" aria-label=\"Back to messages\"><span class=\"yi yi-arrow-left\" aria-hidden=\"true\"></span></button>\n <div class=\"yan-msgs__grow\">\n <div class=\"yan-msgs__headname\">{{ t.conv ? name(t.conv) : '' }}</div>\n <span class=\"yan-security {{ e2ee.cls }}\"><span class=\"yi yi-{{ e2ee.icon }}\" style=\"--yi:14px\" aria-hidden=\"true\"></span>{{ e2ee.text }}</span>\n </div>\n </div>\n @if (t.missing) {\n <div class=\"yan-empty yan-msgs__placeholder\"><span class=\"yi yi-messages\" style=\"--yi:28px\" aria-hidden=\"true\"></span><div class=\"yan-empty__title\">This conversation isn't available</div><div>It may have been declined, or you left it.</div></div>\n } @else {\n <div class=\"yan-thread yan-msgs__scroll\" #scroller (scroll)=\"onScroll()\">\n @if (t.next) {\n <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--ghost yan-msgs__older\" [attr.aria-disabled]=\"t.loading\" (click)=\"store.loadOlder(sel()!)\">Earlier messages</button>\n }\n @if (t.failed) {\n <div class=\"yan-error\" role=\"alert\"><span class=\"yi yi-alert-circle\" style=\"--yi:14px\" aria-hidden=\"true\"></span>We couldn't load this conversation. <button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--ghost\" (click)=\"reload()\">Try again</button></div>\n } @else if (t.loading && !t.items.length) {\n <div class=\"yan-bubble yan-skeleton yan-msgs__skb\" aria-hidden=\"true\"></div>\n <div class=\"yan-bubble yan-bubble--me yan-skeleton yan-msgs__skb\" aria-hidden=\"true\"></div>\n } @else if (!t.items.length) {\n <div class=\"yan-msgs__cap yan-msgs__start\">Messages here are end-to-end encrypted. Only the people in this conversation can read them.</div>\n } @else if (hasUnreadable()) {\n <div class=\"yan-msgs__cap yan-msgs__lost\">Messages sent before you set up this device can't be read here. They're still on the devices you had then.</div>\n }\n @for (m of t.items; track m.clientMsgId || m.id) {\n @if (showSender(m, $index)) {<div class=\"yan-msgs__from\">{{ who(m.senderId) }}</div>}\n <div class=\"yan-bubble\" [class.yan-bubble--me]=\"m.mine\" [class.yan-msgs__unreadable]=\"m.state === 'unreadable'\" [class.yan-msgs__pending]=\"m.state === 'pending'\">{{ m.text }}</div>\n @if (m.state === 'failed') {\n <div class=\"yan-msgs__failed\" role=\"alert\">{{ m.error || 'Not sent.' }} <button type=\"button\" class=\"yan-btn yan-btn--link yan-btn--sm\" (click)=\"store.retry(sel()!, m)\">Try again</button></div>\n } @else if (m.id === seenOn()) {\n <div class=\"yan-msgs__seen\">Seen</div>\n }\n }\n @if (typingName(); as tn) {<div class=\"yan-msgs__cap yan-msgs__typing\" aria-live=\"polite\">{{ tn }} is typing…</div>}\n </div>\n @if (store.crypto() === 'failed') {\n <div class=\"yan-banner yan-banner--warning yan-msgs__banner\" role=\"alert\"><span class=\"yi yi-alert-triangle\" aria-hidden=\"true\"></span>Messages can't be set up in this browser: it needs storage and WebAssembly, which some private windows block. <button type=\"button\" class=\"yan-btn yan-btn--sm\" (click)=\"store.retryCrypto()\">Try again</button></div>\n }\n @if (t.conv?.myState === 'request') {\n <div class=\"yan-msgs__reqbar\">\n <div class=\"yan-msgs__cap\">{{ name(t.conv!) }} isn't in your network. Accept to reply; decline and it's removed. {{ expires(t.conv!) }}.</div>\n <div class=\"yan-cluster\"><button type=\"button\" class=\"yan-btn yan-btn--sm\" [attr.aria-disabled]=\"busy()\" (click)=\"accept(t.conv!)\">Accept</button><button type=\"button\" class=\"yan-btn yan-btn--sm yan-btn--secondary\" [attr.aria-disabled]=\"busy()\" (click)=\"decline(t.conv!)\">Decline</button></div>\n </div>\n } @else if (t.conv) {\n @if (pending(); as note) {<div class=\"yan-msgs__cap yan-msgs__note\">{{ note }}</div>}\n <form class=\"yan-msgs__composer\" (submit)=\"$event.preventDefault(); send()\">\n <input class=\"yan-input\" [value]=\"draft()\" (input)=\"onDraft($event)\" [placeholder]=\"placeholder()\" [attr.aria-label]=\"placeholder()\" maxlength=\"4000\" autocomplete=\"off\" />\n <button type=\"submit\" class=\"yan-btn yan-btn--accent\" aria-label=\"Send\" [attr.aria-disabled]=\"!draft().trim()\"><span class=\"yi yi-send\" style=\"--yi:18px\" aria-hidden=\"true\"></span></button>\n </form>\n }\n }\n }\n </div>\n </div>\n `,\n})\nexport class MessagesPage implements OnInit, OnDestroy {\n protected readonly store = inject(MessagesStore);\n private readonly host = inject(MESSAGES_HOST);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly toast = inject(ToastService);\n private sub?: Subscription;\n private readonly scroller = viewChild<ElementRef<HTMLElement>>('scroller');\n private atBottom = true;\n\n protected readonly e2ee = E2EE_LABEL;\n readonly sel = signal<string | null>(null);\n readonly draft = signal('');\n readonly busy = signal(false);\n readonly signedIn = signal(false);\n\n readonly thread = computed(() => {\n const id = this.sel();\n return id && id !== 'requests' ? this.store.thread(id)() : { conv: null, items: [] as Bubble[], loading: false, failed: false, missing: false };\n });\n\n readonly requestsSub = computed(() => {\n const r = this.store.requests();\n return requestsLine(r.length, r[0] ? this.name(r[0]) : undefined);\n });\n\n /** The message that carries \"Seen\": your last one, once everyone else has read it. */\n readonly seenOn = computed(() => {\n const t = this.thread();\n const me = this.store.me();\n if (!t.conv || !me) return null;\n const ok = t.items.filter((b) => b.state === 'ok' || b.state === 'unreadable');\n const lastMine = [...ok].reverse().find((b) => b.mine)?.id;\n return seen(t.conv, me, ok.map((b) => b.id), lastMine) ? lastMine! : null;\n });\n\n readonly hasUnreadable = computed(() => this.thread().items.some((b) => b.state === 'unreadable' && b.unreadable === 'missing-key'));\n\n readonly pending = computed(() => {\n const t = this.thread();\n const me = this.store.me();\n return t.conv && me ? pendingFor(t.conv, me, this.store.people()) : null;\n });\n\n readonly typingName = computed(() => {\n const id = this.sel();\n const who = id ? this.store.typing()[id] : undefined;\n return who ? personName(this.store.people()[who]) : null;\n });\n\n readonly placeholder = computed(() => {\n const c = this.thread().conv;\n if (!c) return 'Message';\n return c.kind === 'group' ? 'Message group' : `Message ${firstName(this.name(c))}`;\n });\n\n constructor() {\n // keep the newest message in view as messages arrive, unless you've scrolled up to read\n effect(() => {\n const n = this.thread().items.length;\n if (!n) return;\n queueMicrotask(() => requestAnimationFrame(() => this.toBottom()));\n });\n }\n\n ngOnInit(): void {\n this.signedIn.set(!!this.store.me());\n if (this.signedIn()) void this.store.start();\n this.sub = this.route.paramMap.subscribe((p) => {\n const id = p.get('id') ?? (this.route.snapshot.url.at(-1)?.path === 'requests' ? 'requests' : null);\n this.sel.set(id);\n this.draft.set('');\n this.atBottom = true;\n if (id && id !== 'requests' && this.signedIn()) void this.store.openThread(id);\n });\n }\n\n ngOnDestroy(): void {\n this.sub?.unsubscribe();\n }\n\n go(path: string[]): void {\n void this.router.navigate(['/messages', ...path]);\n }\n\n signIn(): void {\n this.host.requestSignIn(this.router.url);\n }\n\n reload(): void {\n const id = this.sel();\n if (id && id !== 'requests') void this.store.openThread(id);\n }\n\n name(c: Conversation): string {\n return conversationName(c, this.store.me() ?? '', this.store.people());\n }\n\n kind(c: Conversation): string {\n return kindLabel(c);\n }\n\n who(userId: string): string {\n return personName(this.store.people()[userId]);\n }\n\n hueFor(c: Conversation): number {\n const o = others(c, this.store.me() ?? '');\n return c.kind === 'direct' && o[0] ? hueOf(o[0].userId) : hueOf(c.id);\n }\n\n initialFor(c: Conversation): string {\n return initials(this.name(c));\n }\n\n ago(iso: string): string {\n return timeAgo(iso);\n }\n\n expires(c: Conversation): string {\n return expiresIn(c.requestUntil);\n }\n\n typingIn(c: Conversation): string {\n const who = this.store.typing()[c.id];\n return who ? `${firstName(personName(this.store.people()[who]))} is typing…` : '';\n }\n\n /** Groups name the sender above a run of their messages. */\n showSender(m: Bubble, i: number): boolean {\n const t = this.thread();\n if (t.conv?.kind !== 'group' || m.mine) return false;\n const prev = t.items[i - 1];\n return !prev || prev.senderId !== m.senderId;\n }\n\n onDraft(e: Event): void {\n this.draft.set((e.target as HTMLInputElement).value);\n const id = this.sel();\n if (id && id !== 'requests' && this.draft().trim()) this.store.typed(id);\n }\n\n async send(): Promise<void> {\n const id = this.sel();\n const text = this.draft().trim();\n // while encryption is still starting, the message waits as pending: the store sends it once it's ready\n if (!id || id === 'requests' || !text) return;\n this.draft.set('');\n this.atBottom = true;\n await this.store.send(id, text);\n }\n\n async accept(c: Conversation): Promise<void> {\n if (this.busy()) return;\n this.busy.set(true);\n try {\n await this.store.accept(c.id);\n this.go([c.id]);\n } catch (e) {\n this.toast.show(errorText(e, \"Couldn't accept. Try again.\"));\n } finally {\n this.busy.set(false);\n }\n }\n\n async decline(c: Conversation): Promise<void> {\n if (this.busy()) return;\n this.busy.set(true);\n try {\n await this.store.decline(c.id);\n this.go(['requests']);\n } catch (e) {\n this.toast.show(errorText(e, \"Couldn't decline. Try again.\"));\n } finally {\n this.busy.set(false);\n }\n }\n\n onScroll(): void {\n const el = this.scroller()?.nativeElement;\n if (el) this.atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 80;\n }\n\n private toBottom(): void {\n const el = this.scroller()?.nativeElement;\n if (el && this.atBottom) el.scrollTop = el.scrollHeight;\n }\n}\n\nfunction firstName(n: string): string {\n return n.startsWith('@') ? n : n.split(' ')[0];\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { Router, ActivatedRoute } from '@angular/router';
4
- import { M as MessagesStore, a as MESSAGES_HOST, f as errorCode, d as errorText } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BtQC73sF.mjs';
4
+ import { M as MessagesStore, a as MESSAGES_HOST, f as errorCode, d as errorText } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BYCxC81Q.mjs';
5
5
 
6
6
  /** `/messages/to/:userId`: finds or starts the direct conversation, then shows it in its place. */
7
7
  class StartPage {
@@ -57,4 +57,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
57
57
  }] });
58
58
 
59
59
  export { StartPage };
60
- //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-start.page-gJ1cJDfy.mjs.map
60
+ //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages-start.page-D97JIFrb.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-start.page-gJ1cJDfy.mjs","sources":["../../../projects/messages/src/lib/start.page.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { errorCode, errorText } from './messaging-api';\nimport { MessagesStore } from './messages.store';\nimport { MESSAGES_HOST } from './tokens';\n\n/** `/messages/to/:userId`: finds or starts the direct conversation, then shows it in its place. */\n@Component({\n selector: 'yan-messages-start',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (error(); as e) {\n <div class=\"yan-card\"><div class=\"yan-empty\"><span class=\"yi yi-messages\" aria-hidden=\"true\"></span><div class=\"yan-empty__title\">{{ e }}</div><button type=\"button\" class=\"yan-btn yan-btn--secondary\" (click)=\"back()\">Back</button></div></div>\n } @else {\n <div class=\"yan-card\" aria-busy=\"true\"><div class=\"yan-empty\"><span class=\"yi yi-shield-lock\" aria-hidden=\"true\"></span><div>Opening the conversation…</div></div></div>\n }\n `,\n})\nexport class StartPage implements OnInit {\n private readonly store = inject(MessagesStore);\n private readonly host = inject(MESSAGES_HOST);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n readonly error = signal<string | null>(null);\n\n async ngOnInit(): Promise<void> {\n const userId = this.route.snapshot.paramMap.get('userId') ?? '';\n if (!this.store.me()) return this.host.requestSignIn(this.router.url);\n if (userId === this.store.me()) {\n this.error.set(\"You can't message yourself.\");\n return;\n }\n try {\n const c = await this.store.startDirect(userId);\n await this.router.navigate(['/messages', c.id], { replaceUrl: true });\n } catch (e) {\n this.error.set(errorCode(e) === 'cant_message' ? \"You can't message this person.\" : errorText(e, \"Couldn't open the conversation.\"));\n }\n }\n\n back(): void {\n history.length > 1 ? history.back() : void this.router.navigate(['/messages']);\n }\n}\n"],"names":[],"mappings":";;;;;AAMA;MAaa,SAAS,CAAA;AAZtB,IAAA,WAAA,GAAA;AAamB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;AAC7B,QAAA,IAAA,CAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AAC5B,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AACtC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAgB,IAAI,4EAAC;AAoB7C,IAAA;AAlBC,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;AAC/D,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE;AAAE,YAAA,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QACrE,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE;AAC9B,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC;YAC7C;QACF;AACA,QAAA,IAAI;YACF,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;YAC9C,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACvE;QAAE,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,cAAc,GAAG,gCAAgC,GAAG,SAAS,CAAC,CAAC,EAAE,iCAAiC,CAAC,CAAC;QACtI;IACF;IAEA,IAAI,GAAA;QACF,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC;IAChF;+GAxBW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAT,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EARV;;;;;;AAMT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAEU,SAAS,EAAA,UAAA,EAAA,CAAA;kBAZrB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE;;;;;;AAMT,EAAA,CAAA;AACF,iBAAA;;;;;"}
1
+ {"version":3,"file":"chisquare-tech-yan-ngx-apps-messages-start.page-D97JIFrb.mjs","sources":["../../../projects/messages/src/lib/start.page.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { errorCode, errorText } from './messaging-api';\nimport { MessagesStore } from './messages.store';\nimport { MESSAGES_HOST } from './tokens';\n\n/** `/messages/to/:userId`: finds or starts the direct conversation, then shows it in its place. */\n@Component({\n selector: 'yan-messages-start',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (error(); as e) {\n <div class=\"yan-card\"><div class=\"yan-empty\"><span class=\"yi yi-messages\" aria-hidden=\"true\"></span><div class=\"yan-empty__title\">{{ e }}</div><button type=\"button\" class=\"yan-btn yan-btn--secondary\" (click)=\"back()\">Back</button></div></div>\n } @else {\n <div class=\"yan-card\" aria-busy=\"true\"><div class=\"yan-empty\"><span class=\"yi yi-shield-lock\" aria-hidden=\"true\"></span><div>Opening the conversation…</div></div></div>\n }\n `,\n})\nexport class StartPage implements OnInit {\n private readonly store = inject(MessagesStore);\n private readonly host = inject(MESSAGES_HOST);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n readonly error = signal<string | null>(null);\n\n async ngOnInit(): Promise<void> {\n const userId = this.route.snapshot.paramMap.get('userId') ?? '';\n if (!this.store.me()) return this.host.requestSignIn(this.router.url);\n if (userId === this.store.me()) {\n this.error.set(\"You can't message yourself.\");\n return;\n }\n try {\n const c = await this.store.startDirect(userId);\n await this.router.navigate(['/messages', c.id], { replaceUrl: true });\n } catch (e) {\n this.error.set(errorCode(e) === 'cant_message' ? \"You can't message this person.\" : errorText(e, \"Couldn't open the conversation.\"));\n }\n }\n\n back(): void {\n history.length > 1 ? history.back() : void this.router.navigate(['/messages']);\n }\n}\n"],"names":[],"mappings":";;;;;AAMA;MAaa,SAAS,CAAA;AAZtB,IAAA,WAAA,GAAA;AAamB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;AAC7B,QAAA,IAAA,CAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AAC5B,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AACtC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAgB,IAAI,4EAAC;AAoB7C,IAAA;AAlBC,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;AAC/D,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE;AAAE,YAAA,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QACrE,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE;AAC9B,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC;YAC7C;QACF;AACA,QAAA,IAAI;YACF,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;YAC9C,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACvE;QAAE,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,cAAc,GAAG,gCAAgC,GAAG,SAAS,CAAC,CAAC,EAAE,iCAAiC,CAAC,CAAC;QACtI;IACF;IAEA,IAAI,GAAA;QACF,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC;IAChF;+GAxBW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAT,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EARV;;;;;;AAMT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAEU,SAAS,EAAA,UAAA,EAAA,CAAA;kBAZrB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,UAAU,EAAE,IAAI;oBAChB,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE;;;;;;AAMT,EAAA,CAAA;AACF,iBAAA;;;;;"}
@@ -1,2 +1,2 @@
1
- export { g as E2eeMachine, h as MEGOLM, i as MESSAGES_API_BASE, j as MESSAGES_E2EE_WASM, a as MESSAGES_HOST, l as MESSAGES_ROUTES, m as MESSAGES_SOCIAL_BASE, M as MessagesStore, n as MessagingApi, O as OLM, q as forgetE2ee } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BtQC73sF.mjs';
1
+ export { g as E2eeMachine, h as MEGOLM, i as MESSAGES_API_BASE, j as MESSAGES_E2EE_WASM, a as MESSAGES_HOST, l as MESSAGES_ROUTES, m as MESSAGES_SOCIAL_BASE, M as MessagesStore, n as MessagingApi, O as OLM, q as forgetE2ee } from './chisquare-tech-yan-ngx-apps-messages-chisquare-tech-yan-ngx-apps-messages-BYCxC81Q.mjs';
2
2
  //# sourceMappingURL=chisquare-tech-yan-ngx-apps-messages.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chisquare-tech/yan-ngx-apps-messages",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.1.3",
6
6
  "@angular/core": "^21.1.3",