@linktr.ee/messaging-react 3.9.0-rc-1783580190 → 3.9.1-rc-1783576271

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 (88) hide show
  1. package/dist/Card-CyBRO0Ex.cjs +2 -0
  2. package/dist/Card-CyBRO0Ex.cjs.map +1 -0
  3. package/dist/Card-DYNxwKX6.js +132 -0
  4. package/dist/Card-DYNxwKX6.js.map +1 -0
  5. package/dist/Card-DmfP-4oF.cjs +2 -0
  6. package/dist/Card-DmfP-4oF.cjs.map +1 -0
  7. package/dist/Card-PBfzY620.cjs +2 -0
  8. package/dist/Card-PBfzY620.cjs.map +1 -0
  9. package/dist/Card-dZkL-om-.js +163 -0
  10. package/dist/Card-dZkL-om-.js.map +1 -0
  11. package/dist/Card-xR3OTXRB.js +107 -0
  12. package/dist/Card-xR3OTXRB.js.map +1 -0
  13. package/dist/LockedThumbnail-BblFdDJp.js +220 -0
  14. package/dist/LockedThumbnail-BblFdDJp.js.map +1 -0
  15. package/dist/LockedThumbnail-eE8ljauK.cjs +2 -0
  16. package/dist/LockedThumbnail-eE8ljauK.cjs.map +1 -0
  17. package/dist/assets/index.css +1 -1
  18. package/dist/index-Bxezkdl6.cjs +2 -0
  19. package/dist/index-Bxezkdl6.cjs.map +1 -0
  20. package/dist/{index-CmVOs9Jy.js → index-FY6hmphi.js} +1198 -1226
  21. package/dist/index-FY6hmphi.js.map +1 -0
  22. package/dist/index.cjs +1 -1
  23. package/dist/index.d.ts +98 -161
  24. package/dist/index.js +1 -1
  25. package/dist/testing.d.ts +0 -1
  26. package/package.json +2 -2
  27. package/src/components/ChannelList/CustomChannelPreview.test.tsx +0 -95
  28. package/src/components/ChannelList/CustomChannelPreview.tsx +9 -21
  29. package/src/components/CustomMessage/CustomMessage.stories.tsx +1 -54
  30. package/src/components/CustomMessage/MessageTag.tsx +0 -8
  31. package/src/components/CustomMessage/SentMessageDeliveryStatus.test.tsx +29 -11
  32. package/src/components/CustomMessage/SentMessageDeliveryStatus.tsx +22 -26
  33. package/src/components/CustomMessage/context.tsx +1 -1
  34. package/src/components/CustomMessage/index.tsx +42 -76
  35. package/src/components/CustomMessageInput/CustomMessageInput.stories.tsx +3 -5
  36. package/src/components/LockedAttachment/LockedAttachment.stories.tsx +450 -0
  37. package/src/components/LockedAttachment/components/Composer/Card.tsx +221 -0
  38. package/src/components/LockedAttachment/components/Composer/index.ts +2 -0
  39. package/src/components/LockedAttachment/components/Received/Card.tsx +191 -0
  40. package/src/components/{CustomMessage/LockedAttachment/components/Media → LockedAttachment/components/Received}/CardActions.tsx +2 -9
  41. package/src/components/LockedAttachment/components/Received/index.ts +2 -0
  42. package/src/components/LockedAttachment/components/Sent/Card.tsx +177 -0
  43. package/src/components/LockedAttachment/components/Sent/index.ts +2 -0
  44. package/src/components/{CustomMessage/LockedAttachment → LockedAttachment}/components/_shared/CardBody.tsx +7 -8
  45. package/src/components/{CustomMessage/LockedAttachment → LockedAttachment}/components/_shared/GalleryThumbnail.tsx +39 -31
  46. package/src/components/LockedAttachment/components/_shared/LockBadge.tsx +39 -0
  47. package/src/components/{CustomMessage/LockedAttachment/components/_shared/MediaShell.tsx → LockedAttachment/components/_shared/LockedCardShell.tsx} +8 -8
  48. package/src/components/{CustomMessage/LockedAttachment/components/_shared/SingleThumbnail.tsx → LockedAttachment/components/_shared/LockedThumbnail.tsx} +7 -11
  49. package/src/components/LockedAttachment/index.tsx +63 -0
  50. package/src/components/LockedAttachment/types.ts +51 -0
  51. package/src/index.ts +8 -3
  52. package/src/stream-custom-data.ts +0 -1
  53. package/src/styles.css +0 -12
  54. package/src/types.ts +1 -1
  55. package/dist/Card-415OfRhw.cjs +0 -2
  56. package/dist/Card-415OfRhw.cjs.map +0 -1
  57. package/dist/Card-Q9e8pbMP.js +0 -694
  58. package/dist/Card-Q9e8pbMP.js.map +0 -1
  59. package/dist/Card-dg4NGPoC.cjs +0 -2
  60. package/dist/Card-dg4NGPoC.cjs.map +0 -1
  61. package/dist/Card-qS17qnN0.js +0 -103
  62. package/dist/Card-qS17qnN0.js.map +0 -1
  63. package/dist/LoadingDots-Ct3WmVlT.js +0 -59
  64. package/dist/LoadingDots-Ct3WmVlT.js.map +0 -1
  65. package/dist/LoadingDots-D9GGphgM.cjs +0 -2
  66. package/dist/LoadingDots-D9GGphgM.cjs.map +0 -1
  67. package/dist/index-ChRwg_g6.cjs +0 -2
  68. package/dist/index-ChRwg_g6.cjs.map +0 -1
  69. package/dist/index-CmVOs9Jy.js.map +0 -1
  70. package/src/components/CustomMessage/LockedAttachment/LockedAttachment.stories.tsx +0 -541
  71. package/src/components/CustomMessage/LockedAttachment/LockedAttachment.test.tsx +0 -117
  72. package/src/components/CustomMessage/LockedAttachment/components/Media/Card.tsx +0 -358
  73. package/src/components/CustomMessage/LockedAttachment/components/Media/types.ts +0 -79
  74. package/src/components/CustomMessage/LockedAttachment/components/Text/Card.tsx +0 -153
  75. package/src/components/CustomMessage/LockedAttachment/components/Text/types.ts +0 -58
  76. package/src/components/CustomMessage/LockedAttachment/components/_shared/CardThumbnail.tsx +0 -92
  77. package/src/components/CustomMessage/LockedAttachment/components/_shared/LoadingDots.tsx +0 -36
  78. package/src/components/CustomMessage/LockedAttachment/components/_shared/LockBadge.tsx +0 -63
  79. package/src/components/CustomMessage/LockedAttachment/components/_shared/PreviewToggle.tsx +0 -58
  80. package/src/components/CustomMessage/LockedAttachment/components/_shared/PriceLockRow.tsx +0 -21
  81. package/src/components/CustomMessage/LockedAttachment/components/_shared/PurchaseStatusBadge.tsx +0 -74
  82. package/src/components/CustomMessage/LockedAttachment/components/_shared/SkeletonTextLines.tsx +0 -29
  83. package/src/components/CustomMessage/LockedAttachment/components/_shared/TextShell.tsx +0 -28
  84. package/src/components/CustomMessage/LockedAttachment/components/_shared/usePreviewToggle.test.ts +0 -67
  85. package/src/components/CustomMessage/LockedAttachment/components/_shared/usePreviewToggle.ts +0 -89
  86. package/src/components/CustomMessage/LockedAttachment/components/_shared/useReceivedSource.ts +0 -83
  87. package/src/components/CustomMessage/LockedAttachment/index.tsx +0 -105
  88. package/src/components/CustomMessage/LockedAttachment/types.ts +0 -44
