Provides a React hook that enables click-to-expand image gallery functionality for chat attachment images within a chat thread panel. ## Key Components ### `useChatAttachmentImageGallery()` Primary export. Returns `{ panelRef, modal }`: - **`panelRef`** — `RefObject` to attach to the chat content wrapper; installs a delegated `click` listener - **`modal`** — JSX element (`ImageGalleryModal`) rendered when open, or `null` when closed (enabling React garbage collection of blob URLs) ### `GalleryState` (interface) Internal state shape: `{ isOpen: boolean, images: string[], initialIndex: number }` ### `absolutize(prefix: string)` (internal) Normalizes relative URL prefixes (e.g. `/api/storage/view/`) to absolute URLs for reliable comparison against browser-resolved `.src` values. ## Usage Example ```typescript // In a chat panel host component export function ChatPanel() { const { panelRef, modal } = useChatAttachmentImageGallery() return ( <> {/* panelRef wraps the scrollable message list */}
{/* ...message bubbles rendered here... */}
{/* modal renders outside overflow-hidden bubbles */} {modal} ) } ``` ## Click Delegation Flow ```mermaid graph TD Click["Click Event"] --> ImgCheck{"img src starts\nwith viewUrlPrefix?"} ImgCheck -->|No| Ignore["Ignore click"] ImgCheck -->|Yes| BubbleWalk["Walk up to\n[data-message-role]"] BubbleWalk --> NoBubble{"Bubble found?"} NoBubble -->|No| SingleImg["Open modal with\nsingle image"] NoBubble -->|Yes| Collect["Collect all matching\nimgs in bubble (DOM order)"] Collect --> OpenModal["Open ImageGalleryModal\nwith computed initialIndex"] ``` > **Note:** The hook filters `` elements by `attachmentViewUrlPrefix` from the chat runtime context, ensuring avatar and UI images are never intercepted.