@linktr.ee/messaging-react 2.0.0 → 2.0.1-rc-1778694826
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-CFFNq49v.js +163 -0
- package/dist/Card-CFFNq49v.js.map +1 -0
- package/dist/Card-CsJvUF_b.js +107 -0
- package/dist/Card-CsJvUF_b.js.map +1 -0
- package/dist/Card-D32U6KfZ.js +85 -0
- package/dist/Card-D32U6KfZ.js.map +1 -0
- package/dist/Card-DlMSDSdm.js +132 -0
- package/dist/Card-DlMSDSdm.js.map +1 -0
- package/dist/Card-DlSSJPip.js +60 -0
- package/dist/Card-DlSSJPip.js.map +1 -0
- package/dist/Card-zGbhRBwv.js +48 -0
- package/dist/Card-zGbhRBwv.js.map +1 -0
- package/dist/CardThumbnail-DTBuRQHF.js +239 -0
- package/dist/CardThumbnail-DTBuRQHF.js.map +1 -0
- package/dist/LockedThumbnail-DpJx169C.js +220 -0
- package/dist/LockedThumbnail-DpJx169C.js.map +1 -0
- package/dist/assets/index.css +1 -1
- package/dist/{index-Brz9orsI.js → index-DfcRe-Hj.js} +939 -889
- package/dist/index-DfcRe-Hj.js.map +1 -0
- package/dist/index.d.ts +217 -28
- package/dist/index.js +16 -15
- package/package.json +1 -1
- package/src/components/ChannelView.test.tsx +11 -0
- package/src/components/ChannelView.tsx +35 -32
- package/src/components/CustomMessage/index.tsx +2 -3
- package/src/components/CustomTypingIndicator/CustomTypingIndicator.stories.tsx +57 -17
- package/src/components/CustomTypingIndicator/CustomTypingIndicator.test.tsx +187 -0
- package/src/components/CustomTypingIndicator/DmAgentContext.ts +3 -0
- package/src/components/CustomTypingIndicator/index.tsx +101 -37
- package/src/components/LinkAttachment/LinkAttachment.stories.tsx +307 -0
- package/src/components/LinkAttachment/components/Composer/Card.tsx +117 -0
- package/src/components/LinkAttachment/components/Composer/index.ts +2 -0
- package/src/components/LinkAttachment/components/Received/Card.tsx +132 -0
- package/src/components/LinkAttachment/components/Received/index.ts +2 -0
- package/src/components/LinkAttachment/components/Sent/Card.tsx +57 -0
- package/src/components/LinkAttachment/components/Sent/index.ts +2 -0
- package/src/components/LinkAttachment/components/_shared/CardBody.tsx +117 -0
- package/src/components/LinkAttachment/components/_shared/CardCta.tsx +69 -0
- package/src/components/LinkAttachment/components/_shared/CardShell.tsx +120 -0
- package/src/components/LinkAttachment/components/_shared/CardThumbnail.tsx +156 -0
- package/src/components/LinkAttachment/components/_shared/normalizeExternalHref.ts +56 -0
- package/src/components/LinkAttachment/index.tsx +68 -0
- package/src/components/LinkAttachment/types.ts +69 -0
- package/src/components/LockedAttachment/LockedAttachment.stories.tsx +230 -89
- package/src/components/LockedAttachment/components/Composer/Card.tsx +221 -0
- package/src/components/LockedAttachment/components/Composer/index.ts +2 -0
- package/src/components/LockedAttachment/components/Received/Card.tsx +191 -0
- package/src/components/LockedAttachment/components/Received/CardActions.tsx +91 -0
- package/src/components/LockedAttachment/components/Received/index.ts +2 -0
- package/src/components/LockedAttachment/components/Sent/Card.tsx +177 -0
- package/src/components/LockedAttachment/components/Sent/index.ts +2 -0
- package/src/components/LockedAttachment/components/_shared/CardBody.tsx +94 -0
- package/src/components/LockedAttachment/components/_shared/GalleryThumbnail.tsx +178 -0
- package/src/components/LockedAttachment/components/_shared/LockBadge.tsx +39 -0
- package/src/components/LockedAttachment/components/_shared/LockedCardShell.tsx +36 -0
- package/src/components/LockedAttachment/components/_shared/LockedThumbnail.tsx +128 -0
- package/src/components/LockedAttachment/index.tsx +43 -12
- package/src/components/LockedAttachment/types.ts +17 -0
- package/src/components/MediaMessage/index.tsx +8 -2
- package/src/index.ts +15 -1
- package/src/styles.css +7 -0
- package/dist/Card-BHknCeHw.js +0 -138
- package/dist/Card-BHknCeHw.js.map +0 -1
- package/dist/Card-DT7_ms2p.js +0 -127
- package/dist/Card-DT7_ms2p.js.map +0 -1
- package/dist/index-Brz9orsI.js.map +0 -1
- package/src/components/LockedAttachment/components/Creator/Card.tsx +0 -210
- package/src/components/LockedAttachment/components/Creator/index.tsx +0 -2
- package/src/components/LockedAttachment/components/Visitor/Card.tsx +0 -155
- package/src/components/LockedAttachment/components/Visitor/CardActions.tsx +0 -62
- package/src/components/LockedAttachment/components/Visitor/LockBadge.tsx +0 -12
- package/src/components/LockedAttachment/components/Visitor/index.ts +0 -2
package/dist/index.d.ts
CHANGED
|
@@ -241,15 +241,38 @@ export declare interface ChannelViewProps {
|
|
|
241
241
|
sendButton?: ComponentType<any>;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
export declare interface
|
|
244
|
+
export declare interface ComposerCardProps extends LockedAttachmentBaseProps {
|
|
245
|
+
/** Placeholder shown in the title slot before the composer types one. */
|
|
245
246
|
placeholderTitle?: string;
|
|
247
|
+
/** Placeholder shown in the amount slot before one is configured. */
|
|
246
248
|
placeholderAmountText?: string;
|
|
247
|
-
|
|
249
|
+
/**
|
|
250
|
+
* When provided, renders a dismiss X in the thumbnail corner. Called when
|
|
251
|
+
* the composer clicks it to remove the attachment.
|
|
252
|
+
*/
|
|
248
253
|
onDismiss?: () => void;
|
|
254
|
+
/** Fired the first time the composer taps the thumbnail to preview. */
|
|
249
255
|
onPreviewClick?: () => void;
|
|
256
|
+
/**
|
|
257
|
+
* Lazily loads the underlying source so the composer can preview the
|
|
258
|
+
* attachment they're about to send. Called the first time the thumbnail is
|
|
259
|
+
* tapped; the returned source is cached and reused on subsequent toggles.
|
|
260
|
+
*/
|
|
250
261
|
onFetchSource?: () => Promise<LockedAttachmentSource | void>;
|
|
262
|
+
/**
|
|
263
|
+
* When provided, renders a pencil button in the body bottom-right that the
|
|
264
|
+
* composer can use to edit the attachment metadata (e.g. open the price /
|
|
265
|
+
* gallery editor). Matches the Composer "Button" instance in Figma.
|
|
266
|
+
*/
|
|
267
|
+
onEditClick?: () => void;
|
|
251
268
|
}
|
|
252
269
|
|
|
270
|
+
/**
|
|
271
|
+
* @deprecated Renamed to `SentCardProps`. Drafting usages (with `onDismiss`)
|
|
272
|
+
* should migrate to `ComposerCardProps`.
|
|
273
|
+
*/
|
|
274
|
+
export declare type CreatorCardProps = SentCardProps;
|
|
275
|
+
|
|
253
276
|
export declare const CustomMessageProvider: Provider<Partial<CustomMessageRegistry>>;
|
|
254
277
|
|
|
255
278
|
export declare interface CustomMessageRegistry {
|
|
@@ -300,9 +323,142 @@ export declare function getMessageDisplayText({ message, viewerLanguage, }: {
|
|
|
300
323
|
|
|
301
324
|
export declare function isLinkAttachment(a: Attachment): boolean;
|
|
302
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Link attachments (image / file media + 1P/3P Link Apps) shown in the chat
|
|
328
|
+
* thread. Mirrors the `LockedAttachment` API — render `LinkAttachment.Composer`
|
|
329
|
+
* while drafting, `LinkAttachment.Sent` after posting, and
|
|
330
|
+
* `LinkAttachment.Received` in the recipient's thread. Maps to the
|
|
331
|
+
* "Attachments" and "LinkApps" sections of the messaging design system.
|
|
332
|
+
*
|
|
333
|
+
* Two visual layouts via the `layout` prop:
|
|
334
|
+
* - **Featured** (default) — 180px hero thumbnail above the body. Used by
|
|
335
|
+
* image / file Attachments and by hero-image LinkApps (Spotify with
|
|
336
|
+
* cover art, TikTok with a frame, etc.).
|
|
337
|
+
* - **Classic** — compact card with no hero thumbnail; title /
|
|
338
|
+
* description / URL / CTA only. Used for LinkApp embeds without
|
|
339
|
+
* artwork (FAQ, Form) and any link preview that lacks OG imagery.
|
|
340
|
+
*
|
|
341
|
+
* Image / file Attachments use `layout="featured"` and skip the title /
|
|
342
|
+
* description / URL body entirely (`CardBody` collapses to nothing when no
|
|
343
|
+
* text content is provided). LinkApps always carry a title + description
|
|
344
|
+
* and prefix the title with an `appIcon` brand badge.
|
|
345
|
+
*/
|
|
346
|
+
export declare const LinkAttachment: {
|
|
347
|
+
Composer: (props: LinkAttachmentComposerCardProps) => JSX_2.Element;
|
|
348
|
+
Sent: (props: LinkAttachmentSentCardProps) => JSX_2.Element;
|
|
349
|
+
Received: (props: LinkAttachmentReceivedCardProps) => JSX_2.Element;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Shared props for the three `LinkAttachment.*` variants (Composer, Sent,
|
|
354
|
+
* Received). Maps to the "Attachments" + "LinkApps" sections of the messaging
|
|
355
|
+
* design system in Figma — a 280px-wide card with an optional 180px hero
|
|
356
|
+
* thumbnail, a title (optionally prefixed with a brand badge for Link Apps),
|
|
357
|
+
* a description, and either a URL footer or a CTA button.
|
|
358
|
+
*/
|
|
359
|
+
export declare interface LinkAttachmentBaseProps {
|
|
360
|
+
title?: string;
|
|
361
|
+
/** Placeholder shown in the title slot before one is configured (dark variants only). */
|
|
362
|
+
placeholderTitle?: string;
|
|
363
|
+
/** Secondary description rendered below the title. */
|
|
364
|
+
description?: string;
|
|
365
|
+
/**
|
|
366
|
+
* Optional URL displayed at the bottom of the card (e.g. `tr.ee/briemix`).
|
|
367
|
+
* Ignored when `cta` is provided. Also used as the navigation target for
|
|
368
|
+
* the Received card when no `cta` is set.
|
|
369
|
+
*/
|
|
370
|
+
url?: string;
|
|
371
|
+
/** MIME type of the hero thumbnail — drives the type icon for empty states. */
|
|
372
|
+
mimeType?: string;
|
|
373
|
+
/** Hero thumbnail (180px tall) shown above the title block. */
|
|
374
|
+
thumbnailUrl?: string;
|
|
375
|
+
/**
|
|
376
|
+
* Source URL for playable media (video, audio). When provided alongside a
|
|
377
|
+
* video / audio `mimeType`, the hero region renders an inline player with
|
|
378
|
+
* native controls instead of the static thumbnail / type-icon.
|
|
379
|
+
*/
|
|
380
|
+
sourceUrl?: string;
|
|
381
|
+
/**
|
|
382
|
+
* Visual layout — `'featured'` keeps the 180px hero thumbnail above the
|
|
383
|
+
* body, `'classic'` drops the hero entirely for a compact text-only
|
|
384
|
+
* card. Defaults to `'featured'`.
|
|
385
|
+
*/
|
|
386
|
+
layout?: LinkAttachmentLayout;
|
|
387
|
+
/**
|
|
388
|
+
* Optional 16x16 brand badge rendered before the title (used by Link Apps:
|
|
389
|
+
* Spotify, TikTok, FAQ, Form, etc.). Consumers render whatever they want
|
|
390
|
+
* — typically a colored 4px-rounded square containing a glyph or `<img>`.
|
|
391
|
+
*/
|
|
392
|
+
appIcon?: default_2.ReactNode;
|
|
393
|
+
/**
|
|
394
|
+
* Optional call-to-action rendered below the description. When set,
|
|
395
|
+
* replaces the URL footer (e.g. FAQ "View FAQs", Form "Complete form").
|
|
396
|
+
*/
|
|
397
|
+
cta?: LinkAttachmentCta;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export declare interface LinkAttachmentComposerCardProps extends LinkAttachmentBaseProps {
|
|
401
|
+
/**
|
|
402
|
+
* When provided, renders a dismiss X in the thumbnail corner. Called when
|
|
403
|
+
* the composer clicks it to remove the attachment.
|
|
404
|
+
*/
|
|
405
|
+
onDismiss?: () => void;
|
|
406
|
+
/**
|
|
407
|
+
* When provided, renders a pencil button to the right of the description
|
|
408
|
+
* that the composer can use to edit the attachment metadata.
|
|
409
|
+
*/
|
|
410
|
+
onEditClick?: () => void;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export declare interface LinkAttachmentCta {
|
|
414
|
+
label: string;
|
|
415
|
+
/** When set, the CTA renders as an `<a>` opening in a new tab. */
|
|
416
|
+
href?: string;
|
|
417
|
+
/** When set, called on click (in addition to `href` navigation if provided). */
|
|
418
|
+
onClick?: () => void;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Visual layout for a `LinkAttachment.*` card.
|
|
423
|
+
*
|
|
424
|
+
* - `featured` — full card with a 180px hero thumbnail above the body.
|
|
425
|
+
* The default; matches the "Attachments" frames and the hero-image
|
|
426
|
+
* "LinkApps" frames in Figma.
|
|
427
|
+
* - `classic` — compact card without a hero thumbnail. Title /
|
|
428
|
+
* description / URL / CTA only. Used for Link App embeds that don't
|
|
429
|
+
* carry artwork (and for plain link previews without OG imagery).
|
|
430
|
+
*/
|
|
431
|
+
export declare type LinkAttachmentLayout = 'featured' | 'classic';
|
|
432
|
+
|
|
433
|
+
export declare interface LinkAttachmentReceivedCardProps extends LinkAttachmentBaseProps {
|
|
434
|
+
/**
|
|
435
|
+
* Fired when the recipient activates the card. Behavior depends on how
|
|
436
|
+
* the card is configured:
|
|
437
|
+
* - **Link app with a CTA** (FAQ / Form): the CTA owns navigation;
|
|
438
|
+
* `onClick` fires when the recipient taps the CTA itself, alongside
|
|
439
|
+
* `cta.onClick` (use for analytics).
|
|
440
|
+
* - **Link app with a URL** (Spotify / TikTok / generic link): the card
|
|
441
|
+
* chrome is an `<a target="_blank">` opening `url` — `onClick` fires
|
|
442
|
+
* alongside the navigation (use for analytics).
|
|
443
|
+
* - **Image / file / placeholder attachment**: the card has no URL, so
|
|
444
|
+
* it renders as a button. `onClick` is the consumer's hook for
|
|
445
|
+
* opening an image / file preview (lightbox).
|
|
446
|
+
* - **Video / audio attachment**: the shell stays non-interactive so
|
|
447
|
+
* the native media controls remain operable — `onClick` is ignored
|
|
448
|
+
* in this configuration.
|
|
449
|
+
*/
|
|
450
|
+
onClick?: () => void;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export declare interface LinkAttachmentSentCardProps extends LinkAttachmentBaseProps {
|
|
454
|
+
}
|
|
455
|
+
|
|
303
456
|
export declare const LockedAttachment: {
|
|
304
|
-
|
|
305
|
-
|
|
457
|
+
Composer: (props: ComposerCardProps) => JSX_2.Element;
|
|
458
|
+
Sent: (props: SentCardProps) => JSX_2.Element;
|
|
459
|
+
Received: (props: ReceivedCardProps) => JSX_2.Element;
|
|
460
|
+
Creator: (props: SentCardProps) => JSX_2.Element;
|
|
461
|
+
Visitor: (props: ReceivedCardProps) => JSX_2.Element;
|
|
306
462
|
};
|
|
307
463
|
|
|
308
464
|
declare interface LockedAttachmentBaseProps {
|
|
@@ -312,6 +468,14 @@ declare interface LockedAttachmentBaseProps {
|
|
|
312
468
|
detail?: string;
|
|
313
469
|
amountText?: string;
|
|
314
470
|
paymentStatus?: PaymentStatus;
|
|
471
|
+
/**
|
|
472
|
+
* When provided with 2+ items, the card renders as a mixed-media carousel
|
|
473
|
+
* (e.g. a couple of photos + a video) instead of a single thumbnail. Each
|
|
474
|
+
* item brings its own thumbnail and optional source so that
|
|
475
|
+
* `LockedAttachment.Composer` / `.Sent` / `.Received` can all share the
|
|
476
|
+
* same carousel chrome.
|
|
477
|
+
*/
|
|
478
|
+
gallery?: LockedAttachmentGalleryItem[];
|
|
315
479
|
}
|
|
316
480
|
|
|
317
481
|
export declare interface LockedAttachmentContextValue {
|
|
@@ -321,6 +485,15 @@ export declare interface LockedAttachmentContextValue {
|
|
|
321
485
|
onFetchSource?: (message: LocalMessage, channel: Channel) => Promise<LockedAttachmentSource | void>;
|
|
322
486
|
}
|
|
323
487
|
|
|
488
|
+
export declare interface LockedAttachmentGalleryItem {
|
|
489
|
+
/** MIME type of this carousel item — drives the per-item play / lock affordance. */
|
|
490
|
+
mimeType: string;
|
|
491
|
+
/** Poster image used for both the locked (blurred) and unlocked preview state. */
|
|
492
|
+
thumbnailUrl?: string;
|
|
493
|
+
/** Underlying source (image or video URL) — shown only when unlocked. */
|
|
494
|
+
sourceUrl?: string;
|
|
495
|
+
}
|
|
496
|
+
|
|
324
497
|
export declare interface LockedAttachmentSource {
|
|
325
498
|
/** Proxied URL used by the media player for in-app playback. */
|
|
326
499
|
sourceUrl: string;
|
|
@@ -501,10 +674,48 @@ export declare interface Participant {
|
|
|
501
674
|
*/
|
|
502
675
|
declare type PaymentStatus = 'pending' | 'paid' | 'failed' | 'refunded';
|
|
503
676
|
|
|
677
|
+
export declare interface ReceivedCardProps extends LockedAttachmentBaseProps {
|
|
678
|
+
/**
|
|
679
|
+
* Called when the recipient clicks Unlock on an unpaid attachment.
|
|
680
|
+
* Use this to open a checkout flow. Omit to hide the Unlock button.
|
|
681
|
+
*/
|
|
682
|
+
onUnlockClick?: () => void;
|
|
683
|
+
/**
|
|
684
|
+
* Called to fetch the attachment source — fired automatically when
|
|
685
|
+
* `paymentStatus` transitions to `'paid'`, or immediately on click when
|
|
686
|
+
* `paymentStatus` is already `'paid'`. Return a `LockedAttachmentSource`
|
|
687
|
+
* to unlock the card.
|
|
688
|
+
*/
|
|
689
|
+
onFetchSource?: () => Promise<LockedAttachmentSource | void>;
|
|
690
|
+
/**
|
|
691
|
+
* Called when the recipient clicks Download on an unlocked card.
|
|
692
|
+
* Omit to hide the Download button.
|
|
693
|
+
*/
|
|
694
|
+
onDownloadClick?: () => void;
|
|
695
|
+
/**
|
|
696
|
+
* When true, shows a loading spinner on the Unlock button.
|
|
697
|
+
* Driven by the LockedAttachmentContext (e.g. checkout in progress).
|
|
698
|
+
*/
|
|
699
|
+
isUnlocking?: boolean;
|
|
700
|
+
}
|
|
701
|
+
|
|
504
702
|
export declare function resolveLinkAttachment(message: LocalMessage): Attachment | undefined;
|
|
505
703
|
|
|
506
704
|
export declare function resolveMediaFromMessage(message: LocalMessage): MediaMessageResolved | null;
|
|
507
705
|
|
|
706
|
+
export declare interface SentCardProps extends LockedAttachmentBaseProps {
|
|
707
|
+
/** Placeholder shown in the title slot when no title is set. */
|
|
708
|
+
placeholderTitle?: string;
|
|
709
|
+
/** Fired the first time the sender taps the thumbnail to preview their own attachment. */
|
|
710
|
+
onPreviewClick?: () => void;
|
|
711
|
+
/**
|
|
712
|
+
* Lazily loads the underlying source so the sender can preview the attachment.
|
|
713
|
+
* Called the first time the thumbnail is tapped; the returned source is cached
|
|
714
|
+
* and reused on subsequent toggles.
|
|
715
|
+
*/
|
|
716
|
+
onFetchSource?: () => Promise<LockedAttachmentSource | void>;
|
|
717
|
+
}
|
|
718
|
+
|
|
508
719
|
export declare function useCustomMessage<K extends keyof CustomMessageRegistry>(key: K): CustomMessageRegistry[K];
|
|
509
720
|
|
|
510
721
|
/**
|
|
@@ -528,30 +739,8 @@ declare interface UseMessageVoteResult {
|
|
|
528
739
|
*/
|
|
529
740
|
export declare const useMessaging: () => MessagingContextValue;
|
|
530
741
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
* Called when the visitor clicks Unlock on an unpaid attachment.
|
|
534
|
-
* Use this to open a checkout flow. Omit to hide the Unlock button.
|
|
535
|
-
*/
|
|
536
|
-
onUnlockClick?: () => void;
|
|
537
|
-
/**
|
|
538
|
-
* Called to fetch the attachment source — fired automatically when
|
|
539
|
-
* paymentStatus transitions to 'paid', or immediately on click when
|
|
540
|
-
* paymentStatus is already 'paid'. Return a LockedAttachmentSource to
|
|
541
|
-
* unlock the card.
|
|
542
|
-
*/
|
|
543
|
-
onFetchSource?: () => Promise<LockedAttachmentSource | void>;
|
|
544
|
-
/**
|
|
545
|
-
* Called when the visitor clicks Download on an unlocked card.
|
|
546
|
-
* Omit to hide the Download button.
|
|
547
|
-
*/
|
|
548
|
-
onDownloadClick?: () => void;
|
|
549
|
-
/**
|
|
550
|
-
* When true, shows loading dots on the Unlock button.
|
|
551
|
-
* Driven by the LockedAttachmentContext (e.g. checkout in progress, payment processing).
|
|
552
|
-
*/
|
|
553
|
-
isUnlocking?: boolean;
|
|
554
|
-
}
|
|
742
|
+
/** @deprecated Renamed to `ReceivedCardProps`. */
|
|
743
|
+
export declare type VisitorCardProps = ReceivedCardProps;
|
|
555
744
|
|
|
556
745
|
export declare type VoteSelection = 'up' | 'down' | null;
|
|
557
746
|
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as e, b as t, C as n, c as i, d as o, e as g, F as m, f as M, L as r, h as l, M as h, i as u, j as L, k as c, l as d, m as C, n as v, o as A, p as k, q as p, u as F, s as f, t as q } from "./index-DfcRe-Hj.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ActionButton,
|
|
4
4
|
t as Avatar,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
n as ChannelEmptyState,
|
|
6
|
+
i as ChannelList,
|
|
7
7
|
o as ChannelView,
|
|
8
8
|
g as CustomMessageProvider,
|
|
9
9
|
m as FaqList,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
l as
|
|
10
|
+
M as FaqListItem,
|
|
11
|
+
r as LinkAttachment,
|
|
12
|
+
l as LockedAttachment,
|
|
13
|
+
h as MediaMessage,
|
|
13
14
|
u as MessageVoteButtons,
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
L as MessagingProvider,
|
|
16
|
+
c as MessagingShell,
|
|
16
17
|
d as formatRelativeTime,
|
|
17
18
|
C as getMessageDisplayText,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
v as isLinkAttachment,
|
|
20
|
+
A as normalizeLanguageCode,
|
|
21
|
+
k as resolveLinkAttachment,
|
|
22
|
+
p as resolveMediaFromMessage,
|
|
23
|
+
F as useCustomMessage,
|
|
24
|
+
f as useMessageVote,
|
|
25
|
+
q as useMessaging
|
|
25
26
|
};
|
|
26
27
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -28,6 +28,17 @@ vi.mock('stream-chat-react', () => ({
|
|
|
28
28
|
),
|
|
29
29
|
useMessageContext: () => ({ message: { id: 'message-1', text: 'hello' } }),
|
|
30
30
|
useChannelStateContext: () => ({ channel: activeChannel }),
|
|
31
|
+
useChatContext: () => ({ client: { user: { id: 'visitor-1' } } }),
|
|
32
|
+
useTypingContext: () => ({ typing: {} }),
|
|
33
|
+
useAIState: () => ({ aiState: 'AI_STATE_IDLE' }),
|
|
34
|
+
AIStates: {
|
|
35
|
+
Error: 'AI_STATE_ERROR',
|
|
36
|
+
ExternalSources: 'AI_STATE_EXTERNAL_SOURCES',
|
|
37
|
+
Generating: 'AI_STATE_GENERATING',
|
|
38
|
+
Idle: 'AI_STATE_IDLE',
|
|
39
|
+
Stop: 'AI_STATE_STOP',
|
|
40
|
+
Thinking: 'AI_STATE_THINKING',
|
|
41
|
+
},
|
|
31
42
|
}))
|
|
32
43
|
|
|
33
44
|
vi.mock('../providers/MessagingProvider', () => ({
|
|
@@ -28,6 +28,7 @@ import { CustomMessage } from './CustomMessage'
|
|
|
28
28
|
import { CustomMessageInput } from './CustomMessageInput'
|
|
29
29
|
import { CustomSystemMessage } from './CustomSystemMessage'
|
|
30
30
|
import CustomTypingIndicator from './CustomTypingIndicator'
|
|
31
|
+
import { DmAgentEnabledContext } from './CustomTypingIndicator/DmAgentContext'
|
|
31
32
|
import { ChannelEmptyState } from './MessagingShell/ChannelEmptyState'
|
|
32
33
|
import { LoadingState } from './MessagingShell/LoadingState'
|
|
33
34
|
|
|
@@ -495,38 +496,40 @@ export const ChannelView = React.memo<ChannelViewProps>(
|
|
|
495
496
|
className
|
|
496
497
|
)}
|
|
497
498
|
>
|
|
498
|
-
<
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
499
|
+
<DmAgentEnabledContext.Provider value={dmAgentEnabled ?? false}>
|
|
500
|
+
<Channel
|
|
501
|
+
channel={channel}
|
|
502
|
+
MessageSystem={CustomSystemMessage}
|
|
503
|
+
EmptyStateIndicator={CustomChannelEmptyState}
|
|
504
|
+
LoadingIndicator={LoadingState}
|
|
505
|
+
DateSeparator={CustomDateSeparator}
|
|
506
|
+
TypingIndicator={CustomTypingIndicator}
|
|
507
|
+
doSendMessageRequest={doSendMessageRequest}
|
|
508
|
+
{...(sendButton ? { SendButton: sendButton } : {})}
|
|
509
|
+
>
|
|
510
|
+
<ChannelViewInner
|
|
511
|
+
onBack={onBack}
|
|
512
|
+
showBackButton={showBackButton}
|
|
513
|
+
renderMessageInputActions={renderMessageInputActions}
|
|
514
|
+
renderConversationFooter={renderConversationFooter}
|
|
515
|
+
onLeaveConversation={onLeaveConversation}
|
|
516
|
+
onBlockParticipant={onBlockParticipant}
|
|
517
|
+
CustomChannelEmptyState={CustomChannelEmptyState}
|
|
518
|
+
showDeleteConversation={showDeleteConversation}
|
|
519
|
+
onDeleteConversationClick={onDeleteConversationClick}
|
|
520
|
+
onBlockParticipantClick={onBlockParticipantClick}
|
|
521
|
+
onReportParticipantClick={onReportParticipantClick}
|
|
522
|
+
showStarButton={showStarButton}
|
|
523
|
+
dmAgentEnabled={dmAgentEnabled}
|
|
524
|
+
chatbotVotingEnabled={chatbotVotingEnabled}
|
|
525
|
+
renderChannelBanner={renderChannelBanner}
|
|
526
|
+
customProfileContent={customProfileContent}
|
|
527
|
+
customChannelActions={customChannelActions}
|
|
528
|
+
renderMessage={renderMessage}
|
|
529
|
+
viewerLanguage={viewerLanguage}
|
|
530
|
+
/>
|
|
531
|
+
</Channel>
|
|
532
|
+
</DmAgentEnabledContext.Provider>
|
|
530
533
|
</div>
|
|
531
534
|
)
|
|
532
535
|
}
|
|
@@ -227,21 +227,20 @@ const CustomMessageWithContext = (props: CustomMessageWithContextProps) => {
|
|
|
227
227
|
{isAttachment ? (
|
|
228
228
|
<div className="str-chat__message-bubble-wrapper">
|
|
229
229
|
{isMine ? (
|
|
230
|
-
<LockedAttachment.
|
|
230
|
+
<LockedAttachment.Sent
|
|
231
231
|
title={message.metadata?.attachment_title}
|
|
232
232
|
mimeType={message.metadata?.attachment_mime_type}
|
|
233
233
|
thumbnailUrl={message.metadata?.attachment_thumbnail}
|
|
234
234
|
amountText={message.metadata?.amount_text}
|
|
235
235
|
detail={message.metadata?.attachment_detail}
|
|
236
236
|
paymentStatus={message.metadata?.payment_status}
|
|
237
|
-
isUnlocking={isUnlocking(message.id)}
|
|
238
237
|
onPreviewClick={() => onUnlockClick?.(message, channel)}
|
|
239
238
|
onFetchSource={async () =>
|
|
240
239
|
await onFetchSource?.(message, channel)
|
|
241
240
|
}
|
|
242
241
|
/>
|
|
243
242
|
) : (
|
|
244
|
-
<LockedAttachment.
|
|
243
|
+
<LockedAttachment.Received
|
|
245
244
|
title={message.metadata?.attachment_title}
|
|
246
245
|
mimeType={message.metadata?.attachment_mime_type}
|
|
247
246
|
thumbnailUrl={message.metadata?.attachment_thumbnail}
|
|
@@ -2,16 +2,21 @@ import type { Meta, StoryFn } from '@storybook/react'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import type { Event } from 'stream-chat'
|
|
4
4
|
import {
|
|
5
|
+
AIStates,
|
|
5
6
|
ChannelStateProvider,
|
|
6
7
|
ChatProvider,
|
|
7
8
|
TypingProvider,
|
|
8
9
|
} from 'stream-chat-react'
|
|
9
10
|
|
|
11
|
+
import { DmAgentEnabledContext } from './DmAgentContext'
|
|
12
|
+
|
|
10
13
|
import CustomTypingIndicator from '.'
|
|
11
14
|
|
|
12
15
|
type StoryProps = {
|
|
13
16
|
typingEventsEnabled?: boolean
|
|
14
17
|
typing?: Record<string, Event>
|
|
18
|
+
aiState?: string
|
|
19
|
+
dmAgentEnabled?: boolean
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
const currentUser = {
|
|
@@ -33,10 +38,38 @@ const defaultTyping: Record<string, Event> = {
|
|
|
33
38
|
} as Event,
|
|
34
39
|
}
|
|
35
40
|
|
|
41
|
+
type ListenerMap = Record<string, (event: { ai_state: string; cid: string }) => void>
|
|
42
|
+
|
|
43
|
+
const createMockChannel = ({ aiState }: { aiState?: string }) => {
|
|
44
|
+
const listeners: ListenerMap = {}
|
|
45
|
+
const channel = {
|
|
46
|
+
cid: 'messaging:test',
|
|
47
|
+
state: {
|
|
48
|
+
members: {
|
|
49
|
+
[currentUser.id]: { user: currentUser },
|
|
50
|
+
[typingUser.id]: { user: typingUser },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
on(eventType: string, handler: ListenerMap[string]) {
|
|
54
|
+
listeners[eventType] = handler
|
|
55
|
+
// Fire the requested AI state synchronously so the hook picks it up.
|
|
56
|
+
if (eventType === 'ai_indicator.update' && aiState) {
|
|
57
|
+
handler({ ai_state: aiState, cid: 'messaging:test' })
|
|
58
|
+
}
|
|
59
|
+
return { unsubscribe: () => {} }
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
return channel
|
|
63
|
+
}
|
|
64
|
+
|
|
36
65
|
const StoryWrapper: React.FC<StoryProps> = ({
|
|
37
66
|
typingEventsEnabled = true,
|
|
38
|
-
typing =
|
|
67
|
+
typing = {},
|
|
68
|
+
aiState,
|
|
69
|
+
dmAgentEnabled = true,
|
|
39
70
|
}) => {
|
|
71
|
+
const channel = createMockChannel({ aiState })
|
|
72
|
+
|
|
40
73
|
const chatContextValue = {
|
|
41
74
|
client: {
|
|
42
75
|
user: currentUser,
|
|
@@ -57,18 +90,7 @@ const StoryWrapper: React.FC<StoryProps> = ({
|
|
|
57
90
|
}
|
|
58
91
|
|
|
59
92
|
const channelStateValue = {
|
|
60
|
-
channel
|
|
61
|
-
state: {
|
|
62
|
-
members: {
|
|
63
|
-
[currentUser.id]: {
|
|
64
|
-
user: currentUser,
|
|
65
|
-
},
|
|
66
|
-
[typingUser.id]: {
|
|
67
|
-
user: typingUser,
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
93
|
+
channel,
|
|
72
94
|
channelCapabilities: {},
|
|
73
95
|
channelConfig: {
|
|
74
96
|
typing_events: typingEventsEnabled,
|
|
@@ -85,9 +107,11 @@ const StoryWrapper: React.FC<StoryProps> = ({
|
|
|
85
107
|
<ChatProvider value={chatContextValue as never}>
|
|
86
108
|
<ChannelStateProvider value={channelStateValue as never}>
|
|
87
109
|
<TypingProvider value={{ typing }}>
|
|
88
|
-
<
|
|
89
|
-
<
|
|
90
|
-
|
|
110
|
+
<DmAgentEnabledContext.Provider value={dmAgentEnabled}>
|
|
111
|
+
<div className="relative h-20 w-[200px] bg-[#f4f4f4] p-3">
|
|
112
|
+
<CustomTypingIndicator />
|
|
113
|
+
</div>
|
|
114
|
+
</DmAgentEnabledContext.Provider>
|
|
91
115
|
</TypingProvider>
|
|
92
116
|
</ChannelStateProvider>
|
|
93
117
|
</ChatProvider>
|
|
@@ -104,7 +128,9 @@ const meta: Meta<StoryProps> = {
|
|
|
104
128
|
export default meta
|
|
105
129
|
|
|
106
130
|
export const Default: StoryFn<StoryProps> = (args) => <StoryWrapper {...args} />
|
|
107
|
-
Default.args = {
|
|
131
|
+
Default.args = {
|
|
132
|
+
typing: defaultTyping,
|
|
133
|
+
}
|
|
108
134
|
|
|
109
135
|
export const HiddenWhenNoTyping: StoryFn<StoryProps> = (args) => (
|
|
110
136
|
<StoryWrapper {...args} />
|
|
@@ -112,3 +138,17 @@ export const HiddenWhenNoTyping: StoryFn<StoryProps> = (args) => (
|
|
|
112
138
|
HiddenWhenNoTyping.args = {
|
|
113
139
|
typing: {},
|
|
114
140
|
}
|
|
141
|
+
|
|
142
|
+
export const AiAgentThinking: StoryFn<StoryProps> = (args) => (
|
|
143
|
+
<StoryWrapper {...args} />
|
|
144
|
+
)
|
|
145
|
+
AiAgentThinking.args = {
|
|
146
|
+
aiState: AIStates.Thinking,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export const AiAgentGenerating: StoryFn<StoryProps> = (args) => (
|
|
150
|
+
<StoryWrapper {...args} />
|
|
151
|
+
)
|
|
152
|
+
AiAgentGenerating.args = {
|
|
153
|
+
aiState: AIStates.Generating,
|
|
154
|
+
}
|