@adminide-stack/yantra-mobile 12.0.105-alpha.0 → 12.0.106-alpha.0

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.
Files changed (33) hide show
  1. package/lib/features/messaging/BlockedContactsScreen.js +127 -0
  2. package/lib/features/messaging/BlockedContactsScreen.js.map +1 -0
  3. package/lib/features/messaging/ChatAttachments.js +4 -2
  4. package/lib/features/messaging/ChatAttachments.js.map +1 -1
  5. package/lib/features/messaging/ChatComponents.js +194 -10
  6. package/lib/features/messaging/ChatComponents.js.map +1 -1
  7. package/lib/features/messaging/ChatInfoScreen.js +173 -17
  8. package/lib/features/messaging/ChatInfoScreen.js.map +1 -1
  9. package/lib/features/messaging/ConversationListScreen.js +17 -1
  10. package/lib/features/messaging/ConversationListScreen.js.map +1 -1
  11. package/lib/features/messaging/MediaGalleryScreen.js +264 -0
  12. package/lib/features/messaging/MediaGalleryScreen.js.map +1 -0
  13. package/lib/features/messaging/NativeChatExperience.js +137 -18
  14. package/lib/features/messaging/NativeChatExperience.js.map +1 -1
  15. package/lib/features/messaging/NewGroupScreen.js +191 -0
  16. package/lib/features/messaging/NewGroupScreen.js.map +1 -0
  17. package/lib/features/messaging/PollComposer.js +137 -0
  18. package/lib/features/messaging/PollComposer.js.map +1 -0
  19. package/lib/features/messaging/PollVotesScreen.js +122 -0
  20. package/lib/features/messaging/PollVotesScreen.js.map +1 -0
  21. package/lib/features/messaging/ThreadScreen.js +180 -13
  22. package/lib/features/messaging/ThreadScreen.js.map +1 -1
  23. package/lib/features/messaging/chatLinks.js +39 -2
  24. package/lib/features/messaging/chatLinks.js.map +1 -1
  25. package/lib/features/messaging/chatModel.js +186 -19
  26. package/lib/features/messaging/chatModel.js.map +1 -1
  27. package/lib/features/messaging/chatOperations.js +111 -2
  28. package/lib/features/messaging/chatOperations.js.map +1 -1
  29. package/lib/features/messaging/nativeChatChannelQuery.js +7 -2
  30. package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -1
  31. package/lib/features/messaging/useChatData.js +248 -10
  32. package/lib/features/messaging/useChatData.js.map +1 -1
  33. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"chatModel.js","sources":["../../../src/features/messaging/chatModel.ts"],"sourcesContent":["/**\n * Pure shaping between messenger-box's wire types and what the chat UI renders.\n *\n * Everything here is a plain function over plain data - no React, no seams, no\n * clock beyond what is passed in - because this is where the bugs that actually\n * ruin a chat client live: messages in the wrong order, a duplicate after a\n * reconnect, an optimistic row that never resolves, a DM titled with your own\n * name. Those are all cheap to unit-test and expensive to debug on a device.\n */\n\nexport interface ChatUser {\n id: string;\n givenName?: string | null;\n familyName?: string | null;\n username?: string | null;\n email?: string | null;\n picture?: string | null;\n profile?: { displayName?: string | null; picture?: string | null } | null;\n}\n\nexport interface WirePost {\n id: string;\n message?: string | null;\n type?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n editedAt?: string | null;\n deletedAt?: string | null;\n rootId?: string | null;\n parentId?: string | null;\n filenames?: (string | null)[] | null;\n props?: Record<string, unknown> | null;\n /** Attached files (messenger-box `Post.files`, linked to the post by id). */\n files?: { data?: (WireFile | null)[] | null } | null;\n author?: ChatUser | null;\n creator?: ChatUser | null;\n reactionSummary?: WireReaction[] | null;\n /** The viewer starred it (resolved for the caller only). */\n viewerStarred?: boolean | null;\n /** The chat it is in - present on cross-chat lists such as starred messages. */\n channel?: { id?: string | null } | null;\n}\n\nexport interface WireFile {\n id?: string | null;\n name?: string | null;\n mimeType?: string | null;\n url?: string | null;\n width?: number | null;\n height?: number | null;\n size?: number | null;\n}\n\n/** What a message's `props.attachmentKind` says the attachments are (set when sending). */\nexport type ChatAttachmentKind = 'image' | 'audio' | 'file';\n\n/**\n * One attached file. `url` is what the server returned (an image-resizer thumbnail for every\n * type) or, while sending, the local file; `key` is the storage key, from which the UI builds\n * the full-size / playable CDN URL (see `attachmentUrl`).\n */\nexport interface ChatAttachment {\n id: string;\n kind: ChatAttachmentKind;\n name: string;\n mimeType: string;\n url: string;\n key: string | null;\n width?: number | null;\n height?: number | null;\n /** Voice notes: recorded length (from the message's props). */\n durationMs?: number | null;\n}\n\nexport interface WireReaction {\n reaction: string;\n count: number;\n userIds?: (string | null)[] | null;\n}\n\n/** One Tapback on a message, grouped across users. */\nexport interface ChatReaction {\n reaction: string;\n count: number;\n /** The viewer is one of the reactors. */\n mine: boolean;\n userIds: string[];\n}\n\nexport interface WireChannelMember {\n id?: string | null;\n user?: ChatUser | null;\n msgCount?: number | null;\n lastViewedAt?: string | null;\n /** This member's devices have the channel's messages up to then. */\n lastDeliveredAt?: string | null;\n}\n\nexport interface WireChannel {\n id: string;\n type?: string | null;\n orgName?: string | null;\n title?: string | null;\n displayName?: string | null;\n topic?: string | null;\n lastPostAt?: string | null;\n totalMsgCount?: number | null;\n createdAt?: string | null;\n lastMessage?: WirePost | null;\n creator?: ChatUser | null;\n members?: (WireChannelMember | null)[] | null;\n /** Until when the VIEWER muted this chat (resolved for the caller only); null when not muted. */\n viewerMutedUntil?: string | null;\n /** When the viewer pinned / archived this chat in their own list; null when not. */\n viewerPinnedAt?: string | null;\n viewerArchivedAt?: string | null;\n /** The viewer's unsent draft here (resolved for the caller only). */\n viewerDraft?: string | null;\n}\n\n/** Where an optimistic message is in its lifecycle. */\nexport type ChatSendState = 'sending' | 'sent' | 'failed';\n\n/** The message a reply quotes, copied into the reply when it is sent (`props.replyTo`). */\nexport interface ChatReplyRef {\n id: string;\n authorId: string | null;\n authorName: string;\n /** The quoted text, or the attachment label for a photo / voice message. */\n body: string;\n}\n\n/** What the ticks on the viewer's own message say. */\nexport type ChatMessageStatus = 'sending' | 'failed' | 'sent' | 'delivered' | 'read';\n\n/** WhatsApp lets you edit a message for 15 minutes and delete it for everyone for about two days. */\nexport const EDIT_WINDOW_MS = 15 * 60_000;\nexport const DELETE_FOR_EVERYONE_WINDOW_MS = 48 * 3_600_000;\n\nexport interface ChatMessage {\n id: string;\n body: string;\n createdAt: number;\n authorId: string | null;\n authorName: string;\n authorAvatar?: string | null;\n isMine: boolean;\n isDeleted: boolean;\n isEdited: boolean;\n attachments: ChatAttachment[];\n /** Tapbacks, in first-use order. Empty when nobody reacted. */\n reactions: ChatReaction[];\n /** The message this one replies to. */\n replyTo?: ChatReplyRef | null;\n /** The viewer starred it. */\n starred?: boolean;\n /** Sent on from another chat (\"Forwarded\"). */\n forwarded?: boolean;\n /** Present only on messages this device is still sending. */\n sendState?: ChatSendState;\n /** The optimistic id this row replaced, so the UI can animate rather than jump. */\n replacedClientId?: string;\n}\n\nexport interface ChatConversation {\n id: string;\n title: string;\n subtitle: string;\n avatarUrl?: string | null;\n /** Sort key; 0 when the channel has never had a message. */\n lastActivity: number;\n unreadCount: number;\n isDirect: boolean;\n /** The other participant, for a DM. Null for groups. */\n peer: ChatUser | null;\n /** The other members' names, for a group's header (\"Asha, Ben, Chen\"). */\n memberNames: string[];\n /** The newest message is the viewer's own, so the list shows its ticks. */\n lastMessageMine: boolean;\n /** Who wrote the newest message in a group, when it was not the viewer. */\n lastAuthorName: string;\n /** When the newest message was sent (epoch millis), for its ticks. */\n lastMessageAt: number;\n /**\n * Everyone else has read up to here (epoch millis): the earliest `lastViewedAt` among the\n * other members. The viewer's messages at or before it show blue ticks. 0 = unknown.\n */\n readWatermark: number;\n /** Everyone else's devices have received up to here: two gray ticks. 0 = unknown. */\n deliveredWatermark: number;\n /** The viewer silenced this chat's notifications until then (epoch millis). 0 = not muted. */\n mutedUntil: number;\n /** Pinned to the top of the viewer's list (epoch millis); 0 = not pinned. */\n pinnedAt: number;\n /** Archived out of the viewer's list (epoch millis); 0 = not archived. */\n archivedAt: number;\n /** The newest message was deleted for everyone. */\n lastMessageDeleted: boolean;\n /** The viewer's unsent text in this chat; the list shows it as \"Draft: …\". */\n draft: string;\n}\n\n/**\n * A person's display name, in the order a human would expect.\n *\n * Email is the last resort and is truncated at the `@`: a transcript full of\n * `someone@example.com` is worse than one full of `someone`.\n */\n/** Ids in a stable order, the last tiebreak for a sort. */\nfunction compareIds(a: string, b: string): number {\n if (a === b) return 0;\n return a < b ? -1 : 1;\n}\n\nexport function displayNameOf(user?: ChatUser | null, fallback = 'Unknown'): string {\n if (!user) return fallback;\n const profileName = user.profile?.displayName?.trim();\n if (profileName) return profileName;\n const fullName = [user.givenName, user.familyName].filter(Boolean).join(' ').trim();\n if (fullName) return fullName;\n const username = user.username?.trim();\n if (username) return username;\n const email = user.email?.trim();\n if (email) return email.split('@')[0] || fallback;\n return fallback;\n}\n\nfunction memberNames(channel: WireChannel, viewerId: string): string[] {\n return (channel.members ?? [])\n .map((member) => member?.user)\n .filter((user): user is ChatUser => user != null && Boolean(user.id) && String(user.id) !== viewerId)\n .map((user) => displayNameOf(user, ''))\n .filter(Boolean)\n .slice(0, 3);\n}\n\n/**\n * messenger-box populates `author` on some write paths and `creator` on others\n * (`sendMessage` sets creator). Reading only one shows \"Unknown\" for a large\n * fraction of real transcripts.\n */\nexport function pickAuthor(post: WirePost): ChatUser | null {\n return post.author ?? post.creator ?? null;\n}\n\n/** Epoch millis, tolerant of nulls and unparseable values. */\nexport function toEpoch(value?: string | number | null): number {\n if (value == null) return 0;\n if (typeof value === 'number') return Number.isFinite(value) ? value : 0;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\nfunction kindOfMime(mimeType: string): ChatAttachmentKind {\n if (mimeType.startsWith('image/')) return 'image';\n if (mimeType.startsWith('audio/')) return 'audio';\n return 'file';\n}\n\n/**\n * The storage key inside a file URL. messenger-box hands back image-resizer URLs\n * (`<handler>/fit-in/150x150/<key>`) for every attachment; a plain storage URL or a bare key\n * also works.\n */\nexport function fileKeyFromUrl(url: string | null | undefined): string | null {\n const value = (url ?? '').trim();\n if (!value) return null;\n const resized = value.match(/\\/fit-in\\/\\d+x\\d+\\/(.+)$/);\n if (resized) return decodeURIComponent(resized[1].split('?')[0]);\n if (!/^[a-z]+:\\/\\//i.test(value)) return value.split('?')[0];\n if (/^(file|content|ph|assets-library):/i.test(value)) return null;\n try {\n return decodeURIComponent(new URL(value).pathname.replace(/^\\/+/, '')) || null;\n } catch {\n return null;\n }\n}\n\n/** Full-size (image) or playable (audio) URL: the CDN copy when a base is known, else what we have. */\nexport function attachmentUrl(attachment: ChatAttachment, fileBaseUrl?: string | null): string {\n if (!attachment.key || !fileBaseUrl) return attachment.url;\n return `${fileBaseUrl.replace(/\\/+$/, '')}/${attachment.key}`;\n}\n\n/** `props` is an AnyObject scalar: an object from some paths, a JSON string from others. */\nfunction propsOf(post: WirePost | null | undefined): Record<string, unknown> {\n const raw = post?.props as unknown;\n if (raw && typeof raw === 'object') return raw as Record<string, unknown>;\n if (typeof raw === 'string') {\n try {\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n }\n return {};\n}\n\nexport function toChatAttachments(post: WirePost): ChatAttachment[] {\n const props = propsOf(post) as { attachmentKind?: unknown; voiceDurationMs?: unknown };\n const durationMs = typeof props.voiceDurationMs === 'number' ? props.voiceDurationMs : null;\n return (post.files?.data ?? [])\n .filter((f): f is WireFile => Boolean(f?.url))\n .map((f, i) => {\n const mimeType = f.mimeType ?? 'application/octet-stream';\n const kind = kindOfMime(mimeType);\n return {\n id: String(f.id ?? `${post.id}-${i}`),\n kind,\n name: f.name ?? 'file',\n mimeType,\n url: String(f.url),\n key: fileKeyFromUrl(f.url),\n width: f.width ?? null,\n height: f.height ?? null,\n durationMs: kind === 'audio' ? durationMs : null,\n };\n });\n}\n\n/**\n * The text of an attachment-only message. messenger-box requires non-blank message text, so this\n * label is sent as the text: push notifications and other clients read it, and this app hides it\n * inside the bubble (see `toChatMessage`).\n */\nexport const ATTACHMENT_LABELS: Record<ChatAttachmentKind, string> = {\n image: '📷 Photo',\n audio: '🎤 Voice message',\n file: '📎 Attachment',\n};\n\n/** Chat-list preview for a message that is only an attachment. */\nexport function attachmentPreview(post: WirePost | null | undefined): string {\n const kind = propsOf(post).attachmentKind;\n return typeof kind === 'string' && kind in ATTACHMENT_LABELS ? ATTACHMENT_LABELS[kind as ChatAttachmentKind] : '';\n}\n\nconst LABEL_TEXTS = new Set(Object.values(ATTACHMENT_LABELS));\n\n/** The bubble text: an attachment-only message's label is not shown next to the attachment itself. */\nfunction bodyOf(post: WirePost, hasAttachments: boolean): string {\n const body = post.message ?? '';\n const trimmed = body.trim();\n const label = attachmentPreview(post);\n if (label && trimmed === label) return '';\n // Same label with the files attached, even if props did not come back.\n return hasAttachments && LABEL_TEXTS.has(trimmed) ? '' : body;\n}\n\nexport function toChatReactions(summary: WireReaction[] | null | undefined, viewerId: string): ChatReaction[] {\n return (summary ?? [])\n .filter((r) => r && r.reaction && r.count > 0)\n .map((r) => {\n const userIds = (r.userIds ?? []).filter((u): u is string => typeof u === 'string' && u.length > 0);\n return { reaction: r.reaction, count: r.count, userIds, mine: userIds.includes(viewerId) };\n });\n}\n\n/** Longest quote a reply carries; the bubble shows two lines of it anyway. */\nconst REPLY_QUOTE_MAX = 200;\n\n/** The quote a reply to `message` carries. */\nexport function replyRefOf(message: ChatMessage): ChatReplyRef {\n const kind = message.attachments[0]?.kind;\n const body = message.body.trim() || (kind ? ATTACHMENT_LABELS[kind] : '');\n return {\n id: message.id,\n authorId: message.authorId,\n authorName: message.authorName,\n body: body.length > REPLY_QUOTE_MAX ? `${body.slice(0, REPLY_QUOTE_MAX - 1)}…` : body,\n };\n}\n\n/** `props.replyTo`, when it is a well-formed quote; anything else is ignored rather than rendered. */\nfunction replyOf(post: WirePost): ChatReplyRef | null {\n const raw = propsOf(post).replyTo as Partial<Record<keyof ChatReplyRef, unknown>> | undefined;\n if (!raw || typeof raw !== 'object' || typeof raw.id !== 'string' || !raw.id) return null;\n return {\n id: raw.id,\n authorId: typeof raw.authorId === 'string' ? raw.authorId : null,\n authorName: typeof raw.authorName === 'string' && raw.authorName ? raw.authorName : 'Unknown',\n body: typeof raw.body === 'string' ? raw.body.slice(0, REPLY_QUOTE_MAX) : '',\n };\n}\n\nexport function toChatMessage(post: WirePost, viewerId: string): ChatMessage {\n const author = pickAuthor(post);\n const attachments = toChatAttachments(post);\n return {\n id: String(post.id),\n body: bodyOf(post, attachments.length > 0),\n createdAt: toEpoch(post.createdAt),\n authorId: author?.id ? String(author.id) : null,\n authorName: displayNameOf(author),\n authorAvatar: author?.picture ?? author?.profile?.picture ?? null,\n isMine: !!author?.id && String(author.id) === viewerId,\n isDeleted: !!post.deletedAt,\n isEdited: !!post.editedAt,\n attachments,\n reactions: toChatReactions(post.reactionSummary, viewerId),\n replyTo: replyOf(post),\n starred: Boolean(post.viewerStarred),\n forwarded: propsOf(post).forwarded === true,\n };\n}\n\n/** The list preview of a message deleted for everyone, as WhatsApp words it. */\nexport function deletedPreview(mine: boolean): string {\n return mine ? 'You deleted this message' : 'This message was deleted';\n}\n\n/**\n * The ticks on one of the viewer's messages: a clock while sending, one gray tick once the\n * server has it, two gray ticks once everyone else's phone has it, two blue ticks once everyone\n * else has opened the chat since it was sent.\n */\nexport function messageStatus(message: ChatMessage, readWatermark: number, deliveredWatermark = 0): ChatMessageStatus {\n if (message.sendState === 'sending') return 'sending';\n if (message.sendState === 'failed') return 'failed';\n if (!message.createdAt) return 'sent';\n if (readWatermark > 0 && message.createdAt <= readWatermark) return 'read';\n if (deliveredWatermark > 0 && message.createdAt <= deliveredWatermark) return 'delivered';\n return 'sent';\n}\n\n/**\n * How far everyone else's phones have received: per other member the later of\n * `lastDeliveredAt` and `lastViewedAt` (having read it means having it), then the earliest\n * of those. 0 when any other member's phone has reported nothing.\n */\nexport function deliveredWatermarkOf(channel: WireChannel, viewerId: string): number {\n const others = (channel.members ?? []).filter(\n (m): m is WireChannelMember => Boolean(m?.user?.id) && String(m!.user!.id) !== viewerId,\n );\n if (!others.length) return 0;\n let watermark = Number.POSITIVE_INFINITY;\n for (const member of others) {\n const got = Math.max(toEpoch(member.lastDeliveredAt), toEpoch(member.lastViewedAt));\n if (!got) return 0;\n watermark = Math.min(watermark, got);\n }\n return watermark;\n}\n\n/** The viewer can still edit this message (their own text, within 15 minutes). */\nexport function canEditMessage(message: ChatMessage, now: number): boolean {\n return (\n message.isMine &&\n !message.isDeleted &&\n (!message.sendState || message.sendState === 'sent') &&\n message.attachments.length === 0 &&\n Boolean(message.body.trim()) &&\n now - message.createdAt <= EDIT_WINDOW_MS\n );\n}\n\n/** The viewer can still delete this message for everyone (their own, within 48 hours). */\nexport function canDeleteForEveryone(message: ChatMessage, now: number): boolean {\n return (\n message.isMine &&\n !message.isDeleted &&\n (!message.sendState || message.sendState === 'sent') &&\n now - message.createdAt <= DELETE_FOR_EVERYONE_WINDOW_MS\n );\n}\n\n/**\n * Where the \"N unread messages\" band goes: above the oldest of the `unreadCount` newest\n * messages from other people. Null when nothing is unread or that message is not loaded.\n */\nexport function firstUnreadId(messages: ChatMessage[], unreadCount: number): string | null {\n if (unreadCount <= 0) return null;\n const fromOthers = messages.filter((m) => !m.isMine);\n return fromOthers.length >= unreadCount ? fromOthers[fromOthers.length - unreadCount].id : null;\n}\n\n/** Who has a message, for Message info. */\nexport interface MessageReceipts {\n readBy: string[];\n deliveredTo: string[];\n /** Neither delivered nor read yet. */\n remaining: string[];\n}\n\n/**\n * Message info, WhatsApp-style, from each other member's watermarks: read once they opened\n * the chat after it was sent, delivered once their phone had the chat's messages after it was\n * sent. Watermarks say WHETHER, not exactly when, so Message info shows no per-person time.\n */\nexport function messageReceipts(\n message: Pick<ChatMessage, 'createdAt'>,\n channel: WireChannel,\n viewerId: string,\n): MessageReceipts {\n const out: MessageReceipts = { readBy: [], deliveredTo: [], remaining: [] };\n const others = (channel.members ?? []).filter(\n (m): m is WireChannelMember => m != null && Boolean(m.user?.id) && String(m.user!.id) !== viewerId,\n );\n others.forEach((member) => {\n const name = displayNameOf(member.user);\n const sent = message.createdAt;\n if (sent && toEpoch(member.lastViewedAt) >= sent) out.readBy.push(name);\n else if (sent && toEpoch(member.lastDeliveredAt) >= sent) out.deliveredTo.push(name);\n else out.remaining.push(name);\n });\n return out;\n}\n\n/**\n * How far everyone else has read: the EARLIEST other member's `lastViewedAt`, so a group\n * message turns blue only once every member has seen it (as WhatsApp does). 0 when any\n * other member has never opened the chat or the server did not say.\n */\nexport function readWatermarkOf(channel: WireChannel, viewerId: string): number {\n const others = (channel.members ?? []).filter(\n (m): m is WireChannelMember => Boolean(m?.user?.id) && String(m!.user!.id) !== viewerId,\n );\n if (!others.length) return 0;\n let watermark = Number.POSITIVE_INFINITY;\n for (const member of others) {\n const viewed = toEpoch(member.lastViewedAt);\n if (!viewed) return 0;\n watermark = Math.min(watermark, viewed);\n }\n return watermark;\n}\n\n/** Until when the viewer muted this chat (epoch millis); 0 when it is not muted. */\nexport function mutedUntilOf(channel: WireChannel): number {\n return toEpoch(channel.viewerMutedUntil ?? null);\n}\n\nexport function isMuted(conversation: Pick<ChatConversation, 'mutedUntil'>, now: number): boolean {\n return conversation.mutedUntil > now;\n}\n\n/** \"Always\" is stored as a far-future instant so the server compares one date for every option. */\nexport const MUTE_FOREVER_ISO = '9999-12-31T23:59:59.000Z';\nconst MUTE_FOREVER_EPOCH = Date.parse(MUTE_FOREVER_ISO);\n\nexport type ChatMuteOption = '8h' | '1w' | 'always';\n\nexport const MUTE_OPTIONS: ReadonlyArray<{ key: ChatMuteOption; label: string }> = [\n { key: '8h', label: '8 hours' },\n { key: '1w', label: '1 week' },\n { key: 'always', label: 'Always' },\n];\n\n/** The `mutedUntil` an option sends, as ISO. */\nexport function muteUntilFor(option: ChatMuteOption, now: number): string {\n if (option === 'always') return MUTE_FOREVER_ISO;\n const span = option === '8h' ? 8 * 3_600_000 : 7 * 86_400_000;\n return new Date(now + span).toISOString();\n}\n\n/** Replace one message's reactions with the server's latest summary. */\nexport function applyReactionSummary(\n messages: ChatMessage[],\n messageId: string,\n summary: WireReaction[] | null | undefined,\n viewerId: string,\n): ChatMessage[] {\n return messages.map((m) => (m.id === messageId ? { ...m, reactions: toChatReactions(summary, viewerId) } : m));\n}\n\n/**\n * The viewer's reactions after picking `emoji` (null = remove). One Tapback per person,\n * like iMessage: a new pick replaces the old one, the same pick removes it.\n */\nexport function withViewerReaction(reactions: ChatReaction[], emoji: string | null, viewerId: string): ChatReaction[] {\n const current = reactions.find((r) => r.mine)?.reaction ?? null;\n const next = emoji && emoji !== current ? emoji : null;\n const out = reactions\n .map((r) =>\n r.mine ? { ...r, mine: false, count: r.count - 1, userIds: r.userIds.filter((u) => u !== viewerId) } : r,\n )\n .filter((r) => r.count > 0);\n if (!next) return out;\n const idx = out.findIndex((r) => r.reaction === next);\n if (idx >= 0) {\n const r = out[idx];\n out[idx] = { ...r, mine: true, count: r.count + 1, userIds: [...r.userIds, viewerId] };\n return out;\n }\n return [...out, { reaction: next, count: 1, mine: true, userIds: [viewerId] }];\n}\n\n/**\n * Merge a batch of messages into the transcript: de-duplicated by id, oldest\n * first.\n *\n * De-duplication is the whole point. The same message arrives twice all the\n * time - the subscription delivers it while the head-page refetch that follows\n * a reconnect also returns it, and offset paging re-reads a row when something\n * lands mid-scroll. LAST WRITE WINS on a collision, so a server row replaces\n * the optimistic copy rather than the other way round.\n *\n * Ties break on id, not on insertion order: two messages can share a timestamp\n * to the millisecond, and an unstable comparator makes them swap places on\n * every render.\n */\nexport function mergeMessages(existing: ChatMessage[], incoming: ChatMessage[]): ChatMessage[] {\n const byId = new Map<string, ChatMessage>();\n for (const m of existing) byId.set(m.id, m);\n for (const m of incoming) byId.set(m.id, m);\n return Array.from(byId.values()).sort((a, b) => a.createdAt - b.createdAt || compareIds(a.id, b.id));\n}\n\n/**\n * Reconcile a server message with the optimistic row it confirms.\n *\n * Matched on (author, body, nearby timestamp) rather than an echoed client id,\n * because `sendMessage` does not round-trip one. The window is deliberately\n * generous - a slow network is normal - and the cost of a miss is a brief\n * duplicate that the next refetch cleans up, not a lost message.\n */\nexport function reconcileOptimistic(messages: ChatMessage[], confirmed: ChatMessage, windowMs = 60_000): ChatMessage[] {\n // Only the viewer's OWN message can confirm the viewer's pending row.\n // Without this, someone else sending the identical text inside the window\n // consumes the optimistic slot: their message is relabelled as yours and\n // yours disappears. \"ok\", \"thanks\" and \"👍\" collide constantly.\n if (!confirmed.isMine) return mergeMessages(messages, [confirmed]);\n\n // Attachment sends pick the post id up front, so the pending row already has the real id.\n const sameIdIdx = messages.findIndex((m) => m.id === confirmed.id && m.sendState === 'sending');\n if (sameIdIdx !== -1) {\n const next = messages.slice();\n const pending = messages[sameIdIdx];\n next[sameIdIdx] = {\n ...confirmed,\n // Keep the local previews until the server copy lists its files.\n attachments: confirmed.attachments.length ? confirmed.attachments : pending.attachments,\n sendState: 'sent',\n };\n return next;\n }\n\n const pendingIdx = messages.findIndex(\n (m) =>\n m.sendState === 'sending' &&\n m.isMine &&\n m.body === confirmed.body &&\n // Same author, not merely both \"mine\" - guards the same collision\n // when authorId is populated on both sides.\n (!m.authorId || !confirmed.authorId || m.authorId === confirmed.authorId) &&\n Math.abs(m.createdAt - confirmed.createdAt) <= windowMs,\n );\n if (pendingIdx === -1) return mergeMessages(messages, [confirmed]);\n\n const next = messages.slice();\n next[pendingIdx] = { ...confirmed, sendState: 'sent', replacedClientId: messages[pendingIdx].id };\n // Still merge: the same id may already be present from a concurrent refetch.\n return mergeMessages(\n next.filter((m) => m.id !== confirmed.id || m.replacedClientId),\n [next[pendingIdx]],\n );\n}\n\n/**\n * The other participant in a DM.\n *\n * Falls back to null rather than to the viewer: a conversation labelled with\n * your own name is a bug users notice immediately, and every DM the viewer\n * created before members were populated would hit it.\n */\nexport function peerOf(channel: WireChannel, viewerId: string): ChatUser | null {\n const members = (channel.members ?? []).filter(Boolean) as WireChannelMember[];\n const other = members.find((m) => m.user?.id && String(m.user.id) !== viewerId);\n return other?.user ?? null;\n}\n\n/**\n * How many messages the viewer has not read.\n *\n * `member.msgCount` is the count the member has SEEN, so unread is the channel\n * total minus that - clamped at zero because the two counters are updated on\n * different write paths and briefly disagree.\n */\nexport function unreadOf(channel: WireChannel, viewerId: string): number {\n const mine = (channel.members ?? []).find((m) => m?.user?.id && String(m.user.id) === viewerId);\n if (!mine) return 0;\n const total = channel.totalMsgCount ?? 0;\n const seen = mine.msgCount ?? 0;\n return Math.max(0, total - seen);\n}\n\nconst DIRECT_TYPES = new Set(['DIRECT', 'Direct', 'direct']);\n\nfunction looksLikeMachineTitle(value?: string | null): boolean {\n const label = value?.trim() ?? '';\n if (!label) return true;\n if (/^chat[\\s_-]*channel\\b/i.test(label) || /^chat-channel-/i.test(label)) return true;\n if (/^[a-f0-9]{8,}$/i.test(label)) return true;\n if (label.includes('__')) return true;\n if (/^group(\\s+chat)?$/i.test(label)) return true;\n return false;\n}\n\n/** The name a person gave the channel; '' when it only carries a machine id like \"a__b\". */\nfunction storedLabelOf(channel: WireChannel): string {\n if (!looksLikeMachineTitle(channel.displayName)) return channel.displayName!.trim();\n if (!looksLikeMachineTitle(channel.title)) return channel.title!.trim();\n return '';\n}\n\n/** Every other member's name, for a group header; `memberNames` caps at three for a title. */\nfunction allMemberNames(channel: WireChannel, viewerId: string): string[] {\n return (channel.members ?? [])\n .map((member) => member?.user)\n .filter((user): user is ChatUser => user != null && Boolean(user.id) && String(user.id) !== viewerId)\n .map((user) => displayNameOf(user, ''))\n .filter(Boolean);\n}\n\nexport function toConversation(channel: WireChannel, viewerId: string): ChatConversation {\n const peerCandidate = peerOf(channel, viewerId);\n const explicitDirect = DIRECT_TYPES.has(String(channel.type ?? ''));\n const populatedMembers = (channel.members ?? []).filter(Boolean);\n const twoParty = populatedMembers.length === 2 && Boolean(peerCandidate);\n const hasMachineLabel = looksLikeMachineTitle(channel.displayName) && looksLikeMachineTitle(channel.title);\n const storedLabel = storedLabelOf(channel);\n // Two members is a DM - unless the channel is typed (not DIRECT) and someone\n // named it something other than the other person (\"standup\" with two people\n // in it is still a group).\n const namedGroup =\n Boolean(channel.type) &&\n Boolean(storedLabel) &&\n storedLabel.toLowerCase() !== displayNameOf(peerCandidate, '').toLowerCase();\n const isDirect =\n explicitDirect || (twoParty && !namedGroup) || (!channel.type && hasMachineLabel && Boolean(peerCandidate));\n const peer = isDirect ? peerCandidate : null;\n\n const names = memberNames(channel, viewerId);\n const lastAuthor = channel.lastMessage ? pickAuthor(channel.lastMessage) : null;\n const lastAuthorName = lastAuthor && String(lastAuthor.id) !== viewerId ? displayNameOf(lastAuthor, '') : '';\n const creatorName = displayNameOf(channel.creator, '');\n const groupFallback = names.length\n ? names.join(', ')\n : lastAuthorName || (creatorName && creatorName !== 'Unknown' ? creatorName : 'Chat');\n const title = isDirect\n ? displayNameOf(peer, storedLabel || lastAuthorName || 'Direct message')\n : storedLabel || groupFallback;\n const topic = looksLikeMachineTitle(channel.topic) ? '' : (channel.topic ?? '').trim();\n const lastMessageMine = Boolean(lastAuthor?.id) && String(lastAuthor!.id) === viewerId;\n const lastMessageDeleted = Boolean(channel.lastMessage?.deletedAt);\n const preview = lastMessageDeleted\n ? deletedPreview(lastMessageMine)\n : channel.lastMessage?.message?.trim() || attachmentPreview(channel.lastMessage) || topic;\n\n return {\n id: String(channel.id),\n title,\n subtitle: preview === title ? '' : preview,\n avatarUrl:\n peer?.picture ??\n peer?.profile?.picture ??\n channel.members?.find((member) => member?.user?.picture)?.user?.picture ??\n lastAuthor?.picture ??\n lastAuthor?.profile?.picture ??\n null,\n lastActivity: toEpoch(channel.lastPostAt) || toEpoch(channel.createdAt),\n unreadCount: unreadOf(channel, viewerId),\n isDirect,\n peer,\n memberNames: allMemberNames(channel, viewerId),\n lastMessageMine,\n lastAuthorName: channel.lastMessage && !lastMessageMine ? lastAuthorName : '',\n lastMessageAt: toEpoch(channel.lastMessage?.createdAt),\n readWatermark: readWatermarkOf(channel, viewerId),\n mutedUntil: mutedUntilOf(channel),\n deliveredWatermark: deliveredWatermarkOf(channel, viewerId),\n pinnedAt: toEpoch(channel.viewerPinnedAt ?? null),\n archivedAt: toEpoch(channel.viewerArchivedAt ?? null),\n lastMessageDeleted,\n draft: (channel.viewerDraft ?? '').trim(),\n };\n}\n\n/**\n * Conversation list order: most recent first, then title, then id.\n *\n * The trailing keys matter more than they look. A channel with no messages has\n * `lastActivity === 0`, so a fresh account is entirely ties; without a stable\n * tiebreak the list reshuffles on every poll.\n */\nexport function sortConversations(list: ChatConversation[]): ChatConversation[] {\n // Pinned chats stay on top (most recently pinned first), as in WhatsApp.\n return list\n .slice()\n .sort(\n (a, b) =>\n Number(b.pinnedAt > 0) - Number(a.pinnedAt > 0) ||\n b.pinnedAt - a.pinnedAt ||\n b.lastActivity - a.lastActivity ||\n a.title.localeCompare(b.title) ||\n compareIds(a.id, b.id),\n );\n}\n\n/** Stable key for collapsing duplicate list rows (same person, multiple channel ids). */\nexport function conversationListKey(c: ChatConversation): string {\n if (c.peer?.id) return `peer:${String(c.peer.id)}`;\n const title = c.title.trim().toLowerCase();\n if (!title || title === 'chat' || title === 'unknown') return `id:${c.id}`;\n // Multi-person groups use comma-separated titles; keep those distinct.\n if (title.includes(',')) return `id:${c.id}`;\n if (c.isDirect) return `title:${title}`;\n // Server often returns duplicate 1:1 channels as untyped GROUP rows with the peer's name.\n return `title:${title}`;\n}\n\n/** A row's title when it names one person, lowercased; '' for groups and placeholders. */\nfunction personTitle(c: ChatConversation): string {\n const title = c.title.trim().toLowerCase();\n if (!title || title === 'chat' || title === 'unknown' || title.includes(',')) return '';\n return title;\n}\n\n/**\n * One row per conversation, newest first. The server also returns a person's\n * 1:1 chat as untyped rows under their name, so a row that names its peer and a\n * peerless row with the same name are one person - but two peers who share a\n * name stay two rows.\n */\nexport function dedupeConversationList(list: ChatConversation[]): ChatConversation[] {\n const peers = new Set<string>();\n const peerTitles = new Set<string>();\n const titles = new Set<string>();\n return sortConversations(list).filter((c) => {\n const title = personTitle(c);\n const peerId = c.peer?.id ? String(c.peer.id) : '';\n if (peerId) {\n if (peers.has(peerId) || (title && titles.has(title))) return false;\n peers.add(peerId);\n if (title) peerTitles.add(title);\n return true;\n }\n if (!title) return true;\n if (titles.has(title) || peerTitles.has(title)) return false;\n titles.add(title);\n return true;\n });\n}\n\n/** @deprecated Use dedupeConversationList */\nexport function dedupeDirectConversations(list: ChatConversation[]): ChatConversation[] {\n return dedupeConversationList(list);\n}\n\nexport function mergeConversations(existing: ChatConversation[], incoming: ChatConversation[]): ChatConversation[] {\n const byId = new Map<string, ChatConversation>();\n for (const c of existing) byId.set(c.id, c);\n for (const c of incoming) byId.set(c.id, c);\n return dedupeConversationList(Array.from(byId.values()));\n}\n\n/** The list preview after a post: unchanged for an empty one, hidden when it only repeats the title. */\nfunction subtitleAfterPost(conv: ChatConversation, preview: string | null | undefined): string {\n if (!preview) return conv.subtitle;\n return preview === conv.title ? '' : preview;\n}\n\n/** Refresh preview + sort key when a new post lands (send echo or subscription). */\nexport function patchConversationAfterPost(conv: ChatConversation, post: WirePost, viewerId: string): ChatConversation {\n const preview = post.message?.trim() || attachmentPreview(post);\n const nextSubtitle = subtitleAfterPost(conv, preview);\n const activity = toEpoch(post.createdAt) || Date.now();\n const author = pickAuthor(post);\n const fromPeer = Boolean(author) && String(author!.id) !== viewerId;\n return {\n ...conv,\n subtitle: nextSubtitle,\n lastActivity: activity,\n unreadCount: fromPeer ? conv.unreadCount + 1 : conv.unreadCount,\n lastMessageMine: Boolean(author) && !fromPeer,\n lastAuthorName: fromPeer ? displayNameOf(author, '') : '',\n lastMessageAt: activity,\n lastMessageDeleted: false,\n };\n}\n\n/**\n * An edit or a delete-for-everyone: only the list preview can change, and only when the\n * changed message is the newest one. Never touches unread or the sort order.\n */\nexport function patchConversationAfterUpdate(\n conv: ChatConversation,\n post: WirePost,\n viewerId: string,\n): ChatConversation {\n const at = toEpoch(post.createdAt);\n if (!at || at !== conv.lastMessageAt) return conv;\n const author = pickAuthor(post);\n const mine = Boolean(author?.id) && String(author!.id) === viewerId;\n if (post.deletedAt) return { ...conv, subtitle: deletedPreview(mine), lastMessageDeleted: true };\n const preview = post.message?.trim() || attachmentPreview(post);\n return { ...conv, subtitle: subtitleAfterPost(conv, preview) };\n}\n\nexport type ChatListFilter = 'all' | 'unread' | 'groups';\n\n/** The rows a filter chip keeps. */\nexport function filterConversations(list: ChatConversation[], filter: ChatListFilter): ChatConversation[] {\n if (filter === 'unread') return list.filter((c) => c.unreadCount > 0);\n if (filter === 'groups') return list.filter((c) => !c.isDirect);\n return list;\n}\n\n/** What the empty list says, and offers, for the current search and filter. */\nexport function emptyListCopy({\n searching,\n filter,\n canInvite,\n}: {\n searching: boolean;\n filter: ChatListFilter;\n canInvite: boolean;\n}): { title: string; detail: string; action: 'all' | 'new' | null } {\n if (searching) return { title: 'No chats found', detail: 'Try a different search or filter.', action: null };\n if (filter === 'unread') return { title: 'No unread chats', detail: 'You’re all caught up.', action: 'all' };\n if (filter === 'groups') return { title: 'No group chats', detail: 'Groups you’re in show here.', action: 'all' };\n if (canInvite) {\n return {\n title: 'No conversations yet',\n detail: 'Tap the compose button to find people from your contacts.',\n action: 'new',\n };\n }\n return {\n title: 'No conversations yet',\n detail: 'Contacts are unavailable in this build, so new chats cannot be started here yet.',\n action: null,\n };\n}\n\n/**\n * Day separators, computed against a caller-supplied \"now\".\n *\n * The clock is a parameter so this is testable and so a device with a skewed\n * clock does not silently label everything \"Today\".\n */\nexport function dayLabel(epoch: number, now: number): string {\n if (!epoch) return '';\n const d = new Date(epoch);\n const n = new Date(now);\n const sameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n if (sameDay(d, n)) return 'Today';\n const yesterday = new Date(now);\n yesterday.setDate(yesterday.getDate() - 1);\n if (sameDay(d, yesterday)) return 'Yesterday';\n return d.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: d.getFullYear() === n.getFullYear() ? undefined : 'numeric',\n });\n}\n\n/** Short clock label for a bubble. */\nexport function timeLabel(epoch: number): string {\n if (!epoch) return '';\n return new Date(epoch).toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n}\n\n/** Relative age for the conversation list. */\nexport function relativeLabel(epoch: number, now: number): string {\n if (!epoch) return '';\n const diff = now - epoch;\n if (diff < 60_000) return 'now';\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m`;\n const d = new Date(epoch);\n const n = new Date(now);\n if (d.getFullYear() === n.getFullYear() && d.getMonth() === n.getMonth() && d.getDate() === n.getDate()) {\n return timeLabel(epoch);\n }\n if (diff < 7 * 86_400_000) return d.toLocaleDateString(undefined, { weekday: 'short' });\n return d.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });\n}\n\n/** Initials for the avatar fallback; never more than two glyphs. */\nexport function initialsOf(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (!parts.length) return '?';\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n}\n\n/** \"Muted\", \"Muted until 9:30 PM\", \"Muted until Oct 20\" - '' when not muted. */\nexport function muteLabel(mutedUntil: number, now: number): string {\n if (mutedUntil <= now) return '';\n // Anything past the year 3000 is the \"Always\" sentinel, whatever exact instant a server wrote.\n if (mutedUntil >= MUTE_FOREVER_EPOCH || new Date(mutedUntil).getFullYear() >= 3000) return 'Muted';\n const sameDay = new Date(mutedUntil).toDateString() === new Date(now).toDateString();\n return sameDay\n ? `Muted until ${timeLabel(mutedUntil)}`\n : `Muted until ${new Date(mutedUntil).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}`;\n}\n"],"names":["_a","_b","next"],"mappings":"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"}