@@ -4,14 +4,14 @@ import React from 'react'
4
4
  import {
5
5
  AttachmentThumbnail,
6
6
  renderTypeIcon,
7
- } from '../../../../AttachmentCard'
7
+ } from '../../../AttachmentCard'
8
8
  import type { LockedAttachmentSource, PaymentStatus } from '../../types'
9
9
 
10
10
  import { LockBadge } from './LockBadge'
11
- import type { CardVariant } from './MediaShell'
11
+ import type { LockedCardVariant } from './LockedCardShell'
12
12
 
13
- export interface SingleThumbnailProps {
14
- variant: CardVariant
13
+ export interface LockedThumbnailProps {
14
+ variant: LockedCardVariant
15
15
  mimeType: string
16
16
  thumbnailUrl?: string
17
17
  title?: string
@@ -40,7 +40,7 @@ export interface SingleThumbnailProps {
40
40
  * - preview/paid: clear thumbnail (the underlying source)
41
41
  * - empty: type-icon placeholder
42
42
  */
43
- const SingleThumbnail: React.FC<SingleThumbnailProps> = ({
43
+ const LockedThumbnail: React.FC<LockedThumbnailProps> = ({
44
44
  variant,
45
45
  mimeType,
46
46
  thumbnailUrl,
@@ -98,11 +98,7 @@ const SingleThumbnail: React.FC<SingleThumbnailProps> = ({
98
98
  })}
99
99
  </div>
100
100
  )}
101
- <LockBadge
102
- paymentStatus={paymentStatus}
103
- mimeType={mimeType}
104
- isLocked={showLocked}
105
- />
101
+ <LockBadge paymentStatus={paymentStatus} mimeType={mimeType} />
106
102
  </div>
107
103
  ) : (
108
104
  <AttachmentThumbnail
@@ -129,4 +125,4 @@ const SingleThumbnail: React.FC<SingleThumbnailProps> = ({
129
125
  )
130
126
  }
131
127
 
132
- export default SingleThumbnail
128
+ export default LockedThumbnail
@@ -0,0 +1,63 @@
1
+ import React, { Suspense } from 'react'
2
+
3
+ import type { ComposerCardProps } from './components/Composer/Card'
4
+ import type { ReceivedCardProps } from './components/Received/Card'
5
+ import type { SentCardProps } from './components/Sent/Card'
6
+
7
+ const ComposerCardLazy = React.lazy(() => import('./components/Composer/Card'))
8
+ const SentCardLazy = React.lazy(() => import('./components/Sent/Card'))
9
+ const ReceivedCardLazy = React.lazy(() => import('./components/Received/Card'))
10
+
11
+ const LockedAttachmentFallback = () => (
12
+ <div
13
+ className="w-[280px] min-h-[200px] animate-pulse rounded-md bg-black/[0.06] shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_1px_2px_rgba(0,0,0,0.04),0_8px_32px_rgba(0,0,0,0.1)]"
14
+ aria-hidden
15
+ />
16
+ )
17
+
18
+ const Composer = (props: ComposerCardProps) => (
19
+ <Suspense fallback={<LockedAttachmentFallback />}>
20
+ <ComposerCardLazy {...props} />
21
+ </Suspense>
22
+ )
23
+
24
+ const Sent = (props: SentCardProps) => (
25
+ <Suspense fallback={<LockedAttachmentFallback />}>
26
+ <SentCardLazy {...props} />
27
+ </Suspense>
28
+ )
29
+
30
+ const Received = (props: ReceivedCardProps) => (
31
+ <Suspense fallback={<LockedAttachmentFallback />}>
32
+ <ReceivedCardLazy {...props} />
33
+ </Suspense>
34
+ )
35
+
36
+ /**
37
+ * @deprecated Renamed to `LockedAttachment.Sent` (post-send sender card) or
38
+ * `LockedAttachment.Composer` (drafting state). This alias maps to `Sent`
39
+ * because that matches the previous in-thread usage; pre-send / drafting
40
+ * usages (e.g. with `onDismiss`) should migrate to `LockedAttachment.Composer`.
41
+ */
42
+ const Creator = Sent
43
+
44
+ /** @deprecated Renamed to `LockedAttachment.Received`. */
45
+ const Visitor = Received
46
+
47
+ const LockedAttachment = { Composer, Sent, Received, Creator, Visitor }
48
+
49
+ export default LockedAttachment
50
+ export type { ComposerCardProps, SentCardProps, ReceivedCardProps }
51
+ /**
52
+ * @deprecated Renamed to `SentCardProps`. Drafting usages (with `onDismiss`)
53
+ * should migrate to `ComposerCardProps`.
54
+ */
55
+ export type CreatorCardProps = SentCardProps
56
+ /** @deprecated Renamed to `ReceivedCardProps`. */
57
+ export type VisitorCardProps = ReceivedCardProps
58
+ export type {
59
+ PaymentStatus,
60
+ LockedAttachmentSource,
61
+ LockedAttachmentGalleryItem,
62
+ LockedAttachmentContextValue,
63
+ } from './types'
@@ -0,0 +1,51 @@
1
+ import type { Channel, LocalMessage } from 'stream-chat'
2
+
3
+ import type { PaymentStatus } from '../../stream-custom-data'
4
+
5
+ export interface LockedAttachmentBaseProps {
6
+ title?: string
7
+ mimeType?: string
8
+ thumbnailUrl?: string
9
+ detail?: string
10
+ amountText?: string
11
+ paymentStatus?: PaymentStatus
12
+ /**
13
+ * When provided with 2+ items, the card renders as a mixed-media carousel
14
+ * (e.g. a couple of photos + a video) instead of a single thumbnail. Each
15
+ * item brings its own thumbnail and optional source so that
16
+ * `LockedAttachment.Composer` / `.Sent` / `.Received` can all share the
17
+ * same carousel chrome.
18
+ */
19
+ gallery?: LockedAttachmentGalleryItem[]
20
+ }
21
+
22
+ export interface LockedAttachmentGalleryItem {
23
+ /** MIME type of this carousel item — drives the per-item play / lock affordance. */
24
+ mimeType: string
25
+ /** Poster image used for both the locked (blurred) and unlocked preview state. */
26
+ thumbnailUrl?: string
27
+ /** Underlying source (image or video URL) — shown only when unlocked. */
28
+ sourceUrl?: string
29
+ }
30
+
31
+ export interface LockedAttachmentSource {
32
+ /** Proxied URL used by the media player for in-app playback. */
33
+ sourceUrl: string
34
+ /** URL opened when the visitor clicks Download — may be a file or a web destination. */
35
+ redeemUrl?: string
36
+ /** Thumbnail URL from the fetched asset — overrides the metadata thumbnail when present. */
37
+ thumbnailUrl?: string
38
+ }
39
+
40
+ export type { PaymentStatus }
41
+
42
+ export interface LockedAttachmentContextValue {
43
+ isUnlocking: (id: string) => boolean
44
+ onUnlockClick?: (message: LocalMessage, channel: Channel) => void
45
+ onDownloadClick?: (message: LocalMessage, channel: Channel) => void
46
+ onFetchSource?: (message: LocalMessage, channel: Channel) => Promise<LockedAttachmentSource | void>
47
+ }
48
+
49
+ export const defaultLockedAttachmentContextValue: LockedAttachmentContextValue = {
50
+ isUnlocking: () => false,
51
+ }
package/src/index.ts CHANGED
@@ -6,7 +6,7 @@ export { MessagingShell } from './components/MessagingShell'
6
6
  export { ChannelList } from './components/ChannelList'
7
7
  export { ChannelView } from './components/ChannelView'
8
8
  export { default as ActionButton } from './components/ActionButton'
9
- export { default as LockedAttachment } from './components/CustomMessage/LockedAttachment'
9
+ export { default as LockedAttachment } from './components/LockedAttachment'
10
10
  export { default as LinkAttachment } from './components/LinkAttachment'
11
11
  export { default as MessageAttachment } from './components/MessageAttachment'
12
12
  export { Avatar } from './components/Avatar'
@@ -69,10 +69,15 @@ export type {
69
69
  export type { AvatarProps } from './components/Avatar'
70
70
  export type { ActionButtonProps } from './components/ActionButton'
71
71
  export type {
72
- LockedAttachmentProps,
72
+ ComposerCardProps,
73
+ SentCardProps,
74
+ ReceivedCardProps,
73
75
  LockedAttachmentGalleryItem,
74
76
  LockedAttachmentContextValue,
75
- } from './components/CustomMessage/LockedAttachment'
77
+ // Deprecated aliases preserved for backwards compatibility:
78
+ CreatorCardProps,
79
+ VisitorCardProps,
80
+ } from './components/LockedAttachment'
76
81
  export type {
77
82
  ComposerCardProps as LinkAttachmentComposerCardProps,
78
83
  SentCardProps as LinkAttachmentSentCardProps,
@@ -41,7 +41,6 @@ export interface MessageMetadata {
41
41
  amount_text?: string
42
42
  payment_status?: PaymentStatus
43
43
  attachment_title?: string
44
- attachment_content_type?: 'text' | 'media'
45
44
  attachment_mime_type?: string
46
45
  attachment_thumbnail?: string
47
46
  attachment_detail?: string
package/src/styles.css CHANGED
@@ -831,15 +831,3 @@
831
831
  color: #016e1a;
832
832
  background-color: #dbf0e0;
833
833
  }
834
-
835
- /** Remove padding from the text inside the locked attachment text shell,
836
- and inherit TextShell's explicit colour — stream-chat-react's own
837
- `MessageText` sets its own (black) colour that only gets overridden by
838
- `.str-chat`'s CSS vars, which the Composer preview doesn't have. */
839
- .message-locked-attachment-text .str-chat__message-text {
840
- padding: 0rem !important;
841
- }
842
-
843
- .message-locked-attachment-text .str-chat__message-text-inner {
844
- color: inherit;
845
- }
package/src/types.ts CHANGED
@@ -20,7 +20,7 @@ import type {
20
20
 
21
21
  import type { MessageMetadata } from './stream-custom-data'
22
22
 
23
- export type { LockedAttachmentSource } from './components/CustomMessage/LockedAttachment'
23
+ export type { LockedAttachmentSource } from './components/LockedAttachment'
24
24
 
25
25
  /**
26
26
  * Callback invoked when a user clicks a link inside the channel view.
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),h=require("@phosphor-icons/react"),d=require("./LoadingDots-D9GGphgM.cjs"),x=require("classnames"),r=({children:s})=>e.jsxs("div",{className:"flex items-center gap-1 text-xs font-medium",children:[e.jsx(h.LockSimpleIcon,{className:"size-3.5 shrink-0 opacity-55",weight:"fill","aria-hidden":!0}),s]}),c=({variant:s="dark"})=>{const a=s==="dark"?"bg-white/25":"bg-black/15";return e.jsxs("div",{className:"flex flex-col gap-2 str-chat__message-text my-1 animate-pulse","aria-hidden":!0,children:[e.jsx("div",{className:x("h-3 w-40 rounded-full",a)}),e.jsx("div",{className:x("h-3 w-24 rounded-full",a)})]})},n=({isMine:s,children:a,className:i})=>e.jsx("div",{className:x("message-locked-attachment-text","relative flex min-w-[225px] max-w-[280px] flex-col gap-1 rounded-[1.5rem] px-4 py-3","text-[0.875rem] leading-[1.3125rem] tracking-[0.14px]",s?"bg-[#1e2330] text-white":"bg-[#f2f1ef] text-black","shadow-[0_1px_2px_rgba(0,0,0,0.08)]",i),children:a}),u=({renderedText:s,amountText:a,placeholderAmountText:i,onDismiss:t})=>e.jsxs(n,{isMine:!0,className:"pr-8",children:[s||e.jsx(c,{variant:"dark"}),e.jsx(r,{children:e.jsx("span",{className:a?"text-white/55":"text-white/30",children:a||i})}),t&&e.jsx("button",{type:"button",onClick:t,className:"absolute right-3 top-3 flex size-6 shrink-0 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/15","aria-label":"Dismiss attachment",children:e.jsx(h.XIcon,{className:"size-3",weight:"bold"})})]}),j=({amountText:s,placeholderAmountText:a})=>e.jsxs(n,{isMine:!1,children:[e.jsx(c,{variant:"light"}),e.jsx(r,{children:e.jsx("span",{className:"opacity-55",children:s||a})})]}),m=({renderedText:s,amountText:a,paymentStatus:i="pending"})=>{const t=i==="paid";return e.jsxs(n,{isMine:!0,children:[t&&s?s:e.jsx(c,{variant:"dark"}),e.jsxs(r,{children:[a&&e.jsx("span",{className:"text-white/55",children:a}),e.jsx(d.PurchaseStatusBadge,{isMine:!0,paymentStatus:i})]})]})},f=({renderedText:s,amountText:a,paymentStatus:i,onUnlockClick:t,isUnlocking:l=!1})=>{if(i==="paid"&&s)return e.jsxs(n,{isMine:!1,children:[s,e.jsxs(r,{children:[a!=null&&e.jsx("span",{className:"opacity-55",children:a}),e.jsx(d.PurchaseStatusBadge,{isMine:!1,paymentStatus:"paid"})]})]});const o=l?"Unlocking message.":"Unlock this message.";return e.jsx(n,{isMine:!1,children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex flex-1 flex-col gap-2",children:[e.jsx(c,{variant:"light"}),e.jsx("span",{className:"sr-only","aria-live":"polite",children:o}),e.jsx(r,{children:a!=null&&e.jsx("span",{className:"opacity-55",children:a})})]}),e.jsx("button",{type:"button",onClick:t,disabled:l,"aria-label":l?"Unlocking message":"Unlock message","aria-busy":l,title:l?"Unlocking message":"Unlock message",className:"flex size-10 shrink-0 items-center justify-center rounded-full bg-[#121110] text-white hover:bg-[#2a2928]",children:l?e.jsx(d.LoadingDots,{}):e.jsx(h.LockSimpleIcon,{className:"size-4",weight:"fill","aria-hidden":!0})})]})})},g=s=>s.isDraft?e.jsx(u,{...s}):s.isPreview?e.jsx(j,{...s}):s.isMine?e.jsx(m,{...s}):e.jsx(f,{...s});exports.default=g;
2
- //# sourceMappingURL=Card-415OfRhw.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Card-415OfRhw.cjs","sources":["../src/components/CustomMessage/LockedAttachment/components/_shared/PriceLockRow.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/SkeletonTextLines.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/TextShell.tsx","../src/components/CustomMessage/LockedAttachment/components/Text/Card.tsx"],"sourcesContent":["import { LockSimpleIcon } from '@phosphor-icons/react'\nimport type React from 'react'\n\n/**\n * The lock-icon + amount/status row shared by every LockedAttachment text-mode\n * card. Only the wrapper and the leading lock icon are shared — the amount and\n * any trailing status live in `children`, since they genuinely differ per card\n * (placeholder fallback vs. paid badge vs. bare amount).\n */\nconst PriceLockRow: React.FC<React.PropsWithChildren> = ({ children }) => (\n <div className=\"flex items-center gap-1 text-xs font-medium\">\n <LockSimpleIcon\n className=\"size-3.5 shrink-0 opacity-55\"\n weight=\"fill\"\n aria-hidden\n />\n {children}\n </div>\n)\n\nexport default PriceLockRow\n","import classNames from 'classnames'\nimport React from 'react'\n\nexport interface SkeletonTextLinesProps {\n /** Matches the bubble it sits in — \"dark\" for the sender's own bubble. */\n variant: 'light' | 'dark'\n}\n\n/**\n * Two skeleton bars standing in for the redacted text of a paid text-only\n * message — the real content is never sent to the client until purchase, so\n * there's nothing to render yet.\n *\n * Uses explicit black/white (not `bg-current`) because Tailwind doesn't\n * support opacity modifiers on the `current` color — `bg-current/30` silently\n * produces no CSS rule at all.\n */\nconst SkeletonTextLines: React.FC<SkeletonTextLinesProps> = ({ variant = 'dark' }) => {\n const colour = variant === 'dark' ? 'bg-white/25' : 'bg-black/15'\n\n return (\n <div className=\"flex flex-col gap-2 str-chat__message-text my-1 animate-pulse\" aria-hidden>\n <div className={classNames('h-3 w-40 rounded-full', colour)} />\n <div className={classNames('h-3 w-24 rounded-full', colour)} />\n </div>\n )\n}\n\nexport default SkeletonTextLines\n","import classNames from 'classnames'\nimport React from 'react'\n\n/**\n * Chat-bubble chrome for a paid text-only message/preview. Deliberately\n * doesn't lean on `.str-chat`'s CSS variables (`--str-chat__message-bubble-*`)\n * — this renders in the Composer preview too, which sits outside any\n * `.str-chat` ancestor, so every value here (radius, colour, type scale) is\n * hardcoded to match the Figma spec directly.\n */\nconst TextShell: React.FC<\n React.PropsWithChildren<{ isMine: boolean; className?: string }>\n> = ({ isMine, children, className }) => (\n <div\n className={classNames(\n 'message-locked-attachment-text',\n 'relative flex min-w-[225px] max-w-[280px] flex-col gap-1 rounded-[1.5rem] px-4 py-3',\n 'text-[0.875rem] leading-[1.3125rem] tracking-[0.14px]',\n isMine ? 'bg-[#1e2330] text-white' : 'bg-[#f2f1ef] text-black',\n 'shadow-[0_1px_2px_rgba(0,0,0,0.08)]',\n className\n )}\n >\n {children}\n </div>\n)\n\nexport default TextShell\n","import { LockSimpleIcon, XIcon } from '@phosphor-icons/react'\nimport type React from 'react'\n\nimport LoadingDots from '../_shared/LoadingDots'\nimport PriceLockRow from '../_shared/PriceLockRow'\nimport PurchaseStatusBadge from '../_shared/PurchaseStatusBadge'\nimport SkeletonTextLines from '../_shared/SkeletonTextLines'\nimport TextShell from '../_shared/TextShell'\n\nimport type {\n TextCardDraftProps,\n TextCardOtherProps,\n TextCardOwnProps,\n TextCardPreviewProps,\n TextCardProps,\n} from './types'\n\nexport type { TextCardProps } from './types'\n\nconst DraftTextCard: React.FC<TextCardDraftProps> = ({\n renderedText,\n amountText,\n placeholderAmountText,\n onDismiss,\n}) => (\n <TextShell isMine className=\"pr-8\">\n {renderedText || <SkeletonTextLines variant=\"dark\" />}\n <PriceLockRow>\n <span className={amountText ? 'text-white/55' : 'text-white/30'}>\n {amountText || placeholderAmountText}\n </span>\n </PriceLockRow>\n {onDismiss && (\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"absolute right-3 top-3 flex size-6 shrink-0 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/15\"\n aria-label=\"Dismiss attachment\"\n >\n <XIcon className=\"size-3\" weight=\"bold\" />\n </button>\n )}\n </TextShell>\n)\n\nconst PreviewTextCard: React.FC<TextCardPreviewProps> = ({\n amountText,\n placeholderAmountText,\n}) => (\n <TextShell isMine={false}>\n <SkeletonTextLines variant=\"light\" />\n <PriceLockRow>\n <span className=\"opacity-55\">{amountText || placeholderAmountText}</span>\n </PriceLockRow>\n </TextShell>\n)\n\nconst OwnTextCard: React.FC<TextCardOwnProps> = ({\n renderedText,\n amountText,\n paymentStatus = 'pending',\n}) => {\n const isPaid = paymentStatus === 'paid'\n\n return (\n <TextShell isMine>\n {isPaid && renderedText ? (\n renderedText\n ) : (\n <SkeletonTextLines variant=\"dark\" />\n )}\n <PriceLockRow>\n {amountText && <span className=\"text-white/55\">{amountText}</span>}\n <PurchaseStatusBadge isMine paymentStatus={paymentStatus} />\n </PriceLockRow>\n </TextShell>\n )\n}\n\nconst OtherTextCard: React.FC<TextCardOtherProps> = ({\n renderedText,\n amountText,\n paymentStatus,\n onUnlockClick,\n isUnlocking = false,\n}) => {\n const isPaid = paymentStatus === 'paid'\n\n if (isPaid && renderedText) {\n return (\n <TextShell isMine={false}>\n {renderedText}\n <PriceLockRow>\n {amountText != null && (\n <span className=\"opacity-55\">{amountText}</span>\n )}\n <PurchaseStatusBadge isMine={false} paymentStatus=\"paid\" />\n </PriceLockRow>\n </TextShell>\n )\n }\n\n const ariaLabel = isUnlocking\n ? 'Unlocking message.'\n : 'Unlock this message.'\n\n return (\n <TextShell isMine={false}>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex flex-1 flex-col gap-2\">\n <SkeletonTextLines variant=\"light\" />\n <span className=\"sr-only\" aria-live=\"polite\">\n {ariaLabel}\n </span>\n <PriceLockRow>\n {amountText != null && (\n <span className=\"opacity-55\">{amountText}</span>\n )}\n </PriceLockRow>\n </div>\n <button\n type=\"button\"\n onClick={onUnlockClick}\n disabled={isUnlocking}\n aria-label={isUnlocking ? 'Unlocking message' : 'Unlock message'}\n aria-busy={isUnlocking}\n title={isUnlocking ? 'Unlocking message' : 'Unlock message'}\n className=\"flex size-10 shrink-0 items-center justify-center rounded-full bg-[#121110] text-white hover:bg-[#2a2928]\"\n >\n {isUnlocking ? (\n <LoadingDots />\n ) : (\n <LockSimpleIcon className=\"size-4\" weight=\"fill\" aria-hidden />\n )}\n </button>\n </div>\n </TextShell>\n )\n}\n\nconst TextCard: React.FC<TextCardProps> = (props) => {\n if (props.isDraft) {\n return <DraftTextCard {...props} />\n } else if (props.isPreview) {\n return <PreviewTextCard {...props} />\n } else if (props.isMine) {\n return <OwnTextCard {...props} />\n } else {\n return <OtherTextCard {...props} />\n }\n}\n\nexport default TextCard\n"],"names":["PriceLockRow","children","jsxs","jsx","LockSimpleIcon","SkeletonTextLines","variant","colour","classNames","TextShell","isMine","className","DraftTextCard","renderedText","amountText","placeholderAmountText","onDismiss","XIcon","PreviewTextCard","OwnTextCard","paymentStatus","isPaid","PurchaseStatusBadge","OtherTextCard","onUnlockClick","isUnlocking","ariaLabel","LoadingDots","TextCard","props"],"mappings":"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"}