{"version":3,"file":"Card-BIbqWagz.cjs","names":[],"sources":["../src/components/CustomMessage/LockedAttachment/components/_shared/CardBody.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/LockBadge.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/GalleryThumbnail.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/SingleThumbnail.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/CardThumbnail.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/MediaShell.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/PreviewToggle.tsx","../src/components/CustomMessage/LockedAttachment/components/_shared/usePreviewToggle.ts","../src/components/CustomMessage/LockedAttachment/components/_shared/useReceivedSource.ts","../src/components/CustomMessage/LockedAttachment/components/Media/CardActions.tsx","../src/components/CustomMessage/LockedAttachment/components/Media/Card.tsx"],"sourcesContent":["import classNames from 'classnames'\nimport React from 'react'\n\nimport { renderTypeIcon } from '../../../../AttachmentCard'\n\nimport type { CardVariant } from './MediaShell'\n\nexport interface CardBodyProps {\n  variant: CardVariant\n  title?: string\n  placeholderTitle?: string\n  mimeType: string\n  detail?: string\n  statusBadge?: React.ReactNode\n  action?: React.ReactNode\n  /** Overrides the auto-detected type icon (used by Gallery to swap in an `Images` icon). */\n  icon?: React.ReactNode\n  /** Optional control rendered on the right of the title/status block (e.g. Composer edit pencil). */\n  trailingAction?: React.ReactNode\n}\n\n/**\n * Title + status row layout shared by Composer and `LockedAttachment.Media`.\n * Layout matches the Figma `Container > Labels` group (16px h-padding, 12px v-padding,\n * 4px gap between title and status row, 4px gap inside status row).\n */\nconst CardBody: React.FC<CardBodyProps> = ({\n  variant,\n  title,\n  placeholderTitle = 'Attachment title',\n  mimeType,\n  detail,\n  statusBadge,\n  action,\n  icon,\n  trailingAction,\n}) => {\n  const isDark = variant === 'dark'\n  const displayTitle = title || placeholderTitle\n  const titleDimmed = !title\n\n  const typeIcon =\n    icon ??\n    renderTypeIcon(mimeType, {\n      className: classNames(\n        'size-5 shrink-0',\n        isDark ? 'text-white/55' : 'text-black/55'\n      ),\n      weight: 'regular',\n    })\n\n  return (\n    <div className=\"px-4 py-3\">\n      <div className=\"flex items-end gap-3\">\n        <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n          {displayTitle.trim() !== '' && (\n            <p\n              className={classNames(\n                'truncate text-base font-medium leading-6',\n                {\n                  'text-black/90': !isDark && !titleDimmed,\n                  'text-black/30': !isDark && titleDimmed,\n                  'text-white/30': isDark && titleDimmed,\n                  'text-white': isDark && !titleDimmed,\n                }\n              )}\n            >\n              {displayTitle}\n            </p>\n          )}\n\n          <div className=\"flex flex-wrap items-center gap-1\">\n            {typeIcon}\n\n            {detail != null && detail !== '' && (\n              <span\n                className={classNames(\n                  'text-xs font-medium',\n                  isDark ? 'text-white/55' : 'text-black/55'\n                )}\n              >\n                {detail}\n              </span>\n            )}\n\n            {statusBadge}\n          </div>\n        </div>\n\n        {trailingAction && <div className=\"shrink-0\">{trailingAction}</div>}\n      </div>\n\n      {action}\n    </div>\n  )\n}\n\nexport default CardBody\n","import { LockOpenIcon, LockSimpleIcon, PlayIcon } from '@phosphor-icons/react'\nimport classNames from 'classnames'\nimport React from 'react'\n\nimport { getSourceType } from '../../../../AttachmentCard'\nimport type { PaymentStatus } from '../../types'\n\nexport interface LockBadgeProps {\n  paymentStatus?: PaymentStatus\n  mimeType?: string\n  /**\n   * Overrides the `mimeType`-derived playable check. Lets a caller that\n   * already knows per-item playability (e.g. `GalleryThumbnail`, checking a\n   * carousel item's own mimeType rather than the card's single `mimeType`)\n   * skip re-deriving it.\n   */\n  isPlayable?: boolean\n  /** Whether the item is still locked. Play only ever shows once unlocked —\n   * a locked item always shows the lock, even for otherwise-playable media. */\n  isLocked: boolean\n}\n\n/**\n * Centered 48x48 lock badge that overlays the thumbnail of any locked attachment.\n * Uses `bg-black/30`. Stays `pointer-events-none` so clicks pass through to\n * the underlying player/toggle; the play state highlights via `group-hover`\n * (same `bg-black/40` as the gallery's prev/next arrows) — the ancestor\n * providing `group` must wrap the actual clickable/hoverable player area.\n *\n * For playable media (video/audio) that's unlocked, the badge shows a play\n * icon instead of a lock — matching the convention used by `GalleryThumbnail`.\n */\nexport const LockBadge: React.FC<LockBadgeProps> = ({\n  paymentStatus,\n  mimeType,\n  isPlayable,\n  isLocked,\n}) => {\n  const sourceType = mimeType ? getSourceType(mimeType) : undefined\n  const resolvedIsPlayable =\n    isPlayable ?? (sourceType === 'video' || sourceType === 'audio')\n\n  const Icon =\n    resolvedIsPlayable && !isLocked\n      ? PlayIcon\n      : paymentStatus === 'paid'\n        ? LockOpenIcon\n        : LockSimpleIcon\n  return (\n    <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n      <div\n        className={classNames(\n          'flex size-12 items-center justify-center rounded-full bg-black/30 text-white',\n          Icon === PlayIcon && 'group-hover:bg-black/40'\n        )}\n      >\n        <Icon className=\"size-6\" weight=\"fill\" />\n      </div>\n    </div>\n  )\n}\n","import { CaretLeftIcon, CaretRightIcon } from '@phosphor-icons/react'\nimport classNames from 'classnames'\nimport React, { useState } from 'react'\n\nimport { optimizeMessagingAttachmentUrl } from '../../../../../utils/cdnImageUrl'\nimport { AttachmentThumbnail, getSourceType } from '../../../../AttachmentCard'\nimport type { LockedAttachmentGalleryItem, PaymentStatus } from '../../types'\n\nimport { LockBadge } from './LockBadge'\nimport type { CardVariant } from './MediaShell'\n\nexport interface GalleryThumbnailProps {\n  variant: CardVariant\n  gallery: LockedAttachmentGalleryItem[]\n  title?: string\n  /** When true, all items are shown blurred + the locked/play badge is overlaid. */\n  showLocked: boolean\n  paymentStatus?: PaymentStatus\n  /** Top-right slot (e.g. dismiss X on Composer). Rendered inside the thumbnail. */\n  topRight?: React.ReactNode\n}\n\nfunction isPlayableItem(item: LockedAttachmentGalleryItem): boolean {\n  const sourceType = getSourceType(item.mimeType)\n  return sourceType === 'video' || sourceType === 'audio'\n}\n\n/**\n * Mixed-media carousel used by every LockedAttachment card when its `gallery`\n * prop has 2+ items. Matches the \"Gallery\" frames in the Figma design system:\n * 337/386 aspect ratio, prev/next caret buttons, a counter pill, and a center\n * lock / play indicator that swaps based on the current item.\n */\nconst GalleryThumbnail: React.FC<GalleryThumbnailProps> = ({\n  variant,\n  gallery,\n  title,\n  showLocked,\n  paymentStatus,\n  topRight,\n}) => {\n  const [index, setIndex] = useState(0)\n  const total = gallery.length\n  const safeIndex = Math.min(index, total - 1)\n  const current = gallery[safeIndex]\n  const isVideoItem = isPlayableItem(current)\n  const optimizedCurrentThumbnailUrl = optimizeMessagingAttachmentUrl(\n    current.thumbnailUrl\n  )\n\n  // Stop propagation so arrow taps don't bubble up to the outer preview-toggle\n  // wrapper on PreviewMediaCard / OwnMediaCard.\n  const goPrev = (e: React.MouseEvent) => {\n    e.stopPropagation()\n    setIndex((i) => Math.max(0, i - 1))\n  }\n  const goNext = (e: React.MouseEvent) => {\n    e.stopPropagation()\n    setIndex((i) => Math.min(total - 1, i + 1))\n  }\n  const atStart = safeIndex === 0\n  const atEnd = safeIndex === total - 1\n\n  const isDark = variant === 'dark'\n\n  // Locked + unlocked render entirely separate trees so the locked state\n  // doesn't end up stacking a blurred `<img>` on top of an underlying\n  // `AttachmentThumbnail` (whose `bg-white/10` poster shell otherwise\n  // shows through as a visible horizontal seam).\n  //\n  // The locked placeholder is absolutely positioned, so it needs the fixed\n  // 337/386 box for height; unlocked content (video, natural-sized image)\n  // manages its own height and can expand/shrink per item.\n  //\n  // The locked branch uses `filter: blur` on a single full-size `<img>`\n  // — not `backdrop-filter` — so the rounded corners are clipped\n  // normally without any clip-path workarounds (see SingleThumbnail).\n  return (\n    <div\n      className={classNames(\n        'group relative overflow-hidden rounded-t-md',\n        showLocked ? 'aspect-[337/386]' : undefined\n      )}\n    >\n      {showLocked ? (\n        <div\n          className={classNames(\n            'absolute inset-0',\n            isDark ? 'bg-white/10' : 'bg-black/5'\n          )}\n        >\n          {current.thumbnailUrl && (\n            <img\n              src={optimizedCurrentThumbnailUrl ?? current.thumbnailUrl}\n              alt=\"\"\n              aria-hidden\n              draggable={false}\n              // `scale-110` hides the fuzzy edge that `filter: blur` leaves\n              // around the image bounds.\n              className=\"absolute inset-0 h-full w-full scale-110 object-cover blur-[40px]\"\n            />\n          )}\n        </div>\n      ) : (\n        <AttachmentThumbnail\n          key={safeIndex}\n          mimeType={current.mimeType}\n          sourceUrl={current.sourceUrl}\n          thumbnailUrl={current.thumbnailUrl}\n          title={title}\n          variant={variant}\n          mediaPlayerProps={{ autoPlay: true }}\n        />\n      )}\n\n      {/* LOCK while locked. Once unlocked, video/audio autoplays via\n          `mediaPlayerProps` and MediaPlayer already has its own inline\n          controls, so no separate Play affordance is shown. */}\n      {showLocked && (\n        <LockBadge\n          paymentStatus={paymentStatus}\n          isPlayable={isVideoItem}\n          isLocked={showLocked}\n        />\n      )}\n\n      {total > 1 && (\n        <React.Fragment>\n          <button\n            type=\"button\"\n            onClick={goPrev}\n            disabled={atStart}\n            aria-label=\"Previous item\"\n            className={classNames(\n              'absolute left-3 top-1/2 -translate-y-1/2 flex size-7 items-center justify-center rounded-full bg-black/30 text-white transition-opacity',\n              atStart ? 'opacity-40' : 'hover:bg-black/40'\n            )}\n          >\n            <CaretLeftIcon className=\"size-5\" weight=\"bold\" />\n          </button>\n          <button\n            type=\"button\"\n            onClick={goNext}\n            disabled={atEnd}\n            aria-label=\"Next item\"\n            className={classNames(\n              'absolute right-3 top-1/2 -translate-y-1/2 flex size-7 items-center justify-center rounded-full bg-black/30 text-white transition-opacity',\n              atEnd ? 'opacity-40' : 'hover:bg-black/40'\n            )}\n          >\n            <CaretRightIcon className=\"size-5\" weight=\"bold\" />\n          </button>\n\n          <div className=\"pointer-events-none absolute bottom-10 left-1/2 flex size-8 -translate-x-1/2 items-center justify-center rounded-full bg-black/30\">\n            <span className=\"text-xs font-medium leading-none text-white\">\n              {safeIndex + 1}/{total}\n            </span>\n          </div>\n        </React.Fragment>\n      )}\n\n      {topRight && (\n        <div className=\"pointer-events-auto absolute right-3 top-3 z-10\">\n          {topRight}\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default GalleryThumbnail\n","import classNames from 'classnames'\nimport React from 'react'\n\nimport { optimizeMessagingAttachmentUrl } from '../../../../../utils/cdnImageUrl'\nimport { AttachmentThumbnail, renderTypeIcon } from '../../../../AttachmentCard'\nimport type { LockedAttachmentSource, PaymentStatus } from '../../types'\n\nimport { LockBadge } from './LockBadge'\nimport type { CardVariant } from './MediaShell'\n\nexport interface SingleThumbnailProps {\n  variant: CardVariant\n  mimeType: string\n  thumbnailUrl?: string\n  title?: string\n  /**\n   * When provided, the underlying source is shown unblurred (preview / unlocked state).\n   * When undefined, the thumbnail is treated as locked: blurred with a central lock badge.\n   */\n  source?: LockedAttachmentSource\n  /**\n   * Forces the locked appearance even when a source is provided. Used for the\n   * Composer card where the locked treatment is the default and the user toggles\n   * a preview in place.\n   */\n  showLocked: boolean\n  paymentStatus?: PaymentStatus\n  /** Top-right overlay (e.g. dismiss X on Composer). Rendered inside the thumbnail. */\n  topRight?: React.ReactNode\n  /** When true, renders the unlocked image with aspect-video + object-contain. */\n  containedImage?: boolean\n}\n\n/**\n * Renders the 180px-tall media area for a LockedAttachment card.\n * Handles three visual states:\n *   - locked:       blurred thumbnail + centered 48px lock badge\n *   - preview/paid: clear thumbnail (the underlying source)\n *   - empty:        type-icon placeholder\n */\nconst SingleThumbnail: React.FC<SingleThumbnailProps> = ({\n  variant,\n  mimeType,\n  thumbnailUrl,\n  title,\n  source,\n  showLocked,\n  paymentStatus,\n  topRight,\n  containedImage = false,\n}) => {\n  const effectiveSourceUrl = showLocked ? undefined : source?.sourceUrl\n  const effectiveThumbnailUrl = showLocked\n    ? thumbnailUrl\n    : (source?.thumbnailUrl ?? thumbnailUrl)\n  const optimizedThumbnailUrl = optimizeMessagingAttachmentUrl(\n    effectiveThumbnailUrl\n  )\n\n  const isDark = variant === 'dark'\n\n  // Locked + unlocked render entirely separate trees so the locked state\n  // doesn't end up stacking a blurred `<img>` on top of an underlying\n  // `AttachmentThumbnail` (whose `bg-white/10` poster shell otherwise\n  // shows through as a visible horizontal seam at the 16:9 boundary).\n  //\n  // The locked branch uses `filter: blur` on a single full-size `<img>`\n  // — not `backdrop-filter` — because `backdrop-filter` paints in its\n  // own compositing layer that escapes ancestor `overflow: hidden` on\n  // Chrome/Safari and flattens the card's top corners. `filter` is\n  // clipped normally, so the rounded corners stay round without any\n  // clip-path workarounds.\n  return (\n    <div className=\"relative overflow-hidden rounded-t-md\">\n      {showLocked ? (\n        <div\n          className={classNames(\n            'relative aspect-video overflow-hidden',\n            isDark ? 'bg-white/10' : 'bg-black/5'\n          )}\n        >\n          {effectiveThumbnailUrl ? (\n            <img\n              src={optimizedThumbnailUrl ?? effectiveThumbnailUrl}\n              alt=\"\"\n              aria-hidden\n              draggable={false}\n              // `scale-110` hides the fuzzy semi-transparent edge that\n              // `filter: blur` leaves around the image bounds.\n              className=\"absolute inset-0 h-full w-full scale-110 object-cover blur-[40px]\"\n            />\n          ) : (\n            <div className=\"absolute inset-0 flex items-center justify-center\">\n              {renderTypeIcon(mimeType, {\n                className: isDark\n                  ? 'size-12 text-white/20'\n                  : 'size-12 text-black/20',\n                weight: 'regular',\n              })}\n            </div>\n          )}\n          <LockBadge\n            paymentStatus={paymentStatus}\n            mimeType={mimeType}\n            isLocked={showLocked}\n          />\n        </div>\n      ) : (\n        <AttachmentThumbnail\n          mimeType={mimeType}\n          sourceUrl={effectiveSourceUrl}\n          thumbnailUrl={effectiveThumbnailUrl}\n          title={title}\n          variant={variant}\n          containedImage={containedImage}\n          mediaPlayerProps={\n            effectiveSourceUrl\n              ? { autoPlay: true, loop: true, controls: true, muted: false }\n              : undefined\n          }\n        />\n      )}\n\n      {topRight && (\n        <div className=\"pointer-events-auto absolute right-3 top-3 z-10\">\n          {topRight}\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default SingleThumbnail\n","import { ImagesIcon } from '@phosphor-icons/react'\nimport type React from 'react'\n\nimport type {\n  LockedAttachmentGalleryItem,\n  LockedAttachmentSource,\n  PaymentStatus,\n} from '../../types'\n\nimport GalleryThumbnail from './GalleryThumbnail'\nimport type { CardVariant } from './MediaShell'\nimport SingleThumbnail from './SingleThumbnail'\n\nexport interface CardThumbnailProps {\n  variant: CardVariant\n  gallery: LockedAttachmentGalleryItem[]\n  title?: string\n  showLocked: boolean\n  paymentStatus?: PaymentStatus\n  /** Single-asset props — ignored when the card renders as a gallery. */\n  mimeType: string\n  thumbnailUrl?: string\n  source?: LockedAttachmentSource\n  containedImage?: boolean\n  /** Top-right overlay (e.g. Composer dismiss X). Rendered inside the thumbnail. */\n  topRight?: React.ReactNode\n}\n\n/** True when the card should render as a mixed-media carousel (2+ items). */\nexport const isGalleryCard = (\n  gallery: LockedAttachmentGalleryItem[]\n): boolean => gallery.length >= 2\n\n/**\n * The body-row icon a card shows when it renders as a gallery — `CardBody`\n * otherwise auto-detects the icon from `mimeType`. Returned as a ready node so\n * every card shares the same size/tone treatment.\n */\nexport const galleryBodyIcon = (variant: CardVariant): React.ReactNode => (\n  <ImagesIcon\n    className={\n      variant === 'dark'\n        ? 'size-5 shrink-0 text-white/55'\n        : 'size-5 shrink-0 text-black/55'\n    }\n  />\n)\n\n/**\n * Owns the single-vs-gallery thumbnail decision shared by Composer /\n * `LockedAttachment.Media` cards: renders `GalleryThumbnail` for a 2+ item `gallery`,\n * else `SingleThumbnail` for the single asset. Callers pass the superset of\n * props; the unused half is ignored by whichever branch renders.\n */\nconst CardThumbnail: React.FC<CardThumbnailProps> = ({\n  variant,\n  gallery,\n  title,\n  showLocked,\n  paymentStatus,\n  mimeType,\n  thumbnailUrl,\n  source,\n  containedImage,\n  topRight,\n}) =>\n  isGalleryCard(gallery) ? (\n    <GalleryThumbnail\n      variant={variant}\n      gallery={gallery}\n      title={title}\n      showLocked={showLocked}\n      paymentStatus={paymentStatus}\n      topRight={topRight}\n    />\n  ) : (\n    <SingleThumbnail\n      variant={variant}\n      mimeType={mimeType}\n      thumbnailUrl={thumbnailUrl}\n      title={title}\n      source={source}\n      showLocked={showLocked}\n      paymentStatus={paymentStatus}\n      topRight={topRight}\n      containedImage={containedImage}\n    />\n  )\n\nexport default CardThumbnail\n","import classNames from 'classnames'\nimport React from 'react'\n\nexport type CardVariant = 'dark' | 'light'\n\nexport interface MediaShellProps {\n  variant: CardVariant\n  children: React.ReactNode\n  rootRef?: React.Ref<HTMLDivElement>\n  'data-testid'?: string\n}\n\n/**\n * Outer chrome for every LockedAttachment card.\n * Mirrors the 16px radius treatment from the Figma design system.\n */\nconst MediaShell: React.FC<MediaShellProps> = ({\n  variant,\n  children,\n  rootRef,\n  'data-testid': dataTestId,\n}) => (\n  <div\n    ref={rootRef}\n    data-testid={dataTestId}\n    className={classNames(\n      'relative w-[280px] select-none overflow-hidden rounded-md',\n      variant === 'dark' ? 'bg-[#1e2330]' : 'bg-white',\n      'shadow-[0_1px_2px_rgba(0,0,0,0.08)]'\n    )}\n  >\n    {children}\n  </div>\n)\n\nexport default MediaShell\n","import React from 'react'\n\nexport interface PreviewToggleProps {\n  /** Toggles the preview; omit to render `children` with no wrapper at all (nothing to toggle). */\n  onToggle: (() => void | Promise<void>) | undefined\n  isBusy: boolean\n  isPreviewVisible: boolean\n  children: React.ReactNode\n}\n\n/**\n * Makes a locked thumbnail clickable to toggle its preview. Uses a\n * `role=\"button\"` div rather than a native `<button>` because the thumbnail\n * it wraps can itself contain interactive children (gallery carousel arrows,\n * a Composer dismiss X) — nesting a real `<button>` around those would\n * produce invalid, inaccessible nested-interactive-element markup.\n */\nconst PreviewToggle: React.FC<PreviewToggleProps> = ({\n  onToggle,\n  isBusy,\n  isPreviewVisible,\n  children,\n}) => {\n  if (!onToggle) return <React.Fragment>{children}</React.Fragment>\n\n  return (\n    <div\n      role=\"button\"\n      tabIndex={isBusy ? -1 : 0}\n      aria-label=\"Toggle preview\"\n      aria-busy={isBusy}\n      aria-pressed={isPreviewVisible}\n      aria-disabled={isBusy || undefined}\n      onClick={isBusy ? undefined : onToggle}\n      onKeyDown={(e) => {\n        if (isBusy) return\n        // Only handle keys that originate on the wrapper itself, not on\n        // inner interactive elements (dismiss X, carousel arrows). Without\n        // this guard, pressing Enter/Space on a focused child would bubble\n        // up and toggle the preview in addition to activating the child.\n        if (e.target !== e.currentTarget) return\n        if (e.key === 'Enter' || e.key === ' ') {\n          e.preventDefault()\n          void onToggle()\n        }\n      }}\n      className={\n        !isBusy\n          ? 'block w-full cursor-pointer text-left'\n          : 'block w-full text-left'\n      }\n    >\n      {children}\n    </div>\n  )\n}\n\nexport default PreviewToggle\n","import { useCallback, useRef, useState } from 'react'\n\nimport type { LockedAttachmentSource } from '../../types'\n\nexport interface UsePreviewToggleOptions {\n  /** Gallery items carry their own per-item sources on the `gallery` prop already, so toggling skips the async fetch entirely. */\n  isGallery: boolean\n  /**\n   * Lazily loads the underlying source; the resolved value is cached in\n   * `source` and reused on subsequent toggles.\n   */\n  onFetchSource?: () => Promise<LockedAttachmentSource | void>\n  /** Fired on every toggle tap, before any visibility/fetch logic runs. */\n  onPreviewClick?: () => void\n}\n\nexport interface UsePreviewToggleResult {\n  source: LockedAttachmentSource | undefined\n  isPreviewVisible: boolean\n  isLoadingPreview: boolean\n  handleToggle: () => Promise<void>\n  /**\n   * `handleToggle` when the card can actually be previewed (gallery, or a\n   * fetch/click handler is wired), else `undefined` — pass straight to\n   * `PreviewToggle.onToggle` so a non-previewable card renders no\n   * toggle affordance.\n   */\n  togglePreview: (() => Promise<void>) | undefined\n}\n\n/**\n * Shared preview-toggle state for Composer/Media isMine: flips a locked thumbnail to\n * its unlocked preview, lazily fetching and caching the source on first\n * reveal. Media !isMine doesn't use this — it fetches on scroll-into-view/paid\n * instead of on a toggle tap.\n */\nexport function usePreviewToggle({\n  isGallery,\n  onFetchSource,\n  onPreviewClick,\n}: UsePreviewToggleOptions): UsePreviewToggleResult {\n  const [source, setSource] = useState<LockedAttachmentSource | undefined>()\n  const [isPreviewVisible, setIsPreviewVisible] = useState(false)\n  const [isLoadingPreview, setIsLoadingPreview] = useState(false)\n  const fetchingRef = useRef(false)\n\n  const handleToggle = useCallback(async () => {\n    onPreviewClick?.()\n    if (isPreviewVisible) {\n      setIsPreviewVisible(false)\n      return\n    }\n    if (isGallery) {\n      setIsPreviewVisible(true)\n      return\n    }\n    if (source) {\n      setIsPreviewVisible(true)\n      return\n    }\n    if (!onFetchSource) return\n    if (fetchingRef.current) return\n    fetchingRef.current = true\n    setIsLoadingPreview(true)\n    try {\n      const result = await onFetchSource()\n      if (result) {\n        setSource(result)\n        setIsPreviewVisible(true)\n      }\n    } finally {\n      fetchingRef.current = false\n      setIsLoadingPreview(false)\n    }\n  }, [isPreviewVisible, isGallery, source, onPreviewClick, onFetchSource])\n\n  const togglePreview =\n    isGallery || onFetchSource != null || onPreviewClick != null\n      ? handleToggle\n      : undefined\n\n  return {\n    source,\n    isPreviewVisible,\n    isLoadingPreview,\n    handleToggle,\n    togglePreview,\n  }\n}\n","/* eslint-disable react-hooks/refs -- pre-existing pattern flagged by the React\n   Compiler rules added in eslint-plugin-react-hooks v7; refactoring it is\n   out of scope for the lint toolchain upgrade. */\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nimport type {\n  FetchSourceHandler,\n  LockedAttachmentSource,\n  PaymentStatus,\n} from '../../types'\n\nexport interface UseReceivedSourceOptions {\n  paymentStatus?: PaymentStatus\n  onFetchSource?: FetchSourceHandler\n  /** Called on Unlock click while the card is still unpaid (opens checkout). */\n  onUnlockClick?: () => void\n}\n\nexport interface UseReceivedSourceResult {\n  source: LockedAttachmentSource | undefined\n  /** Attach to the card root so the paid-source auto-fetch can observe it. */\n  cardRef: React.RefObject<HTMLDivElement>\n  /** Fetches the source when already paid, else defers to `onUnlockClick`. */\n  handleUnlockClick: () => void\n}\n\n/**\n * Media !isMine's source-reveal logic: unlike Composer/Media isMine's\n * tap-to-toggle (`usePreviewToggle`), the recipient's card reveals its source\n * by fetching once — on click when already paid, or automatically the first\n * time a paid card scrolls fully into view. The fetch is guarded so it runs\n * at most once in flight.\n */\nexport function useReceivedSource({\n  paymentStatus,\n  onFetchSource,\n  onUnlockClick,\n}: UseReceivedSourceOptions): UseReceivedSourceResult {\n  const [source, setSource] = useState<LockedAttachmentSource | undefined>()\n\n  const cardRef = useRef<HTMLDivElement>(null)\n  const fetchingRef = useRef(false)\n\n  const onFetchSourceRef = useRef(onFetchSource)\n  onFetchSourceRef.current = onFetchSource\n\n  const fetchSource = useCallback(async (): Promise<void> => {\n    if (fetchingRef.current) return\n    fetchingRef.current = true\n    try {\n      const result = await onFetchSourceRef.current?.()\n      if (result) setSource(result)\n    } finally {\n      fetchingRef.current = false\n    }\n  }, [])\n\n  const handleUnlockClick = useCallback(() => {\n    if (paymentStatus === 'paid') {\n      void fetchSource()\n    } else {\n      onUnlockClick?.()\n    }\n  }, [paymentStatus, fetchSource, onUnlockClick])\n\n  // Auto-fetch the source once the paid card scrolls into view.\n  useEffect(() => {\n    if (!cardRef.current) return\n    if (paymentStatus !== 'paid' || source !== undefined) return\n\n    const observer = new IntersectionObserver(\n      ([entry]) => {\n        if (entry.isIntersecting) {\n          void fetchSource()\n          observer.disconnect()\n        }\n      },\n      { threshold: 1.0 }\n    )\n\n    observer.observe(cardRef.current)\n    return () => observer.disconnect()\n  }, [paymentStatus, source, fetchSource])\n\n  return { source, cardRef, handleUnlockClick }\n}\n","import { DownloadSimpleIcon, LockSimpleIcon } from '@phosphor-icons/react'\nimport React from 'react'\n\nimport LoadingDots from '../_shared/LoadingDots'\n\nexport interface ReceivedCardActionsProps {\n  /** Whether the card is currently locked. Drives which CTA we render. */\n  isLocked: boolean\n  /**\n   * When unlocked, the URL used as the Download link's `href` (opens in a new\n   * tab). When omitted, the Download CTA falls back to a plain `<button>`\n   * that just calls `onDownloadClicked` — useful for galleries where the\n   * single-source URL doesn't exist.\n   */\n  sourceUrl?: string\n  /** Optional alternate href that takes precedence over `sourceUrl`. */\n  redeemUrl?: string\n  onUnlockClicked?: () => void\n  onDownloadClicked?: () => void\n  isUnlocking?: boolean\n}\n\nconst buttonClass =\n  'mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928]'\n\n/**\n * Renders the primary CTA below the body of a Received card.\n * - Locked + onUnlockClicked → \"Unlock\" button\n * - Unlocked + onDownloadClicked + (redeemUrl || sourceUrl) → \"Download\" link\n * - Unlocked + onDownloadClicked + no URL → \"Download\" button (e.g. gallery)\n * Otherwise renders nothing.\n */\nconst ReceivedCardActions: React.FC<ReceivedCardActionsProps> = ({\n  isLocked,\n  sourceUrl,\n  redeemUrl,\n  onUnlockClicked,\n  onDownloadClicked,\n  isUnlocking = false,\n}) => {\n  if (isLocked && onUnlockClicked != null) {\n    return (\n      <button\n        type=\"button\"\n        onClick={onUnlockClicked}\n        disabled={isUnlocking}\n        aria-label={isUnlocking ? 'Unlocking' : 'Unlock'}\n        aria-busy={isUnlocking}\n        title={isUnlocking ? 'Unlocking' : 'Unlock'}\n        className={buttonClass}\n      >\n        {isUnlocking ? (\n          <LoadingDots />\n        ) : (\n          <React.Fragment>\n            <LockSimpleIcon className=\"size-4\" weight=\"fill\" />\n            Unlock\n          </React.Fragment>\n        )}\n      </button>\n    )\n  }\n\n  if (!isLocked && onDownloadClicked != null) {\n    const href = redeemUrl ?? sourceUrl\n    if (href != null) {\n      return (\n        <a\n          href={href}\n          aria-label=\"Download\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n          onClick={onDownloadClicked}\n          className={`${buttonClass} !text-white`}\n        >\n          <DownloadSimpleIcon className=\"size-4\" weight=\"bold\" />\n          Download\n        </a>\n      )\n    }\n\n    return (\n      <button\n        type=\"button\"\n        onClick={onDownloadClicked}\n        aria-label=\"Download\"\n        className={buttonClass}\n      >\n        <DownloadSimpleIcon className=\"size-4\" weight=\"bold\" />\n        Download\n      </button>\n    )\n  }\n\n  return null\n}\n\nexport default ReceivedCardActions\n","import { PencilSimpleIcon, XIcon } from '@phosphor-icons/react'\nimport React from 'react'\n\nimport { getSourceType } from '../../../../AttachmentCard'\nimport CardBody from '../_shared/CardBody'\nimport CardThumbnail, {\n  galleryBodyIcon,\n  isGalleryCard,\n} from '../_shared/CardThumbnail'\nimport MediaShell from '../_shared/MediaShell'\nimport PreviewToggle from '../_shared/PreviewToggle'\nimport PurchaseStatusBadge from '../_shared/PurchaseStatusBadge'\nimport { usePreviewToggle } from '../_shared/usePreviewToggle'\nimport { useReceivedSource } from '../_shared/useReceivedSource'\n\nimport ReceivedCardActions from './CardActions'\nimport type {\n  MediaCardDraftProps,\n  MediaCardOtherProps,\n  MediaCardOwnProps,\n  MediaCardPreviewProps,\n  MediaCardProps,\n} from './types'\n\nexport type { MediaCardProps } from './types'\n\n/**\n * Media card while still drafting — the locked thumbnail (single or gallery)\n * the composer taps to preview the attachment they're about to send, plus\n * the title/price body with optional dismiss X and edit pencil.\n */\nconst DraftMediaCard: React.FC<MediaCardDraftProps> = ({\n  title,\n  mimeType = 'application/octet-stream',\n  thumbnailUrl,\n  detail,\n  amountText,\n  placeholderTitle,\n  placeholderAmountText,\n  gallery = [],\n  onDismiss,\n  onPreviewClick,\n  onFetchSource,\n  onEditClick,\n}) => {\n  const isGallery = isGalleryCard(gallery)\n\n  // Gallery is always previewable in the composer because each item's source\n  // is already provided up-front via `gallery[*].sourceUrl`.\n  const { source, isPreviewVisible, isLoadingPreview, togglePreview } =\n    usePreviewToggle({ isGallery, onFetchSource, onPreviewClick })\n\n  const showLocked = !isPreviewVisible\n  const isBusy = isLoadingPreview\n\n  const statusBadge = (\n    <React.Fragment>\n      <span className=\"text-xs font-medium text-white/55\">&bull;</span>\n      <span\n        className={\n          amountText\n            ? 'text-xs font-medium text-white/55'\n            : 'text-xs font-medium text-white/30'\n        }\n      >\n        {amountText || placeholderAmountText}\n      </span>\n    </React.Fragment>\n  )\n\n  const dismissButton = onDismiss ? (\n    <button\n      type=\"button\"\n      onClick={(e) => {\n        // Stop the click from bubbling up into the outer preview-toggle\n        // wrapper when both are wired up at the same time.\n        e.stopPropagation()\n        onDismiss()\n      }}\n      className=\"flex size-6 items-center justify-center rounded-full bg-[#121110] text-white\"\n      aria-label=\"Dismiss attachment\"\n    >\n      <XIcon className=\"size-3\" weight=\"bold\" />\n    </button>\n  ) : undefined\n\n  const editButton = onEditClick ? (\n    <button\n      type=\"button\"\n      onClick={onEditClick}\n      aria-label=\"Edit attachment\"\n      className=\"flex size-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/15\"\n    >\n      <PencilSimpleIcon className=\"size-5\" weight=\"regular\" />\n    </button>\n  ) : undefined\n\n  return (\n    <MediaShell variant=\"dark\">\n      <PreviewToggle\n        onToggle={togglePreview}\n        isBusy={isBusy}\n        isPreviewVisible={!showLocked}\n      >\n        <CardThumbnail\n          variant=\"dark\"\n          gallery={gallery}\n          title={title}\n          showLocked={showLocked}\n          mimeType={mimeType}\n          thumbnailUrl={thumbnailUrl}\n          source={source}\n          topRight={dismissButton}\n        />\n      </PreviewToggle>\n\n      <CardBody\n        variant=\"dark\"\n        title={title}\n        placeholderTitle={placeholderTitle}\n        mimeType={mimeType}\n        detail={detail}\n        statusBadge={statusBadge}\n        icon={isGallery ? galleryBodyIcon('dark') : undefined}\n        trailingAction={editButton}\n      />\n    </MediaShell>\n  )\n}\n\n/**\n * Static mockup of what the recipient will see before purchase — always\n * locked/blurred (the lock badge renders from `showLocked` alone, no toggle\n * wiring needed), no interactivity, no real content revealed.\n */\nconst PreviewMediaCard: React.FC<MediaCardPreviewProps> = ({\n  title,\n  mimeType = 'application/octet-stream',\n  thumbnailUrl,\n  detail,\n  amountText,\n  placeholderTitle,\n  placeholderAmountText,\n  gallery = [],\n}) => {\n  const isGallery = isGalleryCard(gallery)\n\n  const statusBadge = (\n    <React.Fragment>\n      <span className=\"text-xs font-medium text-black/55\">&bull;</span>\n      <span\n        className={\n          amountText\n            ? 'text-xs font-medium text-black/55'\n            : 'text-xs font-medium text-black/30'\n        }\n      >\n        {amountText || placeholderAmountText}\n      </span>\n    </React.Fragment>\n  )\n\n  return (\n    <MediaShell variant=\"light\">\n      <CardThumbnail\n        variant=\"light\"\n        gallery={gallery}\n        title={title}\n        showLocked\n        mimeType={mimeType}\n        thumbnailUrl={thumbnailUrl}\n      />\n\n      <CardBody\n        variant=\"light\"\n        title={title}\n        placeholderTitle={placeholderTitle}\n        mimeType={mimeType}\n        detail={detail}\n        statusBadge={statusBadge}\n        icon={isGallery ? galleryBodyIcon('light') : undefined}\n      />\n    </MediaShell>\n  )\n}\n/**\n * The sender's ('mine') view of a paid media attachment: the locked\n * thumbnail (single or gallery) they can tap to preview their own\n * attachment, plus the title/purchase-status body.\n */\nconst OwnMediaCard: React.FC<MediaCardOwnProps> = ({\n  title,\n  mimeType = 'application/octet-stream',\n  thumbnailUrl,\n  detail,\n  amountText,\n  placeholderTitle,\n  paymentStatus = 'pending',\n  gallery = [],\n  onPreviewClick,\n  onFetchSource,\n}) => {\n  const isGallery = isGalleryCard(gallery)\n\n  // Gallery is always previewable for the sender because each item's source\n  // is already provided up-front via `gallery[*].sourceUrl`.\n  const { source, isPreviewVisible, isLoadingPreview, togglePreview } =\n    usePreviewToggle({ isGallery, onFetchSource, onPreviewClick })\n\n  const showLocked = !isPreviewVisible\n  const isBusy = isLoadingPreview\n\n  return (\n    <MediaShell variant=\"dark\">\n      <PreviewToggle\n        onToggle={togglePreview}\n        isBusy={isBusy}\n        isPreviewVisible={!showLocked}\n      >\n        <CardThumbnail\n          variant=\"dark\"\n          gallery={gallery}\n          title={title}\n          showLocked={showLocked}\n          paymentStatus={paymentStatus}\n          mimeType={mimeType}\n          thumbnailUrl={thumbnailUrl}\n          source={source}\n        />\n      </PreviewToggle>\n\n      <CardBody\n        variant=\"dark\"\n        title={title}\n        placeholderTitle={placeholderTitle}\n        mimeType={mimeType}\n        detail={detail}\n        statusBadge={\n          <PurchaseStatusBadge\n            isMine={true}\n            paymentStatus={paymentStatus}\n            amountText={amountText}\n          />\n        }\n        icon={isGallery ? galleryBodyIcon('dark') : undefined}\n      />\n    </MediaShell>\n  )\n}\n\n/**\n * The recipient's ('other') view of a paid media attachment: the locked\n * thumbnail (single or gallery) with an Unlock/Download CTA. The source is\n * revealed by fetching once — on click when already paid, or automatically\n * the first time a paid card scrolls into view.\n */\nconst OtherMediaCard: React.FC<MediaCardOtherProps> = ({\n  title,\n  amountText,\n  thumbnailUrl,\n  mimeType = 'application/octet-stream',\n  detail,\n  gallery = [],\n  onUnlockClick,\n  onFetchSource,\n  onDownloadClick,\n  paymentStatus,\n  isUnlocking = false,\n}) => {\n  const isGallery = isGalleryCard(gallery)\n\n  const { source, cardRef, handleUnlockClick } = useReceivedSource({\n    paymentStatus,\n    onFetchSource,\n    onUnlockClick,\n  })\n\n  const effectiveSourceUrl = source?.sourceUrl\n  const effectiveRedeemUrl = source?.redeemUrl\n\n  // For gallery, the per-item sources are carried by `gallery` itself, so\n  // the lock state is driven by paymentStatus rather than the single\n  // `effectiveSourceUrl`. Everything else still respects the source fetch.\n  const isLocked = isGallery\n    ? paymentStatus !== 'paid'\n    : effectiveSourceUrl === undefined\n  const sourceType = getSourceType(mimeType)\n\n  // For gallery, ReceivedCardActions falls back to a plain <button>\n  // (no anchor) because the gallery has no single sourceUrl to link to —\n  // the per-item sources live on `gallery` itself.\n  const actionSourceUrl = isGallery ? undefined : effectiveSourceUrl\n\n  return (\n    <MediaShell\n      variant=\"light\"\n      rootRef={cardRef}\n      data-testid=\"locked-attachment\"\n    >\n      <CardThumbnail\n        variant=\"light\"\n        gallery={gallery}\n        title={title}\n        showLocked={isLocked}\n        paymentStatus={paymentStatus}\n        mimeType={mimeType}\n        thumbnailUrl={thumbnailUrl}\n        source={source}\n        containedImage={!isLocked && sourceType === 'document'}\n      />\n\n      <CardBody\n        variant=\"light\"\n        title={title}\n        mimeType={mimeType}\n        detail={detail}\n        statusBadge={\n          <PurchaseStatusBadge\n            isMine={false}\n            paymentStatus={paymentStatus}\n            amountText={amountText}\n          />\n        }\n        icon={isGallery ? galleryBodyIcon('light') : undefined}\n        action={\n          <ReceivedCardActions\n            isLocked={isLocked}\n            isUnlocking={isUnlocking}\n            sourceUrl={actionSourceUrl}\n            redeemUrl={effectiveRedeemUrl}\n            onUnlockClicked={handleUnlockClick}\n            onDownloadClicked={onDownloadClick}\n          />\n        }\n      />\n    </MediaShell>\n  )\n}\n\n/**\n * The card either party sees for a paid media attachment. `isDraft`/`isPreview`\n * select the composer's own drafting view / a static receiver-side mockup;\n * otherwise `isMine` selects the sender's sent view vs. the recipient's\n * unlock/download view.\n */\nconst MediaCard: React.FC<MediaCardProps> = (props) => {\n  if (props.isDraft) {\n    return <DraftMediaCard {...props} />\n  } else if (props.isPreview) {\n    return <PreviewMediaCard {...props} />\n  } else if (props.isMine) {\n    return <OwnMediaCard {...props} />\n  } else {\n    return <OtherMediaCard {...props} />\n  }\n}\n\nexport default MediaCard\n"],"mappings":"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"}