import { useCallback, useState } from 'react' /** * Optional click handler used by every viewer-backed attachment. * * Return `false` to cancel the default open behavior — useful for * route-based viewers or confirmation modals. Any other return value * (including `void`/`undefined`) lets the built-in viewer open as * normal. The `index` argument identifies the row in stacked * attachments and is `0` for the single-attachment shape. */ export type ViewerClickHandler = (index: number) => boolean | void export interface UseViewerResult { viewerOpen: boolean viewerIndex: number /** * Open the viewer at the given index. Forwards to the caller's * `onClick` first so analytics + intercept logic can fire before * the viewer mounts; if `onClick` returns `false` the open is * skipped entirely. */ handleActivate: (index: number) => void closeViewer: () => void } /** * Tiny piece of state shared by every `MessageAttachment` that opens * a fullscreen viewer (`Image`, `Video`, `Pdf`). Tracks the open flag * + the active index, and threads the caller's `onClick` callback * through `handleActivate` so consumers can intercept the open * (e.g. analytics) or cancel it (return `false` to swap in a * route-based viewer / confirmation modal). */ export const useViewer = (onClick?: ViewerClickHandler): UseViewerResult => { const [viewerOpen, setViewerOpen] = useState(false) const [viewerIndex, setViewerIndex] = useState(0) const handleActivate = useCallback( (index: number) => { if (onClick?.(index) === false) return setViewerIndex(index) setViewerOpen(true) }, [onClick] ) const closeViewer = useCallback(() => setViewerOpen(false), []) return { viewerOpen, viewerIndex, handleActivate, closeViewer } }