1
+ {"version":3,"file":"chatModel.js","sources":["../../../src/features/messaging/chatModel.ts"],"sourcesContent":["/**\n * Pure shaping between messenger-box's wire types and what the chat UI renders.\n *\n * Everything here is a plain function over plain data - no React, no seams, no\n * clock beyond what is passed in - because this is where the bugs that actually\n * ruin a chat client live: messages in the wrong order, a duplicate after a\n * reconnect, an optimistic row that never resolves, a DM titled with your own\n * name. Those are all cheap to unit-test and expensive to debug on a device.\n */\n\nexport interface ChatUser {\n id: string;\n givenName?: string | null;\n familyName?: string | null;\n username?: string | null;\n email?: string | null;\n picture?: string | null;\n profile?: { displayName?: string | null; picture?: string | null } | null;\n}\n\nexport interface WirePost {\n id: string;\n message?: string | null;\n type?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n editedAt?: string | null;\n deletedAt?: string | null;\n rootId?: string | null;\n parentId?: string | null;\n filenames?: (string | null)[] | null;\n /** A server-authored group system line (\"Alex added Sam\"); renders as a centered notice. */\n fromServer?: boolean | null;\n props?: Record<string, unknown> | null;\n /** Attached files (messenger-box `Post.files`, linked to the post by id). */\n files?: { data?: (WireFile | null)[] | null } | null;\n author?: ChatUser | null;\n creator?: ChatUser | null;\n reactionSummary?: WireReaction[] | null;\n /** The viewer starred it (resolved for the caller only). */\n viewerStarred?: boolean | null;\n /** The chat it is in - present on cross-chat lists such as starred messages. */\n channel?: { id?: string | null } | null;\n}\n\nexport interface WireFile {\n id?: string | null;\n name?: string | null;\n mimeType?: string | null;\n url?: string | null;\n width?: number | null;\n height?: number | null;\n size?: number | null;\n}\n\n/** What a message's `props.attachmentKind` says the attachments are (set when sending). */\nexport type ChatAttachmentKind = 'image' | 'audio' | 'file';\n\n/**\n * One attached file. `url` is what the server returned (an image-resizer thumbnail for every\n * type) or, while sending, the local file; `key` is the storage key, from which the UI builds\n * the full-size / playable CDN URL (see `attachmentUrl`).\n */\nexport interface ChatAttachment {\n id: string;\n kind: ChatAttachmentKind;\n name: string;\n mimeType: string;\n url: string;\n key: string | null;\n width?: number | null;\n height?: number | null;\n /** Voice notes: recorded length (from the message's props). */\n durationMs?: number | null;\n}\n\nexport interface WireReaction {\n reaction: string;\n count: number;\n userIds?: (string | null)[] | null;\n}\n\n/** One Tapback on a message, grouped across users. */\nexport interface ChatReaction {\n reaction: string;\n count: number;\n /** The viewer is one of the reactors. */\n mine: boolean;\n userIds: string[];\n}\n\nexport interface WireChannelMember {\n id?: string | null;\n user?: ChatUser | null;\n msgCount?: number | null;\n lastViewedAt?: string | null;\n /** This member's devices have the channel's messages up to then. */\n lastDeliveredAt?: string | null;\n /** 'admin' for a group admin, else 'member'. */\n roles?: string | null;\n}\n\nexport interface WireChannel {\n id: string;\n type?: string | null;\n orgName?: string | null;\n title?: string | null;\n displayName?: string | null;\n topic?: string | null;\n description?: string | null;\n lastPostAt?: string | null;\n totalMsgCount?: number | null;\n createdAt?: string | null;\n lastMessage?: WirePost | null;\n creator?: ChatUser | null;\n members?: (WireChannelMember | null)[] | null;\n /**\n * Channel settings; `onlyAdminsSend` locks a group's composer for non-admins,\n * `disappearingSeconds` is the auto-delete timer (0 / unset = off).\n */\n settings?: { onlyAdminsSend?: boolean | null; disappearingSeconds?: number | null } | null;\n /** How many unread messages mention the viewer (resolved for the caller only). */\n viewerUnreadMentions?: number | null;\n /** Until when the VIEWER muted this chat (resolved for the caller only); null when not muted. */\n viewerMutedUntil?: string | null;\n /** When the viewer pinned / archived this chat in their own list; null when not. */\n viewerPinnedAt?: string | null;\n viewerArchivedAt?: string | null;\n /** The viewer's unsent draft here (resolved for the caller only). */\n viewerDraft?: string | null;\n}\n\n/** Where an optimistic message is in its lifecycle. */\nexport type ChatSendState = 'sending' | 'sent' | 'failed';\n\n/** The message a reply quotes, copied into the reply when it is sent (`props.replyTo`). */\nexport interface ChatReplyRef {\n id: string;\n authorId: string | null;\n authorName: string;\n /** The quoted text, or the attachment label for a photo / voice message. */\n body: string;\n}\n\n/** What the ticks on the viewer's own message say. */\nexport type ChatMessageStatus = 'sending' | 'failed' | 'sent' | 'delivered' | 'read';\n\n/** A group system event, parsed from a server-authored post's `props.system`. */\nexport interface ChatSystemEvent {\n event: string;\n actorId: string | null;\n targetIds: string[];\n value?: string | null;\n}\n\n/** One option of a poll, with its live tally (derived from the shared voter-id arrays). */\nexport interface ChatPollOption {\n id: string;\n text: string;\n /** How many members picked this option. */\n count: number;\n /** The voters' account ids (non-anonymous, like WhatsApp). */\n voterIds: string[];\n /** The viewer picked this option. */\n mine: boolean;\n}\n\n/** A poll message (`props.poll`). Votes are shared and non-anonymous. */\nexport interface ChatPoll {\n question: string;\n /** Members may pick more than one option. */\n multiple: boolean;\n options: ChatPollOption[];\n /** Distinct members who have voted on anything. */\n totalVoters: number;\n}\n\n/** The WhatsApp-style disappearing-timer choices (seconds). 0 = off. */\nexport const DISAPPEARING_OPTIONS: ReadonlyArray<{ label: string; seconds: number }> = [\n { label: 'Off', seconds: 0 },\n { label: '24 hours', seconds: 86400 },\n { label: '7 days', seconds: 604800 },\n { label: '90 days', seconds: 7776000 },\n];\n\n/** A disappearing timer in words, for the info row and the system line (e.g. 604800 -> \"7 days\"). */\nexport function disappearingLabel(seconds: number | null | undefined): string {\n const s = Number(seconds) || 0;\n const match = DISAPPEARING_OPTIONS.find((o) => o.seconds === s);\n if (match) return match.label;\n return s > 0 ? 'On' : 'Off';\n}\n\n/** A group member, for the picker, the info screen and @mention rendering. */\nexport interface ChatGroupMember {\n id: string;\n name: string;\n avatarUrl?: string | null;\n isAdmin: boolean;\n isYou: boolean;\n}\n\n/** WhatsApp lets you edit a message for 15 minutes and delete it for everyone for about two days. */\nexport const EDIT_WINDOW_MS = 15 * 60_000;\nexport const DELETE_FOR_EVERYONE_WINDOW_MS = 48 * 3_600_000;\n\nexport interface ChatMessage {\n id: string;\n body: string;\n createdAt: number;\n authorId: string | null;\n authorName: string;\n authorAvatar?: string | null;\n isMine: boolean;\n isDeleted: boolean;\n isEdited: boolean;\n attachments: ChatAttachment[];\n /** Tapbacks, in first-use order. Empty when nobody reacted. */\n reactions: ChatReaction[];\n /** The message this one replies to. */\n replyTo?: ChatReplyRef | null;\n /** The viewer starred it. */\n starred?: boolean;\n /** Sent on from another chat (\"Forwarded\"). */\n forwarded?: boolean;\n /** A centered system notice (\"Alex added Sam\") rather than a bubble. */\n system?: ChatSystemEvent | null;\n /** Member ids this message @mentions (groups). */\n mentions?: string[];\n /** A poll (`props.poll`), with live per-option tallies. */\n poll?: ChatPoll | null;\n /** Kept past the disappearing sweep (`props.kept`); shows a \"Kept\" marker. */\n kept?: boolean;\n /** The disappearing sweep removed this message (`props.disappeared`): drop the row. */\n disappeared?: boolean;\n /** Present only on messages this device is still sending. */\n sendState?: ChatSendState;\n /** The optimistic id this row replaced, so the UI can animate rather than jump. */\n replacedClientId?: string;\n}\n\nexport interface ChatConversation {\n id: string;\n title: string;\n subtitle: string;\n avatarUrl?: string | null;\n /** Sort key; 0 when the channel has never had a message. */\n lastActivity: number;\n unreadCount: number;\n isDirect: boolean;\n /** The other participant, for a DM. Null for groups. */\n peer: ChatUser | null;\n /** The other members' names, for a group's header (\"Asha, Ben, Chen\"). */\n memberNames: string[];\n /** A group's members (empty for a DM): the source for info, the picker and @mentions. */\n members: ChatGroupMember[];\n /** The viewer is an admin of this group. */\n viewerIsAdmin: boolean;\n /** Only admins may send in this group. */\n onlyAdminsSend: boolean;\n /** Disappearing-messages timer for this chat in seconds; 0 = off. */\n disappearingSeconds: number;\n /** Who created the group (always an admin, cannot be removed). */\n creatorId: string | null;\n /** The group's description, shown on the info screen. */\n description: string;\n /** How many unread messages mention the viewer (the \"@\" badge). */\n unreadMentions: number;\n /** The newest message is the viewer's own, so the list shows its ticks. */\n lastMessageMine: boolean;\n /** Who wrote the newest message in a group, when it was not the viewer. */\n lastAuthorName: string;\n /** When the newest message was sent (epoch millis), for its ticks. */\n lastMessageAt: number;\n /**\n * Everyone else has read up to here (epoch millis): the earliest `lastViewedAt` among the\n * other members. The viewer's messages at or before it show blue ticks. 0 = unknown.\n */\n readWatermark: number;\n /** Everyone else's devices have received up to here: two gray ticks. 0 = unknown. */\n deliveredWatermark: number;\n /** The viewer silenced this chat's notifications until then (epoch millis). 0 = not muted. */\n mutedUntil: number;\n /** Pinned to the top of the viewer's list (epoch millis); 0 = not pinned. */\n pinnedAt: number;\n /** Archived out of the viewer's list (epoch millis); 0 = not archived. */\n archivedAt: number;\n /** The newest message was deleted for everyone. */\n lastMessageDeleted: boolean;\n /** The viewer's unsent text in this chat; the list shows it as \"Draft: …\". */\n draft: string;\n}\n\n/**\n * A person's display name, in the order a human would expect.\n *\n * Email is the last resort and is truncated at the `@`: a transcript full of\n * `someone@example.com` is worse than one full of `someone`.\n */\n/** Ids in a stable order, the last tiebreak for a sort. */\nfunction compareIds(a: string, b: string): number {\n if (a === b) return 0;\n return a < b ? -1 : 1;\n}\n\nexport function displayNameOf(user?: ChatUser | null, fallback = 'Unknown'): string {\n if (!user) return fallback;\n const profileName = user.profile?.displayName?.trim();\n if (profileName) return profileName;\n const fullName = [user.givenName, user.familyName].filter(Boolean).join(' ').trim();\n if (fullName) return fullName;\n const username = user.username?.trim();\n if (username) return username;\n const email = user.email?.trim();\n if (email) return email.split('@')[0] || fallback;\n return fallback;\n}\n\nfunction memberNames(channel: WireChannel, viewerId: string): string[] {\n return (channel.members ?? [])\n .map((member) => member?.user)\n .filter((user): user is ChatUser => user != null && Boolean(user.id) && String(user.id) !== viewerId)\n .map((user) => displayNameOf(user, ''))\n .filter(Boolean)\n .slice(0, 3);\n}\n\n/**\n * messenger-box populates `author` on some write paths and `creator` on others\n * (`sendMessage` sets creator). Reading only one shows \"Unknown\" for a large\n * fraction of real transcripts.\n */\nexport function pickAuthor(post: WirePost): ChatUser | null {\n return post.author ?? post.creator ?? null;\n}\n\n/** Epoch millis, tolerant of nulls and unparseable values. */\nexport function toEpoch(value?: string | number | null): number {\n if (value == null) return 0;\n if (typeof value === 'number') return Number.isFinite(value) ? value : 0;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\nfunction kindOfMime(mimeType: string): ChatAttachmentKind {\n if (mimeType.startsWith('image/')) return 'image';\n if (mimeType.startsWith('audio/')) return 'audio';\n return 'file';\n}\n\n/**\n * The storage key inside a file URL. messenger-box hands back image-resizer URLs\n * (`<handler>/fit-in/150x150/<key>`) for every attachment; a plain storage URL or a bare key\n * also works.\n */\nexport function fileKeyFromUrl(url: string | null | undefined): string | null {\n const value = (url ?? '').trim();\n if (!value) return null;\n const resized = value.match(/\\/fit-in\\/\\d+x\\d+\\/(.+)$/);\n if (resized) return decodeURIComponent(resized[1].split('?')[0]);\n if (!/^[a-z]+:\\/\\//i.test(value)) return value.split('?')[0];\n if (/^(file|content|ph|assets-library):/i.test(value)) return null;\n try {\n return decodeURIComponent(new URL(value).pathname.replace(/^\\/+/, '')) || null;\n } catch {\n return null;\n }\n}\n\n/** Full-size (image) or playable (audio) URL: the CDN copy when a base is known, else what we have. */\nexport function attachmentUrl(attachment: ChatAttachment, fileBaseUrl?: string | null): string {\n if (!attachment.key || !fileBaseUrl) return attachment.url;\n return `${fileBaseUrl.replace(/\\/+$/, '')}/${attachment.key}`;\n}\n\n/** `props` is an AnyObject scalar: an object from some paths, a JSON string from others. */\nfunction propsOf(post: WirePost | null | undefined): Record<string, unknown> {\n const raw = post?.props as unknown;\n if (raw && typeof raw === 'object') return raw as Record<string, unknown>;\n if (typeof raw === 'string') {\n try {\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n }\n return {};\n}\n\nexport function toChatAttachments(post: WirePost): ChatAttachment[] {\n const props = propsOf(post) as { attachmentKind?: unknown; voiceDurationMs?: unknown };\n const durationMs = typeof props.voiceDurationMs === 'number' ? props.voiceDurationMs : null;\n return (post.files?.data ?? [])\n .filter((f): f is WireFile => Boolean(f?.url))\n .map((f, i) => {\n const mimeType = f.mimeType ?? 'application/octet-stream';\n const kind = kindOfMime(mimeType);\n return {\n id: String(f.id ?? `${post.id}-${i}`),\n kind,\n name: f.name ?? 'file',\n mimeType,\n url: String(f.url),\n key: fileKeyFromUrl(f.url),\n width: f.width ?? null,\n height: f.height ?? null,\n durationMs: kind === 'audio' ? durationMs : null,\n };\n });\n}\n\n/**\n * The text of an attachment-only message. messenger-box requires non-blank message text, so this\n * label is sent as the text: push notifications and other clients read it, and this app hides it\n * inside the bubble (see `toChatMessage`).\n */\nexport const ATTACHMENT_LABELS: Record<ChatAttachmentKind, string> = {\n image: '📷 Photo',\n audio: '🎤 Voice message',\n file: '📎 Attachment',\n};\n\n/** Chat-list preview for a message that is only an attachment. */\nexport function attachmentPreview(post: WirePost | null | undefined): string {\n const kind = propsOf(post).attachmentKind;\n return typeof kind === 'string' && kind in ATTACHMENT_LABELS ? ATTACHMENT_LABELS[kind as ChatAttachmentKind] : '';\n}\n\n/** Chat-list preview for a poll message (\"📊 Poll · <question>\"); '' when the post is not a poll. */\nexport function pollPreview(post: WirePost | null | undefined): string {\n if (!post) return '';\n const raw = propsOf(post).poll as { question?: unknown; options?: unknown } | undefined;\n if (!raw || typeof raw !== 'object' || !Array.isArray(raw.options)) return '';\n const q = typeof raw.question === 'string' ? raw.question.trim() : '';\n return q ? `📊 Poll · ${q}` : '📊 Poll';\n}\n\nconst LABEL_TEXTS = new Set(Object.values(ATTACHMENT_LABELS));\n\n/** The bubble text: an attachment-only message's label is not shown next to the attachment itself. */\nfunction bodyOf(post: WirePost, hasAttachments: boolean): string {\n const body = post.message ?? '';\n const trimmed = body.trim();\n const label = attachmentPreview(post);\n if (label && trimmed === label) return '';\n // Same label with the files attached, even if props did not come back.\n return hasAttachments && LABEL_TEXTS.has(trimmed) ? '' : body;\n}\n\nexport function toChatReactions(summary: WireReaction[] | null | undefined, viewerId: string): ChatReaction[] {\n return (summary ?? [])\n .filter((r) => r && r.reaction && r.count > 0)\n .map((r) => {\n const userIds = (r.userIds ?? []).filter((u): u is string => typeof u === 'string' && u.length > 0);\n return { reaction: r.reaction, count: r.count, userIds, mine: userIds.includes(viewerId) };\n });\n}\n\n/** Longest quote a reply carries; the bubble shows two lines of it anyway. */\nconst REPLY_QUOTE_MAX = 200;\n\n/** The quote a reply to `message` carries. */\nexport function replyRefOf(message: ChatMessage): ChatReplyRef {\n const kind = message.attachments[0]?.kind;\n const body = message.body.trim() || (kind ? ATTACHMENT_LABELS[kind] : '');\n return {\n id: message.id,\n authorId: message.authorId,\n authorName: message.authorName,\n body: body.length > REPLY_QUOTE_MAX ? `${body.slice(0, REPLY_QUOTE_MAX - 1)}…` : body,\n };\n}\n\n/** `props.replyTo`, when it is a well-formed quote; anything else is ignored rather than rendered. */\nfunction replyOf(post: WirePost): ChatReplyRef | null {\n const raw = propsOf(post).replyTo as Partial<Record<keyof ChatReplyRef, unknown>> | undefined;\n if (!raw || typeof raw !== 'object' || typeof raw.id !== 'string' || !raw.id) return null;\n return {\n id: raw.id,\n authorId: typeof raw.authorId === 'string' ? raw.authorId : null,\n authorName: typeof raw.authorName === 'string' && raw.authorName ? raw.authorName : 'Unknown',\n body: typeof raw.body === 'string' ? raw.body.slice(0, REPLY_QUOTE_MAX) : '',\n };\n}\n\n/** `props.system`, when it is a well-formed group event; else null. */\nfunction systemEventOf(post: WirePost): ChatSystemEvent | null {\n if (!post.fromServer) return null;\n const raw = propsOf(post).system as Partial<Record<string, unknown>> | undefined;\n if (!raw || typeof raw !== 'object' || typeof raw.event !== 'string' || !raw.event) return null;\n return {\n event: raw.event,\n actorId: typeof raw.actorId === 'string' ? raw.actorId : null,\n targetIds: Array.isArray(raw.targetIds) ? raw.targetIds.filter((t): t is string => typeof t === 'string') : [],\n value: typeof raw.value === 'string' ? raw.value : null,\n };\n}\n\n/** Member ids a message @mentions (`props.mentions`). */\nfunction mentionsOf(post: WirePost): string[] {\n const raw = propsOf(post).mentions;\n return Array.isArray(raw) ? raw.filter((m): m is string => typeof m === 'string' && m.length > 0) : [];\n}\n\n/**\n * `props.poll`, parsed into options with live tallies. The per-option `count`/`mine` are DERIVED\n * from the shared `votes` arrays (one accountId list per option) exactly as reactions derive\n * `mine` from userIds - the poll is non-anonymous, so the voter ids live in shared props. Returns\n * null when the post carries no well-formed poll.\n */\nexport function pollOf(post: WirePost, viewerId: string): ChatPoll | null {\n const raw = propsOf(post).poll as\n | { question?: unknown; multiple?: unknown; options?: unknown; votes?: unknown }\n | undefined;\n if (!raw || typeof raw !== 'object' || !Array.isArray(raw.options)) return null;\n const votes = (raw.votes && typeof raw.votes === 'object' ? raw.votes : {}) as Record<string, unknown>;\n const voters = new Set<string>();\n const options: ChatPollOption[] = raw.options\n .map((o) => o as { id?: unknown; text?: unknown })\n .filter((o) => o && typeof o.id === 'string')\n .map((o) => {\n const id = String(o.id);\n const arr = Array.isArray(votes[id]) ? (votes[id] as unknown[]) : [];\n const voterIds = arr.filter((v): v is string => typeof v === 'string' && v.length > 0);\n voterIds.forEach((v) => voters.add(v));\n return {\n id,\n text: typeof o.text === 'string' ? o.text : '',\n count: voterIds.length,\n voterIds,\n mine: voterIds.includes(viewerId),\n };\n });\n if (!options.length) return null;\n return {\n question: typeof raw.question === 'string' ? raw.question : '',\n multiple: raw.multiple === true,\n options,\n totalVoters: voters.size,\n };\n}\n\n/**\n * The centered line for a group system event, named from the viewer's own point of view\n * (\"You added Sam\" / \"Alex added you\"). `nameOf(id)` resolves a member id to a display name.\n */\nexport function systemText(\n system: ChatSystemEvent,\n viewerId: string,\n nameOf: (id: string | null | undefined) => string,\n): string {\n const youOrName = (id: string | null | undefined) => (id && String(id) === viewerId ? 'You' : nameOf(id));\n const actor = youOrName(system.actorId);\n const targets = system.targetIds;\n const targetNames = targets.map((t) => youOrName(t));\n const targetsAreYouOnly = targets.length === 1 && String(targets[0]) === viewerId;\n switch (system.event) {\n case 'group.created':\n return system.value ? `${actor} created the group \"${system.value}\"` : `${actor} created the group`;\n case 'member.added':\n return targetsAreYouOnly ? `${actor} added you` : `${actor} added ${targetNames.join(', ')}`;\n case 'member.removed':\n return targetsAreYouOnly ? `${actor} removed you` : `${actor} removed ${targetNames.join(', ')}`;\n case 'member.left':\n return `${actor} left`;\n case 'admin.granted':\n return targetsAreYouOnly\n ? `${actor} made you an admin`\n : `${actor} made ${targetNames.join(', ')} an admin`;\n case 'admin.dismissed':\n return targetsAreYouOnly\n ? `${actor} dismissed you as admin`\n : `${actor} dismissed ${targetNames.join(', ')} as admin`;\n case 'group.renamed':\n return system.value\n ? `${actor} changed the group name to \"${system.value}\"`\n : `${actor} changed the group name`;\n case 'group.description':\n return `${actor} changed the group description`;\n case 'group.sendPolicy':\n return system.value === 'adminsOnly'\n ? `${actor} changed who can send messages to only admins`\n : `${actor} allowed everyone to send messages`;\n case 'chat.disappearing': {\n if (!system.value || system.value === 'off') return `${actor} turned off disappearing messages`;\n const durations: Record<string, string> = { '24h': '24 hours', '7d': '7 days', '90d': '90 days' };\n const label = durations[system.value] ?? system.value;\n return `${actor} turned on disappearing messages (${label})`;\n }\n default:\n return 'Group updated';\n }\n}\n\nexport function toChatMessage(post: WirePost, viewerId: string): ChatMessage {\n const author = pickAuthor(post);\n const attachments = toChatAttachments(post);\n const system = systemEventOf(post);\n return {\n id: String(post.id),\n body: bodyOf(post, attachments.length > 0),\n createdAt: toEpoch(post.createdAt),\n authorId: author?.id ? String(author.id) : null,\n authorName: displayNameOf(author),\n authorAvatar: author?.picture ?? author?.profile?.picture ?? null,\n isMine: !system && !!author?.id && String(author.id) === viewerId,\n isDeleted: !!post.deletedAt,\n isEdited: !!post.editedAt,\n attachments,\n reactions: toChatReactions(post.reactionSummary, viewerId),\n replyTo: replyOf(post),\n starred: Boolean(post.viewerStarred),\n forwarded: propsOf(post).forwarded === true,\n system,\n mentions: mentionsOf(post),\n poll: pollOf(post, viewerId),\n kept: Boolean(propsOf(post).kept),\n disappeared: propsOf(post).disappeared === true,\n };\n}\n\n/** The list preview of a message deleted for everyone, as WhatsApp words it. */\nexport function deletedPreview(mine: boolean): string {\n return mine ? 'You deleted this message' : 'This message was deleted';\n}\n\n/**\n * The ticks on one of the viewer's messages: a clock while sending, one gray tick once the\n * server has it, two gray ticks once everyone else's phone has it, two blue ticks once everyone\n * else has opened the chat since it was sent.\n */\nexport function messageStatus(message: ChatMessage, readWatermark: number, deliveredWatermark = 0): ChatMessageStatus {\n if (message.sendState === 'sending') return 'sending';\n if (message.sendState === 'failed') return 'failed';\n if (!message.createdAt) return 'sent';\n if (readWatermark > 0 && message.createdAt <= readWatermark) return 'read';\n if (deliveredWatermark > 0 && message.createdAt <= deliveredWatermark) return 'delivered';\n return 'sent';\n}\n\n/**\n * How far everyone else's phones have received: per other member the later of\n * `lastDeliveredAt` and `lastViewedAt` (having read it means having it), then the earliest\n * of those. 0 when any other member's phone has reported nothing.\n */\nexport function deliveredWatermarkOf(channel: WireChannel, viewerId: string): number {\n const others = (channel.members ?? []).filter(\n (m): m is WireChannelMember => Boolean(m?.user?.id) && String(m!.user!.id) !== viewerId,\n );\n if (!others.length) return 0;\n let watermark = Number.POSITIVE_INFINITY;\n for (const member of others) {\n const got = Math.max(toEpoch(member.lastDeliveredAt), toEpoch(member.lastViewedAt));\n if (!got) return 0;\n watermark = Math.min(watermark, got);\n }\n return watermark;\n}\n\n/** The viewer can still edit this message (their own text, within 15 minutes). */\nexport function canEditMessage(message: ChatMessage, now: number): boolean {\n return (\n message.isMine &&\n !message.isDeleted &&\n (!message.sendState || message.sendState === 'sent') &&\n message.attachments.length === 0 &&\n Boolean(message.body.trim()) &&\n now - message.createdAt <= EDIT_WINDOW_MS\n );\n}\n\n/** The viewer can still delete this message for everyone (their own, within 48 hours). */\nexport function canDeleteForEveryone(message: ChatMessage, now: number): boolean {\n return (\n message.isMine &&\n !message.isDeleted &&\n (!message.sendState || message.sendState === 'sent') &&\n now - message.createdAt <= DELETE_FOR_EVERYONE_WINDOW_MS\n );\n}\n\n/**\n * Where the \"N unread messages\" band goes: above the oldest of the `unreadCount` newest\n * messages from other people. Null when nothing is unread or that message is not loaded.\n */\nexport function firstUnreadId(messages: ChatMessage[], unreadCount: number): string | null {\n if (unreadCount <= 0) return null;\n // System lines (\"Alex added Sam\") are not unread messages from a person.\n const fromOthers = messages.filter((m) => !m.isMine && !m.system);\n return fromOthers.length >= unreadCount ? fromOthers[fromOthers.length - unreadCount].id : null;\n}\n\n/** Who has a message, for Message info. */\nexport interface MessageReceipts {\n readBy: string[];\n deliveredTo: string[];\n /** Neither delivered nor read yet. */\n remaining: string[];\n}\n\n/**\n * Message info, WhatsApp-style, from each other member's watermarks: read once they opened\n * the chat after it was sent, delivered once their phone had the chat's messages after it was\n * sent. Watermarks say WHETHER, not exactly when, so Message info shows no per-person time.\n */\nexport function messageReceipts(\n message: Pick<ChatMessage, 'createdAt'>,\n channel: WireChannel,\n viewerId: string,\n): MessageReceipts {\n const out: MessageReceipts = { readBy: [], deliveredTo: [], remaining: [] };\n const others = (channel.members ?? []).filter(\n (m): m is WireChannelMember => m != null && Boolean(m.user?.id) && String(m.user!.id) !== viewerId,\n );\n others.forEach((member) => {\n const name = displayNameOf(member.user);\n const sent = message.createdAt;\n if (sent && toEpoch(member.lastViewedAt) >= sent) out.readBy.push(name);\n else if (sent && toEpoch(member.lastDeliveredAt) >= sent) out.deliveredTo.push(name);\n else out.remaining.push(name);\n });\n return out;\n}\n\n/**\n * How far everyone else has read: the EARLIEST other member's `lastViewedAt`, so a group\n * message turns blue only once every member has seen it (as WhatsApp does). 0 when any\n * other member has never opened the chat or the server did not say.\n */\nexport function readWatermarkOf(channel: WireChannel, viewerId: string): number {\n const others = (channel.members ?? []).filter(\n (m): m is WireChannelMember => Boolean(m?.user?.id) && String(m!.user!.id) !== viewerId,\n );\n if (!others.length) return 0;\n let watermark = Number.POSITIVE_INFINITY;\n for (const member of others) {\n const viewed = toEpoch(member.lastViewedAt);\n if (!viewed) return 0;\n watermark = Math.min(watermark, viewed);\n }\n return watermark;\n}\n\n/** Until when the viewer muted this chat (epoch millis); 0 when it is not muted. */\nexport function mutedUntilOf(channel: WireChannel): number {\n return toEpoch(channel.viewerMutedUntil ?? null);\n}\n\nexport function isMuted(conversation: Pick<ChatConversation, 'mutedUntil'>, now: number): boolean {\n return conversation.mutedUntil > now;\n}\n\n/** \"Always\" is stored as a far-future instant so the server compares one date for every option. */\nexport const MUTE_FOREVER_ISO = '9999-12-31T23:59:59.000Z';\nconst MUTE_FOREVER_EPOCH = Date.parse(MUTE_FOREVER_ISO);\n\nexport type ChatMuteOption = '8h' | '1w' | 'always';\n\nexport const MUTE_OPTIONS: ReadonlyArray<{ key: ChatMuteOption; label: string }> = [\n { key: '8h', label: '8 hours' },\n { key: '1w', label: '1 week' },\n { key: 'always', label: 'Always' },\n];\n\n/** The `mutedUntil` an option sends, as ISO. */\nexport function muteUntilFor(option: ChatMuteOption, now: number): string {\n if (option === 'always') return MUTE_FOREVER_ISO;\n const span = option === '8h' ? 8 * 3_600_000 : 7 * 86_400_000;\n return new Date(now + span).toISOString();\n}\n\n/** Replace one message's reactions with the server's latest summary. */\nexport function applyReactionSummary(\n messages: ChatMessage[],\n messageId: string,\n summary: WireReaction[] | null | undefined,\n viewerId: string,\n): ChatMessage[] {\n return messages.map((m) => (m.id === messageId ? { ...m, reactions: toChatReactions(summary, viewerId) } : m));\n}\n\n/**\n * The viewer's reactions after picking `emoji` (null = remove). One Tapback per person,\n * like iMessage: a new pick replaces the old one, the same pick removes it.\n */\nexport function withViewerReaction(reactions: ChatReaction[], emoji: string | null, viewerId: string): ChatReaction[] {\n const current = reactions.find((r) => r.mine)?.reaction ?? null;\n const next = emoji && emoji !== current ? emoji : null;\n const out = reactions\n .map((r) =>\n r.mine ? { ...r, mine: false, count: r.count - 1, userIds: r.userIds.filter((u) => u !== viewerId) } : r,\n )\n .filter((r) => r.count > 0);\n if (!next) return out;\n const idx = out.findIndex((r) => r.reaction === next);\n if (idx >= 0) {\n const r = out[idx];\n out[idx] = { ...r, mine: true, count: r.count + 1, userIds: [...r.userIds, viewerId] };\n return out;\n }\n return [...out, { reaction: next, count: 1, mine: true, userIds: [viewerId] }];\n}\n\n/**\n * The poll after the viewer taps `optionId`, for optimistic rendering. Single-choice switches\n * the pick (and tapping your current pick clears it); multiple-choice toggles just that option.\n * Mirrors the server's reconciliation so the optimistic row matches what comes back. The caller\n * then sends the resulting `mine` option ids as the complete selection to votePoll.\n */\nexport function withViewerPollVote(poll: ChatPoll, optionId: string, viewerId: string): ChatPoll {\n const tappedWasMine = poll.options.find((o) => o.id === optionId)?.mine ?? false;\n const clear = (o: ChatPollOption): ChatPollOption => ({\n ...o,\n mine: false,\n count: Math.max(0, o.count - 1),\n voterIds: o.voterIds.filter((v) => v !== viewerId),\n });\n const set = (o: ChatPollOption): ChatPollOption =>\n o.mine ? o : { ...o, mine: true, count: o.count + 1, voterIds: [...o.voterIds, viewerId] };\n const options = poll.options.map((o) => {\n if (o.id === optionId) return tappedWasMine ? clear(o) : set(o);\n // Single-choice: selecting one clears the others. Multiple-choice: leave the rest alone.\n if (!poll.multiple && !tappedWasMine && o.mine) return clear(o);\n return o;\n });\n const voters = new Set<string>();\n options.forEach((o) => o.voterIds.forEach((v) => voters.add(v)));\n return { ...poll, options, totalVoters: voters.size };\n}\n\n/**\n * Merge a batch of messages into the transcript: de-duplicated by id, oldest\n * first.\n *\n * De-duplication is the whole point. The same message arrives twice all the\n * time - the subscription delivers it while the head-page refetch that follows\n * a reconnect also returns it, and offset paging re-reads a row when something\n * lands mid-scroll. LAST WRITE WINS on a collision, so a server row replaces\n * the optimistic copy rather than the other way round.\n *\n * Ties break on id, not on insertion order: two messages can share a timestamp\n * to the millisecond, and an unstable comparator makes them swap places on\n * every render.\n */\nexport function mergeMessages(existing: ChatMessage[], incoming: ChatMessage[]): ChatMessage[] {\n const byId = new Map<string, ChatMessage>();\n for (const m of existing) byId.set(m.id, m);\n for (const m of incoming) byId.set(m.id, m);\n return Array.from(byId.values()).sort((a, b) => a.createdAt - b.createdAt || compareIds(a.id, b.id));\n}\n\n/**\n * Reconcile a server message with the optimistic row it confirms.\n *\n * Matched on (author, body, nearby timestamp) rather than an echoed client id,\n * because `sendMessage` does not round-trip one. The window is deliberately\n * generous - a slow network is normal - and the cost of a miss is a brief\n * duplicate that the next refetch cleans up, not a lost message.\n */\nexport function reconcileOptimistic(messages: ChatMessage[], confirmed: ChatMessage, windowMs = 60_000): ChatMessage[] {\n // Only the viewer's OWN message can confirm the viewer's pending row.\n // Without this, someone else sending the identical text inside the window\n // consumes the optimistic slot: their message is relabelled as yours and\n // yours disappears. \"ok\", \"thanks\" and \"👍\" collide constantly.\n if (!confirmed.isMine) return mergeMessages(messages, [confirmed]);\n\n // Attachment sends pick the post id up front, so the pending row already has the real id.\n const sameIdIdx = messages.findIndex((m) => m.id === confirmed.id && m.sendState === 'sending');\n if (sameIdIdx !== -1) {\n const next = messages.slice();\n const pending = messages[sameIdIdx];\n next[sameIdIdx] = {\n ...confirmed,\n // Keep the local previews until the server copy lists its files.\n attachments: confirmed.attachments.length ? confirmed.attachments : pending.attachments,\n sendState: 'sent',\n };\n return next;\n }\n\n const pendingIdx = messages.findIndex(\n (m) =>\n m.sendState === 'sending' &&\n m.isMine &&\n m.body === confirmed.body &&\n // Same author, not merely both \"mine\" - guards the same collision\n // when authorId is populated on both sides.\n (!m.authorId || !confirmed.authorId || m.authorId === confirmed.authorId) &&\n Math.abs(m.createdAt - confirmed.createdAt) <= windowMs,\n );\n if (pendingIdx === -1) return mergeMessages(messages, [confirmed]);\n\n const next = messages.slice();\n next[pendingIdx] = { ...confirmed, sendState: 'sent', replacedClientId: messages[pendingIdx].id };\n // Still merge: the same id may already be present from a concurrent refetch.\n return mergeMessages(\n next.filter((m) => m.id !== confirmed.id || m.replacedClientId),\n [next[pendingIdx]],\n );\n}\n\n/**\n * The other participant in a DM.\n *\n * Falls back to null rather than to the viewer: a conversation labelled with\n * your own name is a bug users notice immediately, and every DM the viewer\n * created before members were populated would hit it.\n */\nexport function peerOf(channel: WireChannel, viewerId: string): ChatUser | null {\n const members = (channel.members ?? []).filter(Boolean) as WireChannelMember[];\n const other = members.find((m) => m.user?.id && String(m.user.id) !== viewerId);\n return other?.user ?? null;\n}\n\n/**\n * How many messages the viewer has not read.\n *\n * `member.msgCount` is the count the member has SEEN, so unread is the channel\n * total minus that - clamped at zero because the two counters are updated on\n * different write paths and briefly disagree.\n */\nexport function unreadOf(channel: WireChannel, viewerId: string): number {\n const mine = (channel.members ?? []).find((m) => m?.user?.id && String(m.user.id) === viewerId);\n if (!mine) return 0;\n const total = channel.totalMsgCount ?? 0;\n const seen = mine.msgCount ?? 0;\n return Math.max(0, total - seen);\n}\n\nconst DIRECT_TYPES = new Set(['DIRECT', 'Direct', 'direct']);\nconst GROUP_TYPES = new Set(['GROUP', 'Group', 'group']);\n\n/** A group's members for the info screen, picker and @mentions - the viewer included, flagged `isYou`. */\nexport function groupMembersOf(channel: WireChannel, viewerId: string): ChatGroupMember[] {\n const creatorId = channel.creator?.id ? String(channel.creator.id) : null;\n return (channel.members ?? [])\n .map((member) => member)\n .filter((m): m is WireChannelMember => m != null && m.user != null && Boolean(m.user.id))\n .map((m) => {\n const id = String(m.user!.id);\n return {\n id,\n name: displayNameOf(m.user, ''),\n avatarUrl: m.user!.picture ?? m.user!.profile?.picture ?? null,\n isAdmin: String(m.roles ?? '') === 'admin' || (creatorId != null && id === creatorId),\n isYou: id === viewerId,\n };\n });\n}\n\nfunction looksLikeMachineTitle(value?: string | null): boolean {\n const label = value?.trim() ?? '';\n if (!label) return true;\n if (/^chat[\\s_-]*channel\\b/i.test(label) || /^chat-channel-/i.test(label)) return true;\n if (/^[a-f0-9]{8,}$/i.test(label)) return true;\n if (label.includes('__')) return true;\n if (/^group(\\s+chat)?$/i.test(label)) return true;\n return false;\n}\n\n/** The name a person gave the channel; '' when it only carries a machine id like \"a__b\". */\nfunction storedLabelOf(channel: WireChannel): string {\n if (!looksLikeMachineTitle(channel.displayName)) return channel.displayName!.trim();\n if (!looksLikeMachineTitle(channel.title)) return channel.title!.trim();\n return '';\n}\n\n/** Every other member's name, for a group header; `memberNames` caps at three for a title. */\nfunction allMemberNames(channel: WireChannel, viewerId: string): string[] {\n return (channel.members ?? [])\n .map((member) => member?.user)\n .filter((user): user is ChatUser => user != null && Boolean(user.id) && String(user.id) !== viewerId)\n .map((user) => displayNameOf(user, ''))\n .filter(Boolean);\n}\n\nexport function toConversation(channel: WireChannel, viewerId: string): ChatConversation {\n const peerCandidate = peerOf(channel, viewerId);\n const explicitDirect = DIRECT_TYPES.has(String(channel.type ?? ''));\n const explicitGroup = GROUP_TYPES.has(String(channel.type ?? ''));\n const populatedMembers = (channel.members ?? []).filter(Boolean);\n const twoParty = populatedMembers.length === 2 && Boolean(peerCandidate);\n const hasMachineLabel = looksLikeMachineTitle(channel.displayName) && looksLikeMachineTitle(channel.title);\n const storedLabel = storedLabelOf(channel);\n // Two members is a DM - unless the channel is typed (not DIRECT) and someone\n // named it something other than the other person (\"standup\" with two people\n // in it is still a group).\n const namedGroup =\n Boolean(channel.type) &&\n Boolean(storedLabel) &&\n storedLabel.toLowerCase() !== displayNameOf(peerCandidate, '').toLowerCase();\n // An explicit GROUP type is always a group, whatever its member count.\n const isDirect =\n !explicitGroup &&\n (explicitDirect || (twoParty && !namedGroup) || (!channel.type && hasMachineLabel && Boolean(peerCandidate)));\n const peer = isDirect ? peerCandidate : null;\n const groupMembers = isDirect ? [] : groupMembersOf(channel, viewerId);\n const viewerIsAdmin = !isDirect && groupMembers.some((m) => m.isYou && m.isAdmin);\n\n const names = memberNames(channel, viewerId);\n const lastAuthor = channel.lastMessage ? pickAuthor(channel.lastMessage) : null;\n const lastAuthorName = lastAuthor && String(lastAuthor.id) !== viewerId ? displayNameOf(lastAuthor, '') : '';\n const creatorName = displayNameOf(channel.creator, '');\n const groupFallback = names.length\n ? names.join(', ')\n : lastAuthorName || (creatorName && creatorName !== 'Unknown' ? creatorName : 'Chat');\n const title = isDirect\n ? displayNameOf(peer, storedLabel || lastAuthorName || 'Direct message')\n : storedLabel || groupFallback;\n const topic = looksLikeMachineTitle(channel.topic) ? '' : (channel.topic ?? '').trim();\n const lastMessageMine = Boolean(lastAuthor?.id) && String(lastAuthor!.id) === viewerId;\n const lastMessageDeleted = Boolean(channel.lastMessage?.deletedAt);\n const preview = lastMessageDeleted\n ? deletedPreview(lastMessageMine)\n : pollPreview(channel.lastMessage) ||\n channel.lastMessage?.message?.trim() ||\n attachmentPreview(channel.lastMessage) ||\n topic;\n\n return {\n id: String(channel.id),\n title,\n subtitle: preview === title ? '' : preview,\n avatarUrl:\n peer?.picture ??\n peer?.profile?.picture ??\n channel.members?.find((member) => member?.user?.picture)?.user?.picture ??\n lastAuthor?.picture ??\n lastAuthor?.profile?.picture ??\n null,\n lastActivity: toEpoch(channel.lastPostAt) || toEpoch(channel.createdAt),\n unreadCount: unreadOf(channel, viewerId),\n isDirect,\n peer,\n memberNames: allMemberNames(channel, viewerId),\n members: groupMembers,\n viewerIsAdmin,\n onlyAdminsSend: Boolean(channel.settings?.onlyAdminsSend),\n disappearingSeconds: Number(channel.settings?.disappearingSeconds) || 0,\n creatorId: channel.creator?.id ? String(channel.creator.id) : null,\n description: (channel.description ?? '').trim(),\n unreadMentions: Math.max(0, channel.viewerUnreadMentions ?? 0),\n lastMessageMine,\n lastAuthorName: channel.lastMessage && !lastMessageMine ? lastAuthorName : '',\n lastMessageAt: toEpoch(channel.lastMessage?.createdAt),\n readWatermark: readWatermarkOf(channel, viewerId),\n mutedUntil: mutedUntilOf(channel),\n deliveredWatermark: deliveredWatermarkOf(channel, viewerId),\n pinnedAt: toEpoch(channel.viewerPinnedAt ?? null),\n archivedAt: toEpoch(channel.viewerArchivedAt ?? null),\n lastMessageDeleted,\n draft: (channel.viewerDraft ?? '').trim(),\n };\n}\n\n/**\n * Conversation list order: most recent first, then title, then id.\n *\n * The trailing keys matter more than they look. A channel with no messages has\n * `lastActivity === 0`, so a fresh account is entirely ties; without a stable\n * tiebreak the list reshuffles on every poll.\n */\nexport function sortConversations(list: ChatConversation[]): ChatConversation[] {\n // Pinned chats stay on top (most recently pinned first), as in WhatsApp.\n return list\n .slice()\n .sort(\n (a, b) =>\n Number(b.pinnedAt > 0) - Number(a.pinnedAt > 0) ||\n b.pinnedAt - a.pinnedAt ||\n b.lastActivity - a.lastActivity ||\n a.title.localeCompare(b.title) ||\n compareIds(a.id, b.id),\n );\n}\n\n/** Stable key for collapsing duplicate list rows (same person, multiple channel ids). */\nexport function conversationListKey(c: ChatConversation): string {\n if (c.peer?.id) return `peer:${String(c.peer.id)}`;\n // A real group (its own channel with members) is always its own row, never folded by title.\n if (!c.isDirect && (c.members?.length ?? 0) > 0) return `id:${c.id}`;\n const title = c.title.trim().toLowerCase();\n if (!title || title === 'chat' || title === 'unknown') return `id:${c.id}`;\n // Multi-person groups use comma-separated titles; keep those distinct.\n if (title.includes(',')) return `id:${c.id}`;\n if (c.isDirect) return `title:${title}`;\n // Server often returns duplicate 1:1 channels as untyped GROUP rows with the peer's name.\n return `title:${title}`;\n}\n\n/** A row's title when it names one person, lowercased; '' for groups and placeholders. */\nfunction personTitle(c: ChatConversation): string {\n // A real group is never \"a person\", so its name never collapses a DM (or vice versa).\n if (!c.isDirect && (c.members?.length ?? 0) > 0) return '';\n const title = c.title.trim().toLowerCase();\n if (!title || title === 'chat' || title === 'unknown' || title.includes(',')) return '';\n return title;\n}\n\n/**\n * One row per conversation, newest first. The server also returns a person's\n * 1:1 chat as untyped rows under their name, so a row that names its peer and a\n * peerless row with the same name are one person - but two peers who share a\n * name stay two rows.\n */\nexport function dedupeConversationList(list: ChatConversation[]): ChatConversation[] {\n const peers = new Set<string>();\n const peerTitles = new Set<string>();\n const titles = new Set<string>();\n return sortConversations(list).filter((c) => {\n const title = personTitle(c);\n const peerId = c.peer?.id ? String(c.peer.id) : '';\n if (peerId) {\n if (peers.has(peerId) || (title && titles.has(title))) return false;\n peers.add(peerId);\n if (title) peerTitles.add(title);\n return true;\n }\n if (!title) return true;\n if (titles.has(title) || peerTitles.has(title)) return false;\n titles.add(title);\n return true;\n });\n}\n\n/** @deprecated Use dedupeConversationList */\nexport function dedupeDirectConversations(list: ChatConversation[]): ChatConversation[] {\n return dedupeConversationList(list);\n}\n\nexport function mergeConversations(existing: ChatConversation[], incoming: ChatConversation[]): ChatConversation[] {\n const byId = new Map<string, ChatConversation>();\n for (const c of existing) byId.set(c.id, c);\n for (const c of incoming) byId.set(c.id, c);\n return dedupeConversationList(Array.from(byId.values()));\n}\n\n/** The list preview after a post: unchanged for an empty one, hidden when it only repeats the title. */\nfunction subtitleAfterPost(conv: ChatConversation, preview: string | null | undefined): string {\n if (!preview) return conv.subtitle;\n return preview === conv.title ? '' : preview;\n}\n\n/** Refresh preview + sort key when a new post lands (send echo or subscription). */\nexport function patchConversationAfterPost(conv: ChatConversation, post: WirePost, viewerId: string): ChatConversation {\n const preview = pollPreview(post) || post.message?.trim() || attachmentPreview(post);\n const nextSubtitle = subtitleAfterPost(conv, preview);\n const activity = toEpoch(post.createdAt) || Date.now();\n const author = pickAuthor(post);\n const fromPeer = Boolean(author) && String(author!.id) !== viewerId;\n return {\n ...conv,\n subtitle: nextSubtitle,\n lastActivity: activity,\n unreadCount: fromPeer ? conv.unreadCount + 1 : conv.unreadCount,\n lastMessageMine: Boolean(author) && !fromPeer,\n lastAuthorName: fromPeer ? displayNameOf(author, '') : '',\n lastMessageAt: activity,\n lastMessageDeleted: false,\n };\n}\n\n/**\n * An edit or a delete-for-everyone: only the list preview can change, and only when the\n * changed message is the newest one. Never touches unread or the sort order.\n */\nexport function patchConversationAfterUpdate(\n conv: ChatConversation,\n post: WirePost,\n viewerId: string,\n): ChatConversation {\n const at = toEpoch(post.createdAt);\n if (!at || at !== conv.lastMessageAt) return conv;\n const author = pickAuthor(post);\n const mine = Boolean(author?.id) && String(author!.id) === viewerId;\n if (post.deletedAt) return { ...conv, subtitle: deletedPreview(mine), lastMessageDeleted: true };\n const preview = pollPreview(post) || post.message?.trim() || attachmentPreview(post);\n return { ...conv, subtitle: subtitleAfterPost(conv, preview) };\n}\n\nexport type ChatListFilter = 'all' | 'unread' | 'groups';\n\n/** The rows a filter chip keeps. */\nexport function filterConversations(list: ChatConversation[], filter: ChatListFilter): ChatConversation[] {\n if (filter === 'unread') return list.filter((c) => c.unreadCount > 0);\n if (filter === 'groups') return list.filter((c) => !c.isDirect);\n return list;\n}\n\n/** What the empty list says, and offers, for the current search and filter. */\nexport function emptyListCopy({\n searching,\n filter,\n canInvite,\n}: {\n searching: boolean;\n filter: ChatListFilter;\n canInvite: boolean;\n}): { title: string; detail: string; action: 'all' | 'new' | null } {\n if (searching) return { title: 'No chats found', detail: 'Try a different search or filter.', action: null };\n if (filter === 'unread') return { title: 'No unread chats', detail: 'You’re all caught up.', action: 'all' };\n if (filter === 'groups') return { title: 'No group chats', detail: 'Groups you’re in show here.', action: 'all' };\n if (canInvite) {\n return {\n title: 'No conversations yet',\n detail: 'Tap the compose button to find people from your contacts.',\n action: 'new',\n };\n }\n return {\n title: 'No conversations yet',\n detail: 'Contacts are unavailable in this build, so new chats cannot be started here yet.',\n action: null,\n };\n}\n\n/**\n * Day separators, computed against a caller-supplied \"now\".\n *\n * The clock is a parameter so this is testable and so a device with a skewed\n * clock does not silently label everything \"Today\".\n */\nexport function dayLabel(epoch: number, now: number): string {\n if (!epoch) return '';\n const d = new Date(epoch);\n const n = new Date(now);\n const sameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n if (sameDay(d, n)) return 'Today';\n const yesterday = new Date(now);\n yesterday.setDate(yesterday.getDate() - 1);\n if (sameDay(d, yesterday)) return 'Yesterday';\n return d.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: d.getFullYear() === n.getFullYear() ? undefined : 'numeric',\n });\n}\n\n/** Short clock label for a bubble. */\nexport function timeLabel(epoch: number): string {\n if (!epoch) return '';\n return new Date(epoch).toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n}\n\n/** Relative age for the conversation list. */\nexport function relativeLabel(epoch: number, now: number): string {\n if (!epoch) return '';\n const diff = now - epoch;\n if (diff < 60_000) return 'now';\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m`;\n const d = new Date(epoch);\n const n = new Date(now);\n if (d.getFullYear() === n.getFullYear() && d.getMonth() === n.getMonth() && d.getDate() === n.getDate()) {\n return timeLabel(epoch);\n }\n if (diff < 7 * 86_400_000) return d.toLocaleDateString(undefined, { weekday: 'short' });\n return d.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });\n}\n\n/** Initials for the avatar fallback; never more than two glyphs. */\nexport function initialsOf(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (!parts.length) return '?';\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n}\n\n/** \"Muted\", \"Muted until 9:30 PM\", \"Muted until Oct 20\" - '' when not muted. */\nexport function muteLabel(mutedUntil: number, now: number): string {\n if (mutedUntil <= now) return '';\n // Anything past the year 3000 is the \"Always\" sentinel, whatever exact instant a server wrote.\n if (mutedUntil >= MUTE_FOREVER_EPOCH || new Date(mutedUntil).getFullYear() >= 3000) return 'Muted';\n const sameDay = new Date(mutedUntil).toDateString() === new Date(now).toDateString();\n return sameDay\n ? `Muted until ${timeLabel(mutedUntil)}`\n : `Muted until ${new Date(mutedUntil).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}`;\n}\n"],"names":["_a","_b","next"],"mappings":"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"}
@@ -9,6 +9,7 @@ const POST_FIELDS = `
9
9
  rootId
10
10
  parentId
11
11
  filenames
12
+ fromServer
12
13
  props
13
14
  author { id givenName familyName username email picture }
14
15
  creator { id givenName familyName username email picture }
@@ -26,12 +27,14 @@ const CHANNEL_FIELDS = `
26
27
  title
