@linktr.ee/messaging-react 2.1.0 → 2.2.0-rc-1778753733
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.
- package/dist/{Card-CsJvUF_b.js → Card-BdTueeyk.js} +2 -2
- package/dist/{Card-CsJvUF_b.js.map → Card-BdTueeyk.js.map} +1 -1
- package/dist/{Card-DlMSDSdm.js → Card-ChR37pLZ.js} +2 -2
- package/dist/{Card-DlMSDSdm.js.map → Card-ChR37pLZ.js.map} +1 -1
- package/dist/{Card-CFFNq49v.js → Card-EKxCn56j.js} +3 -3
- package/dist/{Card-CFFNq49v.js.map → Card-EKxCn56j.js.map} +1 -1
- package/dist/{LockedThumbnail-DpJx169C.js → LockedThumbnail-B16qP3eH.js} +2 -2
- package/dist/{LockedThumbnail-DpJx169C.js.map → LockedThumbnail-B16qP3eH.js.map} +1 -1
- package/dist/index-Dn7BC9xK.js +4748 -0
- package/dist/index-Dn7BC9xK.js.map +1 -0
- package/dist/index.d.ts +591 -25
- package/dist/index.js +24 -19
- package/package.json +1 -1
- package/src/components/CustomMessage/MessageAttachmentConversations.stories.tsx +841 -0
- package/src/components/LinkAttachment/LinkAttachment.stories.tsx +7 -92
- package/src/components/LinkAttachment/LinkAttachment.test.tsx +69 -0
- package/src/components/LinkAttachment/components/Received/Card.tsx +10 -30
- package/src/components/LinkAttachment/components/_shared/CardShell.tsx +5 -1
- package/src/components/LinkAttachment/index.tsx +24 -50
- package/src/components/LinkAttachment/types.ts +12 -5
- package/src/components/MessageAttachment/Audio/AudioAttachment.stories.tsx +203 -0
- package/src/components/MessageAttachment/Audio/index.tsx +189 -0
- package/src/components/MessageAttachment/File/FileAttachment.stories.tsx +352 -0
- package/src/components/MessageAttachment/File/index.tsx +240 -0
- package/src/components/MessageAttachment/Image/ImageAttachment.stories.tsx +288 -0
- package/src/components/MessageAttachment/Image/index.tsx +257 -0
- package/src/components/MessageAttachment/MessageAttachment.test.tsx +783 -0
- package/src/components/MessageAttachment/Pdf/PdfAttachment.stories.tsx +292 -0
- package/src/components/MessageAttachment/Pdf/index.tsx +228 -0
- package/src/components/MessageAttachment/Video/VideoAttachment.stories.tsx +272 -0
- package/src/components/MessageAttachment/Video/index.tsx +281 -0
- package/src/components/MessageAttachment/_shared/Bubble.tsx +173 -0
- package/src/components/MessageAttachment/_shared/CompactDocumentRow.tsx +152 -0
- package/src/components/MessageAttachment/_shared/DismissButton.tsx +39 -0
- package/src/components/MessageAttachment/_shared/DownloadAction.tsx +175 -0
- package/src/components/MessageAttachment/_shared/ImageViewer.tsx +314 -0
- package/src/components/MessageAttachment/_shared/MediaStackGrid.tsx +139 -0
- package/src/components/MessageAttachment/_shared/PdfViewer.tsx +100 -0
- package/src/components/MessageAttachment/_shared/VideoViewer.tsx +171 -0
- package/src/components/MessageAttachment/_shared/ViewerShell.tsx +159 -0
- package/src/components/MessageAttachment/_shared/fileMeta.test.ts +82 -0
- package/src/components/MessageAttachment/_shared/fileMeta.ts +95 -0
- package/src/components/MessageAttachment/_shared/triggerDownload.ts +54 -0
- package/src/components/MessageAttachment/_shared/useViewer.ts +53 -0
- package/src/components/MessageAttachment/index.tsx +149 -0
- package/src/components/MessageAttachment/stories/StoryTable.tsx +72 -0
- package/src/components/MessageAttachment/types.ts +178 -0
- package/src/index.ts +32 -0
- package/dist/Card-D32U6KfZ.js +0 -85
- package/dist/Card-D32U6KfZ.js.map +0 -1
- package/dist/Card-DlSSJPip.js +0 -60
- package/dist/Card-DlSSJPip.js.map +0 -1
- package/dist/Card-zGbhRBwv.js +0 -48
- package/dist/Card-zGbhRBwv.js.map +0 -1
- package/dist/CardThumbnail-DTBuRQHF.js +0 -239
- package/dist/CardThumbnail-DTBuRQHF.js.map +0 -1
- package/dist/index-DfcRe-Hj.js +0 -3103
- package/dist/index-DfcRe-Hj.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ChannelSort } from 'stream-chat';
|
|
|
6
6
|
import { ComponentType } from 'react';
|
|
7
7
|
import { default as default_2 } from 'react';
|
|
8
8
|
import { EmptyStateIndicatorProps } from 'stream-chat-react';
|
|
9
|
+
import { FC } from 'react';
|
|
9
10
|
import { JSX as JSX_2 } from 'react/jsx-runtime';
|
|
10
11
|
import { LocalMessage } from 'stream-chat';
|
|
11
12
|
import { MessagingUser } from '@linktr.ee/messaging-core';
|
|
@@ -25,6 +26,42 @@ declare type AgeSafetySystemType = 'SYSTEM_AGE_SAFETY_BLOCKED';
|
|
|
25
26
|
|
|
26
27
|
export declare type AttachmentSourceType = 'image' | 'audio' | 'video' | 'document';
|
|
27
28
|
|
|
29
|
+
declare interface AudioAttachmentSharedProps extends MessageAttachmentBaseProps {
|
|
30
|
+
/** Audio source URL (`mp3`, `aac`, `wav`, …). */
|
|
31
|
+
src?: string;
|
|
32
|
+
/** MIME type hint — typed onto the inline `<source>` element. */
|
|
33
|
+
mimeType?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Filename — used as the download default name (consumed by the
|
|
36
|
+
* native player's kebab menu). The HTML `<audio>` element doesn't
|
|
37
|
+
* expose a built-in title slot, so we don't render the filename
|
|
38
|
+
* inside the bubble itself.
|
|
39
|
+
*/
|
|
40
|
+
filename?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Stacked audio. Takes precedence over `src` when set. Each item
|
|
43
|
+
* renders its own native `<audio controls>` player, vertically
|
|
44
|
+
* stacked inside the same bubble with an 8px gap between players.
|
|
45
|
+
* Sent + Received only — the composer surface accepts a single
|
|
46
|
+
* attachment at a time.
|
|
47
|
+
*/
|
|
48
|
+
items?: MessageAttachmentAudioItem[];
|
|
49
|
+
/**
|
|
50
|
+
* `<audio preload>` hint applied to every player on the bubble.
|
|
51
|
+
* When omitted, the default depends on the rendered shape:
|
|
52
|
+
*
|
|
53
|
+
* - Single audio (no `items`, or `items.length === 1`) →
|
|
54
|
+
* `'metadata'` so the native player surfaces duration
|
|
55
|
+
* immediately.
|
|
56
|
+
* - Stacked audio (`items.length > 1`) → `'none'` so a thread
|
|
57
|
+
* of voice memos doesn't fan out N parallel metadata requests
|
|
58
|
+
* on first paint.
|
|
59
|
+
*
|
|
60
|
+
* Per-track overrides live on `AudioItem.preload`.
|
|
61
|
+
*/
|
|
62
|
+
preload?: MediaPreloadMode;
|
|
63
|
+
}
|
|
64
|
+
|
|
28
65
|
/**
|
|
29
66
|
* Avatar component that displays a user image or colored initial fallback
|
|
30
67
|
*/
|
|
@@ -41,6 +78,13 @@ export declare interface AvatarProps {
|
|
|
41
78
|
dmAgentEnabled?: boolean;
|
|
42
79
|
}
|
|
43
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Build the meta line shown under the title in compact document / file
|
|
83
|
+
* attachments — `EXT · SIZE` (`PDF · 379.5 KB`). Either part is dropped
|
|
84
|
+
* when not available so audio / generic files still get a useful label.
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildCompactMetaLabel(mimeType?: string, filename?: string, fileSize?: number): string | undefined;
|
|
87
|
+
|
|
44
88
|
/**
|
|
45
89
|
* Empty state component shown when a channel has no messages
|
|
46
90
|
* Returns null to show nothing - the LoadingIndicator handles the loading state
|
|
@@ -267,6 +311,12 @@ export declare interface ComposerCardProps extends LockedAttachmentBaseProps {
|
|
|
267
311
|
onEditClick?: () => void;
|
|
268
312
|
}
|
|
269
313
|
|
|
314
|
+
/** Shared props for the `Composer` state of every attachment type. */
|
|
315
|
+
declare interface ComposerExtras {
|
|
316
|
+
/** Renders a dismiss `×` button overlaid on the attachment. */
|
|
317
|
+
onDismiss?: () => void;
|
|
318
|
+
}
|
|
319
|
+
|
|
270
320
|
/**
|
|
271
321
|
* @deprecated Renamed to `SentCardProps`. Drafting usages (with `onDismiss`)
|
|
272
322
|
* should migrate to `ComposerCardProps`.
|
|
@@ -310,43 +360,129 @@ export declare interface FaqListProps {
|
|
|
310
360
|
avatarName?: string;
|
|
311
361
|
}
|
|
312
362
|
|
|
363
|
+
declare interface FileAttachmentSharedProps extends MessageAttachmentBaseProps {
|
|
364
|
+
/** Source URL of the file (used as the download target). */
|
|
365
|
+
src?: string;
|
|
366
|
+
/** Filename — drives the title + the meta line + the download default name. */
|
|
367
|
+
filename?: string;
|
|
368
|
+
fileSize?: number;
|
|
369
|
+
/** MIME type — drives the type icon. Defaults to `application/octet-stream`. */
|
|
370
|
+
mimeType?: string;
|
|
371
|
+
/**
|
|
372
|
+
* Override displayed title (defaults to `filename`). Useful when a
|
|
373
|
+
* sender renames the attachment before sending.
|
|
374
|
+
*/
|
|
375
|
+
title?: string;
|
|
376
|
+
/**
|
|
377
|
+
* Stacked files. Takes precedence over `src` when set. Each item
|
|
378
|
+
* renders as its own row inside the bubble; clicking a row downloads
|
|
379
|
+
* that file. Sent + Received only — the composer surface accepts a
|
|
380
|
+
* single attachment at a time.
|
|
381
|
+
*/
|
|
382
|
+
items?: MessageAttachmentFileItem[];
|
|
383
|
+
/**
|
|
384
|
+
* Forwarded to the row trigger. When omitted the click still
|
|
385
|
+
* downloads the file. Supply this for analytics, or return `false`
|
|
386
|
+
* to fully intercept the download (e.g. show a confirmation modal,
|
|
387
|
+
* route to a custom preview, throttle large files). Any other
|
|
388
|
+
* return value — including `void`/`undefined` — lets the built-in
|
|
389
|
+
* download proceed. For stacked attachments the `index` argument
|
|
390
|
+
* identifies the row.
|
|
391
|
+
*/
|
|
392
|
+
onClick?: (index: number) => boolean | void;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Format a byte count as a short human-readable string (`'379.5 KB'`).
|
|
397
|
+
* Mirrors the meta line shown next to file attachments in the mobile chat
|
|
398
|
+
* design — `EXT · SIZE`, e.g. `PDF · 379.5 KB`.
|
|
399
|
+
*/
|
|
400
|
+
export declare function formatFileSize(bytes: number): string;
|
|
401
|
+
|
|
313
402
|
/**
|
|
314
403
|
* Format a date - shows time for today, relative time for older messages
|
|
315
404
|
* (e.g., "Just now", "2:08 PM" for today, "Yesterday" for yesterday, "2d" for 2 days ago)
|
|
316
405
|
*/
|
|
317
406
|
export declare const formatRelativeTime: (date: Date) => string;
|
|
318
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Returns the short uppercase extension label shown in the meta line of
|
|
410
|
+
* compact document / file attachments. Prefers the filename extension
|
|
411
|
+
* when present (matches the mobile design which trusts the filename),
|
|
412
|
+
* and falls back to a label derived from the MIME type.
|
|
413
|
+
*/
|
|
414
|
+
export declare function getFileExtensionLabel(mimeType?: string, filename?: string): string | undefined;
|
|
415
|
+
|
|
319
416
|
export declare function getMessageDisplayText({ message, viewerLanguage, }: {
|
|
320
417
|
message?: MessageWithI18n | null;
|
|
321
418
|
viewerLanguage?: string;
|
|
322
419
|
}): string | undefined;
|
|
323
420
|
|
|
421
|
+
declare interface ImageAttachmentSharedProps extends MessageAttachmentBaseProps {
|
|
422
|
+
/** Single image — convenience for the most common case. */
|
|
423
|
+
src?: string;
|
|
424
|
+
alt?: string;
|
|
425
|
+
/** Filename surfaced in the viewer toolbar + download default name. */
|
|
426
|
+
filename?: string;
|
|
427
|
+
/**
|
|
428
|
+
* Stacked images. Takes precedence over `src` when set. Renders a
|
|
429
|
+
* 1 / 2 / 3 / 4-tile grid (5+ collapse into a `+N` overflow tile).
|
|
430
|
+
* Sent + Received only — the composer surface intentionally accepts
|
|
431
|
+
* a single attachment at a time.
|
|
432
|
+
*/
|
|
433
|
+
items?: MessageAttachmentImageItem[];
|
|
434
|
+
/**
|
|
435
|
+
* Native lazy-load hint forwarded to every `<img>` rendered on the
|
|
436
|
+
* bubble surface (Composer thumbnail, single + stacked tiles, and
|
|
437
|
+
* the `+N` overflow tile). Defaults to `'lazy'` — chat surfaces
|
|
438
|
+
* usually scroll a long history, and lazy loading prevents every
|
|
439
|
+
* historical image from being fetched on mount. Set `'eager'` for
|
|
440
|
+
* above-the-fold hero attachments. Per-tile overrides live on
|
|
441
|
+
* `ImageItem.loading`. The opened `ImageViewer` always eager-loads
|
|
442
|
+
* the active image regardless of this value.
|
|
443
|
+
*/
|
|
444
|
+
loading?: ImageLoadingMode;
|
|
445
|
+
/**
|
|
446
|
+
* Forwarded to the Image viewer trigger. When omitted the click
|
|
447
|
+
* still opens the built-in viewer — supply this for analytics, or
|
|
448
|
+
* return `false` to intercept the open (e.g. switch to a route-
|
|
449
|
+
* based gallery / confirmation modal). Any other return value
|
|
450
|
+
* (including `void`/`undefined`) lets the built-in viewer open.
|
|
451
|
+
* For stacked attachments the `index` argument identifies the tile.
|
|
452
|
+
*/
|
|
453
|
+
onClick?: (index: number) => boolean | void;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** Loading hint forwarded to the underlying `<img>` element. */
|
|
457
|
+
declare type ImageLoadingMode = 'lazy' | 'eager';
|
|
458
|
+
|
|
324
459
|
export declare function isLinkAttachment(a: Attachment): boolean;
|
|
325
460
|
|
|
326
461
|
/**
|
|
327
|
-
* Link
|
|
328
|
-
*
|
|
329
|
-
*
|
|
462
|
+
* Link previews (1P / 3P Link Apps) shown in the chat thread. Mirrors
|
|
463
|
+
* the `LockedAttachment` API — render `LinkAttachment.Composer` while
|
|
464
|
+
* drafting, `LinkAttachment.Sent` after posting, and
|
|
330
465
|
* `LinkAttachment.Received` in the recipient's thread. Maps to the
|
|
331
|
-
* "
|
|
466
|
+
* "LinkApps" section of the messaging design system.
|
|
332
467
|
*
|
|
333
468
|
* Two visual layouts via the `layout` prop:
|
|
334
|
-
* - **Featured** (default) — 180px hero thumbnail above the body. Used
|
|
335
|
-
*
|
|
336
|
-
*
|
|
469
|
+
* - **Featured** (default) — 180px hero thumbnail above the body. Used
|
|
470
|
+
* by hero-image LinkApps (Spotify with cover art, TikTok with a
|
|
471
|
+
* frame, etc.).
|
|
337
472
|
* - **Classic** — compact card with no hero thumbnail; title /
|
|
338
473
|
* description / URL / CTA only. Used for LinkApp embeds without
|
|
339
474
|
* artwork (FAQ, Form) and any link preview that lacks OG imagery.
|
|
340
475
|
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
476
|
+
* For chat **document / image / video / audio attachments**, reach for
|
|
477
|
+
* `MessageAttachment.{Image,Video,Audio,Pdf,File}` instead — those
|
|
478
|
+
* render as bubbles with built-in viewers (zoom-capable image
|
|
479
|
+
* lightbox, native PDF viewer, video / audio with download) and a
|
|
480
|
+
* caption slot for accompanying text.
|
|
345
481
|
*/
|
|
346
482
|
export declare const LinkAttachment: {
|
|
347
|
-
Composer:
|
|
348
|
-
Sent:
|
|
349
|
-
Received:
|
|
483
|
+
Composer: FC<LinkAttachmentComposerCardProps>;
|
|
484
|
+
Sent: FC<LinkAttachmentSentCardProps>;
|
|
485
|
+
Received: FC<LinkAttachmentReceivedCardProps>;
|
|
350
486
|
};
|
|
351
487
|
|
|
352
488
|
/**
|
|
@@ -373,9 +509,11 @@ export declare interface LinkAttachmentBaseProps {
|
|
|
373
509
|
/** Hero thumbnail (180px tall) shown above the title block. */
|
|
374
510
|
thumbnailUrl?: string;
|
|
375
511
|
/**
|
|
376
|
-
* Source URL for playable media
|
|
377
|
-
* video / audio `mimeType`, the hero
|
|
378
|
-
* native
|
|
512
|
+
* Source URL for playable media in the hero region. When provided
|
|
513
|
+
* alongside a video / audio `mimeType`, the hero renders an inline
|
|
514
|
+
* native player (used by media-rich link previews that embed a
|
|
515
|
+
* preview clip). For chat document / file attachments, reach for
|
|
516
|
+
* `MessageAttachment.{Pdf,File}` instead.
|
|
379
517
|
*/
|
|
380
518
|
sourceUrl?: string;
|
|
381
519
|
/**
|
|
@@ -422,11 +560,16 @@ export declare interface LinkAttachmentCta {
|
|
|
422
560
|
* Visual layout for a `LinkAttachment.*` card.
|
|
423
561
|
*
|
|
424
562
|
* - `featured` — full card with a 180px hero thumbnail above the body.
|
|
425
|
-
* The default; matches the "
|
|
426
|
-
*
|
|
563
|
+
* The default; matches the hero-image "LinkApps" frames in Figma
|
|
564
|
+
* (Spotify with cover art, TikTok with a frame, etc.).
|
|
427
565
|
* - `classic` — compact card without a hero thumbnail. Title /
|
|
428
566
|
* description / URL / CTA only. Used for Link App embeds that don't
|
|
429
567
|
* carry artwork (and for plain link previews without OG imagery).
|
|
568
|
+
*
|
|
569
|
+
* For document / image / video / audio chat attachments, reach for
|
|
570
|
+
* `MessageAttachment.{Image,Video,Audio,Pdf,File}` instead — those
|
|
571
|
+
* render as bubbles with built-in viewers and download support and
|
|
572
|
+
* carry a `text` slot for accompanying captions.
|
|
430
573
|
*/
|
|
431
574
|
export declare type LinkAttachmentLayout = 'featured' | 'classic';
|
|
432
575
|
|
|
@@ -440,12 +583,11 @@ export declare interface LinkAttachmentReceivedCardProps extends LinkAttachmentB
|
|
|
440
583
|
* - **Link app with a URL** (Spotify / TikTok / generic link): the card
|
|
441
584
|
* chrome is an `<a target="_blank">` opening `url` — `onClick` fires
|
|
442
585
|
* alongside the navigation (use for analytics).
|
|
443
|
-
* - **
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
* in this configuration.
|
|
586
|
+
* - **Hero-image only card**: the card has no URL, so it renders as
|
|
587
|
+
* a button. `onClick` is the consumer's hook for opening a preview.
|
|
588
|
+
* - **Video / audio link previews**: the shell stays non-interactive
|
|
589
|
+
* so the native media controls remain operable — `onClick` is
|
|
590
|
+
* ignored in this configuration.
|
|
449
591
|
*/
|
|
450
592
|
onClick?: () => void;
|
|
451
593
|
}
|
|
@@ -525,6 +667,363 @@ export declare interface MediaMessageResolved {
|
|
|
525
667
|
thumbnailUrl?: string;
|
|
526
668
|
}
|
|
527
669
|
|
|
670
|
+
/** Preload hint forwarded to the underlying `<video>` / `<audio>` element. */
|
|
671
|
+
declare type MediaPreloadMode = 'none' | 'metadata' | 'auto';
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Per-MIME chat attachment cards used inside the messaging stream.
|
|
675
|
+
*
|
|
676
|
+
* Each subnamespace (`Image`, `Video`, `Audio`, `Pdf`, `File`) exposes
|
|
677
|
+
* three states (`Composer`, `Sent`, `Received`) that map to the
|
|
678
|
+
* sender / recipient sides of a chat:
|
|
679
|
+
*
|
|
680
|
+
* - `Composer` — sender draft state with a dismiss `×` affordance.
|
|
681
|
+
* - `Sent` — sender-side state shown after posting.
|
|
682
|
+
* - `Received` — recipient-side state.
|
|
683
|
+
*
|
|
684
|
+
* Sent / Received variants accept an optional `text` prop that renders
|
|
685
|
+
* inside the same bubble as the attachment — mirroring the mobile chat
|
|
686
|
+
* where a sender can pair a caption with an attachment ('Here is the
|
|
687
|
+
* file', 'Here is the image'). Composer prop types intentionally omit
|
|
688
|
+
* `text` (and `items` / `groupPosition`) so the type system enforces
|
|
689
|
+
* the same contract: captions live in the message-input textarea, not
|
|
690
|
+
* inside the draft attachment preview.
|
|
691
|
+
*
|
|
692
|
+
* Stacked attachments — every type except `Composer` accepts an
|
|
693
|
+
* `items={[…]}` prop on Sent / Received that takes precedence over
|
|
694
|
+
* the singular `src`/`filename`/etc. inputs:
|
|
695
|
+
*
|
|
696
|
+
* - Image / Video render a 1 / 2 / 3 / 4-tile grid (5+ collapse
|
|
697
|
+
* into a `+N` overflow tile). Activating any tile opens the
|
|
698
|
+
* built-in `ImageViewer` / `VideoViewer` at that index, with
|
|
699
|
+
* arrow-key navigation between siblings.
|
|
700
|
+
* - Pdf / Audio / File render their compact rows / players in a
|
|
701
|
+
* vertical stack with an 8px gap between rows. Each row keeps
|
|
702
|
+
* its own activation target — Pdf opens the viewer at that
|
|
703
|
+
* index, Audio gets its own native player, and File downloads
|
|
704
|
+
* the asset for that row.
|
|
705
|
+
*
|
|
706
|
+
* The Composer surface accepts only a single attachment at a time,
|
|
707
|
+
* so its props omit `items` / `text`.
|
|
708
|
+
*
|
|
709
|
+
* Image / Video Composer renders bare — just the media with rounded
|
|
710
|
+
* corners and a dismiss overlay, no surrounding bubble — so the draft
|
|
711
|
+
* preview reads as an in-progress attachment instead of a sent
|
|
712
|
+
* message. Sent / Received wrap the media in the shared bubble chrome.
|
|
713
|
+
*
|
|
714
|
+
* Image / Video / Pdf are interactive in every state (Composer, Sent,
|
|
715
|
+
* Received) — clicks open the corresponding native viewer with built-in
|
|
716
|
+
* download. File rows download the asset directly. Audio renders a
|
|
717
|
+
* native `<audio controls>` player which exposes its own download in
|
|
718
|
+
* the kebab menu, so we don't render a separate Download affordance.
|
|
719
|
+
*
|
|
720
|
+
* # Lazy-loading defaults
|
|
721
|
+
*
|
|
722
|
+
* Media attachments bake in network-friendly defaults for long chat
|
|
723
|
+
* histories and expose explicit escape hatches when a caller knows
|
|
724
|
+
* better (e.g. a hero attachment that's already on-screen):
|
|
725
|
+
*
|
|
726
|
+
* - **Image** — every `<img>` rendered on the bubble surface
|
|
727
|
+
* (Composer thumbnail, single + stacked tiles, `+N` overflow)
|
|
728
|
+
* ships with `loading="lazy" decoding="async"`. Override via the
|
|
729
|
+
* attachment's `loading` prop (or `ImageItem.loading` for per-tile
|
|
730
|
+
* control). The opened `ImageViewer` always eager-loads the
|
|
731
|
+
* active image so it appears immediately.
|
|
732
|
+
* - **Video** — the `<video>` rendered inside the `VideoViewer`
|
|
733
|
+
* defaults to `preload="none"`, so no video bytes are fetched
|
|
734
|
+
* until the user opens the viewer. Poster `<img>` thumbnails on
|
|
735
|
+
* the bubble surface are `loading="lazy" decoding="async"`.
|
|
736
|
+
* Override via the attachment's `preload` prop (or
|
|
737
|
+
* `VideoItem.preload` per item). Once the viewer is open the
|
|
738
|
+
* active item bumps to `preload="metadata"` so duration / the
|
|
739
|
+
* first frame appear immediately.
|
|
740
|
+
* - **Audio** — a single audio bubble defaults to
|
|
741
|
+
* `preload="metadata"` so the native player surfaces duration
|
|
742
|
+
* immediately. A stacked audio bubble (`items.length > 1`)
|
|
743
|
+
* defaults to `preload="none"` for every player so a thread of
|
|
744
|
+
* voice memos doesn't fan out N parallel metadata requests on
|
|
745
|
+
* first paint. Override via the attachment's `preload` prop
|
|
746
|
+
* (or `AudioItem.preload` per track).
|
|
747
|
+
* - **Pdf** / **File** — no inline media element to throttle; the
|
|
748
|
+
* bubble renders compact rows that download / open lazily on
|
|
749
|
+
* activation. No `loading` / `preload` props on these surfaces.
|
|
750
|
+
*/
|
|
751
|
+
export declare const MessageAttachment: {
|
|
752
|
+
Image: {
|
|
753
|
+
Composer: FC<MessageAttachmentImageComposerProps>;
|
|
754
|
+
Sent: FC<ImageAttachmentSharedProps>;
|
|
755
|
+
Received: FC<ImageAttachmentSharedProps>;
|
|
756
|
+
};
|
|
757
|
+
Video: {
|
|
758
|
+
Composer: FC<MessageAttachmentVideoComposerProps>;
|
|
759
|
+
Sent: FC<VideoAttachmentSharedProps>;
|
|
760
|
+
Received: FC<VideoAttachmentSharedProps>;
|
|
761
|
+
};
|
|
762
|
+
Audio: {
|
|
763
|
+
Composer: FC<MessageAttachmentAudioComposerProps>;
|
|
764
|
+
Sent: FC<AudioAttachmentSharedProps>;
|
|
765
|
+
Received: FC<AudioAttachmentSharedProps>;
|
|
766
|
+
};
|
|
767
|
+
Pdf: {
|
|
768
|
+
Composer: FC<MessageAttachmentPdfComposerProps>;
|
|
769
|
+
Sent: FC<PdfAttachmentSharedProps>;
|
|
770
|
+
Received: FC<PdfAttachmentSharedProps>;
|
|
771
|
+
};
|
|
772
|
+
File: {
|
|
773
|
+
Composer: FC<MessageAttachmentFileComposerProps>;
|
|
774
|
+
Sent: FC<FileAttachmentSharedProps>;
|
|
775
|
+
Received: FC<FileAttachmentSharedProps>;
|
|
776
|
+
};
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* Composer-only props. Single audio (`src`) only — the composer
|
|
781
|
+
* surface accepts a single attachment at a time, so `items` is not
|
|
782
|
+
* supported. Captions (`text`) and `groupPosition` are also dropped:
|
|
783
|
+
* the composer renders a standalone draft, not part of a same-author
|
|
784
|
+
* run, and captions live in the message-input textarea, not inside
|
|
785
|
+
* the draft attachment preview.
|
|
786
|
+
*/
|
|
787
|
+
export declare interface MessageAttachmentAudioComposerProps extends ComposerExtras {
|
|
788
|
+
src?: string;
|
|
789
|
+
mimeType?: string;
|
|
790
|
+
filename?: string;
|
|
791
|
+
/** See `AudioAttachmentSharedProps.preload`. */
|
|
792
|
+
preload?: MediaPreloadMode;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/** A single audio file inside an Audio attachment (single or stacked). */
|
|
796
|
+
export declare interface MessageAttachmentAudioItem {
|
|
797
|
+
src: string;
|
|
798
|
+
/** MIME type hint — typed onto the inline `<source>` element. */
|
|
799
|
+
mimeType?: string;
|
|
800
|
+
/**
|
|
801
|
+
* Filename — used as the download default name (consumed by the
|
|
802
|
+
* native player's kebab menu).
|
|
803
|
+
*/
|
|
804
|
+
filename?: string;
|
|
805
|
+
/**
|
|
806
|
+
* Per-track override for the `<audio preload>` hint. Defaults to
|
|
807
|
+
* the parent attachment's `preload` value, which itself defaults
|
|
808
|
+
* to `'metadata'` for a single audio (so the native player can
|
|
809
|
+
* surface duration immediately) and `'none'` for a stacked thread
|
|
810
|
+
* (so a fan-out of metadata requests doesn't happen on first paint).
|
|
811
|
+
*/
|
|
812
|
+
preload?: MediaPreloadMode;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
export declare type MessageAttachmentAudioReceivedProps = AudioAttachmentSharedProps;
|
|
816
|
+
|
|
817
|
+
export declare type MessageAttachmentAudioSentProps = AudioAttachmentSharedProps;
|
|
818
|
+
|
|
819
|
+
/** Shared props every `MessageAttachment.*.{Composer|Sent|Received}` accepts. */
|
|
820
|
+
export declare interface MessageAttachmentBaseProps {
|
|
821
|
+
/**
|
|
822
|
+
* Optional text rendered below the attachment inside the same bubble.
|
|
823
|
+
* Mirrors the chat behavior in the mobile screenshots — `'Here is the
|
|
824
|
+
* file'`, `'Here is the image'`, etc.
|
|
825
|
+
*/
|
|
826
|
+
text?: default_2.ReactNode;
|
|
827
|
+
/**
|
|
828
|
+
* Position of this attachment inside a same-author message run —
|
|
829
|
+
* mirrors the corner-flattening stream-chat-react applies to text
|
|
830
|
+
* bubbles in a clustered conversation. Defaults to `'single'`, so
|
|
831
|
+
* standalone usage keeps every corner rounded. Pass the value
|
|
832
|
+
* derived from `bubbleGroupPositionFromStream({ firstOfGroup,
|
|
833
|
+
* endOfGroup, groupedByUser })` when rendering inside a real
|
|
834
|
+
* `CustomMessage` thread to make the attachment visually merge
|
|
835
|
+
* with adjacent bubbles. Image / Video Composer ignore this — the
|
|
836
|
+
* draft preview renders bare without the surrounding bubble.
|
|
837
|
+
*/
|
|
838
|
+
groupPosition?: MessageAttachmentGroupPosition;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Composer-only props. Single file (`src`) only — the composer surface
|
|
843
|
+
* accepts a single attachment at a time, so `items` is not supported.
|
|
844
|
+
* Captions (`text`) and `groupPosition` are also dropped: the composer
|
|
845
|
+
* renders a standalone draft, not part of a same-author run, and
|
|
846
|
+
* captions live in the message-input textarea, not inside the draft
|
|
847
|
+
* attachment preview.
|
|
848
|
+
*/
|
|
849
|
+
export declare interface MessageAttachmentFileComposerProps extends ComposerExtras {
|
|
850
|
+
src?: string;
|
|
851
|
+
filename?: string;
|
|
852
|
+
fileSize?: number;
|
|
853
|
+
mimeType?: string;
|
|
854
|
+
title?: string;
|
|
855
|
+
onClick?: (index: number) => boolean | void;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/** A single generic file inside a File attachment (single or stacked). */
|
|
859
|
+
export declare interface MessageAttachmentFileItem {
|
|
860
|
+
src: string;
|
|
861
|
+
/** Filename — drives the title + the meta line + the download default name. */
|
|
862
|
+
filename?: string;
|
|
863
|
+
/** File size in bytes — formatted into the `EXT · SIZE` meta line. */
|
|
864
|
+
fileSize?: number;
|
|
865
|
+
/** MIME type — drives the type icon. Defaults to `application/octet-stream`. */
|
|
866
|
+
mimeType?: string;
|
|
867
|
+
/** Override displayed title. Defaults to `filename`. */
|
|
868
|
+
title?: string;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
export declare type MessageAttachmentFileReceivedProps = FileAttachmentSharedProps;
|
|
872
|
+
|
|
873
|
+
export declare type MessageAttachmentFileSentProps = FileAttachmentSharedProps;
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Position of a bubble inside a same-author run, mirroring the grouping
|
|
877
|
+
* stream-chat-react applies to consecutive messages from the same user:
|
|
878
|
+
*
|
|
879
|
+
* - `'single'` — standalone message, every corner fully rounded.
|
|
880
|
+
* - `'first'` — first in a 2+ message run; the corner facing the
|
|
881
|
+
* next bubble in the run is flattened.
|
|
882
|
+
* - `'middle'` — both the corner facing the previous bubble and the
|
|
883
|
+
* corner facing the next bubble are flattened.
|
|
884
|
+
* - `'end'` — last in a 2+ message run; the corner facing the
|
|
885
|
+
* previous bubble is flattened (this is also the
|
|
886
|
+
* bubble the avatar attaches to on the receiver side).
|
|
887
|
+
*
|
|
888
|
+
* "Facing" is determined by the bubble's side: sender-aligned bubbles
|
|
889
|
+
* cluster against their right edge, receiver-aligned bubbles against
|
|
890
|
+
* their left edge.
|
|
891
|
+
*/
|
|
892
|
+
export declare type MessageAttachmentGroupPosition = 'single' | 'first' | 'middle' | 'end';
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Convenience adapter that derives the `BubbleGroupPosition` from the
|
|
896
|
+
* three booleans `stream-chat-react` forwards into the `Message` HOC.
|
|
897
|
+
* Drop-in for `useMessageContext()` consumers:
|
|
898
|
+
*
|
|
899
|
+
* ```tsx
|
|
900
|
+
* const { firstOfGroup, endOfGroup, groupedByUser } = useMessageContext()
|
|
901
|
+
* <MessageAttachment.Image.Sent
|
|
902
|
+
* {...props}
|
|
903
|
+
* groupPosition={bubbleGroupPositionFromStream({
|
|
904
|
+
* firstOfGroup, endOfGroup, groupedByUser,
|
|
905
|
+
* })}
|
|
906
|
+
* />
|
|
907
|
+
* ```
|
|
908
|
+
*/
|
|
909
|
+
export declare const messageAttachmentGroupPositionFromStream: ({ firstOfGroup, endOfGroup, groupedByUser, }: {
|
|
910
|
+
firstOfGroup?: boolean;
|
|
911
|
+
endOfGroup?: boolean;
|
|
912
|
+
groupedByUser?: boolean;
|
|
913
|
+
}) => MessageAttachmentGroupPosition;
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Composer-only props. Single image (`src`) is required; stacked
|
|
917
|
+
* `items` and `text` captions are not supported in the composer state.
|
|
918
|
+
*/
|
|
919
|
+
export declare interface MessageAttachmentImageComposerProps {
|
|
920
|
+
src: string;
|
|
921
|
+
alt?: string;
|
|
922
|
+
filename?: string;
|
|
923
|
+
/**
|
|
924
|
+
* Native lazy-load hint forwarded to the composer thumbnail `<img>`.
|
|
925
|
+
* Defaults to `'lazy'`. See `ImageAttachmentSharedProps.loading` for
|
|
926
|
+
* the rationale.
|
|
927
|
+
*/
|
|
928
|
+
loading?: ImageLoadingMode;
|
|
929
|
+
onClick?: (index: number) => boolean | void;
|
|
930
|
+
onDismiss?: () => void;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/** A single image inside an Image attachment (single or stacked). */
|
|
934
|
+
export declare interface MessageAttachmentImageItem {
|
|
935
|
+
src: string;
|
|
936
|
+
alt?: string;
|
|
937
|
+
/** Optional width/height hint — preserved aspect on cover-fit. */
|
|
938
|
+
width?: number;
|
|
939
|
+
height?: number;
|
|
940
|
+
/**
|
|
941
|
+
* Per-tile native lazy-load override. Defaults to the parent
|
|
942
|
+
* attachment's `loading` value (which itself defaults to `'lazy'`).
|
|
943
|
+
* Pass `'eager'` for above-the-fold hero tiles.
|
|
944
|
+
*/
|
|
945
|
+
loading?: ImageLoadingMode;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
export declare type MessageAttachmentImageReceivedProps = ImageAttachmentSharedProps;
|
|
949
|
+
|
|
950
|
+
export declare type MessageAttachmentImageSentProps = ImageAttachmentSharedProps;
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* Composer-only props. Single PDF (`src`) only — the composer surface
|
|
954
|
+
* accepts a single attachment at a time, so `items` is not supported.
|
|
955
|
+
* Captions (`text`) and `groupPosition` are also dropped: the composer
|
|
956
|
+
* renders a standalone draft, not part of a same-author run, and
|
|
957
|
+
* captions live in the message-input textarea, not inside the draft
|
|
958
|
+
* attachment preview.
|
|
959
|
+
*/
|
|
960
|
+
export declare interface MessageAttachmentPdfComposerProps extends ComposerExtras {
|
|
961
|
+
src?: string;
|
|
962
|
+
filename?: string;
|
|
963
|
+
fileSize?: number;
|
|
964
|
+
title?: string;
|
|
965
|
+
onClick?: (index: number) => boolean | void;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/** A single PDF inside a Pdf attachment (single or stacked). */
|
|
969
|
+
export declare interface MessageAttachmentPdfItem {
|
|
970
|
+
src: string;
|
|
971
|
+
/** Filename — drives the title + the meta line + the viewer toolbar. */
|
|
972
|
+
filename?: string;
|
|
973
|
+
/** File size in bytes — formatted into the `EXT · SIZE` meta line. */
|
|
974
|
+
fileSize?: number;
|
|
975
|
+
/** Override displayed title. Defaults to `filename`. */
|
|
976
|
+
title?: string;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
export declare type MessageAttachmentPdfReceivedProps = PdfAttachmentSharedProps;
|
|
980
|
+
|
|
981
|
+
export declare type MessageAttachmentPdfSentProps = PdfAttachmentSharedProps;
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Three messaging states a `MessageAttachment.*` card can render in,
|
|
985
|
+
* mirroring the LinkAttachment / LockedAttachment families.
|
|
986
|
+
*/
|
|
987
|
+
export declare type MessageAttachmentState = 'composer' | 'sent' | 'received';
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Composer-only props. Single video (`src`) is required; stacked
|
|
991
|
+
* `items` and `text` captions are not supported in the composer state.
|
|
992
|
+
*/
|
|
993
|
+
export declare interface MessageAttachmentVideoComposerProps {
|
|
994
|
+
src: string;
|
|
995
|
+
poster?: string;
|
|
996
|
+
mimeType?: string;
|
|
997
|
+
filename?: string;
|
|
998
|
+
/**
|
|
999
|
+
* `<video preload>` hint forwarded into the viewer. Defaults to
|
|
1000
|
+
* `'none'`. See `VideoAttachmentSharedProps.preload`.
|
|
1001
|
+
*/
|
|
1002
|
+
preload?: MediaPreloadMode;
|
|
1003
|
+
onClick?: (index: number) => boolean | void;
|
|
1004
|
+
onDismiss?: () => void;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/** A single video inside a Video attachment (single or stacked). */
|
|
1008
|
+
export declare interface MessageAttachmentVideoItem {
|
|
1009
|
+
src: string;
|
|
1010
|
+
/** Poster / thumbnail rendered before playback starts. */
|
|
1011
|
+
poster?: string;
|
|
1012
|
+
/** Optional MIME type (e.g. `video/mp4`). */
|
|
1013
|
+
mimeType?: string;
|
|
1014
|
+
/**
|
|
1015
|
+
* Per-item override for the `<video preload>` hint. Defaults to the
|
|
1016
|
+
* parent attachment's `preload` value (which itself defaults to
|
|
1017
|
+
* `'none'` so the poster carries the visual weight and no video
|
|
1018
|
+
* bytes are fetched until playback).
|
|
1019
|
+
*/
|
|
1020
|
+
preload?: MediaPreloadMode;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
export declare type MessageAttachmentVideoReceivedProps = VideoAttachmentSharedProps;
|
|
1024
|
+
|
|
1025
|
+
export declare type MessageAttachmentVideoSentProps = VideoAttachmentSharedProps;
|
|
1026
|
+
|
|
528
1027
|
declare type MessageCustomType = 'MESSAGE_TIP' | 'MESSAGE_PAID' | 'MESSAGE_CHATBOT' | 'MESSAGE_ATTACHMENT' | AgeSafetySystemType | DmAgentSystemType;
|
|
529
1028
|
|
|
530
1029
|
export declare interface MessageMetadata {
|
|
@@ -674,6 +1173,36 @@ export declare interface Participant {
|
|
|
674
1173
|
*/
|
|
675
1174
|
declare type PaymentStatus = 'pending' | 'paid' | 'failed' | 'refunded';
|
|
676
1175
|
|
|
1176
|
+
declare interface PdfAttachmentSharedProps extends MessageAttachmentBaseProps {
|
|
1177
|
+
/** Single PDF — convenience for the most common case. */
|
|
1178
|
+
src?: string;
|
|
1179
|
+
/** Filename — drives the title + the meta line + the viewer toolbar. */
|
|
1180
|
+
filename?: string;
|
|
1181
|
+
/** File size in bytes — formatted into the `EXT · SIZE` meta line. */
|
|
1182
|
+
fileSize?: number;
|
|
1183
|
+
/**
|
|
1184
|
+
* Override displayed title (defaults to `filename`). Useful when a
|
|
1185
|
+
* sender re-titles a generated PDF before sending.
|
|
1186
|
+
*/
|
|
1187
|
+
title?: string;
|
|
1188
|
+
/**
|
|
1189
|
+
* Stacked PDFs. Takes precedence over `src` when set. Each item
|
|
1190
|
+
* renders as its own row inside the bubble; clicking a row opens
|
|
1191
|
+
* that PDF in the viewer. Sent + Received only — the composer
|
|
1192
|
+
* surface accepts a single attachment at a time.
|
|
1193
|
+
*/
|
|
1194
|
+
items?: MessageAttachmentPdfItem[];
|
|
1195
|
+
/**
|
|
1196
|
+
* Forwarded to the viewer trigger. When omitted the click still
|
|
1197
|
+
* opens the built-in `PdfViewer`. Supply this to fire analytics, or
|
|
1198
|
+
* return `false` to intercept the open (e.g. swap to a route-based
|
|
1199
|
+
* viewer / confirmation modal). Any other return value (including
|
|
1200
|
+
* `void`/`undefined`) lets the built-in viewer open. For stacked
|
|
1201
|
+
* attachments the `index` argument identifies the row.
|
|
1202
|
+
*/
|
|
1203
|
+
onClick?: (index: number) => boolean | void;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
677
1206
|
export declare interface ReceivedCardProps extends LockedAttachmentBaseProps {
|
|
678
1207
|
/**
|
|
679
1208
|
* Called when the recipient clicks Unlock on an unpaid attachment.
|
|
@@ -739,6 +1268,43 @@ declare interface UseMessageVoteResult {
|
|
|
739
1268
|
*/
|
|
740
1269
|
export declare const useMessaging: () => MessagingContextValue;
|
|
741
1270
|
|
|
1271
|
+
declare interface VideoAttachmentSharedProps extends MessageAttachmentBaseProps {
|
|
1272
|
+
/** Single video — convenience for the most common case. */
|
|
1273
|
+
src?: string;
|
|
1274
|
+
/** Poster image — preview shown before playback starts. */
|
|
1275
|
+
poster?: string;
|
|
1276
|
+
/** MIME type hint — typed onto the inline `<source>` element. */
|
|
1277
|
+
mimeType?: string;
|
|
1278
|
+
/** Filename surfaced in the viewer toolbar + download default name. */
|
|
1279
|
+
filename?: string;
|
|
1280
|
+
/**
|
|
1281
|
+
* Stacked videos. Takes precedence over `src` when set. Renders a
|
|
1282
|
+
* 1 / 2 / 3 / 4-tile grid (5+ collapse into a `+N` overflow tile).
|
|
1283
|
+
* Sent + Received only — the composer surface intentionally accepts
|
|
1284
|
+
* a single attachment at a time.
|
|
1285
|
+
*/
|
|
1286
|
+
items?: MessageAttachmentVideoItem[];
|
|
1287
|
+
/**
|
|
1288
|
+
* `<video preload>` hint forwarded into the viewer. Defaults to
|
|
1289
|
+
* `'none'` — the poster `<img>` carries the visual weight on the
|
|
1290
|
+
* bubble surface, and we shouldn't fetch any video bytes until the
|
|
1291
|
+
* user actually opens the viewer. Per-item overrides live on
|
|
1292
|
+
* `VideoItem.preload`. The opened `VideoViewer` always preloads
|
|
1293
|
+
* metadata for the active item (so duration / first-frame appear
|
|
1294
|
+
* immediately) regardless of this value.
|
|
1295
|
+
*/
|
|
1296
|
+
preload?: MediaPreloadMode;
|
|
1297
|
+
/**
|
|
1298
|
+
* Forwarded to the viewer trigger. When omitted the click still
|
|
1299
|
+
* opens the built-in `VideoViewer` — supply this for analytics, or
|
|
1300
|
+
* return `false` to intercept the open (e.g. switch to a route-
|
|
1301
|
+
* based player / confirmation modal). Any other return value
|
|
1302
|
+
* (including `void`/`undefined`) lets the built-in viewer open.
|
|
1303
|
+
* For stacked attachments the `index` argument identifies the tile.
|
|
1304
|
+
*/
|
|
1305
|
+
onClick?: (index: number) => boolean | void;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
742
1308
|
/** @deprecated Renamed to `ReceivedCardProps`. */
|
|
743
1309
|
export declare type VisitorCardProps = ReceivedCardProps;
|
|
744
1310
|
|