27
28
  displayName
28
29
  topic
30
+ description
29
31
  lastPostAt
30
32
  totalMsgCount
31
33
  createdAt
34
+ settings
32
35
  lastMessage { ${POST_FIELDS} }
33
36
  creator { id givenName familyName username email picture }
34
- members { id user { id givenName familyName username email picture } msgCount lastViewedAt lastDeliveredAt }
37
+ members { id roles user { id givenName familyName username email picture } msgCount lastViewedAt lastDeliveredAt }
35
38
  viewerMutedUntil
36
39
  viewerPinnedAt
37
40
  viewerArchivedAt
@@ -115,6 +118,13 @@ const SET_MESSAGE_STARRED_MUTATION = `
115
118
  setMessageStarred(messageId: $messageId, starred: $starred)
116
119
  }
117
120
  `;
121
+ const KEEP_MESSAGE_MUTATION = `
122
+ mutation ChatKeepMessage($messageId: MessageIdentifier!, $keep: Boolean!) {
123
+ keepMessage(messageId: $messageId, keep: $keep) {
124
+ ${MESSAGE_FIELDS}
125
+ }
126
+ }
127
+ `;
118
128
  const STARRED_MESSAGES_QUERY = `
119
129
  query ChatStarredMessages($limit: Int, $skip: Int) {
120
130
  starredMessages(limit: $limit, skip: $skip) {
@@ -133,6 +143,17 @@ const SEARCH_MESSAGES_QUERY = `
133
143
  }
134
144
  }
135
145
  `;
146
+ const MEDIA_MESSAGES_QUERY = `
147
+ query ChatMediaMessages($channelId: ID, $kind: String!, $limit: Int, $skip: Int) {
148
+ mediaMessages(channelId: $channelId, kind: $kind, limit: $limit, skip: $skip) {
149
+ totalCount
150
+ data {
151
+ ${MESSAGE_FIELDS}
152
+ channel { id }
153
+ }
154
+ }
155
+ }
156
+ `;
136
157
  const SEND_TYPING_MUTATION = `
137
158
  mutation ChatSendTyping($channelId: String!, $action: String!) {
138
159
  sendTypingIndicator(channelId: $channelId, action: $action)
@@ -180,6 +201,60 @@ const CREATE_DIRECT_CHANNEL_MUTATION = `
180
201
  }
181
202
  }
182
203
  `;
204
+ const CREATE_GROUP_CHANNEL_MUTATION = `
205
+ mutation ChatCreateGroup($name: String!, $memberIds: [ID!]!, $description: String) {
206
+ createGroupChannel(name: $name, memberIds: $memberIds, description: $description) {
207
+ ${CHANNEL_FIELDS}
208
+ }
209
+ }
210
+ `;
211
+ const ADD_GROUP_MEMBERS_MUTATION = `
212
+ mutation ChatAddGroupMembers($channelId: String!, $memberIds: [ID!]!) {
213
+ addGroupMembers(channelId: $channelId, memberIds: $memberIds) {
214
+ ${CHANNEL_FIELDS}
215
+ }
216
+ }
217
+ `;
218
+ const REMOVE_GROUP_MEMBER_MUTATION = `
219
+ mutation ChatRemoveGroupMember($channelId: String!, $memberId: ID!) {
220
+ removeGroupMember(channelId: $channelId, memberId: $memberId) {
221
+ ${CHANNEL_FIELDS}
222
+ }
223
+ }
224
+ `;
225
+ const LEAVE_GROUP_MUTATION = `
226
+ mutation ChatLeaveGroup($channelId: String!) {
227
+ leaveGroup(channelId: $channelId)
228
+ }
229
+ `;
230
+ const SET_GROUP_ADMIN_MUTATION = `
231
+ mutation ChatSetGroupAdmin($channelId: String!, $memberId: ID!, $admin: Boolean!) {
232
+ setGroupAdmin(channelId: $channelId, memberId: $memberId, admin: $admin) {
233
+ ${CHANNEL_FIELDS}
234
+ }
235
+ }
236
+ `;
237
+ const UPDATE_GROUP_INFO_MUTATION = `
238
+ mutation ChatUpdateGroupInfo($channelId: String!, $name: String, $description: String) {
239
+ updateGroupInfo(channelId: $channelId, name: $name, description: $description) {
240
+ ${CHANNEL_FIELDS}
241
+ }
242
+ }
243
+ `;
244
+ const SET_GROUP_SEND_POLICY_MUTATION = `
245
+ mutation ChatSetGroupSendPolicy($channelId: String!, $onlyAdmins: Boolean!) {
246
+ setGroupSendPolicy(channelId: $channelId, onlyAdmins: $onlyAdmins) {
247
+ ${CHANNEL_FIELDS}
248
+ }
249
+ }
250
+ `;
251
+ const SET_DISAPPEARING_MUTATION = `
252
+ mutation ChatSetDisappearing($channelId: String!, $seconds: Int!) {
253
+ setDisappearing(channelId: $channelId, seconds: $seconds) {
254
+ ${CHANNEL_FIELDS}
255
+ }
256
+ }
257
+ `;
183
258
  const MESSAGE_ADDED_SUBSCRIPTION_WS = `
184
259
  subscription ChatMessageAdded_WS($channelId: String) {
185
260
  chatMessageAdded(channelId: $channelId) {
@@ -196,6 +271,20 @@ const SET_MESSAGE_REACTION_MUTATION = `
196
271
  }
197
272
  }
198
273
  `;
274
+ const CREATE_POLL_MUTATION = `
275
+ mutation ChatCreatePoll($channelId: String!, $question: String!, $options: [String!]!, $multiple: Boolean) {
276
+ createPoll(channelId: $channelId, question: $question, options: $options, multiple: $multiple) {
277
+ ${MESSAGE_FIELDS}
278
+ }
279
+ }
280
+ `;
281
+ const VOTE_POLL_MUTATION = `
282
+ mutation ChatVotePoll($channelId: String!, $postId: ID!, $optionIds: [String!]!) {
283
+ votePoll(channelId: $channelId, postId: $postId, optionIds: $optionIds) {
284
+ ${MESSAGE_FIELDS}
285
+ }
286
+ }
287
+ `;
199
288
  const REACTION_CHANGED_SUBSCRIPTION_WS = `
200
289
  subscription ChatReactionChanged_WS($channelId: String!) {
201
290
  chatReactionChanged(channelId: $channelId) {
@@ -210,6 +299,26 @@ const CONTACT_MATCHES_QUERY = `
210
299
  chatContactMatches(phoneHashes: $phoneHashes)
211
300
  }
212
301
  `;
302
+ const BLOCK_CONTACT_MUTATION = `
303
+ mutation ChatBlockContact($userId: ID!) {
304
+ blockContact(userId: $userId)
305
+ }
306
+ `;
307
+ const UNBLOCK_CONTACT_MUTATION = `
308
+ mutation ChatUnblockContact($userId: ID!) {
309
+ unblockContact(userId: $userId)
310
+ }
311
+ `;
312
+ const BLOCKED_CONTACTS_QUERY = `
313
+ query ChatBlockedContacts {
314
+ blockedContacts
315
+ }
316
+ `;
317
+ const REPORT_TARGET_MUTATION = `
318
+ mutation ChatReportTarget($targetType: String!, $targetId: ID!, $reason: String, $alsoBlock: Boolean) {
319
+ reportTarget(targetType: $targetType, targetId: $targetId, reason: $reason, alsoBlock: $alsoBlock)
320
+ }
321
+ `;
213
322
  const YANTRA_CHAT_REGISTRATION_STATUS_QUERY = `
214
323
  query YantraChatRegistrationStatus {
215
324
  yantraChatRegistrationStatus {
@@ -243,4 +352,4 @@ const SET_DRAFT_MUTATION = `
243
352
  mutation ChatSetDraft($channelId: ID!, $text: String!) {
244
353
  setChannelDraft(channelId: $channelId, text: $text)
245
354
  }
246
- `;export{ATTACH_UPLOADED_FILES_MUTATION,CHANNELS_QUERY,CHANNEL_READ_STATE_QUERY,CONTACT_MATCHES_QUERY,CREATE_DIRECT_CHANNEL_MUTATION,CREATE_MESSAGE_UPLOAD_LINKS_MUTATION,DELETE_MESSAGE_FOR_EVERYONE_MUTATION,EDIT_MESSAGE_MUTATION,MARK_CHANNEL_DELIVERED_MUTATION,MESSAGES_QUERY,MESSAGE_ADDED_SUBSCRIPTION_WS,MESSAGE_FIELDS,MESSAGE_RECEIPTS_QUERY,MESSAGE_UPDATED_SUBSCRIPTION_WS,POST_FIELDS,REACTION_CHANGED_SUBSCRIPTION_WS,REGISTER_YANTRA_CHAT_MEMBER_MUTATION,SEARCH_MESSAGES_QUERY,SEND_MESSAGE_MUTATION,SEND_TYPING_MUTATION,SET_CHANNEL_LIST_STATE_MUTATION,SET_CHANNEL_MUTE_MUTATION,SET_DRAFT_MUTATION,SET_MESSAGE_REACTION_MUTATION,SET_MESSAGE_STARRED_MUTATION,STARRED_MESSAGES_QUERY,TYPING_SUBSCRIPTION_WS,VIEW_CHANNEL_MUTATION,YANTRA_CHAT_INVITER_QUERY,YANTRA_CHAT_REGISTRATION_STATUS_QUERY};//# sourceMappingURL=chatOperations.js.map
355
+ `;export{ADD_GROUP_MEMBERS_MUTATION,ATTACH_UPLOADED_FILES_MUTATION,BLOCKED_CONTACTS_QUERY,BLOCK_CONTACT_MUTATION,CHANNELS_QUERY,CHANNEL_READ_STATE_QUERY,CONTACT_MATCHES_QUERY,CREATE_DIRECT_CHANNEL_MUTATION,CREATE_GROUP_CHANNEL_MUTATION,CREATE_MESSAGE_UPLOAD_LINKS_MUTATION,CREATE_POLL_MUTATION,DELETE_MESSAGE_FOR_EVERYONE_MUTATION,EDIT_MESSAGE_MUTATION,KEEP_MESSAGE_MUTATION,LEAVE_GROUP_MUTATION,MARK_CHANNEL_DELIVERED_MUTATION,MEDIA_MESSAGES_QUERY,MESSAGES_QUERY,MESSAGE_ADDED_SUBSCRIPTION_WS,MESSAGE_FIELDS,MESSAGE_RECEIPTS_QUERY,MESSAGE_UPDATED_SUBSCRIPTION_WS,POST_FIELDS,REACTION_CHANGED_SUBSCRIPTION_WS,REGISTER_YANTRA_CHAT_MEMBER_MUTATION,REMOVE_GROUP_MEMBER_MUTATION,REPORT_TARGET_MUTATION,SEARCH_MESSAGES_QUERY,SEND_MESSAGE_MUTATION,SEND_TYPING_MUTATION,SET_CHANNEL_LIST_STATE_MUTATION,SET_CHANNEL_MUTE_MUTATION,SET_DISAPPEARING_MUTATION,SET_DRAFT_MUTATION,SET_GROUP_ADMIN_MUTATION,SET_GROUP_SEND_POLICY_MUTATION,SET_MESSAGE_REACTION_MUTATION,SET_MESSAGE_STARRED_MUTATION,STARRED_MESSAGES_QUERY,TYPING_SUBSCRIPTION_WS,UNBLOCK_CONTACT_MUTATION,UPDATE_GROUP_INFO_MUTATION,VIEW_CHANNEL_MUTATION,VOTE_POLL_MUTATION,YANTRA_CHAT_INVITER_QUERY,YANTRA_CHAT_REGISTRATION_STATUS_QUERY};//# sourceMappingURL=chatOperations.js.map